Page MenuHomePhabricator (Chris)

No OneTemporary

Size
4 MB
Referenced Files
None
Subscribers
None
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/mongodb-1.7.4/CREDITS b/mongodb-1.7.4/CREDITS
deleted file mode 100644
index 793f2491..00000000
--- a/mongodb-1.7.4/CREDITS
+++ /dev/null
@@ -1,2 +0,0 @@
-MongoDB Driver for PHP
-Hannes Magnusson, Jeremy Mikola, Derick Rethans, Katherine Walker
diff --git a/mongodb-1.7.4/phongo_compat.h b/mongodb-1.7.4/phongo_compat.h
deleted file mode 100644
index 78e7adab..00000000
--- a/mongodb-1.7.4/phongo_compat.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2015-2017 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.
- */
-
-#ifndef PHONGO_COMPAT_H
-#define PHONGO_COMPAT_H
-
-#include <php.h>
-#include <Zend/zend_string.h>
-#if PHP_VERSION_ID >= 70000
-#include <Zend/zend_portability.h>
-#endif
-
-#ifdef PHP_WIN32
-#include "config.w32.h"
-#else
-#include <php_config.h>
-#endif
-
-#ifndef PHP_FE_END
-#define PHP_FE_END \
- { \
- NULL, NULL, NULL \
- }
-#endif
-
-#ifndef HASH_KEY_NON_EXISTENT
-#define HASH_KEY_NON_EXISTENT HASH_KEY_NON_EXISTANT
-#endif
-
-#if PHP_VERSION_ID >= 70000
-#define str_efree(s) efree((char*) s)
-#else
-#include <Zend/zend_string.h>
-#endif
-
-#if defined(__GNUC__)
-#define ARG_UNUSED __attribute__((unused))
-#else
-#define ARG_UNUSED
-#endif
-
-#if defined(__GNUC__)
-#define PHONGO_GNUC_CHECK_VERSION(major, minor) \
- ((__GNUC__ > (major)) || \
- ((__GNUC__ == (major)) && (__GNUC_MINOR__ >= (minor))))
-#else
-#define PHONGO_GNUC_CHECK_VERSION(major, minor) 0
-#endif
-
-#if PHONGO_GNUC_CHECK_VERSION(7, 0)
-#define PHONGO_BREAK_INTENTIONALLY_MISSING __attribute__((fallthrough));
-#else
-#define PHONGO_BREAK_INTENTIONALLY_MISSING
-#endif
-
-#if PHP_VERSION_ID >= 70000
-#define phongo_char zend_string
-#define phongo_long zend_long
-#if SIZEOF_ZEND_LONG == 8
-#define PHONGO_LONG_FORMAT PRId64
-#elif SIZEOF_ZEND_LONG == 4
-#define PHONGO_LONG_FORMAT PRId32
-#else
-#error Unsupported architecture (integers are neither 32-bit nor 64-bit)
-#endif
-#define SIZEOF_PHONGO_LONG SIZEOF_ZEND_LONG
-#define phongo_create_object_retval zend_object*
-#define phongo_get_gc_table zval**
-#define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t*) ecalloc(1, sizeof(_obj_t) + zend_object_properties_size(_class_type))
-#define PHONGO_TSRMLS_FETCH_FROM_CTX(user_data)
-#define DECLARE_RETURN_VALUE_USED int return_value_used = 1;
-#define EXCEPTION_P(_ex, _zp) ZVAL_OBJ(&_zp, _ex)
-#define ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRL(_key), (char*) (_value));
-#define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRL(_key), (char*) (_value), _len);
-#define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len, (char*) (_value), _value_len);
-#define ADD_ASSOC_LONG_EX(_zv, _key, _value) add_assoc_long_ex(_zv, ZEND_STRL(_key), _value);
-#define ADD_ASSOC_ZVAL_EX(_zv, _key, _value) add_assoc_zval_ex(_zv, ZEND_STRL(_key), _value);
-#define ADD_ASSOC_ZVAL(_zv, _key, _value) add_assoc_zval(_zv, _key, _value);
-#define ADD_ASSOC_NULL_EX(_zv, _key) add_assoc_null_ex(_zv, ZEND_STRL(_key));
-#define ADD_ASSOC_BOOL_EX(_zv, _key, _value) add_assoc_bool_ex(_zv, ZEND_STRL(_key), _value);
-#define ZVAL_INT64_STRING(_zv, _value) \
- do { \
- char tmp[24]; \
- int tmp_len; \
- tmp_len = snprintf(tmp, sizeof(tmp), "%" PRId64, (_value)); \
- ZVAL_STRINGL((_zv), tmp, tmp_len); \
- } while (0)
-#define ADD_ASSOC_INT64_AS_STRING(_zv, _key, _value) \
- do { \
- zval z_int; \
- ZVAL_INT64_STRING(&z_int, (_value)); \
- ADD_ASSOC_ZVAL_EX((_zv), (_key), &z_int); \
- } while (0)
-#define ADD_NEXT_INDEX_STRINGL(_zv, _value, _len) add_next_index_stringl(_zv, _value, _len);
-#define phongo_free_object_arg zend_object
-#define phongo_zpp_char_len size_t
-#define ZEND_HASH_APPLY_COUNT(ht) (ht)->u.v.nApplyCount
-#define PHONGO_RETVAL_STRINGL(s, slen) RETVAL_STRINGL(s, slen)
-#define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen)
-#define PHONGO_RETVAL_STRING(s) RETVAL_STRING(s)
-#define PHONGO_RETURN_STRING(s) RETURN_STRING(s)
-#define PHONGO_RETVAL_SMART_STR(val) PHONGO_RETVAL_STRINGL(ZSTR_VAL((val).s), ZSTR_LEN((val).s));
-#define ZVAL_RETVAL_TYPE zval
-#define ZVAL_STATIC_INIT \
- { \
- { \
- 0 \
- } \
- }
-#else /* PHP_VERSION_ID < 70000 */
-#define phongo_char char
-#define phongo_long long
-#define PHONGO_LONG_FORMAT "ld"
-#define SIZEOF_PHONGO_LONG SIZEOF_LONG
-#define ZSTR_VAL(str) str
-#define phongo_create_object_retval zend_object_value
-#define phongo_get_gc_table zval***
-#define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t*) ecalloc(1, sizeof(_obj_t))
-#define PHONGO_TSRMLS_FETCH_FROM_CTX(user_data) TSRMLS_FETCH_FROM_CTX(user_data)
-#define DECLARE_RETURN_VALUE_USED
-#define EXCEPTION_P(_ex, _zp) _zp = _ex
-#define ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRS(_key), (char*) (_value), 1);
-#define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRS(_key), (char*) (_value), _len, 1);
-#define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len + 1, (char*) (_value), _value_len, 1);
-#define ADD_ASSOC_LONG_EX(_zv, _key, _value) add_assoc_long_ex(_zv, ZEND_STRS(_key), _value);
-#define ADD_ASSOC_ZVAL_EX(_zv, _key, _value) add_assoc_zval_ex(_zv, ZEND_STRS(_key), _value);
-#define ADD_ASSOC_ZVAL(_zv, _key, _value) add_assoc_zval(_zv, _key, _value);
-#define ADD_ASSOC_NULL_EX(_zv, _key) add_assoc_null_ex(_zv, ZEND_STRS(_key));
-#define ADD_ASSOC_BOOL_EX(_zv, _key, _value) add_assoc_bool_ex(_zv, ZEND_STRS(_key), _value);
-#define ZVAL_INT64_STRING(_zv, _value) \
- do { \
- char tmp[24]; \
- int tmp_len; \
- tmp_len = snprintf(tmp, sizeof(tmp), "%" PRId64, (_value)); \
- ZVAL_STRINGL((_zv), tmp, tmp_len, 1); \
- } while (0)
-
-#define ADD_ASSOC_INT64_AS_STRING(_zv, _key, _value) \
- do { \
- zval* z_int; \
- MAKE_STD_ZVAL(z_int); \
- ZVAL_INT64_STRING(z_int, (_value)); \
- ADD_ASSOC_ZVAL_EX((_zv), (_key), z_int); \
- } while (0)
-#define ADD_NEXT_INDEX_STRINGL(_zv, _value, _len) add_next_index_stringl(_zv, _value, _len, 1);
-#define Z_PHPDATE_P(object) ((php_date_obj*) zend_object_store_get_object(object TSRMLS_CC))
-#define Z_ISUNDEF(x) !x
-#define ZVAL_UNDEF(x) \
- do { \
- (*x) = NULL; \
- } while (0)
-#define ZVAL_ARR(z, a) \
- do { \
- HashTable* __arr = (a); \
- zval* __z = (z); \
- Z_ARRVAL_P(__z) = __arr; \
- Z_TYPE_P(__z) = IS_ARRAY; \
- } while (0);
-#define ZVAL_DUP(z, v) \
- do { \
- zval* _z = (z); \
- const zval* _v = (v); \
- *_z = *_v; \
- INIT_PZVAL(_z); \
- zval_copy_ctor(_z); \
- } while (0);
-#define phongo_free_object_arg void
-#define phongo_zpp_char_len int
-#define ZEND_HASH_APPLY_PROTECTION(ht) 1
-#define ZEND_HASH_GET_APPLY_COUNT(ht) ((ht)->nApplyCount)
-#define ZEND_HASH_DEC_APPLY_COUNT(ht) ((ht)->nApplyCount -= 1)
-#define ZEND_HASH_INC_APPLY_COUNT(ht) ((ht)->nApplyCount += 1)
-#define PHONGO_RETVAL_STRINGL(s, slen) RETVAL_STRINGL(s, slen, 1)
-#define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen, 1)
-#define PHONGO_RETVAL_STRING(s) RETVAL_STRING(s, 1)
-#define PHONGO_RETURN_STRING(s) RETURN_STRING(s, 1)
-#define PHONGO_RETVAL_SMART_STR(val) PHONGO_RETVAL_STRINGL((val).c, (val).len);
-#define ZVAL_RETVAL_TYPE zval*
-#define ZVAL_STATIC_INIT zval_used_for_init
-#endif
-
-#if SIZEOF_PHONGO_LONG == 8
-#define ADD_INDEX_INT64(_zv, _index, _value) add_index_long((_zv), (_index), (_value))
-#define ADD_NEXT_INDEX_INT64(_zv, _value) add_next_index_long((_zv), (_value))
-#define ADD_ASSOC_INT64(_zv, _key, _value) add_assoc_long((_zv), (_key), (_value))
-#define ZVAL_INT64(_zv, _value) ZVAL_LONG((_zv), (_value))
-#elif SIZEOF_PHONGO_LONG == 4
-#if PHP_VERSION_ID >= 70000
-#define ADD_INDEX_INT64(_zv, _index, _value) \
- if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
- zval zchild; \
- php_phongo_bson_new_int64(&zchild, (_value) TSRMLS_CC); \
- add_index_zval((_zv), (_index), &zchild); \
- } else { \
- add_index_long((_zv), (_index), (_value)); \
- }
-#define ADD_NEXT_INDEX_INT64(_zv, _value) \
- if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
- zval zchild; \
- php_phongo_bson_new_int64(&zchild, (_value) TSRMLS_CC); \
- add_next_index_zval((_zv), &zchild); \
- } else { \
- add_next_index_long((_zv), (_value)); \
- }
-#define ADD_ASSOC_INT64(_zv, _key, _value) \
- if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
- zval zchild; \
- php_phongo_bson_new_int64(&zchild, (_value) TSRMLS_CC); \
- add_assoc_zval((_zv), (_key), &zchild); \
- } else { \
- add_assoc_long((_zv), (_key), (_value)); \
- }
-#else /* PHP_VERSION_ID < 70000 */
-#define ADD_INDEX_INT64(_zv, _index, _value) \
- if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
- zval* zchild = NULL; \
- TSRMLS_FETCH(); \
- MAKE_STD_ZVAL(zchild); \
- php_phongo_bson_new_int64(zchild, (_value) TSRMLS_CC); \
- add_index_zval((_zv), (_index), zchild); \
- } else { \
- add_index_long((_zv), (_index), (_value)); \
- }
-#define ADD_NEXT_INDEX_INT64(_zv, _value) \
- if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
- zval* zchild = NULL; \
- TSRMLS_FETCH(); \
- MAKE_STD_ZVAL(zchild); \
- php_phongo_bson_new_int64(zchild, (_value) TSRMLS_CC); \
- add_next_index_zval((_zv), zchild); \
- } else { \
- add_next_index_long((_zv), (_value)); \
- }
-#define ADD_ASSOC_INT64(_zv, _key, _value) \
- if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
- zval* zchild = NULL; \
- TSRMLS_FETCH(); \
- MAKE_STD_ZVAL(zchild); \
- php_phongo_bson_new_int64(zchild, (_value) TSRMLS_CC); \
- add_assoc_zval((_zv), (_key), zchild); \
- } else { \
- add_assoc_long((_zv), (_key), (_value)); \
- }
-#endif /* PHP_VERSION_ID */
-#define ZVAL_INT64(_zv, _value) \
- if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
- php_phongo_bson_new_int64((_zv), (_value) TSRMLS_CC); \
- } else { \
- ZVAL_LONG((_zv), (_value)); \
- }
-#else /* SIZEOF_PHONGO_LONG != 8 && SIZEOF_PHONGO_LONG != 4 */
-#error Unsupported architecture (integers are neither 32-bit nor 64-bit)
-#endif /* SIZEOF_PHONGO_LONG */
-
-void phongo_add_exception_prop(const char* prop, int prop_len, zval* value TSRMLS_DC);
-zend_bool php_phongo_zend_hash_apply_protection_begin(HashTable* ht);
-zend_bool php_phongo_zend_hash_apply_protection_end(HashTable* ht);
-
-#endif /* PHONGO_COMPAT_H */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
diff --git a/mongodb-1.7.4/src/LIBMONGOCRYPT_VERSION_CURRENT b/mongodb-1.7.4/src/LIBMONGOCRYPT_VERSION_CURRENT
deleted file mode 100644
index 21e8796a..00000000
--- a/mongodb-1.7.4/src/LIBMONGOCRYPT_VERSION_CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-1.0.3
diff --git a/mongodb-1.7.4/src/LIBMONGOC_VERSION_CURRENT b/mongodb-1.7.4/src/LIBMONGOC_VERSION_CURRENT
deleted file mode 100644
index 4a02d2c3..00000000
--- a/mongodb-1.7.4/src/LIBMONGOC_VERSION_CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-1.16.2
diff --git a/mongodb-1.7.4/src/libmongoc/src/common/common-b64-private.h b/mongodb-1.7.4/src/libmongoc/src/common/common-b64-private.h
deleted file mode 100644
index c6d77e67..00000000
--- a/mongodb-1.7.4/src/libmongoc/src/common/common-b64-private.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2018-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
- *
- * 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.
- */
-
-#include "common-prelude.h"
-
-#ifndef COMMON_B64_PRIVATE_H
-#define COMMON_B64_PRIVATE_H
-
-#include <bson/bson.h>
-
-int
-bson_b64_ntop (uint8_t const *src,
- size_t srclength,
- char *target,
- size_t targsize);
-
-int
-bson_b64_pton (char const *src, uint8_t *target, size_t targsize);
-
-#endif /* COMMON_B64_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h b/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
deleted file mode 100644
index 2a398074..00000000
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2013 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.
- */
-
-#include "mongoc-prelude.h"
-
-#include <bson/bson.h>
-#include <stddef.h>
-
-BSON_BEGIN_DECLS
-
-typedef enum {
- MONGOC_READ_ERR_NONE,
- MONGOC_READ_ERR_OTHER,
- MONGOC_READ_ERR_RETRY,
-} mongoc_read_err_type_t;
-
-mongoc_read_err_type_t
-_mongoc_read_error_get_type (bool cmd_ret,
- const bson_error_t *cmd_err,
- const bson_t *reply);
-
-BSON_END_DECLS
\ No newline at end of file
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c b/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c
deleted file mode 100644
index be84777b..00000000
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2018-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
- *
- * 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.
- */
-
-#include <bson/bson.h>
-
-#include "mongoc-error.h"
-#include "mongoc-error-private.h"
-#include "mongoc-rpc-private.h"
-
-bool
-mongoc_error_has_label (const bson_t *reply, const char *label)
-{
- bson_iter_t iter;
- bson_iter_t error_labels;
-
- BSON_ASSERT (reply);
- BSON_ASSERT (label);
-
- if (bson_iter_init_find (&iter, reply, "errorLabels") &&
- bson_iter_recurse (&iter, &error_labels)) {
- while (bson_iter_next (&error_labels)) {
- if (BSON_ITER_HOLDS_UTF8 (&error_labels) &&
- !strcmp (bson_iter_utf8 (&error_labels, NULL), label)) {
- return true;
- }
- }
- }
-
- return false;
-}
-
-
-/*--------------------------------------------------------------------------
- *
- * _mongoc_read_error_get_type --
- *
- * Checks if the error or reply from a read command is considered
- * retryable according to the retryable reads spec. Checks both
- * for a client error (a network exception) and a server error in
- * the reply. @cmd_ret and @cmd_err come from the result of a
- * read_command function.
- *
- *
- * Return:
- * A mongoc_read_error_type_t indicating the type of error (if any).
- *
- *--------------------------------------------------------------------------
- */
-mongoc_read_err_type_t
-_mongoc_read_error_get_type (bool cmd_ret,
- const bson_error_t *cmd_err,
- const bson_t *reply)
-{
- bson_error_t error;
-
- /* check for a client error. */
- if (!cmd_ret && cmd_err && cmd_err->domain == MONGOC_ERROR_STREAM) {
- /* Retryable reads spec: "considered retryable if [...] any network
- * exception (e.g. socket timeout or error) */
- return MONGOC_READ_ERR_RETRY;
- }
-
- /* check for a server error. */
- if (_mongoc_cmd_check_ok_no_wce (
- reply, MONGOC_ERROR_API_VERSION_2, &error)) {
- return MONGOC_READ_ERR_NONE;
- }
-
- switch (error.code) {
- case 11600: /* InterruptedAtShutdown */
- case 11602: /* InterruptedDueToReplStateChange */
- case 10107: /* NotMaster */
- case 13435: /* NotMasterNoSlaveOk */
- case 13436: /* NotMasterOrSecondary */
- case 189: /* PrimarySteppedDown */
- case 91: /* ShutdownInProgress */
- case 7: /* HostNotFound */
- case 6: /* HostUnreachable */
- case 89: /* NetworkTimeout */
- case 9001: /* SocketException */
- return MONGOC_READ_ERR_RETRY;
- default:
- if (strstr (error.message, "not master") ||
- strstr (error.message, "node is recovering")) {
- return MONGOC_READ_ERR_RETRY;
- }
- return MONGOC_READ_ERR_OTHER;
- }
-}
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-tls-error-001.phpt b/mongodb-1.7.4/tests/manager/manager-ctor-tls-error-001.phpt
deleted file mode 100644
index a64d9552..00000000
--- a/mongodb-1.7.4/tests/manager/manager-ctor-tls-error-001.phpt
+++ /dev/null
@@ -1,36 +0,0 @@
---TEST--
-MongoDB\Driver\Manager::__construct(): tlsInsecure cannot be combined with tlsAllowInvalidHostnames
---FILE--
-<?php
-
-require_once __DIR__ . '/../utils/tools.php';
-
-echo throws(function() {
- new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidHostnames=true');
-}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
-
-echo throws(function() {
- new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['tlsInsecure' => true, 'tlsAllowInvalidHostnames' => true]);
-}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
-
-echo throws(function() {
- new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsInsecure=true', ['tlsAllowInvalidHostnames' => true]);
-}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
-
-echo throws(function() {
- new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsAllowInvalidHostnames=true', ['tlsInsecure' => true]);
-}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
-
-?>
-===DONE===
-<?php exit(0); ?>
---EXPECT--
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidHostnames=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
-===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-tls-error-002.phpt b/mongodb-1.7.4/tests/manager/manager-ctor-tls-error-002.phpt
deleted file mode 100644
index a79b039b..00000000
--- a/mongodb-1.7.4/tests/manager/manager-ctor-tls-error-002.phpt
+++ /dev/null
@@ -1,36 +0,0 @@
---TEST--
-MongoDB\Driver\Manager::__construct(): tlsInsecure cannot be combined with tlsAllowInvalidCertificates
---FILE--
-<?php
-
-require_once __DIR__ . '/../utils/tools.php';
-
-echo throws(function() {
- new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidCertificates=true');
-}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
-
-echo throws(function() {
- new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['tlsInsecure' => true, 'tlsAllowInvalidCertificates' => true]);
-}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
-
-echo throws(function() {
- new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsInsecure=true', ['tlsAllowInvalidCertificates' => true]);
-}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
-
-echo throws(function() {
- new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsAllowInvalidCertificates=true', ['tlsInsecure' => true]);
-}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
-
-?>
-===DONE===
-<?php exit(0); ?>
---EXPECT--
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidCertificates=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
-===DONE===
diff --git a/mongodb-1.7.4/tests/session/session-startTransaction_error-003.phpt b/mongodb-1.7.4/tests/session/session-startTransaction_error-003.phpt
deleted file mode 100644
index d249225a..00000000
--- a/mongodb-1.7.4/tests/session/session-startTransaction_error-003.phpt
+++ /dev/null
@@ -1,34 +0,0 @@
---TEST--
-MongoDB\Driver\Session::startTransaction() with wrong argument for options array on PHP 5
---SKIPIF--
-<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
-<?php skip_if_not_libmongoc_crypto() ?>
-<?php skip_if_no_transactions(); ?>
-<?php skip_if_php_version('>=', '7.0.0'); ?>
---FILE--
-<?php
-require_once __DIR__ . "/../utils/basic.inc";
-
-$manager = new MongoDB\Driver\Manager(URI);
-$session = $manager->startSession();
-
-$options = [
- 2,
- new stdClass,
-];
-
-foreach ($options as $txnOptions) {
- echo raises(function () use ($session, $txnOptions) {
- $session->startTransaction($txnOptions);
- }, E_RECOVERABLE_ERROR), "\n";
-}
-
-?>
-===DONE===
-<?php exit(0); ?>
---EXPECTF--
-OK: Got E_RECOVERABLE_ERROR
-Argument 1 passed to MongoDB\Driver\Session::startTransaction() must be of the type array, int%S given, called in %S
-OK: Got E_RECOVERABLE_ERROR
-Argument 1 passed to MongoDB\Driver\Session::startTransaction() must be of the type array, object given, called in %S
-===DONE===
diff --git a/mongodb-1.8.1/CONTRIBUTING.md b/mongodb-1.8.1/CONTRIBUTING.md
new file mode 100644
index 00000000..cb19cc31
--- /dev/null
+++ b/mongodb-1.8.1/CONTRIBUTING.md
@@ -0,0 +1,524 @@
+# Contributing to the PHP Driver for MongoDB
+
+## Building from Source
+
+Developers who would like to contribute to the driver will need to build it from
+source. The repository may be initialized with:
+
+```
+$ git clone https://github.com/mongodb/mongo-php-driver.git
+$ cd mongo-php-driver
+$ git submodule update --init
+```
+
+The following script may be used to build the driver:
+
+```
+#!/bin/sh
+
+phpize > /dev/null && \
+./configure --enable-mongodb-developer-flags > /dev/null && \
+make clean > /dev/null && make all > /dev/null && make install
+```
+
+## Testing
+
+The extension's test use the PHPT format from PHP internals. This format is
+documented in the following links:
+
+ * [Introduction to PHPT Files](https://qa.php.net/write-test.php)
+ * [PHPT - Test File Layout](https://qa.php.net/phpt_details.php)
+
+Generally, most tests will be based on the following template:
+
+```
+--TEST--
+Description of API or JIRA issue being tested
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php /* One or more skip functions */ ?>
+--FILE--
+<?php
+require_once __DIR__ . "/../utils/basic.inc";
+
+// Test code
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+===DONE===
+```
+
+The `basic-skipif.inc` and `basic.inc` files contain utility functions for the
+`SKIPIF` and `FILE` sections, respectively. If those functions are not needed
+(e.g. skip logic only depends on checking the `PHP_INT_SIZE` constant), the test
+should not include the file. When it doubt, keep it simple.
+
+### Best Practices for `SKIPIF`
+
+The [`skipif.php`](tests/utils/skipif.php) file defines various helper functions
+for use within a test's [`SKIPIF`](https://qa.php.net/phpt_details.php#skipif_section)
+section. When multiple functions are used in a single `SKIPIF` section, they
+should be logically ordered:
+
+ * Any PHP environment requirements should be checked first. For example, if a
+ test requires a 64-bit architecture, start by checking `PHP_INT_SIZE` before
+ anything else.
+ * Any extension build requirements (e.g. `skip_if_not_libmongoc_crypto()`) or
+ test environment requirements (e.g. `skip_if_auth()`) should then be checked.
+ These functions only examine local information, such as `phpinfo()` output or
+ the structure of the `URI` constant, and do not interact with a remote
+ MongoDB server.
+ * Any remote server requirements should then be checked. A general integration
+ test that requires any type of remote server to be accessible might use
+ `skip_if_not_live()` while a test requiring a replica set would prefer
+ `skip_if_not_replica_set()`.
+ * After requiring a remote server to be accessible (optionally with a specific
+ type), you can enforce requirements about that server. This includes checking
+ its server version, storage engine, availability of test commands, etc.
+ * Finally, use `skip_if_not_clean()` if needed to ensure that the collection(s)
+ under test are dropped before the test runs.
+
+As a rule of thumb, your `SKIPIF` logic should be written to allow the test to
+run in as many environments as possible. To paraphrase the
+[robustness principal](https://en.wikipedia.org/wiki/Robustness_principle):
+
+> Be conservative in what/how you test, and liberal in what environment you require
+
+Consider that a well-crafted `EXPECTF` section may allow a `SKIPIF` section to
+be less restrictive.
+
+### Local Mongo Orchestration (and Travis CI)
+
+The test suite depends on [Mongo Orchestration](https://github.com/10gen/mongo-orchestration).
+Mongo Orchestration is an HTTP server that provides a REST API for maintaining
+MongoDB configurations. These configurations are located in ``scripts/presets``
+and for Travis CI in ``scripts/presets/travis``. The presets for Travis CI can
+also be spun-up locally, and that is the preferred testing method. An older way
+using a specific VM is also still available (see further down).
+
+Mongo Orchestration expects that the ``mongod`` (and ``mongos``) binaries are
+available in the ``PATH``.
+
+Once installed, Mongo Orchestration can be started with
+
+```
+~/.local/bin/mongo-orchestration start --no-fork --enable-majority-read-concern
+```
+
+The Travis CI setup uses
+[deployments](https://github.com/mongodb/mongo-php-driver/blob/master/.travis.scripts/setup_mo.sh)
+to test different topologies. Currently, it supports ``STANDALONE``,
+``STANDALONE_OLD`` (for MongoDB versions before 3.6), ``STANDALONE_SSL``,
+``REPLICASET`` and ``SHARDED_CLUSTER``.
+
+The test suite uses the ``MONGODB_URI`` environment variable as connection
+string to run all tests. In order to make the URI available to the test suite,
+you can run the following for a "deployment" in the *root* of the MongoDB
+Driver GIT checkout:
+
+```
+export TRAVIS_BUILD_DIR=`pwd`
+DEPLOYMENT=STANDALONE_AUTH .travis.scripts/setup_mo.sh
+export MONGODB_URI=`cat /tmp/uri.txt`
+```
+
+With this set-up, the tests can be run with `make test`.
+
+### VM-based Mongo Orchestration (legacy set-up)
+
+Alternative to the Travis CI set-up, our test suite also includes scripts to configure test environments
+with [Vagrant](https://www.vagrantup.com/) and
+[Mongo Orchestration](https://github.com/10gen/mongo-orchestration).
+The deployments started in this Vagrant image have hard coded URLs to be used
+with the ``MONGODB_URI`` environment variable:
+
+Deployment | URI
+--------------------------- | ---
+Standalone (MongoDB 4.0) | `mongodb://192.168.112.10:2000`
+Standalone (MongoDB 3.0) | `mongodb://192.168.112.10:2700`
+Standalone with SSL | `mongodb://192.168.112.10:2100`
+Standalone with Auth | `mongodb://root:toor@192.168.112.10:2200/?authSource=admin`
+Standalone with X509 Auth | `mongodb://C=US,ST=New York,L=New York City,O=MongoDB,OU=KernelUser,CN=client@192.168.112.10:2300/?authSource=$external&authMechanism=MONGODB-X509`
+Standalone with Plain Auth | `mongodb://root:toor@192.168.112.10:2400/?authSource=admin`
+Replicaset (MongoDB 4.0) | `mongodb://192.168.112.10:3000,192.168.112.10:3001,192.168.112.10:3002/?replicaSet=REPLICASET`
+Replicaset (MongoDB 3.0) | `mongodb://192.168.112.10:3100,192.168.112.10:3101,192.168.112.10:3102/?replicaSet=REPLICASET_30`
+Replicaset (MongoDB 3.6) | `mongodb://192.168.112.10:3200,192.168.112.10:3201,192.168.112.10:3202/?replicaSet=REPLICASET_36`
+
+The Vagrant images can be started by using:
+
+```
+$ make vm # Starts the test VMs with Vagrant
+$ make test-bootstrap # Starts the mongod servers within the test VM
+```
+
+After this set-up is completed, you need to export the `MONGODB_URI`
+environment variables with one of the values from the table above. The `test`
+make target may be used to execute the test suite:
+
+```
+$ make test # Executes the test suite against the VMs
+```
+
+To find out which VM servers are running at a later point in time, you can run
+`make test-bootstrap` to obtain a list of deployments and their URIs.
+
+#### Restarting Mongo Orchestration
+
+If something goes awry in the test VM, you can reload it by running:
+
+```
+make test-bootstrap
+```
+
+## Updating libmongoc, libbson, and libmongocrypt
+
+The PHP driver can use either system libraries or bundled versions of
+libmongoc, libbson, and libmongocrypt. If a new version of either library is
+available, the submodule and build configuration will need to be updated to
+reflect the new sources and/or package version.
+
+### Updating libmongoc and libbson
+
+#### Update libmongoc to the latest version
+
+```
+$ cd src/libmongoc
+$ git fetch
+$ git checkout 1.15.0
+```
+
+#### Ensure libmongoc version information is correct
+
+The build process for Autotools and Windows rely on
+`src/LIBMONGOC_VERSION_CURRENT` to infer version information for libmongoc and
+libbson. This file can be regenerated using the following Makefile target:
+
+```
+$ make libmongoc-version-current
+```
+
+Alternatively, the `build/calc_release_version.py` script in libmongoc can be
+executed directly.
+
+#### Update sources in build configurations
+
+The Autotools and Windows build configurations (`config.m4` and `config.w32`,
+respectively) define several variables (e.g. `PHP_MONGODB_MONGOC_SOURCES`) that
+collectively enumerate all of the the sources within the libmongoc submodule to
+include in a bundled build.
+
+These variables should each have a shell command in a preceding comment, which
+should be run to regenerate that particular list of source files. In the event
+that either libmongoc or libbson introduce a new source directory, that will
+need to be manually added (follow prior art).
+
+#### Update package dependencies
+
+The Autotools configuration additionally includes some `pkg-config` commands for
+using libmongoc and libbson as system libraries (in lieu of a bundled build).
+When bumping the libmongoc version, be sure to update the version check _and_
+error message in the `pkg-config` blocks for both libmongoc and libbson.
+
+For example, the following lines might be updated for libmongoc:
+
+```
+if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.15.0; then
+
+...
+
+AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.15.0)
+```
+
+#### Update tested versions in evergreen configuration
+
+Evergreen tests against multiple versions of libmongoc. When updating to a newer
+libmongoc version, make sure to update the `libmongoc-version` build axis in
+`.evergreen/config.yml`. In general, we test against two additional versions of
+libmongoc:
+- The upcoming patch release of the current libmongoc minor version (e.g. the
+ `r1.x` branch)
+- The upcoming minor release of libmongoc (e.g. the `master` branch)
+
+#### Update sources in PECL package generation script
+
+If either libmongoc or libbson introduce a new source directory, that may also
+require updating the glob patterns in the `bin/prep-release.php` script to
+ensure new source files will be included in any generated PECL package.
+
+#### Test and commit your changes
+
+Verify that the upgrade was successful by ensuring that the driver can compile
+using both the bundled sources and system libraries for libmongoc and libbson,
+and by ensuring that the test suite passes. Once done, commit the changes to all
+of the above files/paths. For example:
+
+```
+$ git commit -m "Bump libmongoc to 1.15.0" config.m4 config.w32 src/libmongoc src/LIBMONGOC_VERSION_CURRENT
+```
+
+### Updating libmongocrypt
+
+To update libmongocrypt, the steps are similar to the above:
+
+```
+$ cd src/libmongocrypt
+$ git fetch
+$ git checkout 1.0.1
+$ make libmongocrypt-version-current
+```
+
+Package dependencies in `config.m4` must also be updated, as do the sources in
+the PECL generation script.
+
+## Releasing
+
+The follow steps outline the release process for a maintenance branch (e.g.
+releasing the `vX.Y` branch as X.Y.Z).
+
+### Ensure PHP version compatibility
+
+Ensure that the extension compiles on PHP 5.6 through the latest PHP 7.x
+release. Be sure to test both ZTS and non-ZTS builds for PHP 5.x.
+
+### Ensure Windows compatibility
+
+PECL will create Windows DLLs for new releases; however, you must ensure that
+the extension successfully builds on Windows before releasing. Note that PHP 5.6
+requires VS2012, while PHP 7.x requires VS2015.
+
+Given the following assumptions:
+
+ * Build directory is `C:\php-sdk\`
+ * Compiling for PHP 5.6 (VS2012 x86 Native Tools Command Prompt is running)
+ * Extension branch checked out in `C:\php-sdk\phpdev\vc11\x86\pecl\mongodb`
+
+The build process will resemble:
+
+```
+cd c:\php-sdk\
+bin\phpsdk_setvars.bat
+
+cd C:\php-sdk\phpdev\vc11\x86\php-5.6.12-src
+nmake clean
+buildconf --force
+configure --disable-all --with-openssl --enable-cli --enable-json --enable-mongodb=shared --with-mongodb-sasl=yes --with-mongodb-client-side-encryption=yes
+nmake
+```
+
+If the extension was successfully compiled, a `php_mongodb.dll` file should be
+generated in the build directory (e.g. `Release_TS`). You should then verify
+that the extension loads and executes properly:
+
+```
+cd Release_TS
+php.exe -d extension=./php_mongodb.dll -m
+php.exe -d extension=./php_mongodb.dll -r "var_dump(new MongoDB\Driver\Manager);"
+```
+
+See the [internals wiki](https://wiki.php.net/internals/windows/stepbystepbuild)
+for more information.
+
+### Transition JIRA issues and version
+
+All issues associated with the release version should be in the "Closed" state
+and have a resolution of "Fixed". Issues with other resolutions (e.g.
+"Duplicate", "Works as Designed") should be removed from the release version so
+that they do not appear in the release notes.
+
+Check the corresponding ".x" fix version to see if it contains any issues that
+are resolved as "Fixed" and should be included in this release version.
+
+Update the version's release date and status from the
+[Manage Versions](https://jira.mongodb.org/plugins/servlet/project-config/PHPC/versions)
+page.
+
+### Update version info
+
+The PHP driver uses [semantic versioning](http://semver.org/). Do not break
+backwards compatibility in a non-major release or your users will kill you.
+
+Before proceeding, ensure that the `master` branch is up-to-date with all code
+changes in this maintenance branch. This is important because we will later
+merge the ensuing release commits up to master with `--strategy=ours`, which
+will ignore changes from the merged commits.
+
+Update the version and stability constants in `phongo_version.h`. This should
+entail removing the version's "-dev" suffix, changing the stability to
+"stable", and increasing the last digit for `PHP_MONGO_VERSION_DESC`:
+
+```
+#define PHP_MONGODB_VERSION "1.1.8-dev"
+#define PHP_MONGODB_STABILITY "devel"
+#define PHP_MONGODB_VERSION_DESC 1,1,8,0
+```
+
+The above would be changed to:
+
+```
+#define PHP_MONGODB_VERSION "1.1.8"
+#define PHP_MONGODB_STABILITY "stable"
+#define PHP_MONGODB_VERSION_DESC 1,1,8,1
+```
+
+The Makefile targets for creating the PECL package depend on these constants, so
+you must rebuild the extension after updating `phongo_version.h`.
+
+> **Note:** If this is an alpha or beta release, the version string should
+> include the X.Y.Z version followed by the stability and an increment. For
+> instance, the first beta release in the 1.4.0 series would be "1.4.0beta1".
+> Alpha and beta releases use "alpha" and "beta" stability strings,
+> respectively. Release candidates (e.g. "1.4.0RC1") also use "beta" stability.
+> See [Documenting release stability and API stability](https://pear.php.net/manual/en/guide.developers.package2.stability.php)
+> for more information. For each change to the suffixes of
+> `PHP_MONGODB_VERSION`, increment the last digit of
+> `PHP_MONGODB_VERSION_DESC`.
+
+### Build PECL package
+
+Create the PECL package description file with `make package.xml`. This creates
+a `package.xml` file from a template. Version, author, and file information will
+be filled in, but release notes must be copied manually from JIRA.
+
+After copying release notes, use `make package` to create the package file (e.g.
+`mongodb-X.Y.Z.tgz`) and ensure that it can be successfully installed:
+
+```
+$ pecl install -f mongodb-X.Y.Z.tgz
+```
+
+### Commit version update and release notes
+
+Commit the modified `phongo_version.h` file as "Package X.Y.Z"
+
+```
+$ git add phongo_version.h
+$ git commit -m "Package X.Y.Z"
+```
+
+### Tag release
+
+The previous commit will be the target for our release tag:
+
+```
+$ git tag -a -m "Release X.Y.Z" X.Y.Z
+```
+
+### Update version info back to dev
+
+After tagging, the version and stability constants in `phongo_version.h` should be
+updated back to development status.
+
+```
+#define PHP_MONGODB_VERSION "1.1.8"
+#define PHP_MONGODB_STABILITY "stable"
+#define PHP_MONGODB_VERSION_DESC 1,1,8,1
+```
+
+The above would be changed to:
+
+```
+#define PHP_MONGODB_VERSION "1.1.9-dev"
+#define PHP_MONGODB_STABILITY "devel"
+#define PHP_MONGODB_VERSION_DESC 1,1,9,0
+```
+
+Commit this change:
+
+```
+$ git commit -m "Back to -dev" phongo_version.h
+```
+
+> **Note:** If this is an alpha, beta, or RC release, the version string should
+> increment the stability sequence instead of the patch version. For example,
+> if the constants were originally "1.4.0-dev" and "devel" and then changed to
+> "1.4.0beta1" and "beta" for the first beta release, this step would see them
+> ultimately changed to "1.4.0beta2-dev" and "devel".
+
+### Push commits and tags
+
+```
+$ git push
+$ git push --tags
+```
+
+### Release PECL package
+
+The PECL package may be published via the
+[Release Upload](https://pecl.php.net/release-upload.php) form. You will have
+one chance to confirm the package information after uploading.
+
+### Merge the maintenance branch up to master
+
+```
+$ git checkout master
+$ git merge vX.Y --strategy=ours
+$ git push
+```
+
+The `--strategy=ours` option ensures that all changes from the merged commits
+will be ignored.
+
+### Publish release notes
+
+The following template should be used for creating GitHub release notes via
+[this form](https://github.com/mongodb/mongo-php-driver/releases/new). The PECL
+package may also be attached to the release notes.
+
+```
+The PHP team is happy to announce that version X.Y.Z of the [mongodb](http://pecl.php.net/package/mongodb) PHP extension is now available on PECL.
+
+**Release Highlights**
+
+<one or more paragraphs describing important changes in this release>
+
+A complete list of resolved issues in this release may be found at:
+$JIRA_URL
+
+**Documentation**
+
+Documentation is available on PHP.net:
+http://php.net/set.mongodb
+
+**Feedback**
+
+We would appreciate any feedback you might have on the project:
+https://jira.mongodb.org/secure/CreateIssue.jspa?pid=12484&issuetype=6
+
+**Installation**
+
+You can either download and install the source manually, or you can install the extension with:
+
+ pecl install mongodb
+
+or update with:
+
+ pecl upgrade mongodb
+
+Windows binaries are available on PECL:
+http://pecl.php.net/package/mongodb
+```
+
+> **Note:** If this is an alpha or beta release, the installation examples
+> should append the stability to the package name (e.g. "mongodb-beta").
+
+The URL for the list of resolved JIRA issues will need to be updated with each
+release. You may obtain the list from
+[this form](https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=12484).
+
+If commits from community contributors were included in this release, append the
+following section:
+
+```
+**Thanks**
+
+Thanks for our community contributors for X.Y.Z:
+
+ * [$CONTRIBUTOR_NAME](https://github.com/$GITHUB_USERNAME)
+```
+
+Release announcements should also be sent to the [MongoDB Product & Driver Announcements](https://community.mongodb.com/tags/c/community/release-notes/35/php-driver).
+
+Consider announcing each release on Twitter. Significant releases should also be
+announced via [@MongoDB](http://twitter.com/mongodb) as well.
diff --git a/mongodb-1.8.1/CREDITS b/mongodb-1.8.1/CREDITS
new file mode 100644
index 00000000..d9f43d00
--- /dev/null
+++ b/mongodb-1.8.1/CREDITS
@@ -0,0 +1,2 @@
+MongoDB Driver for PHP
+Andreas Braun, Jeremy Mikola
diff --git a/mongodb-1.7.4/LICENSE b/mongodb-1.8.1/LICENSE
similarity index 100%
rename from mongodb-1.7.4/LICENSE
rename to mongodb-1.8.1/LICENSE
diff --git a/mongodb-1.7.4/Makefile.frag b/mongodb-1.8.1/Makefile.frag
similarity index 100%
rename from mongodb-1.7.4/Makefile.frag
rename to mongodb-1.8.1/Makefile.frag
diff --git a/mongodb-1.7.4/README.md b/mongodb-1.8.1/README.md
similarity index 100%
rename from mongodb-1.7.4/README.md
rename to mongodb-1.8.1/README.md
diff --git a/mongodb-1.8.1/THIRD_PARTY_NOTICES b/mongodb-1.8.1/THIRD_PARTY_NOTICES
new file mode 100644
index 00000000..b7ceba30
--- /dev/null
+++ b/mongodb-1.8.1/THIRD_PARTY_NOTICES
@@ -0,0 +1,78 @@
+The MongoDB PHP Driver uses third-party code distributed under different licenses.
+
+The MongoDB PHP Driver uses libbson and libmongoc, which also use third-party
+code distributed under difference licenses. See src/libbson/THIRD_PARTY_NOTICES
+and src/libmongoc/THIRD_PARTY_NOTICES for additional information.
+
+
+License notice for php_array_api.h
+-------------------------------------------------------------------------------
+
+--------------------------------------------------------------------
+ The PHP License, version 3.01
+Copyright (c) 1999 - 2014 The PHP Group. All rights reserved.
+--------------------------------------------------------------------
+
+Redistribution and use in source and binary forms, with or without
+modification, is permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. The name "PHP" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact group@php.net.
+
+ 4. Products derived from this software may not be called "PHP", nor
+ may "PHP" appear in their name, without prior written permission
+ from group@php.net. You may indicate that your software works in
+ conjunction with PHP by saying "Foo for PHP" instead of calling
+ it "PHP Foo" or "phpfoo"
+
+ 5. The PHP Group may publish revised and/or new versions of the
+ license from time to time. Each version will be given a
+ distinguishing version number.
+ Once covered code has been published under a particular version
+ of the license, you may always continue to use it under the terms
+ of that version. You may also choose to use such covered code
+ under the terms of any subsequent version of the license
+ published by the PHP Group. No one other than the PHP Group has
+ the right to modify the terms applicable to covered code created
+ under this License.
+
+ 6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes PHP software, freely available from
+ <http://www.php.net/software/>".
+
+THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
+ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
+DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--------------------------------------------------------------------
+
+This software consists of voluntary contributions made by many
+individuals on behalf of the PHP Group.
+
+The PHP Group can be contacted via Email at group@php.net.
+
+For more information on the PHP Group and the PHP project,
+please see <http://www.php.net>.
+
+PHP includes the Zend Engine, freely available at
+<http://www.zend.com>.
diff --git a/mongodb-1.7.4/Vagrantfile b/mongodb-1.8.1/Vagrantfile
similarity index 100%
rename from mongodb-1.7.4/Vagrantfile
rename to mongodb-1.8.1/Vagrantfile
diff --git a/mongodb-1.7.4/config.m4 b/mongodb-1.8.1/config.m4
similarity index 87%
rename from mongodb-1.7.4/config.m4
rename to mongodb-1.8.1/config.m4
index 1862c437..3ebd922b 100644
--- a/mongodb-1.7.4/config.m4
+++ b/mongodb-1.8.1/config.m4
@@ -1,503 +1,518 @@
dnl config.m4 for extension mongodb
PHP_ARG_ENABLE([mongodb],
[whether to enable MongoDB support],
[AS_HELP_STRING([--enable-mongodb],
[Enable MongoDB support])])
if test "$PHP_MONGODB" != "no"; then
dnl Check PHP version is compatible with this extension
AC_MSG_CHECKING([PHP version])
PHP_MONGODB_PHP_VERSION=$PHP_VERSION
PHP_MONGODB_PHP_VERSION_ID=$PHP_VERSION_ID
if test -z "$PHP_MONGODB_PHP_VERSION"; then
if test -z "$PHP_CONFIG"; then
AC_MSG_ERROR([php-config not found])
fi
PHP_MONGODB_PHP_VERSION=`${PHP_CONFIG} --version`
PHP_MONGODB_PHP_VERSION_ID=`echo "${PHP_MONGODB_PHP_VERSION}" | $AWK 'BEGIN { FS = "."; } { printf "%d", ([$]1 * 100 + [$]2) * 100 + [$]3;}'`
fi
AC_MSG_RESULT($PHP_MONGODB_PHP_VERSION)
- if test "$PHP_MONGODB_PHP_VERSION_ID" -lt "50600"; then
- AC_MSG_ERROR([not supported. Need a PHP version >= 5.6.0 (found $PHP_MONGODB_PHP_VERSION)])
+ if test "$PHP_MONGODB_PHP_VERSION_ID" -lt "70000"; then
+ AC_MSG_ERROR([not supported. Need a PHP version >= 7.0.0 (found $PHP_MONGODB_PHP_VERSION)])
fi
PHP_ARG_ENABLE([mongodb-developer-flags],
[whether to enable developer build flags],
[AS_HELP_STRING([--enable-mongodb-developer-flags],
[MongoDB: Enable developer flags [default=no]])],
[no],
[no])
if test "$PHP_MONGODB_DEVELOPER_FLAGS" = "yes"; then
dnl Warn about functions which might be candidates for format attributes
PHP_CHECK_GCC_ARG(-Wmissing-format-attribute, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wmissing-format-attribute")
dnl Avoid duplicating values for an enum
PHP_CHECK_GCC_ARG(-Wduplicate-enum, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wduplicate-enum")
dnl Warns on mismatches between #ifndef and #define header guards
PHP_CHECK_GCC_ARG(-Wheader-guard, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wheader-guard")
dnl logical not of a non-boolean expression
PHP_CHECK_GCC_ARG(-Wlogical-not-parentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-not-parentheses")
dnl Warn about suspicious uses of logical operators in expressions
PHP_CHECK_GCC_ARG(-Wlogical-op, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-op")
dnl memory error detector.
dnl FIXME: -fsanitize=address,undefined for clang. The PHP_CHECK_GCC_ARG macro isn't happy about that string :(
PHP_CHECK_GCC_ARG(-fsanitize-address, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fsanitize-address")
dnl Enable frame debugging
PHP_CHECK_GCC_ARG(-fno-omit-frame-pointer, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-omit-frame-pointer")
dnl Make sure we don't optimize calls
PHP_CHECK_GCC_ARG(-fno-optimize-sibling-calls, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-optimize-sibling-calls")
PHP_CHECK_GCC_ARG(-Wlogical-op-parentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-op-parentheses")
PHP_CHECK_GCC_ARG(-Wpointer-bool-conversion, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wpointer-bool-conversion")
PHP_CHECK_GCC_ARG(-Wbool-conversion, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wbool-conversion")
PHP_CHECK_GCC_ARG(-Wloop-analysis, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wloop-analysis")
PHP_CHECK_GCC_ARG(-Wsizeof-array-argument, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wsizeof-array-argument")
PHP_CHECK_GCC_ARG(-Wstring-conversion, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wstring-conversion")
PHP_CHECK_GCC_ARG(-Wno-variadic-macros, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-variadic-macros")
PHP_CHECK_GCC_ARG(-Wno-sign-compare, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-sign-compare")
PHP_CHECK_GCC_ARG(-fstack-protector, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fstack-protector")
PHP_CHECK_GCC_ARG(-fno-exceptions, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-exceptions")
PHP_CHECK_GCC_ARG(-Wformat-security, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wformat-security")
PHP_CHECK_GCC_ARG(-Wformat-nonliteral, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wformat-nonliteral")
PHP_CHECK_GCC_ARG(-Winit-self, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Winit-self")
PHP_CHECK_GCC_ARG(-Wwrite-strings, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wwrite-strings")
PHP_CHECK_GCC_ARG(-Wenum-compare, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wenum-compare")
PHP_CHECK_GCC_ARG(-Wempty-body, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wempty-body")
PHP_CHECK_GCC_ARG(-Wparentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wparentheses")
PHP_CHECK_GCC_ARG(-Wdeclaration-after-statement, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wdeclaration-after-statement")
PHP_CHECK_GCC_ARG(-Wmaybe-uninitialized, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wmaybe-uninitialized")
PHP_CHECK_GCC_ARG(-Wimplicit-fallthrough, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wimplicit-fallthrough")
PHP_CHECK_GCC_ARG(-Werror, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Werror")
PHP_CHECK_GCC_ARG(-Wextra, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wextra")
PHP_CHECK_GCC_ARG(-Wno-unused-parameter, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-unused-parameter")
PHP_CHECK_GCC_ARG(-Wno-unused-but-set-variable, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-unused-but-set-variable")
PHP_CHECK_GCC_ARG(-Wno-missing-field-initializers, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-missing-field-initializers")
MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS"
STD_CFLAGS="-g -O0 -Wall"
fi
PHP_ARG_ENABLE([mongodb-coverage],
[whether to enable code coverage],
[AS_HELP_STRING([--enable-mongodb-coverage],
[MongoDB: Enable developer code coverage information [default=no]])],
[no],
[no])
if test "$PHP_MONGODB_COVERAGE" = "yes"; then
if test "$ext_shared" != "yes"; then
AC_MSG_ERROR(code coverage is not supported for static builds)
fi
COVERAGE_CFLAGS="--coverage -g"
COVERAGE_LDFLAGS="--coverage"
MONGODB_SHARED_LIBADD="$MONGODB_SHARED_LIBADD $COVERAGE_LDFLAGS"
fi
PHP_MONGODB_CFLAGS="$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS"
PHP_MONGODB_SOURCES="\
php_phongo.c \
phongo_compat.c \
src/bson.c \
src/bson-encode.c \
src/BSON/Binary.c \
src/BSON/BinaryInterface.c \
src/BSON/DBPointer.c \
src/BSON/Decimal128.c \
src/BSON/Decimal128Interface.c \
src/BSON/Int64.c \
src/BSON/Javascript.c \
src/BSON/JavascriptInterface.c \
src/BSON/MaxKey.c \
src/BSON/MaxKeyInterface.c \
src/BSON/MinKey.c \
src/BSON/MinKeyInterface.c \
src/BSON/ObjectId.c \
src/BSON/ObjectIdInterface.c \
src/BSON/Persistable.c \
src/BSON/Regex.c \
src/BSON/RegexInterface.c \
src/BSON/Serializable.c \
src/BSON/Symbol.c \
src/BSON/Timestamp.c \
src/BSON/TimestampInterface.c \
src/BSON/Type.c \
src/BSON/Undefined.c \
src/BSON/Unserializable.c \
src/BSON/UTCDateTime.c \
src/BSON/UTCDateTimeInterface.c \
src/BSON/functions.c \
src/MongoDB/BulkWrite.c \
src/MongoDB/ClientEncryption.c \
src/MongoDB/Command.c \
src/MongoDB/Cursor.c \
src/MongoDB/CursorId.c \
src/MongoDB/CursorInterface.c \
src/MongoDB/Manager.c \
src/MongoDB/Query.c \
src/MongoDB/ReadConcern.c \
src/MongoDB/ReadPreference.c \
src/MongoDB/Server.c \
src/MongoDB/Session.c \
src/MongoDB/WriteConcern.c \
src/MongoDB/WriteConcernError.c \
src/MongoDB/WriteError.c \
src/MongoDB/WriteResult.c \
src/MongoDB/Exception/AuthenticationException.c \
src/MongoDB/Exception/BulkWriteException.c \
src/MongoDB/Exception/CommandException.c \
src/MongoDB/Exception/ConnectionException.c \
src/MongoDB/Exception/ConnectionTimeoutException.c \
src/MongoDB/Exception/EncryptionException.c \
src/MongoDB/Exception/Exception.c \
src/MongoDB/Exception/ExecutionTimeoutException.c \
src/MongoDB/Exception/InvalidArgumentException.c \
src/MongoDB/Exception/LogicException.c \
src/MongoDB/Exception/RuntimeException.c \
src/MongoDB/Exception/ServerException.c \
src/MongoDB/Exception/SSLConnectionException.c \
src/MongoDB/Exception/UnexpectedValueException.c \
src/MongoDB/Exception/WriteException.c \
src/MongoDB/Monitoring/CommandFailedEvent.c \
src/MongoDB/Monitoring/CommandStartedEvent.c \
src/MongoDB/Monitoring/CommandSubscriber.c \
src/MongoDB/Monitoring/CommandSucceededEvent.c \
src/MongoDB/Monitoring/Subscriber.c \
src/MongoDB/Monitoring/functions.c \
"
PHP_ARG_WITH([mongodb-system-libs],
[whether to compile against system libraries instead of bundled],
[AS_HELP_STRING([--with-mongodb-system-libs=@<:@yes/no@:>@],
[MongoDB: Use system libraries for libbson, libmongoc, and libmongocrypt [default=no]])],
[no],
[no])
PHP_ARG_WITH([libbson],
[whether to use system libbson],
[AS_HELP_STRING([--with-libbson=@<:@yes/no@:>@],
[MongoDB: Use system libbson [default=no]])],
[no],
[no])
PHP_ARG_WITH([libmongoc],
[whether to use system libmongoc],
[AS_HELP_STRING([--with-libmongoc=@<:@yes/no@:>@],
[MongoDB: Use system libmongoc [default=no]])],
[no],
[no])
PHP_ARG_WITH([mongodb-client-side-encryption],
[whether to enable client-side encryption],
[AS_HELP_STRING([--with-mongodb-client-side-encryption=@<:@auto/yes/no@:>@],
[MongoDB: Enable client-side encryption [default=auto]])],
[auto],
[no])
if test "$PHP_LIBBSON" != "no"; then
AC_MSG_WARN(Using --with-libbson is deprecated and will be removed in a future version. Please use --with-system-libs instead)
if test "$PHP_LIBMONGOC" = "no"; then
AC_MSG_ERROR(Cannot use system libbson and bundled libmongoc)
fi
PHP_MONGODB_SYSTEM_LIBS="yes"
fi
if test "$PHP_LIBMONGOC" != "no"; then
AC_MSG_WARN(Using --with-libmongoc is deprecated and will be removed in a future version. Please use --with-system-libs instead)
if test "$PHP_LIBBSON" = "no"; then
AC_MSG_ERROR(Cannot use system libmongoc and bundled libbson)
fi
PHP_MONGODB_SYSTEM_LIBS="yes"
fi
if test "$PHP_MONGODB_SYSTEM_LIBS" != "no"; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
AC_MSG_CHECKING(for libbson)
if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libbson-1.0; then
- if $PKG_CONFIG libbson-1.0 --atleast-version 1.16.2; then
+ if $PKG_CONFIG libbson-1.0 --atleast-version 1.17.0; then
PHP_MONGODB_BSON_CFLAGS=`$PKG_CONFIG libbson-1.0 --cflags`
PHP_MONGODB_BSON_LIBS=`$PKG_CONFIG libbson-1.0 --libs`
PHP_MONGODB_BSON_VERSION=`$PKG_CONFIG libbson-1.0 --modversion`
AC_MSG_RESULT(version $PHP_MONGODB_BSON_VERSION found)
else
- AC_MSG_ERROR(system libbson must be upgraded to version >= 1.16.2)
+ AC_MSG_ERROR(system libbson must be upgraded to version >= 1.17.0)
fi
else
AC_MSG_ERROR(pkgconfig and libbson must be installed)
fi
PHP_MONGODB_CFLAGS="$PHP_MONGODB_CFLAGS $PHP_MONGODB_BSON_CFLAGS"
PHP_EVAL_LIBLINE($PHP_MONGODB_BSON_LIBS, MONGODB_SHARED_LIBADD)
AC_DEFINE(HAVE_SYSTEM_LIBBSON, 1, [Use system libbson])
AC_MSG_CHECKING(for libmongoc)
if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmongoc-1.0; then
- if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.16.2; then
+ if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.17.0; then
PHP_MONGODB_MONGOC_CFLAGS=`$PKG_CONFIG libmongoc-1.0 --cflags`
PHP_MONGODB_MONGOC_LIBS=`$PKG_CONFIG libmongoc-1.0 --libs`
PHP_MONGODB_MONGOC_VERSION=`$PKG_CONFIG libmongoc-1.0 --modversion`
AC_MSG_RESULT(version $PHP_MONGODB_MONGOC_VERSION found)
else
- AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.16.2)
+ AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.17.0)
fi
else
AC_MSG_ERROR(pkgconfig and libmongoc must be installed)
fi
PHP_MONGODB_CFLAGS="$PHP_MONGODB_CFLAGS $PHP_MONGODB_MONGOC_CFLAGS"
PHP_EVAL_LIBLINE($PHP_MONGODB_MONGOC_LIBS, MONGODB_SHARED_LIBADD)
AC_DEFINE(HAVE_SYSTEM_LIBMONGOC, 1, [Use system libmongoc])
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" != "no"; then
AC_MSG_CHECKING(for libmongocrypt)
if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmongocrypt; then
- if $PKG_CONFIG libmongocrypt --atleast-version 1.0.3; then
+ if $PKG_CONFIG libmongocrypt --atleast-version 1.0.4; then
PHP_MONGODB_MONGOCRYPT_CFLAGS=`$PKG_CONFIG libmongocrypt --cflags`
PHP_MONGODB_MONGOCRYPT_LIBS=`$PKG_CONFIG libmongocrypt --libs`
PHP_MONGODB_MONGOCRYPT_VERSION=`$PKG_CONFIG libmongocrypt --modversion`
AC_MSG_RESULT(version $PHP_MONGODB_MONGOCRYPT_VERSION found)
PHP_MONGODB_CFLAGS="$PHP_MONGODB_CFLAGS $PHP_MONGODB_MONGOCRYPT_CFLAGS"
PHP_EVAL_LIBLINE($PHP_MONGODB_MONGOCRYPT_LIBS, MONGODB_SHARED_LIBADD)
AC_DEFINE(HAVE_SYSTEM_LIBMONGOCRYPT, 1, [Use system libmongocrypt])
elif test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "yes"; then
- AC_MSG_ERROR(system libmongocrypt must be upgraded to version >= 1.0.3)
+ AC_MSG_ERROR(system libmongocrypt must be upgraded to version >= 1.0.4)
else
AC_MSG_RESULT(found an older version, compiling without client-side encryption)
fi
else
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "yes"; then
AC_MSG_ERROR(pkgconfig and libmongocrypt must be installed)
else
AC_MSG_RESULT(not found, compiling without client-side encryption)
fi
fi
fi
fi
if test "$PHP_MONGODB_SYSTEM_LIBS" = "no"; then
PHP_MONGODB_BUNDLED_CFLAGS="$STD_CFLAGS -DBSON_COMPILATION -DMONGOC_COMPILATION"
dnl TODO: MONGOCRYPT-219 makes the -std argument obsolete
PHP_MONGODB_LIBMONGOCRYPT_CFLAGS="-DKMS_MSG_STATIC -std=gnu99"
dnl M4 doesn't know if we're building statically or as a shared module, so
dnl attempt to include both paths while ignoring errors. If neither path
dnl exists, report an error during configure (this is later than M4 parsing
dnl during phpize but better than nothing).
m4_pushdef([_include],[
dnl TODO: Fix this for PECL install (PHPC-1218)
dnl if test ! \( -f "$1" -o -f "ext/mongodb/$1" \); then
dnl AC_MSG_ERROR([m4 could not include $1: No such file or directory])
dnl fi
m4_builtin([sinclude],[$1])
m4_builtin([sinclude],[ext/mongodb/][$1])
])
dnl Avoid using AC_CONFIG_MACRO_DIR, which might conflict with PHP
_include([scripts/autotools/m4/as_var_copy.m4])
_include([scripts/autotools/m4/ax_check_compile_flag.m4])
_include([scripts/autotools/m4/ax_prototype.m4])
_include([scripts/autotools/m4/ax_pthread.m4])
_include([scripts/autotools/m4/php_mongodb.m4])
_include([scripts/autotools/m4/pkg.m4])
_include([scripts/autotools/CheckCompiler.m4])
_include([scripts/autotools/CheckHost.m4])
_include([scripts/autotools/libbson/CheckAtomics.m4])
_include([scripts/autotools/libbson/CheckHeaders.m4])
_include([scripts/autotools/libbson/Endian.m4])
_include([scripts/autotools/libbson/FindDependencies.m4])
_include([scripts/autotools/libbson/Versions.m4])
_include([scripts/autotools/libmongoc/CheckCompression.m4])
_include([scripts/autotools/libmongoc/CheckResolv.m4])
_include([scripts/autotools/libmongoc/CheckSasl.m4])
_include([scripts/autotools/libmongoc/CheckSSL.m4])
_include([scripts/autotools/libmongoc/CheckICU.m4])
_include([scripts/autotools/libmongoc/FindDependencies.m4])
_include([scripts/autotools/libmongoc/PlatformFlags.m4])
_include([scripts/autotools/libmongoc/Versions.m4])
_include([scripts/autotools/libmongoc/WeakSymbols.m4])
dnl This include modifies the value of $PHP_MONGODB_CLIENT_SIDE_ENCRYPTION to "yes"
dnl or "no" depending on whether dependencies for libmongocrypt are fulfilled
_include([scripts/autotools/libmongocrypt/CheckSSL.m4])
_include([scripts/autotools/libmongocrypt/Version.m4])
m4_popdef([_include])
AC_SUBST(BSON_EXTRA_ALIGN, 0)
AC_SUBST(BSON_OS, 1)
AC_SUBST(MONGOC_NO_AUTOMATIC_GLOBALS, 1)
+ AC_SUBST(MONGOC_ENABLE_MONGODB_AWS_AUTH, 0)
AC_SUBST(MONGOC_ENABLE_RDTSCP, 0)
AC_SUBST(MONGOC_ENABLE_SHM_COUNTERS, 0)
AC_SUBST(MONGOC_TRACE, 1)
dnl Assignments for metadata handshake. Leave CFLAGS/LDFLAGS empty as they
dnl would likely cause platform info (PHP version) to be truncated. We can
dnl consider restoring CFLAGS/LDFLAGS once CDRIVER-3134 is resolved.
AC_SUBST(MONGOC_CC, [$CC])
AC_SUBST(MONGOC_USER_SET_CFLAGS, [])
AC_SUBST(MONGOC_USER_SET_LDFLAGS, [])
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "yes"; then
AC_SUBST(MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION, 1)
else
AC_SUBST(MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION, 0)
fi
dnl On MacOS, use gcut from the coreutils brew package instead of cut
dnl Generated with: find src/libmongoc/src/common -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
- PHP_MONGODB_COMMON_SOURCES="common-b64.c common-md5.c"
+ PHP_MONGODB_COMMON_SOURCES="common-b64.c common-md5.c common-thread.c"
+
+ dnl Generated with: find src/libmongoc/src/kms-message/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 6- | sort -dz | tr '\000' ' '
+ PHP_MONGODB_KMS_MESSAGE_SOURCES="hexlify.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c"
dnl Generated with: find src/libmongoc/src/libbson/src/bson -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
PHP_MONGODB_BSON_SOURCES="bcon.c bson-atomic.c bson.c bson-clock.c bson-context.c bson-decimal128.c bson-error.c bson-iso8601.c bson-iter.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"
dnl Generated with: find src/libmongoc/src/libbson/src/jsonsl -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
PHP_MONGODB_JSONSL_SOURCES="jsonsl.c"
dnl Generated with: find src/libmongoc/src/libmongoc/src/mongoc -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
- PHP_MONGODB_MONGOC_SOURCES="mongoc-aggregate.c mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-change-stream.c mongoc-client.c mongoc-client-pool.c mongoc-client-session.c mongoc-client-side-encryption.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypt.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-change-stream.c mongoc-cursor-cmd.c mongoc-cursor-cmd-deprecated.c mongoc-cursor-find.c mongoc-cursor-find-cmd.c mongoc-cursor-find-opquery.c mongoc-cursor-legacy.c mongoc-cyrus.c mongoc-database.c mongoc-error.c mongoc-find-and-modify.c mongoc-gridfs-bucket.c mongoc-gridfs-bucket-file.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-handshake.c mongoc-host-list.c mongoc-index.c mongoc-init.c mongoc-libressl.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log.c mongoc-matcher.c mongoc-matcher-op.c mongoc-memcmp.c mongoc-openssl.c mongoc-opts.c mongoc-opts-helpers.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-description.c mongoc-server-stream.c mongoc-set.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-gridfs-download.c mongoc-stream-gridfs-upload.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-libressl.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-command-legacy.c mongoc-write-concern.c"
+ PHP_MONGODB_MONGOC_SOURCES="mongoc-aggregate.c mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-change-stream.c mongoc-client.c mongoc-client-pool.c mongoc-client-session.c mongoc-client-side-encryption.c mongoc-cluster-aws.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypt.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-change-stream.c mongoc-cursor-cmd.c mongoc-cursor-cmd-deprecated.c mongoc-cursor-find.c mongoc-cursor-find-cmd.c mongoc-cursor-find-opquery.c mongoc-cursor-legacy.c mongoc-cyrus.c mongoc-database.c mongoc-error.c mongoc-find-and-modify.c mongoc-gridfs-bucket.c mongoc-gridfs-bucket-file.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-handshake.c mongoc-host-list.c mongoc-http.c mongoc-index.c mongoc-init.c mongoc-interrupt.c mongoc-libressl.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log.c mongoc-matcher.c mongoc-matcher-op.c mongoc-memcmp.c mongoc-ocsp-cache.c mongoc-openssl.c mongoc-opts.c mongoc-opts-helpers.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-description.c mongoc-server-monitor.c mongoc-server-stream.c mongoc-set.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-gridfs-download.c mongoc-stream-gridfs-upload.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-libressl.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-topology-background-monitoring.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-command-legacy.c mongoc-write-concern.c"
dnl Generated with: find src/libmongoc/src/zlib-1.2.11 -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_ZLIB_SOURCES="adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c"
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/common/], $PHP_MONGODB_COMMON_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/libbson/src/bson/], $PHP_MONGODB_BSON_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/libbson/src/jsonsl/], $PHP_MONGODB_JSONSL_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/libmongoc/src/mongoc/], $PHP_MONGODB_MONGOC_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/common/])
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/libbson/src/])
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/libbson/src/jsonsl/])
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/libmongoc/src/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/common/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/libbson/src/bson/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/libbson/src/jsonsl/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/libmongoc/src/mongoc/])
+ dnl If compiling without libmongocrypt, use kms_message sources bundled with libmongoc.
+ dnl If compiling with libmongocrypt, kms_message bundled with libmongocrypt is used as it is most likely newer.
+ if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" != "yes" && test "$PHP_MONGODB_SSL" != "no"; then
+ AC_SUBST(MONGOC_ENABLE_MONGODB_AWS_AUTH, 1)
+ PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/kms-message/src/], $PHP_MONGODB_KMS_MESSAGE_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
+ PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/kms-message/src/])
+ PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/kms-message/src/])
+ fi
+
dnl TODO: Use $ext_srcdir if we can move this after PHP_NEW_EXTENSION
ac_config_dir=PHP_EXT_SRCDIR(mongodb)
AC_CONFIG_FILES([
${ac_config_dir}/src/libmongoc/src/libbson/src/bson/bson-config.h
${ac_config_dir}/src/libmongoc/src/libbson/src/bson/bson-version.h
${ac_config_dir}/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
${ac_config_dir}/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
])
if test "x$bundled_zlib" = "xyes"; then
PHP_MONGODB_ZLIB_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS"
AC_CHECK_HEADER([unistd.h], [PHP_MONGODB_ZLIB_CFLAGS="$PHP_MONGODB_ZLIB_CFLAGS -DHAVE_UNISTD_H=1"], [])
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/zlib-1.2.11/], $PHP_MONGODB_ZLIB_SOURCES, $PHP_MONGODB_ZLIB_CFLAGS)
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/zlib-1.2.11/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/zlib-1.2.11/])
AC_CONFIG_FILES([${ac_config_dir}/src/libmongoc/src/zlib-1.2.11/zconf.h])
fi
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "yes"; then
+ dnl Since libmongocrypt adds kms-message, we can enable AWS auth in this case
+ AC_SUBST(MONGOC_ENABLE_MONGODB_AWS_AUTH, 1)
AC_SUBST(MONGOCRYPT_ENABLE_TRACE, 1)
dnl Generated with: find src/libmongocrypt/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 4- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOCRYPT_SOURCES="mongocrypt-binary.c mongocrypt-buffer.c mongocrypt.c mongocrypt-cache.c mongocrypt-cache-collinfo.c mongocrypt-cache-key.c mongocrypt-ciphertext.c mongocrypt-crypto.c mongocrypt-ctx.c mongocrypt-ctx-datakey.c mongocrypt-ctx-decrypt.c mongocrypt-ctx-encrypt.c mongocrypt-key-broker.c mongocrypt-key.c mongocrypt-kms-ctx.c mongocrypt-log.c mongocrypt-marking.c mongocrypt-opts.c mongocrypt-status.c mongocrypt-traverse-util.c"
dnl Generated with: find src/libmongocrypt/src/crypto -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES="cng.c commoncrypto.c libcrypto.c none.c"
dnl Generated with: find src/libmongocrypt/src/os_posix -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES="os_mutex.c os_once.c"
dnl Generated with: find src/libmongocrypt/src/os_win -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES="os_mutex.c os_once.c"
dnl Generated with: find src/libmongocrypt/kms-message/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
- PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES="hexlify.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_kv_list.c kms_message.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c"
+ PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES="hexlify.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c"
PHP_MONGODB_LIBMONGOCRYPT_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS"
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/src/], $PHP_MONGODB_MONGOCRYPT_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/src/crypto/], $PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/src/os_posix/], $PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/src/os_win/], $PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/kms-message/src/], $PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_INCLUDE([src/libmongocrypt/src/])
PHP_MONGODB_ADD_INCLUDE([src/libmongocrypt/kms-message/src/])
PHP_MONGODB_ADD_INCLUDE([src/libmongocrypt-compat/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/src/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/src/crypto/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/src/os_posix/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/src/os_win/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/kms-message/src/])
AC_CONFIG_FILES([
${ac_config_dir}/src/libmongocrypt/src/mongocrypt-config.h
${ac_config_dir}/src/libmongocrypt/src/mongocrypt.h
])
fi
fi
PHP_NEW_EXTENSION(mongodb, $PHP_MONGODB_SOURCES, $ext_shared,, $PHP_MONGODB_CFLAGS)
PHP_SUBST(MONGODB_SHARED_LIBADD)
PHP_ADD_EXTENSION_DEP(mongodb, date)
PHP_ADD_EXTENSION_DEP(mongodb, json)
PHP_ADD_EXTENSION_DEP(mongodb, spl)
PHP_ADD_EXTENSION_DEP(mongodb, standard)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/BSON/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/MongoDB/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/MongoDB/Exception/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/MongoDB/Monitoring/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/contrib/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/BSON/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/MongoDB/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/MongoDB/Exception/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/MongoDB/Monitoring/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/contrib/])
dnl Necessary to ensure that static builds include "-pthread" when linking
if test "$ext_shared" != "yes"; then
EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM $EXTRA_LDFLAGS"
fi
dnl This must come after PHP_NEW_EXTENSION, otherwise the srcdir won't be set
PHP_ADD_MAKEFILE_FRAGMENT
dnl The libmongocrypt line intentionally uses the PHP_LIBBSON flag as that decides whether to build against bundled or system libraries.
AC_CONFIG_COMMANDS_POST([
if test "$enable_static" = "no"; then
echo "
mongodb was configured with the following options:
Build configuration:
CFLAGS : $CFLAGS
Extra CFLAGS : $STD_CFLAGS $EXTRA_CFLAGS
Developers flags (slow) : $MAINTAINER_CFLAGS
Code Coverage flags (extra slow) : $COVERAGE_CFLAGS
System libmongoc : $PHP_MONGODB_SYSTEM_LIBS
System libbson : $PHP_MONGODB_SYSTEM_LIBS
System libmongocrypt : $PHP_MONGODB_SYSTEM_LIBS
LDFLAGS : $LDFLAGS
EXTRA_LDFLAGS : $EXTRA_LDFLAGS
MONGODB_SHARED_LIBADD : $MONGODB_SHARED_LIBADD
Please submit bugreports at:
https://jira.mongodb.org/browse/PHPC
"
fi
])
fi
dnl: vim: et sw=2
diff --git a/mongodb-1.7.4/config.w32 b/mongodb-1.8.1/config.w32
similarity index 70%
rename from mongodb-1.7.4/config.w32
rename to mongodb-1.8.1/config.w32
index 59be56a2..9b5c327c 100644
--- a/mongodb-1.7.4/config.w32
+++ b/mongodb-1.8.1/config.w32
@@ -1,331 +1,361 @@
// vim:ft=javascript
function mongodb_generate_header(inpath, outpath, replacements)
{
STDOUT.WriteLine("Generating " + outpath);
var infile = FSO.OpenTextFile(inpath, 1);
var outdata = infile.ReadAll();
infile.Close();
for (var key in replacements) {
var replacement = replacements[key];
if (typeof replacement === 'string') {
replacement = replacement.replace(/"/g, '\\"');
}
outdata = outdata.replace(new RegExp('@' + key + '@', 'g'), replacement);
}
var outfile = FSO.CreateTextFile(outpath, true);
outfile.Write(outdata);
outfile.Close();
}
function mongodb_parse_version_file(inpath, prefix)
{
var infile = FSO.OpenTextFile(inpath, 1);
var version = infile.ReadLine();
infile.Close();
var xyz_pre = version.split("-");
var xyz = xyz_pre[0].split(".");
var pre = xyz_pre.length > 1 ? xyz_pre[1] : "";
var replacements = {};
replacements[prefix + "VERSION"] = version;
replacements[prefix + "MAJOR_VERSION"] = xyz[0];
replacements[prefix + "MINOR_VERSION"] = xyz[1];
replacements[prefix + "MICRO_VERSION"] = xyz[2];
replacements[prefix + "PRERELEASE_VERSION"] = pre;
return replacements;
}
+function create_folder_recursive(path)
+{
+ if (FSO.FolderExists(path)) {
+ return;
+ }
+
+ create_folder_recursive(FSO.GetParentFolderName(path));
+ FSO.CreateFolder(path);
+}
+
+function MONGODB_ADD_SOURCES(dir, file_list)
+{
+ // Ensure obj_dir and all parent directories exist
+ create_folder_recursive(FSO.BuildPath(get_define('BUILD_DIR'), dir));
+ ADD_SOURCES(configure_module_dirname + dir, file_list, "mongodb", dir);
+}
+
ARG_ENABLE("mongodb", "MongoDB support", "no");
ARG_WITH("mongodb-sasl", "MongoDB: Build against Cyrus-SASL", "yes");
ARG_WITH("mongodb-client-side-encryption", "MongoDB: Enable client-side encryption", "yes");
if (PHP_MONGODB != "no") {
/* Note: ADD_EXTENSION_DEP() cannot be used to declare that we depend on the
* date and standard extensions. Assume that they're always enabled. */
ADD_EXTENSION_DEP("mongodb", "json", false);
ADD_EXTENSION_DEP("mongodb", "spl", false);
/* MongoDB does not actually depend on PHP's OpenSSL extension, but this is in
* place to ensure that later SSL library checks succeed. This can be removed
* once we support building with Secure Channel. */
ADD_EXTENSION_DEP("mongodb", "openssl", false);
var PHP_MONGODB_CFLAGS="\
/D BSON_COMPILATION /D MONGOC_COMPILATION \
/I" + configure_module_dirname + " \
/I" + configure_module_dirname + "/src/BSON \
/I" + configure_module_dirname + "/src/MongoDB \
/I" + configure_module_dirname + "/src/MongoDB/Exception \
/I" + configure_module_dirname + "/src/contrib \
/I" + configure_module_dirname + "/src/libmongoc/src/common \
/I" + configure_module_dirname + "/src/libmongoc/src/libbson/src \
/I" + configure_module_dirname + "/src/libmongoc/src/libbson/src/jsonsl \
/I" + configure_module_dirname + "/src/libmongoc/src/libmongoc/src \
";
// Condense whitespace in CFLAGS
PHP_MONGODB_CFLAGS = PHP_MONGODB_CFLAGS.replace(/\s+/g, ' ');
// On MacOS, use gcut from the coreutils brew package instead of cut
// Generated with: find src/libmongoc/src/common -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
- var PHP_MONGODB_COMMON_SOURCES="common-b64.c common-md5.c"
+ var PHP_MONGODB_COMMON_SOURCES="common-b64.c common-md5.c common-thread.c"
+
+ // Generated with: find src/libmongoc/src/kms-message/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 6- | sort -dz | tr '\000' ' '
+ var PHP_MONGODB_KMS_MESSAGE_SOURCES="hexlify.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c";
// Generated with: find src/libmongoc/src/libbson/src/bson -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
var PHP_MONGODB_BSON_SOURCES="bcon.c bson-atomic.c bson.c bson-clock.c bson-context.c bson-decimal128.c bson-error.c bson-iso8601.c bson-iter.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";
// Generated with: find src/libmongoc/src/libbson/src/jsonsl -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
var PHP_MONGODB_JSONSL_SOURCES="jsonsl.c";
// Generated with: find src/libmongoc/src/libmongoc/src/mongoc -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
- var PHP_MONGODB_MONGOC_SOURCES="mongoc-aggregate.c mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-change-stream.c mongoc-client.c mongoc-client-pool.c mongoc-client-session.c mongoc-client-side-encryption.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypt.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-change-stream.c mongoc-cursor-cmd.c mongoc-cursor-cmd-deprecated.c mongoc-cursor-find.c mongoc-cursor-find-cmd.c mongoc-cursor-find-opquery.c mongoc-cursor-legacy.c mongoc-cyrus.c mongoc-database.c mongoc-error.c mongoc-find-and-modify.c mongoc-gridfs-bucket.c mongoc-gridfs-bucket-file.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-handshake.c mongoc-host-list.c mongoc-index.c mongoc-init.c mongoc-libressl.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log.c mongoc-matcher.c mongoc-matcher-op.c mongoc-memcmp.c mongoc-openssl.c mongoc-opts.c mongoc-opts-helpers.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-description.c mongoc-server-stream.c mongoc-set.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-gridfs-download.c mongoc-stream-gridfs-upload.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-libressl.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-command-legacy.c mongoc-write-concern.c";
+ var PHP_MONGODB_MONGOC_SOURCES="mongoc-aggregate.c mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-change-stream.c mongoc-client.c mongoc-client-pool.c mongoc-client-session.c mongoc-client-side-encryption.c mongoc-cluster-aws.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypt.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-change-stream.c mongoc-cursor-cmd.c mongoc-cursor-cmd-deprecated.c mongoc-cursor-find.c mongoc-cursor-find-cmd.c mongoc-cursor-find-opquery.c mongoc-cursor-legacy.c mongoc-cyrus.c mongoc-database.c mongoc-error.c mongoc-find-and-modify.c mongoc-gridfs-bucket.c mongoc-gridfs-bucket-file.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-handshake.c mongoc-host-list.c mongoc-http.c mongoc-index.c mongoc-init.c mongoc-interrupt.c mongoc-libressl.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log.c mongoc-matcher.c mongoc-matcher-op.c mongoc-memcmp.c mongoc-ocsp-cache.c mongoc-openssl.c mongoc-opts.c mongoc-opts-helpers.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-description.c mongoc-server-monitor.c mongoc-server-stream.c mongoc-set.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-gridfs-download.c mongoc-stream-gridfs-upload.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-libressl.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-topology-background-monitoring.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-command-legacy.c mongoc-write-concern.c";
EXTENSION("mongodb", "php_phongo.c phongo_compat.c", null, PHP_MONGODB_CFLAGS);
- ADD_SOURCES(configure_module_dirname + "/src", "bson.c bson-encode.c", "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/BSON", "Binary.c BinaryInterface.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c", "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/MongoDB", "BulkWrite.c ClientEncryption.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c Session.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c", "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c CommandException.c ConnectionException.c ConnectionTimeoutException.c EncryptionException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c ServerException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c", "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c Subscriber.c functions.c", "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/common", PHP_MONGODB_COMMON_SOURCES, "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/libbson/src/bson", PHP_MONGODB_BSON_SOURCES, "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/libbson/src/jsonsl", PHP_MONGODB_JSONSL_SOURCES, "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc", PHP_MONGODB_MONGOC_SOURCES, "mongodb");
+ MONGODB_ADD_SOURCES("/src", "bson.c bson-encode.c");
+ MONGODB_ADD_SOURCES("/src/BSON", "Binary.c BinaryInterface.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c");
+ MONGODB_ADD_SOURCES("/src/MongoDB", "BulkWrite.c ClientEncryption.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c Session.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c");
+ MONGODB_ADD_SOURCES("/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c CommandException.c ConnectionException.c ConnectionTimeoutException.c EncryptionException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c ServerException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c");
+ MONGODB_ADD_SOURCES("/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c Subscriber.c functions.c");
+ MONGODB_ADD_SOURCES("/src/libmongoc/src/common", PHP_MONGODB_COMMON_SOURCES);
+ MONGODB_ADD_SOURCES("/src/libmongoc/src/libbson/src/bson", PHP_MONGODB_BSON_SOURCES);
+ MONGODB_ADD_SOURCES("/src/libmongoc/src/libbson/src/jsonsl", PHP_MONGODB_JSONSL_SOURCES);
+ MONGODB_ADD_SOURCES("/src/libmongoc/src/libmongoc/src/mongoc", PHP_MONGODB_MONGOC_SOURCES);
var bson_opts = {
BSON_BYTE_ORDER: 1234,
BSON_OS: 2,
BSON_HAVE_STDBOOL_H: 0,
BSON_HAVE_STRINGS_H: 0,
BSON_HAVE_ATOMIC_32_ADD_AND_FETCH: 0,
BSON_HAVE_ATOMIC_64_ADD_AND_FETCH: 0,
BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES: 0,
BSON_HAVE_CLOCK_GETTIME: 0,
BSON_HAVE_STRNLEN: 0,
BSON_HAVE_SNPRINTF: 0,
BSON_HAVE_STRLCPY: 0,
BSON_HAVE_REALLOCF: 0,
BSON_NEEDS_SET_OUTPUT_FORMAT: 0,
BSON_HAVE_TIMESPEC: 0,
BSON_EXTRA_ALIGN: 0,
BSON_HAVE_SYSCALL_TID: 0,
BSON_HAVE_DECIMAL128: 0,
BSON_HAVE_GMTIME_R: 0,
BSON_HAVE_RAND_R: 0
};
if (CHECK_FUNC_IN_HEADER("stdio.h", "_set_output_format")) {
bson_opts.BSON_NEEDS_SET_OUTPUT_FORMAT = 1;
}
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/bson-config.h.in",
configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/bson-config.h",
bson_opts
);
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/bson-version.h.in",
configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/bson-version.h",
mongodb_parse_version_file(configure_module_dirname + "/src/LIBMONGOC_VERSION_CURRENT", "BSON_")
);
var mongoc_opts = {
// TODO: Support building with Secure Channel on Windows
MONGOC_ENABLE_SSL_SECURE_CHANNEL: 0,
MONGOC_ENABLE_CRYPTO_CNG: 0,
// Secure Transport does not apply to Windows
MONGOC_ENABLE_SSL_SECURE_TRANSPORT: 0,
MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO: 0,
MONGOC_ENABLE_SSL_LIBRESSL: 0,
MONGOC_ENABLE_SSL_OPENSSL: 0,
MONGOC_ENABLE_CRYPTO_LIBCRYPTO: 0,
MONGOC_ENABLE_SSL: 0,
MONGOC_ENABLE_CRYPTO: 0,
MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE: 0,
MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION: 0,
MONGOC_ENABLE_COMPRESSION_SNAPPY: 0,
MONGOC_ENABLE_COMPRESSION_ZLIB: 0,
MONGOC_ENABLE_COMPRESSION_ZSTD: 0,
MONGOC_ENABLE_COMPRESSION: 0,
+ MONGOC_ENABLE_MONGODB_AWS_AUTH: 0,
MONGOC_ENABLE_SASL: 0,
MONGOC_ENABLE_SASL_CYRUS: 0,
MONGOC_ENABLE_SASL_GSSAPI: 0,
MONGOC_ENABLE_SASL_SSPI: 0,
MONGOC_ENABLE_ICU: 0,
MONGOC_ENABLE_RDTSCP: 0,
MONGOC_ENABLE_SHM_COUNTERS: 0,
MONGOC_HAVE_ASN1_STRING_GET0_DATA: 0,
MONGOC_HAVE_SASL_CLIENT_DONE: 0,
MONGOC_HAVE_SCHED_GETCPU: 0,
MONGOC_HAVE_SOCKLEN: 1,
MONGOC_HAVE_WEAK_SYMBOLS: 0,
MONGOC_NO_AUTOMATIC_GLOBALS: 1,
MONGOC_SOCKET_ARG2: "struct sockaddr",
MONGOC_SOCKET_ARG3: "socklen_t",
MONGOC_TRACE: 1,
MONGOC_HAVE_DNSAPI: 0,
MONGOC_HAVE_RES_NSEARCH: 0,
MONGOC_HAVE_RES_NDESTROY: 0,
MONGOC_HAVE_RES_NCLOSE: 0,
MONGOC_HAVE_RES_SEARCH: 0,
MONGOC_HAVE_SS_FAMILY: 0,
MONGOC_CC: "",
MONGOC_USER_SET_CFLAGS: "",
MONGOC_USER_SET_LDFLAGS: ""
};
var mongoc_ssl_path_to_check = PHP_MONGODB;
if (typeof PHP_OPENSSL === 'string') {
mongoc_ssl_path_to_check += ";" + PHP_OPENSSL;
}
var mongoc_ssl_found = false;
/* PHP 7.1.2 introduced SETUP_OPENSSL(), which supports OpenSSL 1.1.x. Earlier
* versions will use the legacy check for OpenSSL 1.0.x and lower. */
if (typeof SETUP_OPENSSL === 'function') {
openssl_type = SETUP_OPENSSL("mongodb", mongoc_ssl_path_to_check);
mongoc_ssl_found = openssl_type > 0;
if (openssl_type >= 2) {
mongoc_opts.MONGOC_HAVE_ASN1_STRING_GET0_DATA = 1;
}
} else if (CHECK_LIB("ssleay32.lib", "mongodb", mongoc_ssl_path_to_check) &&
CHECK_LIB("libeay32.lib", "mongodb", mongoc_ssl_path_to_check) &&
CHECK_LIB("crypt32.lib", "mongodb", mongoc_ssl_path_to_check) &&
CHECK_HEADER_ADD_INCLUDE("openssl/ssl.h", "CFLAGS_MONGODB")) {
mongoc_ssl_found = true;
}
if (mongoc_ssl_found) {
mongoc_opts.MONGOC_ENABLE_SSL_OPENSSL = 1;
mongoc_opts.MONGOC_ENABLE_CRYPTO_LIBCRYPTO = 1;
mongoc_opts.MONGOC_ENABLE_SSL = 1;
mongoc_opts.MONGOC_ENABLE_CRYPTO = 1;
+ mongoc_opts.MONGOC_ENABLE_MONGODB_AWS_AUTH = 1;
+
+ ADD_FLAG("CFLAGS_MONGODB", "/D KMS_MSG_STATIC=1 /D KMS_MESSAGE_ENABLE_CRYPTO=1 /D KMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO=1");
} else {
WARNING("mongodb libopenssl support not enabled, libs not found");
}
// TODO: Support building with native GSSAPI (SSPI) on Windows
if (PHP_MONGODB_SASL != "no" &&
CHECK_LIB("libsasl.lib", "mongodb", PHP_MONGODB) &&
CHECK_HEADER_ADD_INCLUDE("sasl/sasl.h", "CFLAGS_MONGODB")) {
mongoc_opts.MONGOC_ENABLE_SASL = 1;
mongoc_opts.MONGOC_ENABLE_SASL_CYRUS = 1;
if (CHECK_FUNC_IN_HEADER("sasl/sasl.h", "sasl_client_done")) {
mongoc_opts.MONGOC_HAVE_SASL_CLIENT_DONE = 1;
}
} else if (PHP_MONGODB_SASL != "no") {
WARNING("mongodb libsasl support not enabled, libs not found");
}
if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION != "no" && mongoc_ssl_found) {
mongoc_opts.MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION = 1;
ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt/src");
ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt/kms-message/src");
ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt-compat");
- ADD_FLAG("CFLAGS_MONGODB", "/D KMS_MSG_STATIC=1 /D KMS_MESSAGE_ENABLE_CRYPTO=1 /D KMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO=1");
var mongocrypt_opts = {
MONGOCRYPT_ENABLE_TRACE: 1,
MONGOCRYPT_ENABLE_CRYPTO: 1,
MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO: 1,
// TODO: Support building with Secure Channel on Windows
MONGOCRYPT_ENABLE_CRYPTO_CNG: 0,
// Secure Transport does not apply to Windows
MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO: 0
};
// Generated with: find src/libmongocrypt/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 4- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOCRYPT_SOURCES="mongocrypt-binary.c mongocrypt-buffer.c mongocrypt.c mongocrypt-cache.c mongocrypt-cache-collinfo.c mongocrypt-cache-key.c mongocrypt-ciphertext.c mongocrypt-crypto.c mongocrypt-ctx.c mongocrypt-ctx-datakey.c mongocrypt-ctx-decrypt.c mongocrypt-ctx-encrypt.c mongocrypt-key-broker.c mongocrypt-key.c mongocrypt-kms-ctx.c mongocrypt-log.c mongocrypt-marking.c mongocrypt-opts.c mongocrypt-status.c mongocrypt-traverse-util.c";
// Generated with: find src/libmongocrypt/src/crypto -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES="cng.c commoncrypto.c libcrypto.c none.c";
// Generated with: find src/libmongocrypt/src/os_posix -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES="os_mutex.c os_once.c";
// Generated with: find src/libmongocrypt/src/os_win -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES="os_mutex.c os_once.c";
// Generated with: find src/libmongocrypt/kms-message/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
- var PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES="hexlify.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_kv_list.c kms_message.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c";
+ var PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES="hexlify.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c";
- ADD_SOURCES(configure_module_dirname + "/src/libmongocrypt/src", PHP_MONGODB_MONGOCRYPT_SOURCES, "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/libmongocrypt/src/crypto", PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES, "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/libmongocrypt/src/os_posix", PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES, "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/libmongocrypt/src/os_win", PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES, "mongodb");
- ADD_SOURCES(configure_module_dirname + "/src/libmongocrypt/kms-message/src", PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES, "mongodb");
+ MONGODB_ADD_SOURCES("/src/libmongocrypt/src", PHP_MONGODB_MONGOCRYPT_SOURCES);
+ MONGODB_ADD_SOURCES("/src/libmongocrypt/src/crypto", PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES);
+ MONGODB_ADD_SOURCES("/src/libmongocrypt/src/os_posix", PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES);
+ MONGODB_ADD_SOURCES("/src/libmongocrypt/src/os_win", PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES);
+ MONGODB_ADD_SOURCES("/src/libmongocrypt/kms-message/src", PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES);
var mongocrypt_version = mongodb_parse_version_file(configure_module_dirname + "/src/LIBMONGOCRYPT_VERSION_CURRENT", "")
mongocrypt_opts.MONGOCRYPT_BUILD_VERSION = mongocrypt_version.VERSION;
mongodb_generate_header(
configure_module_dirname + "/src/libmongocrypt/src/mongocrypt-config.h.in",
configure_module_dirname + "/src/libmongocrypt/src/mongocrypt-config.h",
mongocrypt_opts
);
mongodb_generate_header(
configure_module_dirname + "/src/libmongocrypt/src/mongocrypt.h.in",
configure_module_dirname + "/src/libmongocrypt/src/mongocrypt.h",
mongocrypt_opts
);
} else if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION != "no") {
+ // No SSL library found, we can't enable libmongocrypt
WARNING("mongodb libmongocrypt support not enabled, crypto libs not found");
}
+ if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION == "no" && mongoc_ssl_found) {
+ // Add kms-message sources bundled with libmongoc
+ MONGODB_ADD_SOURCES("/src/libmongoc/src/kms-message/src", PHP_MONGODB_KMS_MESSAGE_SOURCES);
+ ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongoc/src/kms-message/src");
+ }
+
if (CHECK_LIB("dnsapi.lib", "mongodb", PHP_MONGODB) &&
CHECK_HEADER_ADD_INCLUDE("windns.h", "CFLAGS_MONGODB")) {
mongoc_opts.MONGOC_HAVE_DNSAPI = 1;
}
if (CHECK_LIB("icuuc.lib", "mongodb", PHP_MONGODB) &&
CHECK_HEADER_ADD_INCLUDE("unicode/utf.h", "CFLAGS_MONGODB")) {
mongoc_opts.MONGODB_ENABLE_ICU = 1;
ADD_FLAG("LIBS_MONGODB", "icudt.lib icuin.lib icuio.lib");
/* Compat for ICU before 58.1.*/
if (CHECK_LIB("icule.lib", "mongodb", PHP_MONGODB)) {
ADD_FLAG("LIBS_MONGODB", "icule.lib");
}
if (CHECK_LIB("iculx.lib", "mongodb", PHP_MONGODB)) {
ADD_FLAG("LIBS_MONGODB", "iculx.lib");
}
ADD_FLAG("CFLAGS_MONGODB", "/EHsc /D U_USING_ICU_NAMESPACE=1");
}
if (typeof COMPILER_NAME === 'string') {
mongoc_opts.MONGOC_CC = COMPILER_NAME;
} else if (typeof VC_VERSIONS === 'array' && typeof VC_VERSIONS[VCVERS] === 'string') {
mongoc_opts.MONGOC_CC = VC_VERSIONS[VCVERS];
} else if (typeof COMPILER_NAME_LONG === 'string') {
mongoc_opts.MONGOC_CC = COMPILER_NAME_LONG;
}
/* MONGOC_USER_SET_CFLAGS and MONGOC_USER_SET_LDFLAGS can be left blank, as we
* do not expect CFLAGS or LDFLAGS to be customized at build time. */
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in",
configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h",
mongoc_opts
);
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in",
configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h",
mongodb_parse_version_file(configure_module_dirname + "/src/LIBMONGOC_VERSION_CURRENT", "MONGOC_")
);
}
diff --git a/mongodb-1.7.4/phongo_compat.c b/mongodb-1.8.1/phongo_compat.c
similarity index 89%
rename from mongodb-1.7.4/phongo_compat.c
rename to mongodb-1.8.1/phongo_compat.c
index 9b302e8f..20925e59 100644
--- a/mongodb-1.7.4/phongo_compat.c
+++ b/mongodb-1.8.1/phongo_compat.c
@@ -1,94 +1,88 @@
/*
* Copyright 2015-2017 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.
*/
/* Our Compatability header */
#include "phongo_compat.h"
-void phongo_add_exception_prop(const char* prop, int prop_len, zval* value TSRMLS_DC)
+void phongo_add_exception_prop(const char* prop, int prop_len, zval* value)
{
if (EG(exception)) {
-#if PHP_VERSION_ID >= 70000
zval ex;
- EXCEPTION_P(EG(exception), ex);
+ ZVAL_OBJ(&ex, EG(exception));
zend_update_property(Z_OBJCE(ex), &ex, prop, prop_len, value);
-#else
- zval* ex = NULL;
- EXCEPTION_P(EG(exception), ex);
- zend_update_property(Z_OBJCE_P(ex), ex, prop, prop_len, value TSRMLS_CC);
-#endif
}
}
#ifdef ZEND_HASH_GET_APPLY_COUNT /* PHP 7.2 or earlier recursion protection */
zend_bool php_phongo_zend_hash_apply_protection_begin(HashTable* ht)
{
if (!ht) {
return 1;
}
if (ZEND_HASH_GET_APPLY_COUNT(ht) > 0) {
return 0;
}
if (ZEND_HASH_APPLY_PROTECTION(ht)) {
ZEND_HASH_INC_APPLY_COUNT(ht);
}
return 1;
}
zend_bool php_phongo_zend_hash_apply_protection_end(HashTable* ht)
{
if (!ht) {
return 1;
}
if (ZEND_HASH_GET_APPLY_COUNT(ht) == 0) {
return 0;
}
if (ZEND_HASH_APPLY_PROTECTION(ht)) {
ZEND_HASH_DEC_APPLY_COUNT(ht);
}
return 1;
}
#else /* PHP 7.3 or later */
zend_bool php_phongo_zend_hash_apply_protection_begin(zend_array* ht)
{
if (GC_IS_RECURSIVE(ht)) {
return 0;
}
if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) {
GC_PROTECT_RECURSION(ht);
}
return 1;
}
zend_bool php_phongo_zend_hash_apply_protection_end(zend_array* ht)
{
if (!GC_IS_RECURSIVE(ht)) {
return 0;
}
if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) {
GC_UNPROTECT_RECURSION(ht);
}
return 1;
}
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.8.1/phongo_compat.h b/mongodb-1.8.1/phongo_compat.h
new file mode 100644
index 00000000..c97b0649
--- /dev/null
+++ b/mongodb-1.8.1/phongo_compat.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2015-2017 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.
+ */
+
+#ifndef PHONGO_COMPAT_H
+#define PHONGO_COMPAT_H
+
+#include <php.h>
+#include <Zend/zend_string.h>
+#include <Zend/zend_portability.h>
+
+#ifdef PHP_WIN32
+#include "config.w32.h"
+#else
+#include <php_config.h>
+#endif
+
+#ifndef PHP_FE_END
+#define PHP_FE_END \
+ { \
+ NULL, NULL, NULL \
+ }
+#endif
+
+#ifndef HASH_KEY_NON_EXISTENT
+#define HASH_KEY_NON_EXISTENT HASH_KEY_NON_EXISTANT
+#endif
+
+#if defined(__GNUC__)
+#define ARG_UNUSED __attribute__((unused))
+#else
+#define ARG_UNUSED
+#endif
+
+#if defined(__GNUC__)
+#define PHONGO_GNUC_CHECK_VERSION(major, minor) \
+ ((__GNUC__ > (major)) || \
+ ((__GNUC__ == (major)) && (__GNUC_MINOR__ >= (minor))))
+#else
+#define PHONGO_GNUC_CHECK_VERSION(major, minor) 0
+#endif
+
+#if PHONGO_GNUC_CHECK_VERSION(7, 0)
+#define PHONGO_BREAK_INTENTIONALLY_MISSING __attribute__((fallthrough));
+#else
+#define PHONGO_BREAK_INTENTIONALLY_MISSING
+#endif
+
+#if SIZEOF_ZEND_LONG == 8
+#define PHONGO_LONG_FORMAT PRId64
+#elif SIZEOF_ZEND_LONG == 4
+#define PHONGO_LONG_FORMAT PRId32
+#else
+#error Unsupported architecture (integers are neither 32-bit nor 64-bit)
+#endif
+#define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t*) ecalloc(1, sizeof(_obj_t) + zend_object_properties_size(_class_type))
+#define ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRL(_key), (char*) (_value));
+#define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRL(_key), (char*) (_value), _len);
+#define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len, (char*) (_value), _value_len);
+#define ADD_ASSOC_LONG_EX(_zv, _key, _value) add_assoc_long_ex(_zv, ZEND_STRL(_key), _value);
+#define ADD_ASSOC_ZVAL_EX(_zv, _key, _value) add_assoc_zval_ex(_zv, ZEND_STRL(_key), _value);
+#define ADD_ASSOC_ZVAL(_zv, _key, _value) add_assoc_zval(_zv, _key, _value);
+#define ADD_ASSOC_NULL_EX(_zv, _key) add_assoc_null_ex(_zv, ZEND_STRL(_key));
+#define ADD_ASSOC_BOOL_EX(_zv, _key, _value) add_assoc_bool_ex(_zv, ZEND_STRL(_key), _value);
+#define ZVAL_INT64_STRING(_zv, _value) \
+ do { \
+ char tmp[24]; \
+ int tmp_len; \
+ tmp_len = snprintf(tmp, sizeof(tmp), "%" PRId64, (_value)); \
+ ZVAL_STRINGL((_zv), tmp, tmp_len); \
+ } while (0)
+#define ADD_ASSOC_INT64_AS_STRING(_zv, _key, _value) \
+ do { \
+ zval z_int; \
+ ZVAL_INT64_STRING(&z_int, (_value)); \
+ ADD_ASSOC_ZVAL_EX((_zv), (_key), &z_int); \
+ } while (0)
+#define ADD_NEXT_INDEX_STRINGL(_zv, _value, _len) add_next_index_stringl(_zv, _value, _len);
+#define PHONGO_RETVAL_SMART_STR(val) RETVAL_STRINGL(ZSTR_VAL((val).s), ZSTR_LEN((val).s));
+#define ZVAL_STATIC_INIT \
+ { \
+ { \
+ 0 \
+ } \
+ }
+
+#if SIZEOF_ZEND_LONG == 8
+#define ADD_INDEX_INT64(_zv, _index, _value) add_index_long((_zv), (_index), (_value))
+#define ADD_NEXT_INDEX_INT64(_zv, _value) add_next_index_long((_zv), (_value))
+#define ADD_ASSOC_INT64(_zv, _key, _value) add_assoc_long((_zv), (_key), (_value))
+#define ZVAL_INT64(_zv, _value) ZVAL_LONG((_zv), (_value))
+#elif SIZEOF_ZEND_LONG == 4
+#define ADD_INDEX_INT64(_zv, _index, _value) \
+ if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
+ zval zchild; \
+ php_phongo_bson_new_int64(&zchild, (_value)); \
+ add_index_zval((_zv), (_index), &zchild); \
+ } else { \
+ add_index_long((_zv), (_index), (_value)); \
+ }
+#define ADD_NEXT_INDEX_INT64(_zv, _value) \
+ if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
+ zval zchild; \
+ php_phongo_bson_new_int64(&zchild, (_value)); \
+ add_next_index_zval((_zv), &zchild); \
+ } else { \
+ add_next_index_long((_zv), (_value)); \
+ }
+#define ADD_ASSOC_INT64(_zv, _key, _value) \
+ if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
+ zval zchild; \
+ php_phongo_bson_new_int64(&zchild, (_value)); \
+ add_assoc_zval((_zv), (_key), &zchild); \
+ } else { \
+ add_assoc_long((_zv), (_key), (_value)); \
+ }
+#define ZVAL_INT64(_zv, _value) \
+ if ((_value) > INT32_MAX || (_value) < INT32_MIN) { \
+ php_phongo_bson_new_int64((_zv), (_value)); \
+ } else { \
+ ZVAL_LONG((_zv), (_value)); \
+ }
+#else /* SIZEOF_ZEND_LONG != 8 && SIZEOF_ZEND_LONG != 4 */
+#error Unsupported architecture (integers are neither 32-bit nor 64-bit)
+#endif /* SIZEOF_ZEND_LONG */
+
+void phongo_add_exception_prop(const char* prop, int prop_len, zval* value);
+zend_bool php_phongo_zend_hash_apply_protection_begin(HashTable* ht);
+zend_bool php_phongo_zend_hash_apply_protection_end(HashTable* ht);
+
+#endif /* PHONGO_COMPAT_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/mongodb-1.7.4/phongo_version.h b/mongodb-1.8.1/phongo_version.h
similarity index 90%
rename from mongodb-1.7.4/phongo_version.h
rename to mongodb-1.8.1/phongo_version.h
index ec65a72e..cf1fa102 100644
--- a/mongodb-1.7.4/phongo_version.h
+++ b/mongodb-1.8.1/phongo_version.h
@@ -1,26 +1,26 @@
/*
* Copyright 2014-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.
*/
#ifndef PHONGO_VERSION_H
#define PHONGO_VERSION_H
/* clang-format off */
-#define PHP_MONGODB_VERSION "1.7.4"
+#define PHP_MONGODB_VERSION "1.8.1"
#define PHP_MONGODB_STABILITY "stable"
-#define PHP_MONGODB_VERSION_DESC 1,7,4,1
+#define PHP_MONGODB_VERSION_DESC 1,8,1,1
/* clang-format on */
#endif /* PHONGO_VERSION_H */
diff --git a/mongodb-1.7.4/php_bson.h b/mongodb-1.8.1/php_bson.h
similarity index 91%
rename from mongodb-1.7.4/php_bson.h
rename to mongodb-1.8.1/php_bson.h
index 436496d8..b3dbe748 100644
--- a/mongodb-1.7.4/php_bson.h
+++ b/mongodb-1.8.1/php_bson.h
@@ -1,133 +1,129 @@
/*
* Copyright 2014-2017 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.
*/
#ifndef PHONGO_BSON_H
#define PHONGO_BSON_H
#include <bson/bson.h>
/* PHP Core stuff */
#include <php.h>
#define BSON_UNSERIALIZE_FUNC_NAME "bsonUnserialize"
#define BSON_SERIALIZE_FUNC_NAME "bsonSerialize"
#define PHONGO_ODM_FIELD_NAME "__pclass"
typedef enum {
PHONGO_BSON_NONE = 0x00,
PHONGO_BSON_ADD_ID = 0x01,
PHONGO_BSON_RETURN_ID = 0x02
} php_phongo_bson_flags_t;
typedef enum {
PHONGO_TYPEMAP_NONE,
PHONGO_TYPEMAP_NATIVE_ARRAY,
PHONGO_TYPEMAP_NATIVE_OBJECT,
PHONGO_TYPEMAP_CLASS
} php_phongo_bson_typemap_types;
typedef enum {
PHONGO_FIELD_PATH_ITEM_NONE,
PHONGO_FIELD_PATH_ITEM_ARRAY,
PHONGO_FIELD_PATH_ITEM_DOCUMENT
} php_phongo_bson_field_path_item_types;
typedef struct {
char** elements;
php_phongo_bson_field_path_item_types* element_types;
size_t allocated_size;
size_t size;
size_t ref_count;
bool owns_elements;
} php_phongo_field_path;
typedef struct _php_phongo_field_path_map_element {
php_phongo_field_path* entry;
php_phongo_bson_typemap_types node_type;
zend_class_entry* node_ce;
} php_phongo_field_path_map_element;
typedef struct {
php_phongo_bson_typemap_types document_type;
zend_class_entry* document;
php_phongo_bson_typemap_types array_type;
zend_class_entry* array;
php_phongo_bson_typemap_types root_type;
zend_class_entry* root;
struct {
php_phongo_field_path_map_element** map;
size_t allocated_size;
size_t size;
} field_paths;
} php_phongo_bson_typemap;
typedef struct {
- ZVAL_RETVAL_TYPE zchild;
+ zval zchild;
php_phongo_bson_typemap map;
zend_class_entry* odm;
bool is_visiting_array;
php_phongo_field_path* field_path;
} php_phongo_bson_state;
#define PHONGO_BSON_INIT_STATE(s) \
do { \
memset(&(s), 0, sizeof(php_phongo_bson_state)); \
} while (0)
#define PHONGO_BSON_INIT_DEBUG_STATE(s) \
do { \
memset(&(s), 0, sizeof(php_phongo_bson_state)); \
s.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; \
s.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY; \
} while (0)
-void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out TSRMLS_DC);
+void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out);
bool php_phongo_bson_to_zval_ex(const unsigned char* data, int data_len, php_phongo_bson_state* state);
-#if PHP_VERSION_ID >= 70000
bool php_phongo_bson_to_zval(const unsigned char* data, int data_len, zval* out);
-#else
-bool php_phongo_bson_to_zval(const unsigned char* data, int data_len, zval** out);
-#endif
bool php_phongo_bson_value_to_zval(const bson_value_t* value, zval* zv);
-void php_phongo_zval_to_bson_value(zval* data, php_phongo_bson_flags_t flags, bson_value_t* value TSRMLS_DC);
-bool php_phongo_bson_typemap_to_state(zval* typemap, php_phongo_bson_typemap* map TSRMLS_DC);
+void php_phongo_zval_to_bson_value(zval* data, php_phongo_bson_flags_t flags, bson_value_t* value);
+bool php_phongo_bson_typemap_to_state(zval* typemap, php_phongo_bson_typemap* map);
void php_phongo_bson_state_ctor(php_phongo_bson_state* state);
void php_phongo_bson_state_dtor(php_phongo_bson_state* state);
void php_phongo_bson_state_copy_ctor(php_phongo_bson_state* dst, php_phongo_bson_state* src);
void php_phongo_bson_typemap_dtor(php_phongo_bson_typemap* map);
-void php_phongo_bson_new_timestamp_from_increment_and_timestamp(zval* object, uint32_t increment, uint32_t timestamp TSRMLS_DC);
-void php_phongo_bson_new_int64(zval* object, int64_t integer TSRMLS_DC);
+void php_phongo_bson_new_timestamp_from_increment_and_timestamp(zval* object, uint32_t increment, uint32_t timestamp);
+void php_phongo_bson_new_int64(zval* object, int64_t integer);
php_phongo_field_path* php_phongo_field_path_alloc(bool owns_elements);
void php_phongo_field_path_free(php_phongo_field_path* field_path);
void php_phongo_field_path_write_item_at_current_level(php_phongo_field_path* field_path, const char* element);
void php_phongo_field_path_write_type_at_current_level(php_phongo_field_path* field_path, php_phongo_bson_field_path_item_types element_type);
bool php_phongo_field_path_push(php_phongo_field_path* field_path, const char* element, php_phongo_bson_field_path_item_types element_type);
bool php_phongo_field_path_pop(php_phongo_field_path* field_path);
char* php_phongo_field_path_as_string(php_phongo_field_path* field_path);
#endif /* PHONGO_BSON_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/php_phongo.c b/mongodb-1.8.1/php_phongo.c
similarity index 75%
rename from mongodb-1.7.4/php_phongo.c
rename to mongodb-1.8.1/php_phongo.c
index 83f5dfd4..31d234c5 100644
--- a/mongodb-1.7.4/php_phongo.c
+++ b/mongodb-1.8.1/php_phongo.c
@@ -1,4051 +1,3936 @@
/*
* Copyright 2014-2017 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.
*/
/* External libs */
#include "bson/bson.h"
#include "mongoc/mongoc.h"
/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/standard/info.h>
#include <ext/standard/file.h>
#include <Zend/zend_hash.h>
#include <Zend/zend_interfaces.h>
#include <Zend/zend_exceptions.h>
#include <ext/spl/spl_iterators.h>
#include <ext/spl/spl_exceptions.h>
#include <ext/standard/php_var.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#if PHP_VERSION_ID >= 70000
#include <Zend/zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
#include <mongocrypt/mongocrypt.h>
#endif
/* getpid() */
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef PHP_WIN32
#include <process.h>
#endif
/* Stream wrapper */
#include <main/php_streams.h>
#include <main/php_network.h>
/* Debug log writing */
#include <main/php_open_temporary_file.h>
/* For formating timestamp in the log */
#include <ext/date/php_date.h>
/* String manipulation */
#include <Zend/zend_string.h>
/* PHP array helpers */
#include "php_array_api.h"
/* Our Compatability header */
#include "phongo_compat.h"
/* Our stuffz */
#include "php_phongo.h"
#include "php_bson.h"
#include "src/BSON/functions.h"
#include "src/MongoDB/Monitoring/functions.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "PHONGO"
#define PHONGO_DEBUG_INI "mongodb.debug"
#define PHONGO_DEBUG_INI_DEFAULT ""
+#define PHONGO_METADATA_SEPARATOR " / "
+#define PHONGO_METADATA_SEPARATOR_LEN (sizeof(PHONGO_METADATA_SEPARATOR) - 1)
ZEND_DECLARE_MODULE_GLOBALS(mongodb)
-#if PHP_VERSION_ID >= 70000
#if defined(ZTS) && defined(COMPILE_DL_MONGODB)
ZEND_TSRMLS_CACHE_DEFINE();
#endif
-#endif
/* Declare zend_class_entry dependencies, which are initialized in MINIT */
zend_class_entry* php_phongo_date_immutable_ce;
zend_class_entry* php_phongo_json_serializable_ce;
php_phongo_server_description_type_map_t
php_phongo_server_description_type_map[PHONGO_SERVER_DESCRIPTION_TYPES] = {
{ PHONGO_SERVER_UNKNOWN, "Unknown" },
{ PHONGO_SERVER_STANDALONE, "Standalone" },
{ PHONGO_SERVER_MONGOS, "Mongos" },
{ PHONGO_SERVER_POSSIBLE_PRIMARY, "PossiblePrimary" },
{ PHONGO_SERVER_RS_PRIMARY, "RSPrimary" },
{ PHONGO_SERVER_RS_SECONDARY, "RSSecondary" },
{ PHONGO_SERVER_RS_ARBITER, "RSArbiter" },
{ PHONGO_SERVER_RS_OTHER, "RSOther" },
{ PHONGO_SERVER_RS_GHOST, "RSGhost" },
};
/* {{{ phongo_std_object_handlers */
zend_object_handlers phongo_std_object_handlers;
zend_object_handlers* phongo_get_std_object_handlers(void)
{
return &phongo_std_object_handlers;
}
/* }}} */
/* Forward declarations */
static bool phongo_split_namespace(const char* namespace, char** dbname, char** cname);
/* {{{ Error reporting and logging */
zend_class_entry* phongo_exception_from_phongo_domain(php_phongo_error_domain_t domain)
{
switch (domain) {
case PHONGO_ERROR_INVALID_ARGUMENT:
return php_phongo_invalidargumentexception_ce;
case PHONGO_ERROR_LOGIC:
return php_phongo_logicexception_ce;
case PHONGO_ERROR_RUNTIME:
return php_phongo_runtimeexception_ce;
case PHONGO_ERROR_UNEXPECTED_VALUE:
return php_phongo_unexpectedvalueexception_ce;
case PHONGO_ERROR_MONGOC_FAILED:
return php_phongo_runtimeexception_ce;
case PHONGO_ERROR_CONNECTION_FAILED:
return php_phongo_connectionexception_ce;
}
MONGOC_ERROR("Resolving unknown phongo error domain: %d", domain);
return php_phongo_runtimeexception_ce;
}
zend_class_entry* phongo_exception_from_mongoc_domain(mongoc_error_domain_t domain, mongoc_error_code_t code)
{
if (domain == MONGOC_ERROR_CLIENT) {
if (code == MONGOC_ERROR_CLIENT_AUTHENTICATE) {
return php_phongo_authenticationexception_ce;
}
if (code == MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG) {
return php_phongo_invalidargumentexception_ce;
}
}
if (domain == MONGOC_ERROR_COMMAND && code == MONGOC_ERROR_COMMAND_INVALID_ARG) {
return php_phongo_invalidargumentexception_ce;
}
if (domain == MONGOC_ERROR_SERVER) {
if (code == PHONGO_SERVER_ERROR_EXCEEDED_TIME_LIMIT) {
return php_phongo_executiontimeoutexception_ce;
}
return php_phongo_serverexception_ce;
}
if (domain == MONGOC_ERROR_SERVER_SELECTION && code == MONGOC_ERROR_SERVER_SELECTION_FAILURE) {
return php_phongo_connectiontimeoutexception_ce;
}
if (domain == MONGOC_ERROR_STREAM) {
if (code == MONGOC_ERROR_STREAM_SOCKET) {
return php_phongo_connectiontimeoutexception_ce;
}
return php_phongo_connectionexception_ce;
}
if (domain == MONGOC_ERROR_WRITE_CONCERN) {
return php_phongo_serverexception_ce;
}
if (domain == MONGOC_ERROR_PROTOCOL && code == MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION) {
return php_phongo_connectionexception_ce;
}
if (domain == MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION) {
return php_phongo_encryptionexception_ce;
}
return php_phongo_runtimeexception_ce;
}
-void phongo_throw_exception(php_phongo_error_domain_t domain TSRMLS_DC, const char* format, ...)
+void phongo_throw_exception(php_phongo_error_domain_t domain, const char* format, ...)
{
va_list args;
char* message;
int message_len;
va_start(args, format);
message_len = vspprintf(&message, 0, format, args);
- zend_throw_exception(phongo_exception_from_phongo_domain(domain), message, 0 TSRMLS_CC);
+ zend_throw_exception(phongo_exception_from_phongo_domain(domain), message, 0);
efree(message);
va_end(args);
}
-static void phongo_exception_add_error_labels(const bson_t* reply TSRMLS_DC)
+static int phongo_exception_append_error_labels(zval* labels, const bson_iter_t* iter)
{
- bson_iter_t iter;
+ bson_iter_t error_labels;
+ uint32_t label_count = 0;
+
+ if (!BSON_ITER_HOLDS_ARRAY(iter) || !bson_iter_recurse(iter, &error_labels)) {
+ return label_count;
+ }
+
+ while (bson_iter_next(&error_labels)) {
+ if (BSON_ITER_HOLDS_UTF8(&error_labels)) {
+ const char* error_label;
+ uint32_t error_label_len;
+
+ error_label = bson_iter_utf8(&error_labels, &error_label_len);
+ ADD_NEXT_INDEX_STRINGL(labels, error_label, error_label_len);
+ label_count++;
+ }
+ }
+
+ return label_count;
+}
+
+static void phongo_exception_add_error_labels(const bson_t* reply)
+{
+ bson_iter_t iter, child;
+ zval labels;
+ uint32_t label_count = 0;
if (!reply) {
return;
}
- if (bson_iter_init_find(&iter, reply, "errorLabels")) {
- bson_iter_t error_labels;
-#if PHP_VERSION_ID >= 70000
- zval labels;
+ array_init(&labels);
- array_init(&labels);
-#else
- zval* labels = NULL;
+ if (bson_iter_init_find(&iter, reply, "errorLabels")) {
+ label_count += phongo_exception_append_error_labels(&labels, &iter);
+ }
- ALLOC_INIT_ZVAL(labels);
- array_init(labels);
-#endif
+ if (bson_iter_init_find(&iter, reply, "writeConcernError") && BSON_ITER_HOLDS_DOCUMENT(&iter) &&
+ bson_iter_recurse(&iter, &child) && bson_iter_find(&child, "errorLabels")) {
+ label_count += phongo_exception_append_error_labels(&labels, &child);
+ }
- bson_iter_recurse(&iter, &error_labels);
- while (bson_iter_next(&error_labels)) {
- if (BSON_ITER_HOLDS_UTF8(&error_labels)) {
- const char* error_label;
- uint32_t error_label_len;
+ /* mongoc_write_result_t always reports writeConcernErrors in an array, so
+ * we must iterate this to collect WCE labels for BulkWrite replies. */
+ if (bson_iter_init_find(&iter, reply, "writeConcernErrors") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) {
+ bson_iter_t wce;
- error_label = bson_iter_utf8(&error_labels, &error_label_len);
-#if PHP_VERSION_ID >= 70000
- ADD_NEXT_INDEX_STRINGL(&labels, error_label, error_label_len);
-#else
- ADD_NEXT_INDEX_STRINGL(labels, error_label, error_label_len);
-#endif
+ while (bson_iter_next(&child)) {
+ if (BSON_ITER_HOLDS_DOCUMENT(&child) && bson_iter_recurse(&child, &wce) && bson_iter_find(&wce, "errorLabels")) {
+ label_count += phongo_exception_append_error_labels(&labels, &wce);
}
}
+ }
-#if PHP_VERSION_ID >= 70000
+ if (label_count > 0) {
phongo_add_exception_prop(ZEND_STRL("errorLabels"), &labels);
-#else
- phongo_add_exception_prop(ZEND_STRL("errorLabels"), labels TSRMLS_CC);
-#endif
- zval_ptr_dtor(&labels);
}
+
+ zval_ptr_dtor(&labels);
}
-void phongo_throw_exception_from_bson_error_t_and_reply(bson_error_t* error, const bson_t* reply TSRMLS_DC)
+void phongo_throw_exception_from_bson_error_t_and_reply(bson_error_t* error, const bson_t* reply)
{
/* Server errors (other than ExceededTimeLimit) and write concern errors
* may use CommandException and report the result document for the
* failed command. For BC, ExceededTimeLimit errors will continue to use
* ExcecutionTimeoutException and omit the result document. */
if (reply && ((error->domain == MONGOC_ERROR_SERVER && error->code != PHONGO_SERVER_ERROR_EXCEEDED_TIME_LIMIT) || error->domain == MONGOC_ERROR_WRITE_CONCERN)) {
-#if PHP_VERSION_ID >= 70000
zval zv;
-#else
- zval* zv;
-#endif
- zend_throw_exception(php_phongo_commandexception_ce, error->message, error->code TSRMLS_CC);
+ zend_throw_exception(php_phongo_commandexception_ce, error->message, error->code);
if (php_phongo_bson_to_zval(bson_get_data(reply), reply->len, &zv)) {
-#if PHP_VERSION_ID >= 70000
phongo_add_exception_prop(ZEND_STRL("resultDocument"), &zv);
-#else
- phongo_add_exception_prop(ZEND_STRL("resultDocument"), zv TSRMLS_CC);
-#endif
}
zval_ptr_dtor(&zv);
} else {
- zend_throw_exception(phongo_exception_from_mongoc_domain(error->domain, error->code), error->message, error->code TSRMLS_CC);
+ zend_throw_exception(phongo_exception_from_mongoc_domain(error->domain, error->code), error->message, error->code);
}
- phongo_exception_add_error_labels(reply TSRMLS_CC);
+ phongo_exception_add_error_labels(reply);
}
-void phongo_throw_exception_from_bson_error_t(bson_error_t* error TSRMLS_DC)
+void phongo_throw_exception_from_bson_error_t(bson_error_t* error)
{
- phongo_throw_exception_from_bson_error_t_and_reply(error, NULL TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t_and_reply(error, NULL);
}
static void php_phongo_log(mongoc_log_level_t log_level, const char* log_domain, const char* message, void* user_data)
{
struct timeval tv;
time_t t;
- phongo_long tu;
- phongo_char* dt;
+ zend_long tu;
+ zend_string* dt;
- PHONGO_TSRMLS_FETCH_FROM_CTX(user_data);
(void) user_data;
gettimeofday(&tv, NULL);
t = tv.tv_sec;
tu = tv.tv_usec;
- dt = php_format_date((char*) ZEND_STRL("Y-m-d\\TH:i:s"), t, 0 TSRMLS_CC);
+ dt = php_format_date((char*) ZEND_STRL("Y-m-d\\TH:i:s"), t, 0);
fprintf(MONGODB_G(debug_fd), "[%s.%06" PHONGO_LONG_FORMAT "+00:00] %10s: %-8s> %s\n", ZSTR_VAL(dt), tu, log_domain, mongoc_log_level_str(log_level), message);
fflush(MONGODB_G(debug_fd));
efree(dt);
}
/* }}} */
/* {{{ Init objects */
-static void phongo_cursor_init(zval* return_value, mongoc_client_t* client, mongoc_cursor_t* cursor, zval* readPreference, zval* session TSRMLS_DC) /* {{{ */
+static void phongo_cursor_init(zval* return_value, mongoc_client_t* client, mongoc_cursor_t* cursor, zval* readPreference, zval* session) /* {{{ */
{
php_phongo_cursor_t* intern;
object_init_ex(return_value, php_phongo_cursor_ce);
intern = Z_CURSOR_OBJ_P(return_value);
intern->cursor = cursor;
intern->server_id = mongoc_cursor_get_hint(cursor);
intern->client = client;
intern->advanced = false;
intern->got_iterator = false;
intern->current = 0;
if (readPreference) {
-#if PHP_VERSION_ID >= 70000
ZVAL_ZVAL(&intern->read_preference, readPreference, 1, 0);
-#else
- Z_ADDREF_P(readPreference);
- intern->read_preference = readPreference;
-#endif
}
if (session) {
-#if PHP_VERSION_ID >= 70000
ZVAL_ZVAL(&intern->session, session, 1, 0);
-#else
- Z_ADDREF_P(session);
- intern->session = session;
-#endif
}
} /* }}} */
-static void phongo_cursor_init_for_command(zval* return_value, mongoc_client_t* client, mongoc_cursor_t* cursor, const char* db, zval* command, zval* readPreference, zval* session TSRMLS_DC) /* {{{ */
+static void phongo_cursor_init_for_command(zval* return_value, mongoc_client_t* client, mongoc_cursor_t* cursor, const char* db, zval* command, zval* readPreference, zval* session) /* {{{ */
{
php_phongo_cursor_t* intern;
- phongo_cursor_init(return_value, client, cursor, readPreference, session TSRMLS_CC);
+ phongo_cursor_init(return_value, client, cursor, readPreference, session);
intern = Z_CURSOR_OBJ_P(return_value);
intern->database = estrdup(db);
-#if PHP_VERSION_ID >= 70000
ZVAL_ZVAL(&intern->command, command, 1, 0);
-#else
- Z_ADDREF_P(command);
- intern->command = command;
-#endif
} /* }}} */
-static void phongo_cursor_init_for_query(zval* return_value, mongoc_client_t* client, mongoc_cursor_t* cursor, const char* namespace, zval* query, zval* readPreference, zval* session TSRMLS_DC) /* {{{ */
+static void phongo_cursor_init_for_query(zval* return_value, mongoc_client_t* client, mongoc_cursor_t* cursor, const char* namespace, zval* query, zval* readPreference, zval* session) /* {{{ */
{
php_phongo_cursor_t* intern;
- phongo_cursor_init(return_value, client, cursor, readPreference, session TSRMLS_CC);
+ phongo_cursor_init(return_value, client, cursor, readPreference, session);
intern = Z_CURSOR_OBJ_P(return_value);
/* namespace has already been validated by phongo_execute_query() */
phongo_split_namespace(namespace, &intern->database, &intern->collection);
/* cursor has already been advanced by phongo_execute_query() calling
* phongo_cursor_advance_and_check_for_error() */
intern->advanced = true;
-#if PHP_VERSION_ID >= 70000
ZVAL_ZVAL(&intern->query, query, 1, 0);
-#else
- Z_ADDREF_P(query);
- intern->query = query;
-#endif
} /* }}} */
-void phongo_server_init(zval* return_value, mongoc_client_t* client, uint32_t server_id TSRMLS_DC) /* {{{ */
+void phongo_server_init(zval* return_value, mongoc_client_t* client, uint32_t server_id) /* {{{ */
{
php_phongo_server_t* server;
object_init_ex(return_value, php_phongo_server_ce);
server = Z_SERVER_OBJ_P(return_value);
server->server_id = server_id;
server->client = client;
}
/* }}} */
-void phongo_session_init(zval* return_value, mongoc_client_session_t* client_session TSRMLS_DC) /* {{{ */
+void phongo_session_init(zval* return_value, mongoc_client_session_t* client_session) /* {{{ */
{
php_phongo_session_t* session;
object_init_ex(return_value, php_phongo_session_ce);
session = Z_SESSION_OBJ_P(return_value);
session->client_session = client_session;
session->client = mongoc_client_session_get_client(client_session);
}
/* }}} */
-void phongo_readconcern_init(zval* return_value, const mongoc_read_concern_t* read_concern TSRMLS_DC) /* {{{ */
+void phongo_readconcern_init(zval* return_value, const mongoc_read_concern_t* read_concern) /* {{{ */
{
php_phongo_readconcern_t* intern;
object_init_ex(return_value, php_phongo_readconcern_ce);
intern = Z_READCONCERN_OBJ_P(return_value);
intern->read_concern = mongoc_read_concern_copy(read_concern);
}
/* }}} */
-void phongo_readpreference_init(zval* return_value, const mongoc_read_prefs_t* read_prefs TSRMLS_DC) /* {{{ */
+void phongo_readpreference_init(zval* return_value, const mongoc_read_prefs_t* read_prefs) /* {{{ */
{
php_phongo_readpreference_t* intern;
object_init_ex(return_value, php_phongo_readpreference_ce);
intern = Z_READPREFERENCE_OBJ_P(return_value);
intern->read_preference = mongoc_read_prefs_copy(read_prefs);
}
/* }}} */
-void phongo_writeconcern_init(zval* return_value, const mongoc_write_concern_t* write_concern TSRMLS_DC) /* {{{ */
+void phongo_writeconcern_init(zval* return_value, const mongoc_write_concern_t* write_concern) /* {{{ */
{
php_phongo_writeconcern_t* intern;
object_init_ex(return_value, php_phongo_writeconcern_ce);
intern = Z_WRITECONCERN_OBJ_P(return_value);
intern->write_concern = mongoc_write_concern_copy(write_concern);
}
/* }}} */
-zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson TSRMLS_DC) /* {{{ */
+zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson) /* {{{ */
{
bson_iter_t iter;
php_phongo_writeconcernerror_t* intern;
object_init_ex(return_value, php_phongo_writeconcernerror_ce);
intern = Z_WRITECONCERNERROR_OBJ_P(return_value);
intern->code = 0;
if (bson_iter_init_find(&iter, bson, "code") && BSON_ITER_HOLDS_INT32(&iter)) {
intern->code = bson_iter_int32(&iter);
}
if (bson_iter_init_find(&iter, bson, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) {
uint32_t errmsg_len;
const char* err_msg = bson_iter_utf8(&iter, &errmsg_len);
intern->message = estrndup(err_msg, errmsg_len);
}
if (bson_iter_init_find(&iter, bson, "errInfo") && BSON_ITER_HOLDS_DOCUMENT(&iter)) {
uint32_t len;
const uint8_t* data = NULL;
bson_iter_document(&iter, &len, &data);
if (!php_phongo_bson_to_zval(data, len, &intern->info)) {
zval_ptr_dtor(&intern->info);
ZVAL_UNDEF(&intern->info);
return false;
}
}
return true;
} /* }}} */
-zend_bool phongo_writeerror_init(zval* return_value, bson_t* bson TSRMLS_DC) /* {{{ */
+zend_bool phongo_writeerror_init(zval* return_value, bson_t* bson) /* {{{ */
{
bson_iter_t iter;
php_phongo_writeerror_t* intern;
object_init_ex(return_value, php_phongo_writeerror_ce);
intern = Z_WRITEERROR_OBJ_P(return_value);
intern->code = 0;
intern->index = 0;
if (bson_iter_init_find(&iter, bson, "code") && BSON_ITER_HOLDS_INT32(&iter)) {
intern->code = bson_iter_int32(&iter);
}
if (bson_iter_init_find(&iter, bson, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) {
uint32_t errmsg_len;
const char* err_msg = bson_iter_utf8(&iter, &errmsg_len);
intern->message = estrndup(err_msg, errmsg_len);
}
if (bson_iter_init_find(&iter, bson, "errInfo") && BSON_ITER_HOLDS_DOCUMENT(&iter)) {
uint32_t len;
const uint8_t* data = NULL;
bson_iter_document(&iter, &len, &data);
if (!php_phongo_bson_to_zval(data, len, &intern->info)) {
zval_ptr_dtor(&intern->info);
ZVAL_UNDEF(&intern->info);
return false;
}
}
if (bson_iter_init_find(&iter, bson, "index") && BSON_ITER_HOLDS_INT32(&iter)) {
intern->index = bson_iter_int32(&iter);
}
return true;
} /* }}} */
-static php_phongo_writeresult_t* phongo_writeresult_init(zval* return_value, bson_t* reply, mongoc_client_t* client, uint32_t server_id TSRMLS_DC) /* {{{ */
+static php_phongo_writeresult_t* phongo_writeresult_init(zval* return_value, bson_t* reply, mongoc_client_t* client, uint32_t server_id) /* {{{ */
{
php_phongo_writeresult_t* writeresult;
object_init_ex(return_value, php_phongo_writeresult_ce);
writeresult = Z_WRITERESULT_OBJ_P(return_value);
writeresult->reply = bson_copy(reply);
writeresult->server_id = server_id;
writeresult->client = client;
return writeresult;
} /* }}} */
/* }}} */
/* {{{ CRUD */
/* Splits a namespace name into the database and collection names, allocated with estrdup. */
static bool phongo_split_namespace(const char* namespace, char** dbname, char** cname) /* {{{ */
{
char* dot = strchr(namespace, '.');
if (!dot) {
return false;
}
if (cname) {
*cname = estrdup(namespace + (dot - namespace) + 1);
}
if (dbname) {
*dbname = estrndup(namespace, dot - namespace);
}
return true;
} /* }}} */
/* Parses the "readConcern" option for an execute method. If mongoc_opts is not
* NULL, the option will be appended. On error, false is returned and an
* exception is thrown. */
-static bool phongo_parse_read_concern(zval* options, bson_t* mongoc_opts TSRMLS_DC) /* {{{ */
+static bool phongo_parse_read_concern(zval* options, bson_t* mongoc_opts) /* {{{ */
{
zval* option = NULL;
mongoc_read_concern_t* read_concern;
if (!options) {
return true;
}
if (Z_TYPE_P(options) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
return false;
}
option = php_array_fetchc(options, "readConcern");
if (!option) {
return true;
}
- if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_readconcern_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
+ if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_readconcern_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
return false;
}
read_concern = Z_READCONCERN_OBJ_P(option)->read_concern;
if (mongoc_opts && !mongoc_read_concern_append(read_concern, mongoc_opts)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"readConcern\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"readConcern\" option");
return false;
}
return true;
} /* }}} */
/* Parses the "readPreference" option for an execute method. If zreadPreference
* is not NULL, it will be assigned to the option. On error, false is returned
* and an exception is thrown. */
-bool phongo_parse_read_preference(zval* options, zval** zreadPreference TSRMLS_DC) /* {{{ */
+bool phongo_parse_read_preference(zval* options, zval** zreadPreference) /* {{{ */
{
zval* option = NULL;
if (!options) {
return true;
}
if (Z_TYPE_P(options) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
return false;
}
option = php_array_fetchc(options, "readPreference");
if (!option) {
return true;
}
- if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_readpreference_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"readPreference\" option to be %s, %s given", ZSTR_VAL(php_phongo_readpreference_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
+ if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_readpreference_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"readPreference\" option to be %s, %s given", ZSTR_VAL(php_phongo_readpreference_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
return false;
}
if (zreadPreference) {
*zreadPreference = option;
}
return true;
} /* }}} */
/* Parses the "session" option for an execute method. The client object should
* correspond to the Manager executing the operation and will be used to ensure
* that the session is correctly associated with that client. If mongoc_opts is
* not NULL, the option will be appended. If zsession is not NULL, it will be
* assigned to the option. On error, false is returned and an exception is
* thrown. */
-bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession TSRMLS_DC) /* {{{ */
+bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession) /* {{{ */
{
zval* option = NULL;
const mongoc_client_session_t* client_session;
if (!options) {
return true;
}
if (Z_TYPE_P(options) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
return false;
}
option = php_array_fetchc(options, "session");
if (!option) {
return true;
}
- if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_session_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"session\" option to be %s, %s given", ZSTR_VAL(php_phongo_session_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
+ if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_session_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"session\" option to be %s, %s given", ZSTR_VAL(php_phongo_session_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
return false;
}
client_session = Z_SESSION_OBJ_P(option)->client_session;
if (client != mongoc_client_session_get_client(client_session)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot use Session started from a different Manager");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot use Session started from a different Manager");
return false;
}
if (mongoc_opts && !mongoc_client_session_append(client_session, mongoc_opts, NULL)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"session\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"session\" option");
return false;
}
if (zsession) {
*zsession = option;
}
return true;
} /* }}} */
/* Parses the "writeConcern" option for an execute method. If mongoc_opts is not
* NULL, the option will be appended. If zwriteConcern is not NULL, it will be
* assigned to the option. On error, false is returned and an exception is
* thrown. */
-static bool phongo_parse_write_concern(zval* options, bson_t* mongoc_opts, zval** zwriteConcern TSRMLS_DC) /* {{{ */
+static bool phongo_parse_write_concern(zval* options, bson_t* mongoc_opts, zval** zwriteConcern) /* {{{ */
{
zval* option = NULL;
mongoc_write_concern_t* write_concern;
if (!options) {
return true;
}
if (Z_TYPE_P(options) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
return false;
}
option = php_array_fetchc(options, "writeConcern");
if (!option) {
return true;
}
- if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_writeconcern_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"writeConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_writeconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
+ if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_writeconcern_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"writeConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_writeconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
return false;
}
write_concern = Z_WRITECONCERN_OBJ_P(option)->write_concern;
if (mongoc_opts && !mongoc_write_concern_append(write_concern, mongoc_opts)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"writeConcern\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"writeConcern\" option");
return false;
}
if (zwriteConcern) {
*zwriteConcern = option;
}
return true;
}
-bool phongo_execute_bulk_write(mongoc_client_t* client, const char* namespace, php_phongo_bulkwrite_t* bulk_write, zval* options, uint32_t server_id, zval* return_value, int return_value_used TSRMLS_DC) /* {{{ */
+bool phongo_execute_bulk_write(mongoc_client_t* client, const char* namespace, php_phongo_bulkwrite_t* bulk_write, zval* options, uint32_t server_id, zval* return_value) /* {{{ */
{
bson_error_t error = { 0 };
int success;
bson_t reply = BSON_INITIALIZER;
mongoc_bulk_operation_t* bulk = bulk_write->bulk;
php_phongo_writeresult_t* writeresult;
zval* zwriteConcern = NULL;
zval* zsession = NULL;
const mongoc_write_concern_t* write_concern = NULL;
if (bulk_write->executed) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "BulkWrite objects may only be executed once and this instance has already been executed");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "BulkWrite objects may only be executed once and this instance has already been executed");
return false;
}
if (!phongo_split_namespace(namespace, &bulk_write->database, &bulk_write->collection)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s: %s", "Invalid namespace provided", namespace);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s: %s", "Invalid namespace provided", namespace);
return false;
}
- if (!phongo_parse_session(options, client, NULL, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, client, NULL, &zsession)) {
/* Exception should already have been thrown */
return false;
}
- if (!phongo_parse_write_concern(options, NULL, &zwriteConcern TSRMLS_CC)) {
+ if (!phongo_parse_write_concern(options, NULL, &zwriteConcern)) {
/* Exception should already have been thrown */
return false;
}
/* If a write concern was not specified, libmongoc will use the client's
* write concern; however, we should still fetch it for the write result.
* Additionally, we need to check if an unacknowledged write concern would
* conflict with an explicit session. */
write_concern = zwriteConcern ? Z_WRITECONCERN_OBJ_P(zwriteConcern)->write_concern : mongoc_client_get_write_concern(client);
if (zsession && !mongoc_write_concern_is_acknowledged(write_concern)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot combine \"session\" option with an unacknowledged write concern");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot combine \"session\" option with an unacknowledged write concern");
return false;
}
mongoc_bulk_operation_set_database(bulk, bulk_write->database);
mongoc_bulk_operation_set_collection(bulk, bulk_write->collection);
mongoc_bulk_operation_set_client(bulk, client);
mongoc_bulk_operation_set_hint(bulk, server_id);
if (zsession) {
mongoc_bulk_operation_set_client_session(bulk, Z_SESSION_OBJ_P(zsession)->client_session);
}
if (zwriteConcern) {
mongoc_bulk_operation_set_write_concern(bulk, Z_WRITECONCERN_OBJ_P(zwriteConcern)->write_concern);
}
success = mongoc_bulk_operation_execute(bulk, &reply, &error);
bulk_write->executed = true;
- /* Write succeeded and the user doesn't care for the results */
- if (success && !return_value_used) {
- bson_destroy(&reply);
- return true;
- }
-
- writeresult = phongo_writeresult_init(return_value, &reply, client, mongoc_bulk_operation_get_hint(bulk) TSRMLS_CC);
+ writeresult = phongo_writeresult_init(return_value, &reply, client, mongoc_bulk_operation_get_hint(bulk));
writeresult->write_concern = mongoc_write_concern_copy(write_concern);
/* A BulkWriteException is always thrown if mongoc_bulk_operation_execute()
* fails to ensure that the write result is accessible. If the error does
* not originate from the server (e.g. socket error), throw the appropriate
* exception first. It will be included in BulkWriteException's message and
* will also be accessible via Exception::getPrevious(). */
if (!success) {
if (error.domain != MONGOC_ERROR_SERVER && error.domain != MONGOC_ERROR_WRITE_CONCERN) {
- phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply);
}
/* Argument errors occur before command execution, so there is no need
* to layer this InvalidArgumentException behind a BulkWriteException.
* In practice, this will be a "Cannot do an empty bulk write" error. */
if (error.domain == MONGOC_ERROR_COMMAND && error.code == MONGOC_ERROR_COMMAND_INVALID_ARG) {
goto cleanup;
}
if (EG(exception)) {
char* message;
(void) spprintf(&message, 0, "Bulk write failed due to previous %s: %s", PHONGO_ZVAL_EXCEPTION_NAME(EG(exception)), error.message);
- zend_throw_exception(php_phongo_bulkwriteexception_ce, message, 0 TSRMLS_CC);
+ zend_throw_exception(php_phongo_bulkwriteexception_ce, message, 0);
efree(message);
} else {
- zend_throw_exception(php_phongo_bulkwriteexception_ce, error.message, error.code TSRMLS_CC);
+ zend_throw_exception(php_phongo_bulkwriteexception_ce, error.message, error.code);
}
/* Ensure error labels are added to the final BulkWriteException. If a
* previous exception was also thrown, error labels will already have
* been added by phongo_throw_exception_from_bson_error_t_and_reply. */
- phongo_exception_add_error_labels(&reply TSRMLS_CC);
- phongo_add_exception_prop(ZEND_STRL("writeResult"), return_value TSRMLS_CC);
+ phongo_exception_add_error_labels(&reply);
+ phongo_add_exception_prop(ZEND_STRL("writeResult"), return_value);
}
cleanup:
bson_destroy(&reply);
return success;
} /* }}} */
/* Advance the cursor and return whether there is an error. On error, false is
* returned and an exception is thrown. */
-bool phongo_cursor_advance_and_check_for_error(mongoc_cursor_t* cursor TSRMLS_DC) /* {{{ */
+bool phongo_cursor_advance_and_check_for_error(mongoc_cursor_t* cursor) /* {{{ */
{
const bson_t* doc = NULL;
if (!mongoc_cursor_next(cursor, &doc)) {
bson_error_t error = { 0 };
/* Check for connection related exceptions */
if (EG(exception)) {
return false;
}
/* Could simply be no docs, which is not an error */
if (mongoc_cursor_error_document(cursor, &error, &doc)) {
- phongo_throw_exception_from_bson_error_t_and_reply(&error, doc TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t_and_reply(&error, doc);
return false;
}
}
return true;
} /* }}} */
-bool phongo_execute_query(mongoc_client_t* client, const char* namespace, zval* zquery, zval* options, uint32_t server_id, zval* return_value, int return_value_used TSRMLS_DC) /* {{{ */
+bool phongo_execute_query(mongoc_client_t* client, const char* namespace, zval* zquery, zval* options, uint32_t server_id, zval* return_value) /* {{{ */
{
const php_phongo_query_t* query;
bson_t opts = BSON_INITIALIZER;
mongoc_cursor_t* cursor;
char* dbname;
char* collname;
mongoc_collection_t* collection;
zval* zreadPreference = NULL;
zval* zsession = NULL;
if (!phongo_split_namespace(namespace, &dbname, &collname)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s: %s", "Invalid namespace provided", namespace);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s: %s", "Invalid namespace provided", namespace);
return false;
}
collection = mongoc_client_get_collection(client, dbname, collname);
efree(dbname);
efree(collname);
query = Z_QUERY_OBJ_P(zquery);
bson_copy_to(query->opts, &opts);
if (query->read_concern) {
mongoc_collection_set_read_concern(collection, query->read_concern);
}
- if (!phongo_parse_read_preference(options, &zreadPreference TSRMLS_CC)) {
+ if (!phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
mongoc_collection_destroy(collection);
bson_destroy(&opts);
return false;
}
- if (!phongo_parse_session(options, client, &opts, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, client, &opts, &zsession)) {
/* Exception should already have been thrown */
mongoc_collection_destroy(collection);
bson_destroy(&opts);
return false;
}
if (!BSON_APPEND_INT32(&opts, "serverId", server_id)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"serverId\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"serverId\" option");
mongoc_collection_destroy(collection);
bson_destroy(&opts);
return false;
}
- cursor = mongoc_collection_find_with_opts(collection, query->filter, &opts, phongo_read_preference_from_zval(zreadPreference TSRMLS_CC));
+ cursor = mongoc_collection_find_with_opts(collection, query->filter, &opts, phongo_read_preference_from_zval(zreadPreference));
mongoc_collection_destroy(collection);
bson_destroy(&opts);
/* maxAwaitTimeMS must be set before the cursor is sent */
if (query->max_await_time_ms) {
mongoc_cursor_set_max_await_time_ms(cursor, query->max_await_time_ms);
}
- if (!phongo_cursor_advance_and_check_for_error(cursor TSRMLS_CC)) {
+ if (!phongo_cursor_advance_and_check_for_error(cursor)) {
mongoc_cursor_destroy(cursor);
return false;
}
- if (!return_value_used) {
- mongoc_cursor_destroy(cursor);
- return true;
- }
-
- phongo_cursor_init_for_query(return_value, client, cursor, namespace, zquery, zreadPreference, zsession TSRMLS_CC);
+ phongo_cursor_init_for_query(return_value, client, cursor, namespace, zquery, zreadPreference, zsession);
return true;
} /* }}} */
static bson_t* create_wrapped_command_envelope(const char* db, bson_t* reply)
{
bson_t* tmp;
size_t max_ns_len = strlen(db) + 5 + 1; /* db + ".$cmd" + '\0' */
char* ns = emalloc(max_ns_len);
snprintf(ns, max_ns_len, "%s.$cmd", db);
tmp = BCON_NEW("cursor", "{", "id", BCON_INT64(0), "ns", BCON_UTF8(ns), "firstBatch", "[", BCON_DOCUMENT(reply), "]", "}");
efree(ns);
return tmp;
}
-static zval* phongo_create_implicit_session(mongoc_client_t* client TSRMLS_DC) /* {{{ */
+static zval* phongo_create_implicit_session(mongoc_client_t* client) /* {{{ */
{
mongoc_client_session_t* cs;
zval* zsession;
cs = mongoc_client_start_session(client, NULL, NULL);
if (!cs) {
return NULL;
}
-#if PHP_VERSION_ID >= 70000
zsession = ecalloc(sizeof(zval), 1);
-#else
- ALLOC_INIT_ZVAL(zsession);
-#endif
- phongo_session_init(zsession, cs TSRMLS_CC);
+ phongo_session_init(zsession, cs);
return zsession;
} /* }}} */
-bool phongo_execute_command(mongoc_client_t* client, php_phongo_command_type_t type, const char* db, zval* zcommand, zval* options, uint32_t server_id, zval* return_value, int return_value_used TSRMLS_DC) /* {{{ */
+bool phongo_execute_command(mongoc_client_t* client, php_phongo_command_type_t type, const char* db, zval* zcommand, zval* options, uint32_t server_id, zval* return_value) /* {{{ */
{
const php_phongo_command_t* command;
bson_iter_t iter;
bson_t reply;
bson_error_t error = { 0 };
bson_t opts = BSON_INITIALIZER;
mongoc_cursor_t* cmd_cursor;
zval* zreadPreference = NULL;
zval* zsession = NULL;
bool result = false;
bool free_reply = false;
bool free_zsession = false;
bool is_unacknowledged_write_concern = false;
command = Z_COMMAND_OBJ_P(zcommand);
- if ((type & PHONGO_OPTION_READ_CONCERN) && !phongo_parse_read_concern(options, &opts TSRMLS_CC)) {
+ if ((type & PHONGO_OPTION_READ_CONCERN) && !phongo_parse_read_concern(options, &opts)) {
/* Exception should already have been thrown */
goto cleanup;
}
- if ((type & PHONGO_OPTION_READ_PREFERENCE) && !phongo_parse_read_preference(options, &zreadPreference TSRMLS_CC)) {
+ if ((type & PHONGO_OPTION_READ_PREFERENCE) && !phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
goto cleanup;
}
- if (!phongo_parse_session(options, client, &opts, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, client, &opts, &zsession)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (type & PHONGO_OPTION_WRITE_CONCERN) {
zval* zwriteConcern = NULL;
- if (!phongo_parse_write_concern(options, &opts, &zwriteConcern TSRMLS_CC)) {
+ if (!phongo_parse_write_concern(options, &opts, &zwriteConcern)) {
/* Exception should already have been thrown */
goto cleanup;
}
/* Determine if the explicit or inherited write concern is
* unacknowledged so that we can ensure it does not conflict with an
* explicit or implicit session. */
if (zwriteConcern) {
is_unacknowledged_write_concern = !mongoc_write_concern_is_acknowledged(Z_WRITECONCERN_OBJ_P(zwriteConcern)->write_concern);
} else if (type != PHONGO_COMMAND_RAW) {
is_unacknowledged_write_concern = !mongoc_write_concern_is_acknowledged(mongoc_client_get_write_concern(client));
}
}
if (zsession && is_unacknowledged_write_concern) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot combine \"session\" option with an unacknowledged write concern");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot combine \"session\" option with an unacknowledged write concern");
goto cleanup;
}
/* If an explicit session was not provided and the effective write concern
* is not unacknowledged, attempt to create an implicit client session
* (ignoring any errors). */
if (!zsession && !is_unacknowledged_write_concern) {
- zsession = phongo_create_implicit_session(client TSRMLS_CC);
+ zsession = phongo_create_implicit_session(client);
if (zsession) {
free_zsession = true;
if (!mongoc_client_session_append(Z_SESSION_OBJ_P(zsession)->client_session, &opts, NULL)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending implicit \"sessionId\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending implicit \"sessionId\" option");
goto cleanup;
}
}
}
if (!BSON_APPEND_INT32(&opts, "serverId", server_id)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"serverId\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"serverId\" option");
goto cleanup;
}
/* Although "opts" already always includes the serverId option, the read
* preference is added to the command parts, which is relevant for mongos
* command construction. */
switch (type) {
case PHONGO_COMMAND_RAW:
- result = mongoc_client_command_with_opts(client, db, command->bson, phongo_read_preference_from_zval(zreadPreference TSRMLS_CC), &opts, &reply, &error);
+ result = mongoc_client_command_with_opts(client, db, command->bson, phongo_read_preference_from_zval(zreadPreference), &opts, &reply, &error);
break;
case PHONGO_COMMAND_READ:
- result = mongoc_client_read_command_with_opts(client, db, command->bson, phongo_read_preference_from_zval(zreadPreference TSRMLS_CC), &opts, &reply, &error);
+ result = mongoc_client_read_command_with_opts(client, db, command->bson, phongo_read_preference_from_zval(zreadPreference), &opts, &reply, &error);
break;
case PHONGO_COMMAND_WRITE:
result = mongoc_client_write_command_with_opts(client, db, command->bson, &opts, &reply, &error);
break;
case PHONGO_COMMAND_READ_WRITE:
/* We can pass NULL as readPreference, as this argument was added historically, but has no function */
result = mongoc_client_read_write_command_with_opts(client, db, command->bson, NULL, &opts, &reply, &error);
break;
default:
/* Should never happen, but if it does: exception */
- phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Type '%d' should never have been passed to phongo_execute_command, please file a bug report", type);
+ phongo_throw_exception(PHONGO_ERROR_LOGIC, "Type '%d' should never have been passed to phongo_execute_command, please file a bug report", type);
goto cleanup;
}
free_reply = true;
if (!result) {
- phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply TSRMLS_CC);
- goto cleanup;
- }
-
- if (!return_value_used) {
+ phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply);
goto cleanup;
}
/* According to mongoc_cursor_new_from_command_reply_with_opts(), the reply
* bson_t is ultimately destroyed on both success and failure. */
if (bson_iter_init_find(&iter, &reply, "cursor") && BSON_ITER_HOLDS_DOCUMENT(&iter)) {
bson_t initial_reply = BSON_INITIALIZER;
bson_t cursor_opts = BSON_INITIALIZER;
bson_error_t error = { 0 };
bson_copy_to(&reply, &initial_reply);
bson_append_int32(&cursor_opts, "serverId", -1, server_id);
if (command->max_await_time_ms) {
bson_append_bool(&cursor_opts, "awaitData", -1, 1);
bson_append_int64(&cursor_opts, "maxAwaitTimeMS", -1, command->max_await_time_ms);
bson_append_bool(&cursor_opts, "tailable", -1, 1);
}
if (command->batch_size) {
bson_append_int64(&cursor_opts, "batchSize", -1, command->batch_size);
}
if (zsession && !mongoc_client_session_append(Z_SESSION_OBJ_P(zsession)->client_session, &cursor_opts, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
bson_destroy(&initial_reply);
bson_destroy(&cursor_opts);
result = false;
goto cleanup;
}
cmd_cursor = mongoc_cursor_new_from_command_reply_with_opts(client, &initial_reply, &cursor_opts);
bson_destroy(&cursor_opts);
} else {
bson_t cursor_opts = BSON_INITIALIZER;
bson_t* wrapped_reply = create_wrapped_command_envelope(db, &reply);
bson_append_int32(&cursor_opts, "serverId", -1, server_id);
cmd_cursor = mongoc_cursor_new_from_command_reply_with_opts(client, wrapped_reply, &cursor_opts);
bson_destroy(&cursor_opts);
}
- phongo_cursor_init_for_command(return_value, client, cmd_cursor, db, zcommand, zreadPreference, zsession TSRMLS_CC);
+ phongo_cursor_init_for_command(return_value, client, cmd_cursor, db, zcommand, zreadPreference, zsession);
cleanup:
bson_destroy(&opts);
if (free_reply) {
bson_destroy(&reply);
}
if (free_zsession) {
-#if PHP_VERSION_ID >= 70000
zval_ptr_dtor(zsession);
efree(zsession);
-#else
- zval_ptr_dtor(&zsession);
-#endif
}
return result;
} /* }}} */
/* }}} */
/* {{{ mongoc types from from_zval */
-const mongoc_write_concern_t* phongo_write_concern_from_zval(zval* zwrite_concern TSRMLS_DC) /* {{{ */
+const mongoc_write_concern_t* phongo_write_concern_from_zval(zval* zwrite_concern) /* {{{ */
{
if (zwrite_concern) {
php_phongo_writeconcern_t* intern = Z_WRITECONCERN_OBJ_P(zwrite_concern);
if (intern) {
return intern->write_concern;
}
}
return NULL;
} /* }}} */
-const mongoc_read_concern_t* phongo_read_concern_from_zval(zval* zread_concern TSRMLS_DC) /* {{{ */
+const mongoc_read_concern_t* phongo_read_concern_from_zval(zval* zread_concern) /* {{{ */
{
if (zread_concern) {
php_phongo_readconcern_t* intern = Z_READCONCERN_OBJ_P(zread_concern);
if (intern) {
return intern->read_concern;
}
}
return NULL;
} /* }}} */
-const mongoc_read_prefs_t* phongo_read_preference_from_zval(zval* zread_preference TSRMLS_DC) /* {{{ */
+const mongoc_read_prefs_t* phongo_read_preference_from_zval(zval* zread_preference) /* {{{ */
{
if (zread_preference) {
php_phongo_readpreference_t* intern = Z_READPREFERENCE_OBJ_P(zread_preference);
if (intern) {
return intern->read_preference;
}
}
return NULL;
} /* }}} */
/* }}} */
/* {{{ phongo zval from mongoc types */
php_phongo_server_description_type_t php_phongo_server_description_type(mongoc_server_description_t* sd)
{
const char* name = mongoc_server_description_type(sd);
int i;
for (i = 0; i < PHONGO_SERVER_DESCRIPTION_TYPES; i++) {
if (!strcmp(name, php_phongo_server_description_type_map[i].name)) {
return php_phongo_server_description_type_map[i].type;
}
}
return PHONGO_SERVER_UNKNOWN;
}
bool php_phongo_server_to_zval(zval* retval, mongoc_server_description_t* sd) /* {{{ */
{
mongoc_host_list_t* host = mongoc_server_description_host(sd);
const bson_t* is_master = mongoc_server_description_ismaster(sd);
bson_iter_t iter;
array_init(retval);
ADD_ASSOC_STRING(retval, "host", host->host);
ADD_ASSOC_LONG_EX(retval, "port", host->port);
ADD_ASSOC_LONG_EX(retval, "type", php_phongo_server_description_type(sd));
ADD_ASSOC_BOOL_EX(retval, "is_primary", !strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_PRIMARY].name));
ADD_ASSOC_BOOL_EX(retval, "is_secondary", !strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_SECONDARY].name));
ADD_ASSOC_BOOL_EX(retval, "is_arbiter", !strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_ARBITER].name));
ADD_ASSOC_BOOL_EX(retval, "is_hidden", bson_iter_init_find_case(&iter, is_master, "hidden") && bson_iter_as_bool(&iter));
ADD_ASSOC_BOOL_EX(retval, "is_passive", bson_iter_init_find_case(&iter, is_master, "passive") && bson_iter_as_bool(&iter));
if (bson_iter_init_find(&iter, is_master, "tags") && BSON_ITER_HOLDS_DOCUMENT(&iter)) {
const uint8_t* bytes;
uint32_t len;
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
bson_iter_document(&iter, &len, &bytes);
if (!php_phongo_bson_to_zval_ex(bytes, len, &state)) {
zval_ptr_dtor(&state.zchild);
return false;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(retval, "tags", &state.zchild);
-#else
- ADD_ASSOC_ZVAL_EX(retval, "tags", state.zchild);
-#endif
}
{
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
if (!php_phongo_bson_to_zval_ex(bson_get_data(is_master), is_master->len, &state)) {
zval_ptr_dtor(&state.zchild);
return false;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(retval, "last_is_master", &state.zchild);
-#else
- ADD_ASSOC_ZVAL_EX(retval, "last_is_master", state.zchild);
-#endif
}
- ADD_ASSOC_LONG_EX(retval, "round_trip_time", (phongo_long) mongoc_server_description_round_trip_time(sd));
+ ADD_ASSOC_LONG_EX(retval, "round_trip_time", (zend_long) mongoc_server_description_round_trip_time(sd));
return true;
} /* }}} */
void php_phongo_read_concern_to_zval(zval* retval, const mongoc_read_concern_t* read_concern) /* {{{ */
{
const char* level = mongoc_read_concern_get_level(read_concern);
array_init_size(retval, 1);
if (level) {
ADD_ASSOC_STRING(retval, "level", level);
}
} /* }}} */
/* If options is not an array, insert it as a field in a newly allocated array.
* This may be used to convert legacy options (e.g. ReadPreference option for
* an executeQuery method) into an options array.
*
* A pointer to the array zval will always be returned. If allocated is set to
* true, php_phongo_prep_legacy_option_free() should be used to free the array
* zval later. */
-zval* php_phongo_prep_legacy_option(zval* options, const char* key, bool* allocated TSRMLS_DC) /* {{{ */
+zval* php_phongo_prep_legacy_option(zval* options, const char* key, bool* allocated) /* {{{ */
{
*allocated = false;
if (options && Z_TYPE_P(options) != IS_ARRAY) {
-#if PHP_VERSION_ID >= 70000
zval* new_options = ecalloc(sizeof(zval), 1);
-#else
- zval* new_options = NULL;
- ALLOC_INIT_ZVAL(new_options);
-#endif
array_init_size(new_options, 1);
add_assoc_zval(new_options, key, options);
Z_ADDREF_P(options);
*allocated = true;
return new_options;
}
return options;
} /* }}} */
-void php_phongo_prep_legacy_option_free(zval* options TSRMLS_DC) /* {{{ */
+void php_phongo_prep_legacy_option_free(zval* options) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval_ptr_dtor(options);
efree(options);
-#else
- zval_ptr_dtor(&options);
-#endif
} /* }}} */
/* Prepare tagSets for BSON encoding by converting each array in the set to an
* object. This ensures that empty arrays will serialize as empty documents.
*
* php_phongo_read_preference_tags_are_valid() handles actual validation of the
* tag set structure. */
-void php_phongo_read_preference_prep_tagsets(zval* tagSets TSRMLS_DC) /* {{{ */
+void php_phongo_read_preference_prep_tagsets(zval* tagSets) /* {{{ */
{
HashTable* ht_data;
+ zval* tagSet;
if (Z_TYPE_P(tagSets) != IS_ARRAY) {
return;
}
ht_data = HASH_OF(tagSets);
-#if PHP_VERSION_ID >= 70000
- {
- zval* tagSet;
-
- ZEND_HASH_FOREACH_VAL_IND(ht_data, tagSet)
- {
- ZVAL_DEREF(tagSet);
- if (Z_TYPE_P(tagSet) == IS_ARRAY) {
- SEPARATE_ZVAL_NOREF(tagSet);
- convert_to_object(tagSet);
- }
- }
- ZEND_HASH_FOREACH_END();
- }
-#else
+ ZEND_HASH_FOREACH_VAL_IND(ht_data, tagSet)
{
- HashPosition pos;
- zval** tagSet;
-
- for (
- zend_hash_internal_pointer_reset_ex(ht_data, &pos);
- zend_hash_get_current_data_ex(ht_data, (void**) &tagSet, &pos) == SUCCESS;
- zend_hash_move_forward_ex(ht_data, &pos)) {
-
- if (Z_TYPE_PP(tagSet) == IS_ARRAY) {
- SEPARATE_ZVAL_IF_NOT_REF(tagSet);
- convert_to_object(*tagSet);
- }
+ ZVAL_DEREF(tagSet);
+ if (Z_TYPE_P(tagSet) == IS_ARRAY) {
+ SEPARATE_ZVAL_NOREF(tagSet);
+ convert_to_object(tagSet);
}
}
-#endif
-
- return;
+ ZEND_HASH_FOREACH_END();
} /* }}} */
/* Checks if tags is valid to set on a mongoc_read_prefs_t. It may be null or an
* array of one or more documents. */
bool php_phongo_read_preference_tags_are_valid(const bson_t* tags) /* {{{ */
{
bson_iter_t iter;
if (bson_empty0(tags)) {
return true;
}
if (!bson_iter_init(&iter, tags)) {
return false;
}
while (bson_iter_next(&iter)) {
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
return false;
}
}
return true;
} /* }}} */
void php_phongo_write_concern_to_zval(zval* retval, const mongoc_write_concern_t* write_concern) /* {{{ */
{
const char* wtag = mongoc_write_concern_get_wtag(write_concern);
const int32_t w = mongoc_write_concern_get_w(write_concern);
const int64_t wtimeout = mongoc_write_concern_get_wtimeout_int64(write_concern);
array_init_size(retval, 4);
if (wtag) {
ADD_ASSOC_STRING(retval, "w", wtag);
} else if (mongoc_write_concern_get_wmajority(write_concern)) {
ADD_ASSOC_STRING(retval, "w", PHONGO_WRITE_CONCERN_W_MAJORITY);
} else if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) {
ADD_ASSOC_LONG_EX(retval, "w", w);
}
if (mongoc_write_concern_journal_is_set(write_concern)) {
ADD_ASSOC_BOOL_EX(retval, "j", mongoc_write_concern_get_journal(write_concern));
}
if (wtimeout != 0) {
-#if SIZEOF_LONG == 4
+#if SIZEOF_ZEND_LONG == 4
if (wtimeout > INT32_MAX || wtimeout < INT32_MIN) {
ADD_ASSOC_INT64_AS_STRING(&retval, "wtimeout", wtimeout);
} else {
ADD_ASSOC_LONG_EX(retval, "wtimeout", wtimeout);
}
#else
ADD_ASSOC_LONG_EX(retval, "wtimeout", wtimeout);
#endif
}
} /* }}} */
/* }}} */
-static mongoc_uri_t* php_phongo_make_uri(const char* uri_string TSRMLS_DC) /* {{{ */
+static mongoc_uri_t* php_phongo_make_uri(const char* uri_string) /* {{{ */
{
mongoc_uri_t* uri;
bson_error_t error = { 0 };
uri = mongoc_uri_new_with_error(uri_string, &error);
MONGOC_DEBUG("Connection string: '%s'", uri_string);
if (!uri) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse MongoDB URI: '%s'. %s.", uri_string, error.message);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse MongoDB URI: '%s'. %s.", uri_string, error.message);
return NULL;
}
return uri;
} /* }}} */
static const char* php_phongo_bson_type_to_string(bson_type_t type) /* {{{ */
{
switch (type) {
case BSON_TYPE_EOD:
return "EOD";
case BSON_TYPE_DOUBLE:
return "double";
case BSON_TYPE_UTF8:
return "string";
case BSON_TYPE_DOCUMENT:
return "document";
case BSON_TYPE_ARRAY:
return "array";
case BSON_TYPE_BINARY:
return "Binary";
case BSON_TYPE_UNDEFINED:
return "undefined";
case BSON_TYPE_OID:
return "ObjectId";
case BSON_TYPE_BOOL:
return "boolean";
case BSON_TYPE_DATE_TIME:
return "UTCDateTime";
case BSON_TYPE_NULL:
return "null";
case BSON_TYPE_REGEX:
return "Regex";
case BSON_TYPE_DBPOINTER:
return "DBPointer";
case BSON_TYPE_CODE:
return "Javascript";
case BSON_TYPE_SYMBOL:
return "symbol";
case BSON_TYPE_CODEWSCOPE:
return "Javascript with scope";
case BSON_TYPE_INT32:
return "32-bit integer";
case BSON_TYPE_TIMESTAMP:
return "Timestamp";
case BSON_TYPE_INT64:
return "64-bit integer";
case BSON_TYPE_DECIMAL128:
return "Decimal128";
case BSON_TYPE_MAXKEY:
return "MaxKey";
case BSON_TYPE_MINKEY:
return "MinKey";
default:
return "unknown";
}
} /* }}} */
#define PHONGO_URI_INVALID_TYPE(iter, expected) \
phongo_throw_exception( \
- PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, \
+ PHONGO_ERROR_INVALID_ARGUMENT, \
"Expected %s for \"%s\" URI option, %s given", \
(expected), \
bson_iter_key(&(iter)), \
php_phongo_bson_type_to_string(bson_iter_type(&(iter))))
-static bool php_phongo_uri_finalize_auth(mongoc_uri_t* uri TSRMLS_DC) /* {{{ */
+static bool php_phongo_uri_finalize_auth(mongoc_uri_t* uri) /* {{{ */
{
+ const bson_t* credentials = mongoc_uri_get_credentials(uri);
+ bson_iter_t iter;
+ const char* source = NULL;
+ const char* username = mongoc_uri_get_username(uri);
+ bool require_auth = username != NULL;
+
+ if (bson_iter_init_find_case(&iter, credentials, MONGOC_URI_AUTHSOURCE)) {
+ source = bson_iter_utf8(&iter, NULL);
+ require_auth = true;
+ }
+
/* authSource with GSSAPI or X509 should always be external */
if (mongoc_uri_get_auth_mechanism(uri)) {
if (!strcasecmp(mongoc_uri_get_auth_mechanism(uri), "GSSAPI") ||
!strcasecmp(mongoc_uri_get_auth_mechanism(uri), "MONGODB-X509")) {
- const char* source = mongoc_uri_get_auth_source(uri);
if (source) {
if (strcasecmp(source, "$external")) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse URI options: GSSAPI and X509 require \"$external\" authSource.");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse URI options: GSSAPI and X509 require \"$external\" authSource.");
return false;
}
} else {
mongoc_uri_set_auth_source(uri, "$external");
}
}
- /* MONGODB-X509 is the only mechanism that doesn't require username */
- if (strcasecmp(mongoc_uri_get_auth_mechanism(uri), "MONGODB-X509")) {
+ /* Mechanisms other than MONGODB-X509 and MONGODB-AWS require a username */
+ if (strcasecmp(mongoc_uri_get_auth_mechanism(uri), "MONGODB-X509") &&
+ strcasecmp(mongoc_uri_get_auth_mechanism(uri), "MONGODB-AWS")) {
if (!mongoc_uri_get_username(uri) ||
!strcmp(mongoc_uri_get_username(uri), "")) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse URI options: '%s' authentication mechanism requires username.", mongoc_uri_get_auth_mechanism(uri));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse URI options: '%s' authentication mechanism requires username.", mongoc_uri_get_auth_mechanism(uri));
return false;
}
}
/* MONGODB-X509 errors if a password is supplied. */
if (!strcasecmp(mongoc_uri_get_auth_mechanism(uri), "MONGODB-X509")) {
if (mongoc_uri_get_password(uri)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse URI options: X509 authentication mechanism does not accept a password.");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse URI options: X509 authentication mechanism does not accept a password.");
return false;
}
}
+ } else if (require_auth) {
+ if (source && strcmp(source, "$external") != 0 && (!username || strcmp(username, "") == 0)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse URI options: Default authentication mechanism requires username.");
+ return false;
+ }
+ }
+
+ return true;
+} /* }}} */
+
+static bool php_phongo_uri_finalize_directconnection(mongoc_uri_t* uri) /* {{{ */
+{
+ const mongoc_host_list_t* hosts;
+
+ if (!mongoc_uri_get_option_as_bool(uri, MONGOC_URI_DIRECTCONNECTION, false)) {
+ return true;
+ }
+
+ /* Per the URI options spec, directConnection conflicts with multiple hosts
+ * and SRV URIs, which may resolve to multiple hosts. */
+ if (!strncmp(mongoc_uri_get_string(uri), "mongodb+srv://", 14)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse URI options: SRV URI not allowed with directConnection option.");
+ return false;
+ }
+
+ hosts = mongoc_uri_get_hosts(uri);
+
+ if (hosts && hosts->next) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse URI options: Multiple seeds not allowed with directConnection option.");
+ return false;
}
return true;
} /* }}} */
-static bool php_phongo_uri_finalize_tls(mongoc_uri_t* uri TSRMLS_DC) /* {{{ */
+static bool php_phongo_uri_finalize_tls(mongoc_uri_t* uri) /* {{{ */
{
const bson_t* options;
bson_iter_t iter;
if (!(options = mongoc_uri_get_options(uri))) {
return true;
}
if (bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSINSECURE) &&
(bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) ||
- bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse URI options: %s may not be combined with %s or %s.", MONGOC_URI_TLSINSECURE, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES);
+ bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES) ||
+ bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK) ||
+ bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK))) {
+ phongo_throw_exception(
+ PHONGO_ERROR_INVALID_ARGUMENT,
+ "Failed to parse URI options: %s may not be combined with %s, %s, %s, or %s.",
+ MONGOC_URI_TLSINSECURE,
+ MONGOC_URI_TLSALLOWINVALIDCERTIFICATES,
+ MONGOC_URI_TLSALLOWINVALIDHOSTNAMES,
+ MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK,
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK);
+ return false;
+ }
+
+ if (bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) &&
+ (bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK) ||
+ bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK))) {
+ phongo_throw_exception(
+ PHONGO_ERROR_INVALID_ARGUMENT,
+ "Failed to parse URI options: %s may not be combined with %s or %s.",
+ MONGOC_URI_TLSALLOWINVALIDCERTIFICATES,
+ MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK,
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK);
return false;
}
return true;
} /* }}} */
-static bool php_phongo_apply_options_to_uri(mongoc_uri_t* uri, bson_t* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_apply_options_to_uri(mongoc_uri_t* uri, bson_t* options) /* {{{ */
{
bson_iter_t iter;
/* Return early if there are no options to apply */
if (bson_empty0(options) || !bson_iter_init(&iter, options)) {
return true;
}
while (bson_iter_next(&iter)) {
const char* key = bson_iter_key(&iter);
/* Skip read preference, read concern, and write concern options, as
* those will be processed by other functions. */
if (!strcasecmp(key, MONGOC_URI_JOURNAL) ||
!strcasecmp(key, MONGOC_URI_MAXSTALENESSSECONDS) ||
!strcasecmp(key, MONGOC_URI_READCONCERNLEVEL) ||
!strcasecmp(key, MONGOC_URI_READPREFERENCE) ||
!strcasecmp(key, MONGOC_URI_READPREFERENCETAGS) ||
!strcasecmp(key, MONGOC_URI_SAFE) ||
!strcasecmp(key, MONGOC_URI_SLAVEOK) ||
!strcasecmp(key, MONGOC_URI_W) ||
!strcasecmp(key, MONGOC_URI_WTIMEOUTMS)) {
continue;
}
if (mongoc_uri_option_is_bool(key)) {
/* The option's type is not validated because bson_iter_as_bool() is
* used to cast the value to a boolean. Validation may be introduced
* in PHPC-990. */
if (!mongoc_uri_set_option_as_bool(uri, key, bson_iter_as_bool(&iter))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (mongoc_uri_option_is_int32(key)) {
if (!BSON_ITER_HOLDS_INT32(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "32-bit integer");
return false;
}
if (!mongoc_uri_set_option_as_int32(uri, key, bson_iter_int32(&iter))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (mongoc_uri_option_is_utf8(key)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!strcasecmp(key, MONGOC_URI_REPLICASET) && !strcmp("", bson_iter_utf8(&iter, NULL))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Value for URI option \"%s\" cannot be empty string.", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Value for URI option \"%s\" cannot be empty string.", key);
return false;
}
if (!mongoc_uri_set_option_as_utf8(uri, key, bson_iter_utf8(&iter, NULL))) {
/* Assignment uses mongoc_uri_set_appname() for the "appname"
* option, which validates length in addition to UTF-8 encoding.
* For BC, we report the invalid string to the user. */
if (!strcasecmp(key, MONGOC_URI_APPNAME)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid appname value: '%s'", bson_iter_utf8(&iter, NULL));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Invalid appname value: '%s'", bson_iter_utf8(&iter, NULL));
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
}
return false;
}
continue;
}
if (!strcasecmp(key, "username")) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_username(uri, bson_iter_utf8(&iter, NULL))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, "password")) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_password(uri, bson_iter_utf8(&iter, NULL))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, MONGOC_URI_AUTHMECHANISM)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_auth_mechanism(uri, bson_iter_utf8(&iter, NULL))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, MONGOC_URI_AUTHSOURCE)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_auth_source(uri, bson_iter_utf8(&iter, NULL))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, MONGOC_URI_AUTHMECHANISMPROPERTIES)) {
bson_t properties;
uint32_t len;
const uint8_t* data;
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "array or object");
return false;
}
bson_iter_document(&iter, &len, &data);
if (!bson_init_static(&properties, data, len)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Could not initialize BSON structure for auth mechanism properties");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Could not initialize BSON structure for auth mechanism properties");
return false;
}
if (!mongoc_uri_set_mechanism_properties(uri, &properties)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, MONGOC_URI_GSSAPISERVICENAME)) {
bson_t unused, properties = BSON_INITIALIZER;
if (mongoc_uri_get_mechanism_properties(uri, &unused)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "authMechanismProperties SERVICE_NAME already set, ignoring \"%s\"", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "authMechanismProperties SERVICE_NAME already set, ignoring \"%s\"", key);
return false;
}
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
bson_append_utf8(&properties, "SERVICE_NAME", -1, bson_iter_utf8(&iter, NULL), -1);
if (!mongoc_uri_set_mechanism_properties(uri, &properties)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
bson_destroy(&properties);
return false;
}
bson_destroy(&properties);
continue;
}
if (!strcasecmp(key, MONGOC_URI_COMPRESSORS)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_compressors(uri, bson_iter_utf8(&iter, NULL))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
}
- // Finalize auth options
- if (!php_phongo_uri_finalize_auth(uri TSRMLS_CC)) {
+ /* Validate any interactions between URI options */
+ if (!php_phongo_uri_finalize_auth(uri)) {
+ /* Exception should already have been thrown */
+ return false;
+ }
+
+ if (!php_phongo_uri_finalize_directconnection(uri)) {
/* Exception should already have been thrown */
return false;
}
return true;
} /* }}} */
-static bool php_phongo_apply_rc_options_to_uri(mongoc_uri_t* uri, bson_t* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_apply_rc_options_to_uri(mongoc_uri_t* uri, bson_t* options) /* {{{ */
{
bson_iter_t iter;
mongoc_read_concern_t* new_rc;
const mongoc_read_concern_t* old_rc;
if (!(old_rc = mongoc_uri_get_read_concern(uri))) {
- phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "mongoc_uri_t does not have a read concern");
+ phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED, "mongoc_uri_t does not have a read concern");
return false;
}
/* Return early if there are no options to apply */
if (bson_empty0(options) || !bson_iter_init(&iter, options)) {
return true;
}
new_rc = mongoc_read_concern_copy(old_rc);
while (bson_iter_next(&iter)) {
const char* key = bson_iter_key(&iter);
if (!strcasecmp(key, MONGOC_URI_READCONCERNLEVEL)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
mongoc_read_concern_destroy(new_rc);
return false;
}
mongoc_read_concern_set_level(new_rc, bson_iter_utf8(&iter, NULL));
}
}
mongoc_uri_set_read_concern(uri, new_rc);
mongoc_read_concern_destroy(new_rc);
return true;
} /* }}} */
-static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t* uri, bson_t* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t* uri, bson_t* options) /* {{{ */
{
bson_iter_t iter;
mongoc_read_prefs_t* new_rp;
const mongoc_read_prefs_t* old_rp;
bool ignore_slaveok = false;
if (!(old_rp = mongoc_uri_get_read_prefs_t(uri))) {
- phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "mongoc_uri_t does not have a read preference");
+ phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED, "mongoc_uri_t does not have a read preference");
return false;
}
/* Return early if there are no options to apply */
if (bson_empty0(options) || !bson_iter_init(&iter, options)) {
return true;
}
new_rp = mongoc_read_prefs_copy(old_rp);
while (bson_iter_next(&iter)) {
const char* key = bson_iter_key(&iter);
if (!ignore_slaveok && !strcasecmp(key, MONGOC_URI_SLAVEOK)) {
if (!BSON_ITER_HOLDS_BOOL(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "boolean");
mongoc_read_prefs_destroy(new_rp);
return false;
}
if (bson_iter_bool(&iter)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED);
}
}
if (!strcasecmp(key, MONGOC_URI_READPREFERENCE)) {
const char* str;
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
mongoc_read_prefs_destroy(new_rp);
return false;
}
str = bson_iter_utf8(&iter, NULL);
if (0 == strcasecmp("primary", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY);
} else if (0 == strcasecmp("primarypreferred", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY_PREFERRED);
} else if (0 == strcasecmp("secondary", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY);
} else if (0 == strcasecmp("secondarypreferred", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED);
} else if (0 == strcasecmp("nearest", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_NEAREST);
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Unsupported %s value: '%s'", bson_iter_key(&iter), str);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Unsupported %s value: '%s'", bson_iter_key(&iter), str);
mongoc_read_prefs_destroy(new_rp);
return false;
}
ignore_slaveok = true;
}
if (!strcasecmp(key, MONGOC_URI_READPREFERENCETAGS)) {
bson_t tags;
uint32_t len;
const uint8_t* data;
if (!BSON_ITER_HOLDS_ARRAY(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "array");
mongoc_read_prefs_destroy(new_rp);
return false;
}
bson_iter_array(&iter, &len, &data);
if (!bson_init_static(&tags, data, len)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Could not initialize BSON structure for read preference tags");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Could not initialize BSON structure for read preference tags");
mongoc_read_prefs_destroy(new_rp);
return false;
}
if (!php_phongo_read_preference_tags_are_valid(&tags)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference tags must be an array of zero or more documents");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Read preference tags must be an array of zero or more documents");
mongoc_read_prefs_destroy(new_rp);
return false;
}
mongoc_read_prefs_set_tags(new_rp, &tags);
}
if (!strcasecmp(key, MONGOC_URI_MAXSTALENESSSECONDS)) {
int64_t max_staleness_seconds;
if (!BSON_ITER_HOLDS_INT(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "integer");
mongoc_read_prefs_destroy(new_rp);
return false;
}
max_staleness_seconds = bson_iter_as_int64(&iter);
if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) {
if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be >= %d, %" PRId64 " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, max_staleness_seconds);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected maxStalenessSeconds to be >= %d, %" PRId64 " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, max_staleness_seconds);
mongoc_read_prefs_destroy(new_rp);
return false;
}
if (max_staleness_seconds > INT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be <= %d, %" PRId64 " given", INT32_MAX, max_staleness_seconds);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected maxStalenessSeconds to be <= %d, %" PRId64 " given", INT32_MAX, max_staleness_seconds);
mongoc_read_prefs_destroy(new_rp);
return false;
}
if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with maxStalenessSeconds");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Primary read preference mode conflicts with maxStalenessSeconds");
mongoc_read_prefs_destroy(new_rp);
return false;
}
}
mongoc_read_prefs_set_max_staleness_seconds(new_rp, max_staleness_seconds);
}
}
if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY &&
!bson_empty(mongoc_read_prefs_get_tags(new_rp))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with tags");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Primary read preference mode conflicts with tags");
mongoc_read_prefs_destroy(new_rp);
return false;
}
/* Make sure maxStalenessSeconds is not combined with primary readPreference */
if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY &&
mongoc_read_prefs_get_max_staleness_seconds(new_rp) != MONGOC_NO_MAX_STALENESS) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with maxStalenessSeconds");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Primary read preference mode conflicts with maxStalenessSeconds");
mongoc_read_prefs_destroy(new_rp);
return false;
}
/* This may be redundant in light of the previous checks (primary with tags
* or maxStalenessSeconds), but we'll check anyway in case additional
* validation is implemented. */
if (!mongoc_read_prefs_is_valid(new_rp)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference is not valid");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Read preference is not valid");
mongoc_read_prefs_destroy(new_rp);
return false;
}
mongoc_uri_set_read_prefs_t(uri, new_rp);
mongoc_read_prefs_destroy(new_rp);
return true;
} /* }}} */
-static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* options) /* {{{ */
{
bson_iter_t iter;
mongoc_write_concern_t* new_wc;
const mongoc_write_concern_t* old_wc;
bool ignore_safe = false;
if (!(old_wc = mongoc_uri_get_write_concern(uri))) {
- phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "mongoc_uri_t does not have a write concern");
+ phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED, "mongoc_uri_t does not have a write concern");
return false;
}
/* Return early if there are no options to apply */
if (bson_empty0(options) || !bson_iter_init(&iter, options)) {
return true;
}
new_wc = mongoc_write_concern_copy(old_wc);
while (bson_iter_next(&iter)) {
const char* key = bson_iter_key(&iter);
if (!ignore_safe && !strcasecmp(key, MONGOC_URI_SAFE)) {
if (!BSON_ITER_HOLDS_BOOL(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "boolean");
mongoc_write_concern_destroy(new_wc);
return false;
}
mongoc_write_concern_set_w(new_wc, bson_iter_bool(&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
}
if (!strcasecmp(key, MONGOC_URI_WTIMEOUTMS)) {
int64_t wtimeout;
if (!BSON_ITER_HOLDS_INT(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "integer");
mongoc_write_concern_destroy(new_wc);
return false;
}
wtimeout = bson_iter_as_int64(&iter);
if (wtimeout < 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected wtimeoutMS to be >= 0, %" PRId64 " given", wtimeout);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected wtimeoutMS to be >= 0, %" PRId64 " given", wtimeout);
mongoc_write_concern_destroy(new_wc);
return false;
}
mongoc_write_concern_set_wtimeout_int64(new_wc, wtimeout);
}
if (!strcasecmp(key, MONGOC_URI_JOURNAL)) {
if (!BSON_ITER_HOLDS_BOOL(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "boolean");
mongoc_write_concern_destroy(new_wc);
return false;
}
mongoc_write_concern_set_journal(new_wc, bson_iter_bool(&iter));
}
if (!strcasecmp(key, MONGOC_URI_W)) {
if (BSON_ITER_HOLDS_INT32(&iter)) {
int32_t value = bson_iter_int32(&iter);
switch (value) {
case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED:
case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED:
mongoc_write_concern_set_w(new_wc, value);
break;
default:
if (value > 0) {
mongoc_write_concern_set_w(new_wc, value);
break;
}
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Unsupported w value: %d", value);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Unsupported w value: %d", value);
mongoc_write_concern_destroy(new_wc);
return false;
}
} else if (BSON_ITER_HOLDS_UTF8(&iter)) {
const char* str = bson_iter_utf8(&iter, NULL);
if (0 == strcasecmp(PHONGO_WRITE_CONCERN_W_MAJORITY, str)) {
mongoc_write_concern_set_w(new_wc, MONGOC_WRITE_CONCERN_W_MAJORITY);
} else {
mongoc_write_concern_set_wtag(new_wc, str);
}
} else {
PHONGO_URI_INVALID_TYPE(iter, "32-bit integer or string");
mongoc_write_concern_destroy(new_wc);
return false;
}
ignore_safe = true;
}
}
if (mongoc_write_concern_get_journal(new_wc)) {
int32_t w = mongoc_write_concern_get_w(new_wc);
if (w == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || w == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Journal conflicts with w value: %d", w);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Journal conflicts with w value: %d", w);
mongoc_write_concern_destroy(new_wc);
return false;
}
}
/* This may be redundant in light of the last check (unacknowledged w with
journal), but we'll check anyway in case additional validation is
implemented. */
if (!mongoc_write_concern_is_valid(new_wc)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Write concern is not valid");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Write concern is not valid");
mongoc_write_concern_destroy(new_wc);
return false;
}
mongoc_uri_set_write_concern(uri, new_wc);
mongoc_write_concern_destroy(new_wc);
return true;
} /* }}} */
#ifdef MONGOC_ENABLE_SSL
static void php_phongo_mongoc_ssl_opts_from_uri(mongoc_ssl_opt_t* ssl_opt, mongoc_uri_t* uri, bool* any_ssl_option_set)
{
bool insecure = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSINSECURE, false);
const char* pem_file = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, NULL);
const char* pem_pwd = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, NULL);
const char* ca_file = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCAFILE, NULL);
ssl_opt->pem_file = pem_file ? estrdup(pem_file) : NULL;
ssl_opt->pem_pwd = pem_pwd ? estrdup(pem_pwd) : NULL;
ssl_opt->ca_file = ca_file ? estrdup(ca_file) : NULL;
ssl_opt->weak_cert_validation = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, insecure);
ssl_opt->allow_invalid_hostname = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, insecure);
/* Boolean options default to false, so we cannot consider them for
* any_ssl_option_set. This isn't actually a problem as libmongoc will
* already have assigned them when creating the client, enabling SSL, and
* assigning SSL options. Therefore, we only need to check for non-defaults
* (i.e. non-NULL strings, true booleans). */
if (pem_file || pem_pwd || ca_file || ssl_opt->weak_cert_validation || ssl_opt->allow_invalid_hostname) {
*any_ssl_option_set = true;
}
}
static inline char* php_phongo_fetch_ssl_opt_string(zval* zoptions, const char* key)
{
int plen;
zend_bool pfree;
char* pval;
char* value;
pval = php_array_fetch_string(zoptions, key, &plen, &pfree);
value = pfree ? pval : estrndup(pval, plen);
return value;
}
-static mongoc_ssl_opt_t* php_phongo_make_ssl_opt(mongoc_uri_t* uri, zval* zoptions TSRMLS_DC)
+static mongoc_ssl_opt_t* php_phongo_make_ssl_opt(mongoc_uri_t* uri, zval* zoptions)
{
mongoc_ssl_opt_t* ssl_opt;
bool any_ssl_option_set = false;
if (!zoptions) {
return NULL;
}
#if defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) || defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT)
if (php_array_existsc(zoptions, "ca_dir")) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"ca_dir\" option is not supported by Secure Channel and Secure Transport");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"ca_dir\" option is not supported by Secure Channel and Secure Transport");
return NULL;
}
if (php_array_existsc(zoptions, "capath")) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"capath\" option is not supported by Secure Channel and Secure Transport");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"capath\" option is not supported by Secure Channel and Secure Transport");
return NULL;
}
#endif
#if defined(MONGOC_ENABLE_SSL_LIBRESSL) || defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT)
if (php_array_existsc(zoptions, "crl_file")) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"crl_file\" option is not supported by LibreSSL and Secure Transport");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"crl_file\" option is not supported by LibreSSL and Secure Transport");
return NULL;
}
#endif
ssl_opt = ecalloc(1, sizeof(mongoc_ssl_opt_t));
/* If SSL options are set in the URL, we need to read them and set them on
* the options struct so we can merge potential options from passed in
* driverOptions (zoptions) */
if (mongoc_uri_get_tls(uri)) {
php_phongo_mongoc_ssl_opts_from_uri(ssl_opt, uri, &any_ssl_option_set);
}
#define PHONGO_SSL_OPTION_SWAP_STRING(o, n) \
if ((o)) { \
efree((char*) (o)); \
} \
(o) = php_phongo_fetch_ssl_opt_string(zoptions, n);
/* Apply driver options that don't have a corresponding URI option. These
* are set directly on the SSL options struct. */
if (php_array_existsc(zoptions, "ca_dir")) {
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->ca_dir, "ca_dir");
any_ssl_option_set = true;
} else if (php_array_existsc(zoptions, "capath")) {
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->ca_dir, "capath");
any_ssl_option_set = true;
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"capath\" context driver option is deprecated. Please use the \"ca_dir\" driver option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"capath\" context driver option is deprecated. Please use the \"ca_dir\" driver option instead.");
}
if (php_array_existsc(zoptions, "crl_file")) {
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->crl_file, "crl_file");
any_ssl_option_set = true;
}
#undef PHONGO_SSL_OPTION_SWAP_STRING
if (!any_ssl_option_set) {
efree(ssl_opt);
return NULL;
}
return ssl_opt;
}
static void php_phongo_free_ssl_opt(mongoc_ssl_opt_t* ssl_opt)
{
if (ssl_opt->pem_file) {
- str_efree(ssl_opt->pem_file);
+ efree((char*) ssl_opt->pem_file);
}
if (ssl_opt->pem_pwd) {
- str_efree(ssl_opt->pem_pwd);
+ efree((char*) ssl_opt->pem_pwd);
}
if (ssl_opt->ca_file) {
- str_efree(ssl_opt->ca_file);
+ efree((char*) ssl_opt->ca_file);
}
if (ssl_opt->ca_dir) {
- str_efree(ssl_opt->ca_dir);
+ efree((char*) ssl_opt->ca_dir);
}
if (ssl_opt->crl_file) {
- str_efree(ssl_opt->crl_file);
+ efree((char*) ssl_opt->crl_file);
}
efree(ssl_opt);
}
static inline bool php_phongo_apply_driver_option_to_uri(mongoc_uri_t* uri, zval* zoptions, const char* driverOptionKey, const char* optionKey)
{
bool ret;
char* value;
value = php_phongo_fetch_ssl_opt_string(zoptions, driverOptionKey);
ret = mongoc_uri_set_option_as_utf8(uri, optionKey, value);
efree(value);
return ret;
}
-static bool php_phongo_apply_driver_options_to_uri(mongoc_uri_t* uri, zval* zoptions TSRMLS_DC)
+static bool php_phongo_apply_driver_options_to_uri(mongoc_uri_t* uri, zval* zoptions)
{
if (!zoptions) {
return true;
}
/* Map TLS driver options to the canonical tls options in the URI. */
if (php_array_existsc(zoptions, "allow_invalid_hostname")) {
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, php_array_fetchc_bool(zoptions, "allow_invalid_hostname"))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "allow_invalid_hostname");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "allow_invalid_hostname");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"allow_invalid_hostname\" driver option is deprecated. Please use the \"tlsAllowInvalidHostnames\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"allow_invalid_hostname\" driver option is deprecated. Please use the \"tlsAllowInvalidHostnames\" URI option instead.");
}
if (php_array_existsc(zoptions, "weak_cert_validation")) {
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, php_array_fetchc_bool(zoptions, "weak_cert_validation"))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "weak_cert_validation");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "weak_cert_validation");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"weak_cert_validation\" driver option is deprecated. Please use the \"tlsAllowInvalidCertificates\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"weak_cert_validation\" driver option is deprecated. Please use the \"tlsAllowInvalidCertificates\" URI option instead.");
} else if (php_array_existsc(zoptions, "allow_self_signed")) {
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, php_array_fetchc_bool(zoptions, "allow_self_signed"))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "allow_self_signed");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "allow_self_signed");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"allow_self_signed\" context driver option is deprecated. Please use the \"tlsAllowInvalidCertificates\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"allow_self_signed\" context driver option is deprecated. Please use the \"tlsAllowInvalidCertificates\" URI option instead.");
}
if (php_array_existsc(zoptions, "pem_file")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "pem_file", MONGOC_URI_TLSCERTIFICATEKEYFILE)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "pem_file");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "pem_file");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"pem_file\" driver option is deprecated. Please use the \"tlsCertificateKeyFile\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"pem_file\" driver option is deprecated. Please use the \"tlsCertificateKeyFile\" URI option instead.");
} else if (php_array_existsc(zoptions, "local_cert")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "local_cert", MONGOC_URI_TLSCERTIFICATEKEYFILE)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "local_cert");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "local_cert");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"local_cert\" context driver option is deprecated. Please use the \"tlsCertificateKeyFile\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"local_cert\" context driver option is deprecated. Please use the \"tlsCertificateKeyFile\" URI option instead.");
}
if (php_array_existsc(zoptions, "pem_pwd")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "pem_pwd", MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "pem_pwd");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "pem_pwd");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"pem_pwd\" driver option is deprecated. Please use the \"tlsCertificateKeyFilePassword\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"pem_pwd\" driver option is deprecated. Please use the \"tlsCertificateKeyFilePassword\" URI option instead.");
} else if (php_array_existsc(zoptions, "passphrase")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "passphrase", MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "passphrase");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "passphrase");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"passphrase\" context driver option is deprecated. Please use the \"tlsCertificateKeyFilePassword\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"passphrase\" context driver option is deprecated. Please use the \"tlsCertificateKeyFilePassword\" URI option instead.");
}
if (php_array_existsc(zoptions, "ca_file")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "ca_file", MONGOC_URI_TLSCAFILE)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "ca_file");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "ca_file");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"ca_file\" driver option is deprecated. Please use the \"tlsCAFile\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"ca_file\" driver option is deprecated. Please use the \"tlsCAFile\" URI option instead.");
} else if (php_array_existsc(zoptions, "cafile")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "cafile", MONGOC_URI_TLSCAFILE)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "cafile");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "cafile");
return false;
}
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"cafile\" context driver option is deprecated. Please use the \"tlsCAFile\" URI option instead.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"cafile\" context driver option is deprecated. Please use the \"tlsCAFile\" URI option instead.");
}
return true;
}
#endif
/* APM callbacks */
static void php_phongo_dispatch_handlers(const char* name, zval* z_event)
{
-#if PHP_VERSION_ID >= 70000
zval* value;
ZEND_HASH_FOREACH_VAL_IND(MONGODB_G(subscribers), value)
{
if (EG(exception)) {
break;
}
/* We can't use the zend_call_method_with_1_params macro here, as it
* does a sizeof() on the name argument, which does only work with
* constant names, but not with parameterized ones as it does
* "sizeof(char*)" in that case. */
- zend_call_method(value, NULL, NULL, name, strlen(name), NULL, 1, z_event, NULL TSRMLS_CC);
+ zend_call_method(value, NULL, NULL, name, strlen(name), NULL, 1, z_event, NULL);
}
ZEND_HASH_FOREACH_END();
-#else
- HashPosition pos;
- TSRMLS_FETCH();
-
- zend_hash_internal_pointer_reset_ex(MONGODB_G(subscribers), &pos);
- for (;; zend_hash_move_forward_ex(MONGODB_G(subscribers), &pos)) {
- zval** value;
-
- if (zend_hash_get_current_data_ex(MONGODB_G(subscribers), (void**) &value, &pos) == FAILURE) {
- break;
- }
-
- if (EG(exception)) {
- break;
- }
- /* We can't use the zend_call_method_with_1_params macro here, as it
- * does a sizeof() on the name argument, which does only work with
- * constant names, but not with parameterized ones as it does
- * "sizeof(char*)" in that case. */
- zend_call_method(value, NULL, NULL, name, strlen(name), NULL, 1, z_event, NULL TSRMLS_CC);
- }
-#endif
}
static void php_phongo_command_started(const mongoc_apm_command_started_t* event)
{
php_phongo_commandstartedevent_t* p_event;
-#if PHP_VERSION_ID >= 70000
- zval z_event;
-#else
- zval* z_event = NULL;
-#endif
- TSRMLS_FETCH();
+ zval z_event;
/* Return early if there are no APM subscribers to notify */
if (!MONGODB_G(subscribers) || zend_hash_num_elements(MONGODB_G(subscribers)) == 0) {
return;
}
-#if PHP_VERSION_ID >= 70000
object_init_ex(&z_event, php_phongo_commandstartedevent_ce);
p_event = Z_COMMANDSTARTEDEVENT_OBJ_P(&z_event);
-#else
- MAKE_STD_ZVAL(z_event);
- object_init_ex(z_event, php_phongo_commandstartedevent_ce);
- p_event = Z_COMMANDSTARTEDEVENT_OBJ_P(z_event);
-#endif
p_event->client = mongoc_apm_command_started_get_context(event);
p_event->command_name = estrdup(mongoc_apm_command_started_get_command_name(event));
p_event->server_id = mongoc_apm_command_started_get_server_id(event);
p_event->operation_id = mongoc_apm_command_started_get_operation_id(event);
p_event->request_id = mongoc_apm_command_started_get_request_id(event);
p_event->command = bson_copy(mongoc_apm_command_started_get_command(event));
p_event->database_name = estrdup(mongoc_apm_command_started_get_database_name(event));
-#if PHP_VERSION_ID >= 70000
php_phongo_dispatch_handlers("commandStarted", &z_event);
-#else
- php_phongo_dispatch_handlers("commandStarted", z_event);
-#endif
zval_ptr_dtor(&z_event);
}
static void php_phongo_command_succeeded(const mongoc_apm_command_succeeded_t* event)
{
php_phongo_commandsucceededevent_t* p_event;
-#if PHP_VERSION_ID >= 70000
- zval z_event;
-#else
- zval* z_event = NULL;
-#endif
- TSRMLS_FETCH();
+ zval z_event;
/* Return early if there are no APM subscribers to notify */
if (!MONGODB_G(subscribers) || zend_hash_num_elements(MONGODB_G(subscribers)) == 0) {
return;
}
-#if PHP_VERSION_ID >= 70000
object_init_ex(&z_event, php_phongo_commandsucceededevent_ce);
p_event = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(&z_event);
-#else
- MAKE_STD_ZVAL(z_event);
- object_init_ex(z_event, php_phongo_commandsucceededevent_ce);
- p_event = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(z_event);
-#endif
p_event->client = mongoc_apm_command_succeeded_get_context(event);
p_event->command_name = estrdup(mongoc_apm_command_succeeded_get_command_name(event));
p_event->server_id = mongoc_apm_command_succeeded_get_server_id(event);
p_event->operation_id = mongoc_apm_command_succeeded_get_operation_id(event);
p_event->request_id = mongoc_apm_command_succeeded_get_request_id(event);
p_event->duration_micros = mongoc_apm_command_succeeded_get_duration(event);
p_event->reply = bson_copy(mongoc_apm_command_succeeded_get_reply(event));
-#if PHP_VERSION_ID >= 70000
php_phongo_dispatch_handlers("commandSucceeded", &z_event);
-#else
- php_phongo_dispatch_handlers("commandSucceeded", z_event);
-#endif
zval_ptr_dtor(&z_event);
}
static void php_phongo_command_failed(const mongoc_apm_command_failed_t* event)
{
php_phongo_commandfailedevent_t* p_event;
-#if PHP_VERSION_ID >= 70000
- zval z_event;
-#else
- zval* z_event = NULL;
-#endif
- bson_error_t tmp_error = { 0 };
- zend_class_entry* default_exception_ce;
- TSRMLS_FETCH();
+ zval z_event;
+ bson_error_t tmp_error = { 0 };
+ zend_class_entry* default_exception_ce;
- default_exception_ce = zend_exception_get_default(TSRMLS_C);
+ default_exception_ce = zend_exception_get_default();
/* Return early if there are no APM subscribers to notify */
if (!MONGODB_G(subscribers) || zend_hash_num_elements(MONGODB_G(subscribers)) == 0) {
return;
}
-#if PHP_VERSION_ID >= 70000
object_init_ex(&z_event, php_phongo_commandfailedevent_ce);
p_event = Z_COMMANDFAILEDEVENT_OBJ_P(&z_event);
-#else
- MAKE_STD_ZVAL(z_event);
- object_init_ex(z_event, php_phongo_commandfailedevent_ce);
- p_event = Z_COMMANDFAILEDEVENT_OBJ_P(z_event);
-#endif
p_event->client = mongoc_apm_command_failed_get_context(event);
p_event->command_name = estrdup(mongoc_apm_command_failed_get_command_name(event));
p_event->server_id = mongoc_apm_command_failed_get_server_id(event);
p_event->operation_id = mongoc_apm_command_failed_get_operation_id(event);
p_event->request_id = mongoc_apm_command_failed_get_request_id(event);
p_event->duration_micros = mongoc_apm_command_failed_get_duration(event);
p_event->reply = bson_copy(mongoc_apm_command_failed_get_reply(event));
/* We need to process and convert the error right here, otherwise
* debug_info will turn into a recursive loop, and with the wrong trace
* locations */
mongoc_apm_command_failed_get_error(event, &tmp_error);
- {
-#if PHP_VERSION_ID < 70000
- MAKE_STD_ZVAL(p_event->z_error);
- object_init_ex(p_event->z_error, phongo_exception_from_mongoc_domain(tmp_error.domain, tmp_error.code));
- zend_update_property_string(default_exception_ce, p_event->z_error, ZEND_STRL("message"), tmp_error.message TSRMLS_CC);
- zend_update_property_long(default_exception_ce, p_event->z_error, ZEND_STRL("code"), tmp_error.code TSRMLS_CC);
-#else
- object_init_ex(&p_event->z_error, phongo_exception_from_mongoc_domain(tmp_error.domain, tmp_error.code));
- zend_update_property_string(default_exception_ce, &p_event->z_error, ZEND_STRL("message"), tmp_error.message TSRMLS_CC);
- zend_update_property_long(default_exception_ce, &p_event->z_error, ZEND_STRL("code"), tmp_error.code TSRMLS_CC);
-#endif
- }
+ object_init_ex(&p_event->z_error, phongo_exception_from_mongoc_domain(tmp_error.domain, tmp_error.code));
+ zend_update_property_string(default_exception_ce, &p_event->z_error, ZEND_STRL("message"), tmp_error.message);
+ zend_update_property_long(default_exception_ce, &p_event->z_error, ZEND_STRL("code"), tmp_error.code);
-#if PHP_VERSION_ID >= 70000
php_phongo_dispatch_handlers("commandFailed", &z_event);
-#else
- php_phongo_dispatch_handlers("commandFailed", z_event);
-#endif
zval_ptr_dtor(&z_event);
}
/* Sets the callbacks for APM */
int php_phongo_set_monitoring_callbacks(mongoc_client_t* client)
{
int retval;
mongoc_apm_callbacks_t* callbacks = mongoc_apm_callbacks_new();
mongoc_apm_set_command_started_cb(callbacks, php_phongo_command_started);
mongoc_apm_set_command_succeeded_cb(callbacks, php_phongo_command_succeeded);
mongoc_apm_set_command_failed_cb(callbacks, php_phongo_command_failed);
retval = mongoc_client_set_apm_callbacks(client, callbacks, client);
mongoc_apm_callbacks_destroy(callbacks);
return retval;
}
-static zval* php_phongo_manager_prepare_manager_for_hash(zval* driverOptions, bool* free TSRMLS_DC)
+static zval* php_phongo_manager_prepare_manager_for_hash(zval* driverOptions, bool* free)
{
php_phongo_manager_t* manager;
zval* autoEncryptionOpts = NULL;
zval* keyVaultClient = NULL;
zval* driverOptionsClone = NULL;
zval* autoEncryptionOptsClone = NULL;
-#if PHP_VERSION_ID >= 70000
- zval stackAutoEncryptionOptsClone;
-#endif
+ zval stackAutoEncryptionOptsClone;
*free = false;
if (!driverOptions) {
return NULL;
}
if (!php_array_existsc(driverOptions, "autoEncryption")) {
goto ref;
}
autoEncryptionOpts = php_array_fetchc(driverOptions, "autoEncryption");
if (Z_TYPE_P(autoEncryptionOpts) != IS_ARRAY) {
goto ref;
}
if (!php_array_existsc(autoEncryptionOpts, "keyVaultClient")) {
goto ref;
}
keyVaultClient = php_array_fetchc(autoEncryptionOpts, "keyVaultClient");
- if (Z_TYPE_P(keyVaultClient) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(keyVaultClient), php_phongo_manager_ce TSRMLS_CC)) {
+ if (Z_TYPE_P(keyVaultClient) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(keyVaultClient), php_phongo_manager_ce)) {
goto ref;
}
*free = true;
manager = Z_MANAGER_OBJ_P(keyVaultClient);
-#if PHP_VERSION_ID >= 70000
driverOptionsClone = ecalloc(sizeof(zval), 1);
autoEncryptionOptsClone = &stackAutoEncryptionOptsClone;
-#else
- ALLOC_INIT_ZVAL(driverOptionsClone);
- MAKE_STD_ZVAL(autoEncryptionOptsClone);
-#endif
ZVAL_DUP(autoEncryptionOptsClone, autoEncryptionOpts);
ADD_ASSOC_STRINGL(autoEncryptionOptsClone, "keyVaultClient", manager->client_hash, manager->client_hash_len);
ZVAL_DUP(driverOptionsClone, driverOptions);
ADD_ASSOC_ZVAL_EX(driverOptionsClone, "autoEncryption", autoEncryptionOptsClone);
return driverOptionsClone;
ref:
Z_ADDREF_P(driverOptions);
return driverOptions;
}
/* Creates a hash for a client by concatenating the URI string with serialized
* options arrays. On success, a persistent string is returned (i.e. pefree()
* should be used to free it) and hash_len will be set to the string's length.
* On error, an exception will have been thrown and NULL will be returned. */
-static char* php_phongo_manager_make_client_hash(const char* uri_string, zval* options, zval* driverOptions, size_t* hash_len TSRMLS_DC)
+static char* php_phongo_manager_make_client_hash(const char* uri_string, zval* options, zval* driverOptions, size_t* hash_len)
{
char* hash = NULL;
smart_str var_buf = { 0 };
php_serialize_data_t var_hash;
zval* serializable_driver_options = NULL;
bool free_driver_options = false;
-#if PHP_VERSION_ID >= 70000
zval args;
array_init_size(&args, 4);
ADD_ASSOC_LONG_EX(&args, "pid", getpid());
ADD_ASSOC_STRING(&args, "uri", uri_string);
if (options) {
ADD_ASSOC_ZVAL_EX(&args, "options", options);
Z_ADDREF_P(options);
} else {
ADD_ASSOC_NULL_EX(&args, "options");
}
if (driverOptions) {
- serializable_driver_options = php_phongo_manager_prepare_manager_for_hash(driverOptions, &free_driver_options TSRMLS_CC);
+ serializable_driver_options = php_phongo_manager_prepare_manager_for_hash(driverOptions, &free_driver_options);
ADD_ASSOC_ZVAL_EX(&args, "driverOptions", serializable_driver_options);
} else {
ADD_ASSOC_NULL_EX(&args, "driverOptions");
}
PHP_VAR_SERIALIZE_INIT(var_hash);
php_var_serialize(&var_buf, &args, &var_hash);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
if (!EG(exception)) {
*hash_len = ZSTR_LEN(var_buf.s);
hash = estrndup(ZSTR_VAL(var_buf.s), *hash_len);
}
zval_ptr_dtor(&args);
if (free_driver_options) {
efree(serializable_driver_options);
}
-#else
- zval* args;
+ smart_str_free(&var_buf);
- MAKE_STD_ZVAL(args);
- array_init_size(args, 4);
- ADD_ASSOC_LONG_EX(args, "pid", getpid());
- ADD_ASSOC_STRING(args, "uri", uri_string);
+ return hash;
+}
- if (options) {
- ADD_ASSOC_ZVAL_EX(args, "options", options);
- Z_ADDREF_P(options);
- } else {
- ADD_ASSOC_NULL_EX(args, "options");
+static bool php_phongo_extract_handshake_data(zval* driver, const char* key, char** value, size_t* value_len)
+{
+ zval* zvalue;
+
+ if (!php_array_exists(driver, key)) {
+ *value = NULL;
+ *value_len = 0;
+
+ return true;
}
- if (driverOptions) {
- serializable_driver_options = php_phongo_manager_prepare_manager_for_hash(driverOptions, &free_driver_options TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(args, "driverOptions", serializable_driver_options);
- } else {
- ADD_ASSOC_NULL_EX(args, "driverOptions");
+ zvalue = php_array_fetch(driver, key);
+
+ if (Z_TYPE_P(zvalue) != IS_STRING) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" handshake option to be a string, %s given", key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zvalue));
+ return false;
}
- PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&var_buf, &args, &var_hash TSRMLS_CC);
- PHP_VAR_SERIALIZE_DESTROY(var_hash);
+ *value = estrdup(Z_STRVAL_P(zvalue));
+ *value_len = Z_STRLEN_P(zvalue);
- if (!EG(exception)) {
- *hash_len = var_buf.len;
- hash = estrndup(var_buf.c, *hash_len);
+ return true;
+}
+
+static char* php_phongo_concat_handshake_data(const char* default_value, const char* custom_value, size_t custom_value_len)
+{
+ char* ret;
+ /* Length of the returned value needs to include the trailing null byte */
+ size_t ret_len = strlen(default_value) + 1;
+
+ if (custom_value) {
+ /* Increase the length by that of the custom value as well as one byte for the separator */
+ ret_len += custom_value_len + PHONGO_METADATA_SEPARATOR_LEN;
}
- zval_ptr_dtor(&args);
-#endif
+ ret = ecalloc(sizeof(char*), ret_len);
- smart_str_free(&var_buf);
+ if (custom_value) {
+ snprintf(ret, ret_len, "%s%s%s", default_value, PHONGO_METADATA_SEPARATOR, custom_value);
+ } else {
+ snprintf(ret, ret_len, "%s", default_value);
+ }
- return hash;
+ return ret;
+}
+
+static void php_phongo_handshake_data_append(const char* name, size_t name_len, const char* version, size_t version_len, const char* platform, size_t platform_len)
+{
+ char* php_version_string;
+ size_t php_version_string_len;
+ char* driver_name;
+ char* driver_version;
+ char* full_platform;
+
+ php_version_string_len = strlen(PHP_VERSION);
+ php_version_string = ecalloc(sizeof(char*), 4 + php_version_string_len);
+ snprintf(php_version_string, 4 + php_version_string_len, "PHP %s", PHP_VERSION);
+
+ driver_name = php_phongo_concat_handshake_data("ext-mongodb:PHP", name, name_len);
+ driver_version = php_phongo_concat_handshake_data(PHP_MONGODB_VERSION, version, version_len);
+ full_platform = php_phongo_concat_handshake_data(php_version_string, platform, platform_len);
+
+ MONGOC_DEBUG(
+ "Setting driver handshake data: name %s, version %s, platform %s",
+ driver_name,
+ driver_version,
+ full_platform);
+
+ mongoc_handshake_data_append(driver_name, driver_version, full_platform);
+
+ efree(php_version_string);
+ efree(driver_name);
+ efree(driver_version);
+ efree(full_platform);
+}
+
+static void php_phongo_set_handshake_data(zval* driverOptions)
+{
+ char* name = NULL;
+ size_t name_len = 0;
+ char* version = NULL;
+ size_t version_len = 0;
+ char* platform = NULL;
+ size_t platform_len = 0;
+
+ if (driverOptions && php_array_existsc(driverOptions, "driver")) {
+ zval* driver = php_array_fetchc(driverOptions, "driver");
+
+ if (Z_TYPE_P(driver) != IS_ARRAY) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"driver\" driver option to be an array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(driver));
+ return;
+ }
+
+ if (!php_phongo_extract_handshake_data(driver, "name", &name, &name_len)) {
+ /* Exception already thrown */
+ goto cleanup;
+ }
+
+ if (!php_phongo_extract_handshake_data(driver, "version", &version, &version_len)) {
+ /* Exception already thrown */
+ goto cleanup;
+ }
+
+ if (!php_phongo_extract_handshake_data(driver, "platform", &platform, &platform_len)) {
+ /* Exception already thrown */
+ goto cleanup;
+ }
+ }
+
+ php_phongo_handshake_data_append(name, name_len, version, version_len, platform, platform_len);
+
+cleanup:
+ if (name) {
+ efree(name);
+ }
+ if (version) {
+ efree(version);
+ }
+ if (platform) {
+ efree(platform);
+ }
}
-static mongoc_client_t* php_phongo_make_mongo_client(const mongoc_uri_t* uri TSRMLS_DC) /* {{{ */
+static mongoc_client_t* php_phongo_make_mongo_client(const mongoc_uri_t* uri, zval* driverOptions) /* {{{ */
{
const char *mongoc_version, *bson_version;
#ifdef HAVE_SYSTEM_LIBMONGOC
mongoc_version = mongoc_get_version();
#else
mongoc_version = "bundled";
#endif
#ifdef HAVE_SYSTEM_LIBBSON
bson_version = bson_get_version();
#else
bson_version = "bundled";
#endif
MONGOC_DEBUG(
"Creating Manager, phongo-%s[%s] - mongoc-%s(%s), libbson-%s(%s), php-%s",
PHP_MONGODB_VERSION,
PHP_MONGODB_STABILITY,
MONGOC_VERSION_S,
mongoc_version,
BSON_VERSION_S,
bson_version,
PHP_VERSION);
+ php_phongo_set_handshake_data(driverOptions);
+
return mongoc_client_new_from_uri(uri);
} /* }}} */
-static void php_phongo_persist_client(const char* hash, size_t hash_len, mongoc_client_t* client TSRMLS_DC)
+static void php_phongo_persist_client(const char* hash, size_t hash_len, mongoc_client_t* client)
{
php_phongo_pclient_t* pclient = (php_phongo_pclient_t*) pecalloc(1, sizeof(php_phongo_pclient_t), 1);
pclient->created_by_pid = (int) getpid();
pclient->client = client;
-#if PHP_VERSION_ID >= 70000
zend_hash_str_update_ptr(&MONGODB_G(pclients), hash, hash_len, pclient);
-#else
- zend_hash_update(&MONGODB_G(pclients), hash, hash_len + 1, &pclient, sizeof(php_phongo_pclient_t*), NULL);
-#endif
}
-static mongoc_client_t* php_phongo_find_client(const char* hash, size_t hash_len TSRMLS_DC)
+static mongoc_client_t* php_phongo_find_client(const char* hash, size_t hash_len)
{
-#if PHP_VERSION_ID >= 70000
php_phongo_pclient_t* pclient;
if ((pclient = zend_hash_str_find_ptr(&MONGODB_G(pclients), hash, hash_len)) != NULL) {
return pclient->client;
}
-#else
- php_phongo_pclient_t** pclient;
-
- if (zend_hash_find(&MONGODB_G(pclients), hash, hash_len + 1, (void**) &pclient) == SUCCESS) {
- return (*pclient)->client;
- }
-#endif
return NULL;
}
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
-static bool phongo_manager_set_auto_encryption_opts(php_phongo_manager_t* manager, zval* driverOptions TSRMLS_DC) /* {{{ */
+static bool phongo_manager_set_auto_encryption_opts(php_phongo_manager_t* manager, zval* driverOptions) /* {{{ */
{
zval* zAutoEncryptionOpts;
bson_error_t error = { 0 };
mongoc_auto_encryption_opts_t* auto_encryption_opts = NULL;
bool retval = false;
if (!driverOptions || !php_array_existsc(driverOptions, "autoEncryption")) {
return true;
}
zAutoEncryptionOpts = php_array_fetch(driverOptions, "autoEncryption");
if (Z_TYPE_P(zAutoEncryptionOpts) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"autoEncryption\" driver option to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zAutoEncryptionOpts));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"autoEncryption\" driver option to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zAutoEncryptionOpts));
return false;
}
auto_encryption_opts = mongoc_auto_encryption_opts_new();
if (php_array_existsc(zAutoEncryptionOpts, "keyVaultClient")) {
zval* key_vault_client = php_array_fetch(zAutoEncryptionOpts, "keyVaultClient");
- if (Z_TYPE_P(key_vault_client) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(key_vault_client), php_phongo_manager_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"keyVaultClient\" encryption option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
+ if (Z_TYPE_P(key_vault_client) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(key_vault_client), php_phongo_manager_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultClient\" encryption option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
goto cleanup;
}
mongoc_auto_encryption_opts_set_keyvault_client(auto_encryption_opts, Z_MANAGER_OBJ_P(key_vault_client)->client);
}
if (php_array_existsc(zAutoEncryptionOpts, "keyVaultNamespace")) {
char* key_vault_ns;
char* db_name;
char* coll_name;
int plen;
zend_bool pfree;
key_vault_ns = php_array_fetch_string(zAutoEncryptionOpts, "keyVaultNamespace", &plen, &pfree);
if (!phongo_split_namespace(key_vault_ns, &db_name, &coll_name)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"keyVaultNamespace\" encryption option to contain a full collection name");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultNamespace\" encryption option to contain a full collection name");
if (pfree) {
- str_efree(key_vault_ns);
+ efree(key_vault_ns);
}
goto cleanup;
}
mongoc_auto_encryption_opts_set_keyvault_namespace(auto_encryption_opts, db_name, coll_name);
efree(db_name);
efree(coll_name);
if (pfree) {
- str_efree(key_vault_ns);
+ efree(key_vault_ns);
}
}
if (php_array_existsc(zAutoEncryptionOpts, "kmsProviders")) {
zval* kms_providers = php_array_fetch(zAutoEncryptionOpts, "kmsProviders");
bson_t bson_providers = BSON_INITIALIZER;
if (Z_TYPE_P(kms_providers) != IS_OBJECT && Z_TYPE_P(kms_providers) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"kmsProviders\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"kmsProviders\" encryption option to be an array or object");
goto cleanup;
}
- php_phongo_zval_to_bson(kms_providers, PHONGO_BSON_NONE, &bson_providers, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(kms_providers, PHONGO_BSON_NONE, &bson_providers, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_auto_encryption_opts_set_kms_providers(auto_encryption_opts, &bson_providers);
bson_destroy(&bson_providers);
}
if (php_array_existsc(zAutoEncryptionOpts, "schemaMap")) {
zval* schema_map = php_array_fetch(zAutoEncryptionOpts, "schemaMap");
bson_t bson_map = BSON_INITIALIZER;
if (Z_TYPE_P(schema_map) != IS_OBJECT && Z_TYPE_P(schema_map) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"schemaMap\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"schemaMap\" encryption option to be an array or object");
goto cleanup;
}
- php_phongo_zval_to_bson(schema_map, PHONGO_BSON_NONE, &bson_map, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(schema_map, PHONGO_BSON_NONE, &bson_map, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_auto_encryption_opts_set_schema_map(auto_encryption_opts, &bson_map);
bson_destroy(&bson_map);
}
if (php_array_existsc(zAutoEncryptionOpts, "bypassAutoEncryption")) {
zend_bool bypass_auto_encryption = php_array_fetch_bool(zAutoEncryptionOpts, "bypassAutoEncryption");
mongoc_auto_encryption_opts_set_bypass_auto_encryption(auto_encryption_opts, bypass_auto_encryption);
}
if (php_array_existsc(zAutoEncryptionOpts, "extraOptions")) {
zval* extra_options = php_array_fetch(zAutoEncryptionOpts, "extraOptions");
bson_t bson_options = BSON_INITIALIZER;
- php_phongo_zval_to_bson(extra_options, PHONGO_BSON_NONE, &bson_options, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(extra_options, PHONGO_BSON_NONE, &bson_options, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_auto_encryption_opts_set_extra(auto_encryption_opts, &bson_options);
bson_destroy(&bson_options);
}
if (!mongoc_client_enable_auto_encryption(manager->client, auto_encryption_opts, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
retval = true;
cleanup:
mongoc_auto_encryption_opts_destroy(auto_encryption_opts);
return retval;
}
/* }}} */
-static mongoc_client_encryption_opts_t* phongo_clientencryption_opts_from_zval(mongoc_client_t* defaultKeyVaultClient, zval* options TSRMLS_DC) /* {{{ */
+static mongoc_client_encryption_opts_t* phongo_clientencryption_opts_from_zval(mongoc_client_t* defaultKeyVaultClient, zval* options) /* {{{ */
{
mongoc_client_encryption_opts_t* opts;
opts = mongoc_client_encryption_opts_new();
if (!options || Z_TYPE_P(options) != IS_ARRAY) {
return opts;
}
if (php_array_existsc(options, "keyVaultClient")) {
zval* key_vault_client = php_array_fetch(options, "keyVaultClient");
- if (Z_TYPE_P(key_vault_client) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(key_vault_client), php_phongo_manager_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"keyVaultClient\" encryption option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
+ if (Z_TYPE_P(key_vault_client) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(key_vault_client), php_phongo_manager_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultClient\" encryption option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
goto cleanup;
}
mongoc_client_encryption_opts_set_keyvault_client(opts, Z_MANAGER_OBJ_P(key_vault_client)->client);
} else {
mongoc_client_encryption_opts_set_keyvault_client(opts, defaultKeyVaultClient);
}
if (php_array_existsc(options, "keyVaultNamespace")) {
char* keyvault_namespace;
char* db_name;
char* coll_name;
int plen;
zend_bool pfree;
keyvault_namespace = php_array_fetchc_string(options, "keyVaultNamespace", &plen, &pfree);
if (!phongo_split_namespace(keyvault_namespace, &db_name, &coll_name)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"keyVaultNamespace\" encryption option to contain a full collection name");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultNamespace\" encryption option to contain a full collection name");
if (pfree) {
- str_efree(keyvault_namespace);
+ efree(keyvault_namespace);
}
goto cleanup;
}
mongoc_client_encryption_opts_set_keyvault_namespace(opts, db_name, coll_name);
efree(db_name);
efree(coll_name);
if (pfree) {
- str_efree(keyvault_namespace);
+ efree(keyvault_namespace);
}
}
if (php_array_existsc(options, "kmsProviders")) {
zval* kms_providers = php_array_fetchc(options, "kmsProviders");
bson_t bson_providers = BSON_INITIALIZER;
if (Z_TYPE_P(kms_providers) != IS_ARRAY && Z_TYPE_P(kms_providers) != IS_OBJECT) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"kmsProviders\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"kmsProviders\" encryption option to be an array or object");
goto cleanup;
}
- php_phongo_zval_to_bson(kms_providers, PHONGO_BSON_NONE, &bson_providers, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(kms_providers, PHONGO_BSON_NONE, &bson_providers, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_client_encryption_opts_set_kms_providers(opts, &bson_providers);
bson_destroy(&bson_providers);
}
return opts;
cleanup:
if (opts) {
mongoc_client_encryption_opts_destroy(opts);
}
return NULL;
} /* }}} */
-void phongo_clientencryption_init(php_phongo_clientencryption_t* clientencryption, mongoc_client_t* client, zval* options TSRMLS_DC) /* {{{ */
+void phongo_clientencryption_init(php_phongo_clientencryption_t* clientencryption, mongoc_client_t* client, zval* options) /* {{{ */
{
mongoc_client_encryption_t* ce;
mongoc_client_encryption_opts_t* opts;
bson_error_t error = { 0 };
- opts = phongo_clientencryption_opts_from_zval(client, options TSRMLS_CC);
+ opts = phongo_clientencryption_opts_from_zval(client, options);
if (!opts) {
/* Exception already thrown */
goto cleanup;
}
ce = mongoc_client_encryption_new(opts, &error);
if (!ce) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
clientencryption->client_encryption = ce;
cleanup:
if (opts) {
mongoc_client_encryption_opts_destroy(opts);
}
} /* }}} */
-static mongoc_client_encryption_datakey_opts_t* phongo_clientencryption_datakey_opts_from_zval(zval* options TSRMLS_DC) /* {{{ */
+static mongoc_client_encryption_datakey_opts_t* phongo_clientencryption_datakey_opts_from_zval(zval* options) /* {{{ */
{
mongoc_client_encryption_datakey_opts_t* opts;
opts = mongoc_client_encryption_datakey_opts_new();
if (!options || Z_TYPE_P(options) != IS_ARRAY) {
return opts;
}
if (php_array_existsc(options, "keyAltNames")) {
zval* zkeyaltnames = php_array_fetchc(options, "keyAltNames");
HashTable* ht_data;
uint32_t keyaltnames_count;
char** keyaltnames;
uint32_t i = 0;
uint32_t j = 0;
bool failed = false;
if (!zkeyaltnames || Z_TYPE_P(zkeyaltnames) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected keyAltNames to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zkeyaltnames));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected keyAltNames to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zkeyaltnames));
goto cleanup;
}
ht_data = HASH_OF(zkeyaltnames);
keyaltnames_count = ht_data ? zend_hash_num_elements(ht_data) : 0;
keyaltnames = ecalloc(keyaltnames_count, sizeof(char*));
-#if PHP_VERSION_ID >= 70000
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* keyaltname;
ZEND_HASH_FOREACH_KEY_VAL(ht_data, num_key, string_key, keyaltname)
{
if (i >= keyaltnames_count) {
- phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Iterating over too many keyAltNames. Please file a bug report");
+ phongo_throw_exception(PHONGO_ERROR_LOGIC, "Iterating over too many keyAltNames. Please file a bug report");
failed = true;
break;
}
if (Z_TYPE_P(keyaltname) != IS_STRING) {
if (string_key) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected keyAltName with index \"%s\" to be string, %s given", ZSTR_VAL(string_key), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(keyaltname));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected keyAltName with index \"%s\" to be string, %s given", ZSTR_VAL(string_key), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(keyaltname));
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected keyAltName with index \"%lu\" to be string, %s given", num_key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(keyaltname));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected keyAltName with index \"%lu\" to be string, %s given", num_key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(keyaltname));
}
failed = true;
break;
}
keyaltnames[i] = estrdup(Z_STRVAL_P(keyaltname));
i++;
}
ZEND_HASH_FOREACH_END();
}
-#else
- {
- HashPosition pos;
- char* string_key = NULL;
- uint string_key_len = 0;
- ulong num_key = 0;
- zval** keyaltname;
-
- for (
- zend_hash_internal_pointer_reset_ex(ht_data, &pos);
- zend_hash_get_current_data_ex(ht_data, (void**) &keyaltname, &pos) == SUCCESS;
- zend_hash_move_forward_ex(ht_data, &pos)) {
-
- if (i == keyaltnames_count) {
- phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Iterating over too many keyAltNames. Please file a bug report");
- failed = true;
- break;
- }
-
- if (Z_TYPE_PP(keyaltname) != IS_STRING) {
- if (zend_hash_get_current_key_ex(ht_data, &string_key, &string_key_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected keyAltName with index \"%s\" to be string, %s given", string_key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(*keyaltname));
- } else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected keyAltName with index \"%lu\" to be string, %s given", num_key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(*keyaltname));
- }
-
- failed = true;
- break;
- }
-
- keyaltnames[i] = estrdup(Z_STRVAL_PP(keyaltname));
- i++;
- }
- }
-#endif
if (!failed) {
mongoc_client_encryption_datakey_opts_set_keyaltnames(opts, keyaltnames, keyaltnames_count);
}
for (j = 0; j < i; j++) {
efree(keyaltnames[j]);
}
efree(keyaltnames);
if (failed) {
goto cleanup;
}
}
if (php_array_existsc(options, "masterKey")) {
bson_t masterkey = BSON_INITIALIZER;
- php_phongo_zval_to_bson(php_array_fetchc(options, "masterKey"), PHONGO_BSON_NONE, &masterkey, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(php_array_fetchc(options, "masterKey"), PHONGO_BSON_NONE, &masterkey, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_client_encryption_datakey_opts_set_masterkey(opts, &masterkey);
}
return opts;
cleanup:
if (opts) {
mongoc_client_encryption_datakey_opts_destroy(opts);
}
return NULL;
} /* }}} */
-void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options TSRMLS_DC) /* {{{ */
+void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options) /* {{{ */
{
mongoc_client_encryption_datakey_opts_t* opts;
bson_value_t keyid;
bson_error_t error = { 0 };
- opts = phongo_clientencryption_datakey_opts_from_zval(options TSRMLS_CC);
+ opts = phongo_clientencryption_datakey_opts_from_zval(options);
if (!opts) {
/* Exception already thrown */
goto cleanup;
}
if (!mongoc_client_encryption_create_datakey(clientencryption->client_encryption, kms_provider, opts, &keyid, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
if (!php_phongo_bson_value_to_zval(&keyid, return_value)) {
/* Exception already thrown */
goto cleanup;
}
cleanup:
if (opts) {
mongoc_client_encryption_datakey_opts_destroy(opts);
}
} /* }}} */
-static mongoc_client_encryption_encrypt_opts_t* phongo_clientencryption_encrypt_opts_from_zval(zval* options TSRMLS_DC) /* {{{ */
+static mongoc_client_encryption_encrypt_opts_t* phongo_clientencryption_encrypt_opts_from_zval(zval* options) /* {{{ */
{
mongoc_client_encryption_encrypt_opts_t* opts;
opts = mongoc_client_encryption_encrypt_opts_new();
if (!options || Z_TYPE_P(options) != IS_ARRAY) {
return opts;
}
if (php_array_existsc(options, "keyId")) {
bson_value_t keyid;
- php_phongo_zval_to_bson_value(php_array_fetchc(options, "keyId"), PHONGO_BSON_NONE, &keyid TSRMLS_CC);
+ php_phongo_zval_to_bson_value(php_array_fetchc(options, "keyId"), PHONGO_BSON_NONE, &keyid);
if (EG(exception)) {
goto cleanup;
}
mongoc_client_encryption_encrypt_opts_set_keyid(opts, &keyid);
}
if (php_array_existsc(options, "keyAltName")) {
char* keyaltname;
int plen;
zend_bool pfree;
keyaltname = php_array_fetch_string(options, "keyAltName", &plen, &pfree);
mongoc_client_encryption_encrypt_opts_set_keyaltname(opts, keyaltname);
if (pfree) {
- str_efree(keyaltname);
+ efree(keyaltname);
}
}
if (php_array_existsc(options, "algorithm")) {
char* algorithm;
int plen;
zend_bool pfree;
algorithm = php_array_fetch_string(options, "algorithm", &plen, &pfree);
mongoc_client_encryption_encrypt_opts_set_algorithm(opts, algorithm);
if (pfree) {
- str_efree(algorithm);
+ efree(algorithm);
}
}
return opts;
cleanup:
if (opts) {
mongoc_client_encryption_encrypt_opts_destroy(opts);
}
return NULL;
} /* }}} */
-void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options TSRMLS_DC) /* {{{ */
+void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options) /* {{{ */
{
mongoc_client_encryption_encrypt_opts_t* opts;
bson_value_t ciphertext, value;
bson_error_t error = { 0 };
- php_phongo_zval_to_bson_value(zvalue, PHONGO_BSON_NONE, &value TSRMLS_CC);
+ php_phongo_zval_to_bson_value(zvalue, PHONGO_BSON_NONE, &value);
- opts = phongo_clientencryption_encrypt_opts_from_zval(options TSRMLS_CC);
+ opts = phongo_clientencryption_encrypt_opts_from_zval(options);
if (!opts) {
/* Exception already thrown */
goto cleanup;
}
if (!mongoc_client_encryption_encrypt(clientencryption->client_encryption, &value, opts, &ciphertext, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
if (!php_phongo_bson_value_to_zval(&ciphertext, zciphertext)) {
/* Exception already thrown */
goto cleanup;
}
cleanup:
if (opts) {
mongoc_client_encryption_encrypt_opts_destroy(opts);
}
} /* }}} */
-void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue TSRMLS_DC) /* {{{ */
+void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue) /* {{{ */
{
bson_value_t ciphertext, value;
bson_error_t error = { 0 };
- php_phongo_zval_to_bson_value(zciphertext, PHONGO_BSON_NONE, &ciphertext TSRMLS_CC);
+ php_phongo_zval_to_bson_value(zciphertext, PHONGO_BSON_NONE, &ciphertext);
if (!mongoc_client_encryption_decrypt(clientencryption->client_encryption, &ciphertext, &value, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
return;
}
if (!php_phongo_bson_value_to_zval(&value, zvalue)) {
/* Exception already thrown */
return;
}
}
/* }}} */
#else /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
-static void phongo_throw_exception_no_cse(php_phongo_error_domain_t domain, const char* message TSRMLS_DC) /* {{{ */
+static void phongo_throw_exception_no_cse(php_phongo_error_domain_t domain, const char* message) /* {{{ */
{
- phongo_throw_exception(domain TSRMLS_CC, "%s Please recompile with support for libmongocrypt using the with-mongodb-client-side-encryption configure switch.", message);
+ phongo_throw_exception(domain, "%s Please recompile with support for libmongocrypt using the with-mongodb-client-side-encryption configure switch.", message);
}
/* }}} */
-static bool phongo_manager_set_auto_encryption_opts(php_phongo_manager_t* manager, zval* driverOptions TSRMLS_DC) /* {{{ */
+static bool phongo_manager_set_auto_encryption_opts(php_phongo_manager_t* manager, zval* driverOptions) /* {{{ */
{
if (!driverOptions || !php_array_existsc(driverOptions, "autoEncryption")) {
return true;
}
- phongo_throw_exception_no_cse(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot enable automatic field-level encryption." TSRMLS_CC);
+ phongo_throw_exception_no_cse(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot enable automatic field-level encryption.");
return false;
}
/* }}} */
-void phongo_clientencryption_init(php_phongo_clientencryption_t* clientencryption, mongoc_client_t* client, zval* options TSRMLS_DC) /* {{{ */
+void phongo_clientencryption_init(php_phongo_clientencryption_t* clientencryption, mongoc_client_t* client, zval* options) /* {{{ */
{
- phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot configure clientEncryption object." TSRMLS_CC);
+ phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot configure clientEncryption object.");
}
/* }}} */
-void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options TSRMLS_DC) /* {{{ */
+void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options) /* {{{ */
{
- phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot create encryption key." TSRMLS_CC);
+ phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot create encryption key.");
}
/* }}} */
-void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options TSRMLS_DC) /* {{{ */
+void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options) /* {{{ */
{
- phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot encrypt value." TSRMLS_CC);
+ phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot encrypt value.");
}
/* }}} */
-void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue TSRMLS_DC) /* {{{ */
+void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue) /* {{{ */
{
- phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot decrypt value." TSRMLS_CC);
+ phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot decrypt value.");
}
/* }}} */
#endif
-void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, zval* options, zval* driverOptions TSRMLS_DC) /* {{{ */
+void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, zval* options, zval* driverOptions) /* {{{ */
{
bson_t bson_options = BSON_INITIALIZER;
mongoc_uri_t* uri = NULL;
#ifdef MONGOC_ENABLE_SSL
mongoc_ssl_opt_t* ssl_opt = NULL;
#endif
- if (!(manager->client_hash = php_phongo_manager_make_client_hash(uri_string, options, driverOptions, &manager->client_hash_len TSRMLS_CC))) {
+ if (!(manager->client_hash = php_phongo_manager_make_client_hash(uri_string, options, driverOptions, &manager->client_hash_len))) {
/* Exception should already have been thrown and there is nothing to free */
return;
}
- if ((manager->client = php_phongo_find_client(manager->client_hash, manager->client_hash_len TSRMLS_CC))) {
+ if ((manager->client = php_phongo_find_client(manager->client_hash, manager->client_hash_len))) {
MONGOC_DEBUG("Found client for hash: %s\n", manager->client_hash);
goto cleanup;
}
if (options) {
- php_phongo_zval_to_bson(options, PHONGO_BSON_NONE, &bson_options, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(options, PHONGO_BSON_NONE, &bson_options, NULL);
}
/* An exception may be thrown during BSON conversion */
if (EG(exception)) {
goto cleanup;
}
- if (!(uri = php_phongo_make_uri(uri_string TSRMLS_CC))) {
+ if (!(uri = php_phongo_make_uri(uri_string))) {
/* Exception should already have been thrown */
goto cleanup;
}
- if (!php_phongo_apply_options_to_uri(uri, &bson_options TSRMLS_CC) ||
- !php_phongo_apply_rc_options_to_uri(uri, &bson_options TSRMLS_CC) ||
- !php_phongo_apply_rp_options_to_uri(uri, &bson_options TSRMLS_CC) ||
- !php_phongo_apply_wc_options_to_uri(uri, &bson_options TSRMLS_CC)) {
+ if (!php_phongo_apply_options_to_uri(uri, &bson_options) ||
+ !php_phongo_apply_rc_options_to_uri(uri, &bson_options) ||
+ !php_phongo_apply_rp_options_to_uri(uri, &bson_options) ||
+ !php_phongo_apply_wc_options_to_uri(uri, &bson_options)) {
/* Exception should already have been thrown */
goto cleanup;
}
#ifdef MONGOC_ENABLE_SSL
- if (!php_phongo_apply_driver_options_to_uri(uri, driverOptions TSRMLS_CC)) {
+ if (!php_phongo_apply_driver_options_to_uri(uri, driverOptions)) {
/* Exception should already have been thrown */
goto cleanup;
}
- ssl_opt = php_phongo_make_ssl_opt(uri, driverOptions TSRMLS_CC);
+ ssl_opt = php_phongo_make_ssl_opt(uri, driverOptions);
/* An exception may be thrown during SSL option creation */
if (EG(exception)) {
goto cleanup;
}
- if (!php_phongo_uri_finalize_tls(uri TSRMLS_CC)) {
+ if (!php_phongo_uri_finalize_tls(uri)) {
/* Exception should already have been thrown */
goto cleanup;
}
#else
if (mongoc_uri_get_tls(uri)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot create SSL client. SSL is not enabled in this build.");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot create SSL client. SSL is not enabled in this build.");
goto cleanup;
}
#endif
- manager->client = php_phongo_make_mongo_client(uri TSRMLS_CC);
+ manager->client = php_phongo_make_mongo_client(uri, driverOptions);
mongoc_client_set_error_api(manager->client, MONGOC_ERROR_API_VERSION_2);
if (!manager->client) {
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to create Manager from URI: '%s'", uri_string);
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to create Manager from URI: '%s'", uri_string);
goto cleanup;
}
#ifdef MONGOC_ENABLE_SSL
if (ssl_opt) {
mongoc_client_set_ssl_opts(manager->client, ssl_opt);
}
#endif
- if (!phongo_manager_set_auto_encryption_opts(manager, driverOptions TSRMLS_CC)) {
+ if (!phongo_manager_set_auto_encryption_opts(manager, driverOptions)) {
/* Exception should already have been thrown */
goto cleanup;
}
MONGOC_DEBUG("Created client hash: %s\n", manager->client_hash);
- php_phongo_persist_client(manager->client_hash, manager->client_hash_len, manager->client TSRMLS_CC);
+ php_phongo_persist_client(manager->client_hash, manager->client_hash_len, manager->client);
cleanup:
bson_destroy(&bson_options);
if (uri) {
mongoc_uri_destroy(uri);
}
#ifdef MONGOC_ENABLE_SSL
if (ssl_opt) {
php_phongo_free_ssl_opt(ssl_opt);
}
#endif
} /* }}} */
-bool php_phongo_parse_int64(int64_t* retval, const char* data, phongo_zpp_char_len data_len) /* {{{ */
+bool php_phongo_parse_int64(int64_t* retval, const char* data, size_t data_len) /* {{{ */
{
int64_t value;
char* endptr = NULL;
/* bson_ascii_strtoll() sets errno if conversion fails. If conversion
* succeeds, we still want to ensure that the entire string was parsed. */
value = bson_ascii_strtoll(data, &endptr, 10);
if (errno || (endptr && endptr != ((const char*) data + data_len))) {
return false;
}
*retval = value;
return true;
} /* }}} */
/* {{{ Memory allocation wrappers */
static void* php_phongo_malloc(size_t num_bytes) /* {{{ */
{
return pemalloc(num_bytes, 1);
} /* }}} */
static void* php_phongo_calloc(size_t num_members, size_t num_bytes) /* {{{ */
{
return pecalloc(num_members, num_bytes, 1);
} /* }}} */
static void* php_phongo_realloc(void* mem, size_t num_bytes)
{ /* {{{ */
return perealloc(mem, num_bytes, 1);
} /* }}} */
static void php_phongo_free(void* mem) /* {{{ */
{
if (mem) {
pefree(mem, 1);
}
} /* }}} */
/* }}} */
/* {{{ M[INIT|SHUTDOWN] R[INIT|SHUTDOWN] G[INIT|SHUTDOWN] MINFO INI */
ZEND_INI_MH(OnUpdateDebug)
{
void*** ctx = NULL;
char* tmp_dir = NULL;
- TSRMLS_SET_CTX(ctx);
-
/* Close any previously open log files */
if (MONGODB_G(debug_fd)) {
if (MONGODB_G(debug_fd) != stderr && MONGODB_G(debug_fd) != stdout) {
fclose(MONGODB_G(debug_fd));
}
MONGODB_G(debug_fd) = NULL;
}
if (!new_value || (new_value && !ZSTR_VAL(new_value)[0]) || strcasecmp("0", ZSTR_VAL(new_value)) == 0 || strcasecmp("off", ZSTR_VAL(new_value)) == 0 || strcasecmp("no", ZSTR_VAL(new_value)) == 0 || strcasecmp("false", ZSTR_VAL(new_value)) == 0) {
mongoc_log_trace_disable();
mongoc_log_set_handler(NULL, NULL);
-#if PHP_VERSION_ID >= 70000
- return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
-#else
- return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
-#endif
+ return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
}
if (strcasecmp(ZSTR_VAL(new_value), "stderr") == 0) {
MONGODB_G(debug_fd) = stderr;
} else if (strcasecmp(ZSTR_VAL(new_value), "stdout") == 0) {
MONGODB_G(debug_fd) = stdout;
} else if (
strcasecmp("1", ZSTR_VAL(new_value)) == 0 ||
strcasecmp("on", ZSTR_VAL(new_value)) == 0 ||
strcasecmp("yes", ZSTR_VAL(new_value)) == 0 ||
strcasecmp("true", ZSTR_VAL(new_value)) == 0) {
tmp_dir = NULL;
} else {
tmp_dir = ZSTR_VAL(new_value);
}
if (!MONGODB_G(debug_fd)) {
time_t t;
int fd = -1;
char* prefix;
int len;
- phongo_char* filename;
+ zend_string* filename;
time(&t);
len = spprintf(&prefix, 0, "PHONGO-%ld", t);
- fd = php_open_temporary_fd(tmp_dir, prefix, &filename TSRMLS_CC);
+ fd = php_open_temporary_fd(tmp_dir, prefix, &filename);
if (fd != -1) {
const char* path = ZSTR_VAL(filename);
MONGODB_G(debug_fd) = VCWD_FOPEN(path, "a");
}
efree(filename);
efree(prefix);
close(fd);
}
mongoc_log_trace_enable();
mongoc_log_set_handler(php_phongo_log, ctx);
-#if PHP_VERSION_ID >= 70000
- return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
-#else
- return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
-#endif
+ return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
}
/* {{{ INI entries */
PHP_INI_BEGIN()
-#if PHP_VERSION_ID >= 70000
STD_PHP_INI_ENTRY(PHONGO_DEBUG_INI, PHONGO_DEBUG_INI_DEFAULT, PHP_INI_ALL, OnUpdateDebug, debug, zend_mongodb_globals, mongodb_globals)
-#else
- { 0, PHP_INI_ALL, (char*) PHONGO_DEBUG_INI, sizeof(PHONGO_DEBUG_INI), OnUpdateDebug, (void*) XtOffsetOf(zend_mongodb_globals, debug), (void*) &mglo, NULL, (char*) PHONGO_DEBUG_INI_DEFAULT, sizeof(PHONGO_DEBUG_INI_DEFAULT) - 1, NULL, 0, 0, 0, NULL },
-#endif
PHP_INI_END()
/* }}} */
static void phongo_pclient_reset_once(php_phongo_pclient_t* pclient, int pid)
{
if (pclient->last_reset_by_pid != pid) {
mongoc_client_reset(pclient->client);
pclient->last_reset_by_pid = pid;
}
}
/* Resets the libmongoc client if it has not already been reset for the current
* PID (based on information in the hash table of persisted libmongoc clients).
* This ensures that we do not reset a client multiple times from the same child
* process. */
void php_phongo_client_reset_once(mongoc_client_t* client, int pid)
{
- HashTable* pclients;
+ HashTable* pclients;
+ zval* z_ptr;
+ php_phongo_pclient_t* pclient;
- TSRMLS_FETCH();
pclients = &MONGODB_G(pclients);
-#if PHP_VERSION_ID >= 70000
+ ZEND_HASH_FOREACH_VAL(pclients, z_ptr)
{
- zval* z_ptr;
- php_phongo_pclient_t* pclient;
-
- ZEND_HASH_FOREACH_VAL(pclients, z_ptr)
- {
- if ((Z_TYPE_P(z_ptr) != IS_PTR)) {
- continue;
- }
-
- pclient = (php_phongo_pclient_t*) Z_PTR_P(z_ptr);
-
- if (pclient->client == client) {
- phongo_pclient_reset_once(pclient, pid);
- return;
- }
+ if ((Z_TYPE_P(z_ptr) != IS_PTR)) {
+ continue;
}
- ZEND_HASH_FOREACH_END();
- }
-#else
- {
- HashPosition pos;
- php_phongo_pclient_t** pclient;
- for (
- zend_hash_internal_pointer_reset_ex(pclients, &pos);
- zend_hash_get_current_data_ex(pclients, (void**) &pclient, &pos) == SUCCESS;
- zend_hash_move_forward_ex(pclients, &pos)) {
+ pclient = (php_phongo_pclient_t*) Z_PTR_P(z_ptr);
- if ((*pclient)->client == client) {
- phongo_pclient_reset_once((*pclient), pid);
- return;
- }
+ if (pclient->client == client) {
+ phongo_pclient_reset_once(pclient, pid);
+ return;
}
}
-#endif
+ ZEND_HASH_FOREACH_END();
}
static inline void php_phongo_pclient_destroy(php_phongo_pclient_t* pclient)
{
/* Do not destroy mongoc_client_t objects created by other processes. This
* ensures that we do not shutdown sockets that may still be in use by our
* parent process (see: CDRIVER-2049). While this is a leak, we are already
* in MSHUTDOWN at this point. */
if (pclient->created_by_pid == getpid()) {
mongoc_client_destroy(pclient->client);
}
pefree(pclient, 1);
}
/* {{{ PHP_RINIT_FUNCTION */
PHP_RINIT_FUNCTION(mongodb)
{
/* Initialize HashTable for APM subscribers, which is initialized to NULL in
* GINIT and destroyed and reset to NULL in RSHUTDOWN. */
if (MONGODB_G(subscribers) == NULL) {
ALLOC_HASHTABLE(MONGODB_G(subscribers));
zend_hash_init(MONGODB_G(subscribers), 0, NULL, ZVAL_PTR_DTOR, 0);
}
return SUCCESS;
}
/* }}} */
/* {{{ PHP_GINIT_FUNCTION */
PHP_GINIT_FUNCTION(mongodb)
{
bson_mem_vtable_t bsonMemVTable = {
php_phongo_malloc,
php_phongo_calloc,
php_phongo_realloc,
php_phongo_free,
};
-#if PHP_VERSION_ID >= 70000
#if defined(COMPILE_DL_MONGODB) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE();
-#endif
#endif
memset(mongodb_globals, 0, sizeof(zend_mongodb_globals));
mongodb_globals->bsonMemVTable = bsonMemVTable;
/* Initialize HashTable for persistent clients */
zend_hash_init_ex(&mongodb_globals->pclients, 0, NULL, NULL, 1, 0);
}
/* }}} */
-static zend_class_entry* php_phongo_fetch_internal_class(const char* class_name, size_t class_name_len TSRMLS_DC)
+static zend_class_entry* php_phongo_fetch_internal_class(const char* class_name, size_t class_name_len)
{
-#if PHP_VERSION_ID >= 70000
zend_class_entry* pce;
if ((pce = zend_hash_str_find_ptr(CG(class_table), class_name, class_name_len))) {
return pce;
}
-#else
- zend_class_entry** pce;
-
- if (zend_hash_find(CG(class_table), class_name, class_name_len + 1, (void**) &pce) == SUCCESS) {
- return *pce;
- }
-#endif
return NULL;
}
+static HashTable* php_phongo_std_get_gc(zval* object, zval** table, int* n) /* {{{ */
+{
+ *table = NULL;
+ *n = 0;
+ return zend_std_get_properties(object);
+} /* }}} */
+
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(mongodb)
{
- char* php_version_string;
-
(void) type; /* We don't care if we are loaded via dl() or extension= */
REGISTER_INI_ENTRIES();
/* Initialize libmongoc */
mongoc_init();
- /* Set handshake options */
- php_version_string = malloc(4 + sizeof(PHP_VERSION) + 1);
- snprintf(php_version_string, 4 + sizeof(PHP_VERSION) + 1, "PHP %s", PHP_VERSION);
- mongoc_handshake_data_append("ext-mongodb:PHP", PHP_MONGODB_VERSION, php_version_string);
- free(php_version_string);
-
/* Initialize libbson */
bson_mem_set_vtable(&MONGODB_G(bsonMemVTable));
/* Prep default object handlers to be used when we register the classes */
memcpy(&phongo_std_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ /* Disable cloning by default. Individual classes can opt in if they need to
+ * support this (e.g. BSON objects). */
phongo_std_object_handlers.clone_obj = NULL;
- /*
- phongo_std_object_handlers.get_debug_info = NULL;
- phongo_std_object_handlers.compare_objects = NULL;
- phongo_std_object_handlers.cast_object = NULL;
- phongo_std_object_handlers.count_elements = NULL;
- phongo_std_object_handlers.get_closure = NULL;
- */
+ /* Ensure that get_gc delegates to zend_std_get_properties directly in case
+ * our class defines a get_properties handler for debugging purposes. */
+ phongo_std_object_handlers.get_gc = php_phongo_std_get_gc;
/* Initialize zend_class_entry dependencies.
*
* Although DateTimeImmutable was introduced in PHP 5.5.0,
* php_date_get_immutable_ce() is not available in PHP versions before
* 5.5.24 and 5.6.8.
*
* Although JsonSerializable was introduced in PHP 5.4.0,
* php_json_serializable_ce is not exported in PHP versions before 5.4.26
* and 5.5.10. For later PHP versions, looking up the class manually also
* helps with distros that disable LTDL_LAZY for dlopen() (e.g. Fedora).
*/
- php_phongo_date_immutable_ce = php_phongo_fetch_internal_class(ZEND_STRL("datetimeimmutable") TSRMLS_CC);
- php_phongo_json_serializable_ce = php_phongo_fetch_internal_class(ZEND_STRL("jsonserializable") TSRMLS_CC);
+ php_phongo_date_immutable_ce = php_phongo_fetch_internal_class(ZEND_STRL("datetimeimmutable"));
+ php_phongo_json_serializable_ce = php_phongo_fetch_internal_class(ZEND_STRL("jsonserializable"));
if (php_phongo_json_serializable_ce == NULL) {
zend_error(E_ERROR, "JsonSerializable class is not defined. Please ensure that the 'json' module is loaded before the 'mongodb' module.");
return FAILURE;
}
/* Register base BSON classes first */
php_phongo_type_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_serializable_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_unserializable_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_binary_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_decimal128_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_javascript_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_maxkey_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_minkey_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_objectid_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_regex_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_timestamp_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_utcdatetime_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_binary_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_dbpointer_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_decimal128_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_int64_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_javascript_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_maxkey_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_minkey_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_objectid_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_persistable_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_regex_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_symbol_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_timestamp_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_undefined_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_utcdatetime_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_cursor_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_command_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_cursor_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_cursorid_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_manager_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_query_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_readconcern_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_readpreference_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_server_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_session_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_writeconcern_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_writeerror_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_writeresult_init_ce(INIT_FUNC_ARGS_PASSTHRU);
/* Register base exception classes first */
php_phongo_exception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_runtimeexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_serverexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_connectionexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_writeexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_authenticationexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_bulkwriteexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_commandexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_connectiontimeoutexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_encryptionexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_executiontimeoutexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_invalidargumentexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_logicexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_sslconnectionexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_unexpectedvalueexception_init_ce(INIT_FUNC_ARGS_PASSTHRU);
/* Register base APM classes first */
php_phongo_subscriber_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_commandsubscriber_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_commandstartedevent_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS_PASSTHRU);
REGISTER_STRING_CONSTANT("MONGODB_VERSION", (char*) PHP_MONGODB_VERSION, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("MONGODB_STABILITY", (char*) PHP_MONGODB_STABILITY, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(mongodb)
{
HashTable* pclients = &MONGODB_G(pclients);
+ zval* z_ptr;
(void) type; /* We don't care if we are loaded via dl() or extension= */
/* Destroy mongoc_client_t objects in reverse order. This is necessary to
* prevent segmentation faults as clients may reference other clients in
* encryption settings. */
-#if PHP_VERSION_ID >= 70000
+ ZEND_HASH_REVERSE_FOREACH_VAL(pclients, z_ptr)
{
- zval* z_ptr;
-
- ZEND_HASH_REVERSE_FOREACH_VAL(pclients, z_ptr)
- {
- if ((Z_TYPE_P(z_ptr) != IS_PTR)) {
- continue;
- }
-
- php_phongo_pclient_destroy((php_phongo_pclient_t*) Z_PTR_P(z_ptr));
+ if ((Z_TYPE_P(z_ptr) != IS_PTR)) {
+ continue;
}
- ZEND_HASH_FOREACH_END();
- }
-#else
- {
- HashPosition pos;
- php_phongo_pclient_t** pclient;
- for (
- zend_hash_internal_pointer_end_ex(pclients, &pos);
- zend_hash_get_current_data_ex(pclients, (void**) &pclient, &pos) == SUCCESS;
- zend_hash_move_backwards_ex(pclients, &pos)) {
-
- php_phongo_pclient_destroy(*pclient);
- }
+ php_phongo_pclient_destroy((php_phongo_pclient_t*) Z_PTR_P(z_ptr));
}
-#endif
+ ZEND_HASH_FOREACH_END();
/* Destroy HashTable for persistent clients. mongoc_client_t objects have been destroyed earlier. */
zend_hash_destroy(&MONGODB_G(pclients));
bson_mem_restore_vtable();
/* Cleanup after libmongoc */
mongoc_cleanup();
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
/* }}} */
/* {{{ PHP_RSHUTDOWN_FUNCTION */
PHP_RSHUTDOWN_FUNCTION(mongodb)
{
/* Destroy HashTable for APM subscribers, which was initialized in RINIT */
if (MONGODB_G(subscribers)) {
zend_hash_destroy(MONGODB_G(subscribers));
FREE_HASHTABLE(MONGODB_G(subscribers));
MONGODB_G(subscribers) = NULL;
}
return SUCCESS;
}
/* }}} */
/* {{{ PHP_GSHUTDOWN_FUNCTION */
PHP_GSHUTDOWN_FUNCTION(mongodb)
{
mongodb_globals->debug = NULL;
if (mongodb_globals->debug_fd) {
fclose(mongodb_globals->debug_fd);
mongodb_globals->debug_fd = NULL;
}
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(mongodb)
{
php_info_print_table_start();
php_info_print_table_header(2, "MongoDB support", "enabled");
php_info_print_table_row(2, "MongoDB extension version", PHP_MONGODB_VERSION);
php_info_print_table_row(2, "MongoDB extension stability", PHP_MONGODB_STABILITY);
#ifdef HAVE_SYSTEM_LIBBSON
php_info_print_table_row(2, "libbson headers version", BSON_VERSION_S);
php_info_print_table_row(2, "libbson library version", bson_get_version());
#else
php_info_print_table_row(2, "libbson bundled version", BSON_VERSION_S);
#endif
#ifdef HAVE_SYSTEM_LIBMONGOC
php_info_print_table_row(2, "libmongoc headers version", MONGOC_VERSION_S);
php_info_print_table_row(2, "libmongoc library version", mongoc_get_version());
#else
/* Bundled libraries, buildtime = runtime */
php_info_print_table_row(2, "libmongoc bundled version", MONGOC_VERSION_S);
#endif
#ifdef MONGOC_ENABLE_SSL
php_info_print_table_row(2, "libmongoc SSL", "enabled");
#if defined(MONGOC_ENABLE_SSL_OPENSSL)
php_info_print_table_row(2, "libmongoc SSL library", "OpenSSL");
#elif defined(MONGOC_ENABLE_SSL_LIBRESSL)
php_info_print_table_row(2, "libmongoc SSL library", "LibreSSL");
#elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT)
php_info_print_table_row(2, "libmongoc SSL library", "Secure Transport");
#elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL)
php_info_print_table_row(2, "libmongoc SSL library", "Secure Channel");
#else
php_info_print_table_row(2, "libmongoc SSL library", "unknown");
#endif
#else /* MONGOC_ENABLE_SSL */
php_info_print_table_row(2, "libmongoc SSL", "disabled");
#endif
#ifdef MONGOC_ENABLE_CRYPTO
php_info_print_table_row(2, "libmongoc crypto", "enabled");
#if defined(MONGOC_ENABLE_CRYPTO_LIBCRYPTO)
php_info_print_table_row(2, "libmongoc crypto library", "libcrypto");
#elif defined(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO)
php_info_print_table_row(2, "libmongoc crypto library", "Common Crypto");
#elif defined(MONGOC_ENABLE_CRYPTO_CNG)
php_info_print_table_row(2, "libmongoc crypto library", "CNG");
#else
php_info_print_table_row(2, "libmongoc crypto library", "unknown");
#endif
#ifdef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE
php_info_print_table_row(2, "libmongoc crypto system profile", "enabled");
#else
php_info_print_table_row(2, "libmongoc crypto system profile", "disabled");
#endif
#else /* MONGOC_ENABLE_CRYPTO */
php_info_print_table_row(2, "libmongoc crypto", "disabled");
#endif
#ifdef MONGOC_ENABLE_SASL
php_info_print_table_row(2, "libmongoc SASL", "enabled");
#else
php_info_print_table_row(2, "libmongoc SASL", "disabled");
#endif
#ifdef MONGOC_ENABLE_ICU
php_info_print_table_row(2, "libmongoc ICU", "enabled");
#else
php_info_print_table_row(2, "libmongoc ICU", "disabled");
#endif
#ifdef MONGOC_ENABLE_COMPRESSION
php_info_print_table_row(2, "libmongoc compression", "enabled");
#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY
php_info_print_table_row(2, "libmongoc compression snappy", "enabled");
#else
php_info_print_table_row(2, "libmongoc compression snappy", "disabled");
#endif
#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB
php_info_print_table_row(2, "libmongoc compression zlib", "enabled");
#else
php_info_print_table_row(2, "libmongoc compression zlib", "disabled");
#endif
+#ifdef MONGOC_ENABLE_COMPRESSION_ZSTD
+ php_info_print_table_row(2, "libmongoc compression zstd", "enabled");
+#else
+ php_info_print_table_row(2, "libmongoc compression zstd", "disabled");
+#endif
#else /* MONGOC_ENABLE_COMPRESSION */
php_info_print_table_row(2, "libmongoc compression", "disabled");
#endif
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
#ifdef HAVE_SYSTEM_LIBMONGOCRYPT
php_info_print_table_row(2, "libmongocrypt headers version", MONGOCRYPT_VERSION);
php_info_print_table_row(2, "libmongocrypt library version", mongocrypt_version(NULL));
#else
php_info_print_table_row(2, "libmongocrypt bundled version", MONGOCRYPT_VERSION);
#endif
#ifdef MONGOCRYPT_ENABLE_CRYPTO
php_info_print_table_row(2, "libmongocrypt crypto", "enabled");
#if defined(MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO)
php_info_print_table_row(2, "libmongocrypt crypto library", "libcrypto");
#elif defined(MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO)
php_info_print_table_row(2, "libmongocrypt crypto library", "Common Crypto");
#elif defined(MONGOCRYPT_ENABLE_CRYPTO_CNG)
php_info_print_table_row(2, "libmongocrypt crypto library", "CNG");
#else
php_info_print_table_row(2, "libmongocrypt crypto library", "unknown");
#endif
#else /* MONGOCRYPT_ENABLE_CRYPTO */
php_info_print_table_row(2, "libmongocrypt crypto", "disabled");
#endif
#else /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
php_info_print_table_row(2, "libmongocrypt", "disabled");
#endif
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
}
/* }}} */
/* }}} */
/* {{{ Shared function entries for disabling constructors and unserialize() */
PHP_FUNCTION(MongoDB_disabled___construct) /* {{{ */
{
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Accessing private constructor");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Accessing private constructor");
} /* }}} */
PHP_FUNCTION(MongoDB_disabled___wakeup) /* {{{ */
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "%s", "MongoDB\\Driver objects cannot be serialized");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "%s", "MongoDB\\Driver objects cannot be serialized");
} /* }}} */
/* }}} */
/* {{{ mongodb_functions[]
*/
ZEND_BEGIN_ARG_INFO_EX(ai_bson_fromPHP, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO();
ZEND_BEGIN_ARG_INFO_EX(ai_bson_toPHP, 0, 0, 1)
ZEND_ARG_INFO(0, bson)
ZEND_ARG_ARRAY_INFO(0, typemap, 0)
ZEND_END_ARG_INFO();
ZEND_BEGIN_ARG_INFO_EX(ai_bson_toJSON, 0, 0, 1)
ZEND_ARG_INFO(0, bson)
ZEND_END_ARG_INFO();
ZEND_BEGIN_ARG_INFO_EX(ai_bson_fromJSON, 0, 0, 1)
ZEND_ARG_INFO(0, json)
ZEND_END_ARG_INFO();
ZEND_BEGIN_ARG_INFO_EX(ai_mongodb_driver_monitoring_subscriber, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, subscriber, MongoDB\\Driver\\Monitoring\\Subscriber, 0)
ZEND_END_ARG_INFO();
static const zend_function_entry mongodb_functions[] = {
ZEND_NS_NAMED_FE("MongoDB\\BSON", fromPHP, PHP_FN(MongoDB_BSON_fromPHP), ai_bson_fromPHP)
ZEND_NS_NAMED_FE("MongoDB\\BSON", toPHP, PHP_FN(MongoDB_BSON_toPHP), ai_bson_toPHP)
ZEND_NS_NAMED_FE("MongoDB\\BSON", toJSON, PHP_FN(MongoDB_BSON_toJSON), ai_bson_toJSON)
ZEND_NS_NAMED_FE("MongoDB\\BSON", toCanonicalExtendedJSON, PHP_FN(MongoDB_BSON_toCanonicalExtendedJSON), ai_bson_toJSON)
ZEND_NS_NAMED_FE("MongoDB\\BSON", toRelaxedExtendedJSON, PHP_FN(MongoDB_BSON_toRelaxedExtendedJSON), ai_bson_toJSON)
ZEND_NS_NAMED_FE("MongoDB\\BSON", fromJSON, PHP_FN(MongoDB_BSON_fromJSON), ai_bson_fromJSON)
ZEND_NS_NAMED_FE("MongoDB\\Driver\\Monitoring", addSubscriber, PHP_FN(MongoDB_Driver_Monitoring_addSubscriber), ai_mongodb_driver_monitoring_subscriber)
ZEND_NS_NAMED_FE("MongoDB\\Driver\\Monitoring", removeSubscriber, PHP_FN(MongoDB_Driver_Monitoring_removeSubscriber), ai_mongodb_driver_monitoring_subscriber)
PHP_FE_END
};
/* }}} */
static const zend_module_dep mongodb_deps[] = {
ZEND_MOD_REQUIRED("date")
ZEND_MOD_REQUIRED("json")
ZEND_MOD_REQUIRED("spl")
ZEND_MOD_REQUIRED("standard")
ZEND_MOD_END
};
/* {{{ mongodb_module_entry
*/
zend_module_entry mongodb_module_entry = {
STANDARD_MODULE_HEADER_EX,
NULL,
mongodb_deps,
"mongodb",
mongodb_functions,
PHP_MINIT(mongodb),
PHP_MSHUTDOWN(mongodb),
PHP_RINIT(mongodb),
PHP_RSHUTDOWN(mongodb),
PHP_MINFO(mongodb),
PHP_MONGODB_VERSION,
PHP_MODULE_GLOBALS(mongodb),
PHP_GINIT(mongodb),
PHP_GSHUTDOWN(mongodb),
NULL,
STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */
#ifdef COMPILE_DL_MONGODB
ZEND_GET_MODULE(mongodb)
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/php_phongo.h b/mongodb-1.8.1/php_phongo.h
similarity index 80%
rename from mongodb-1.7.4/php_phongo.h
rename to mongodb-1.8.1/php_phongo.h
index a9a0b843..416a8355 100644
--- a/mongodb-1.7.4/php_phongo.h
+++ b/mongodb-1.8.1/php_phongo.h
@@ -1,250 +1,219 @@
/*
* Copyright 2014-2017 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.
*/
#ifndef PHONGO_H
#define PHONGO_H
/* External libs */
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include "phongo_version.h"
#include "phongo_compat.h"
#include "php_phongo_classes.h"
#define phpext_mongodb_ptr &mongodb_module_entry
extern zend_module_entry mongodb_module_entry;
/* Structure for persisted libmongoc clients. The PID is included to ensure that
* processes do not destroy clients created by other processes (relevant for
* forking). We avoid using pid_t for Windows compatibility. */
typedef struct {
mongoc_client_t* client;
int created_by_pid;
int last_reset_by_pid;
} php_phongo_pclient_t;
ZEND_BEGIN_MODULE_GLOBALS(mongodb)
char* debug;
FILE* debug_fd;
bson_mem_vtable_t bsonMemVTable;
HashTable pclients;
HashTable* subscribers;
ZEND_END_MODULE_GLOBALS(mongodb)
-#if PHP_VERSION_ID >= 70000
#define MONGODB_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(mongodb, v)
#if defined(ZTS) && defined(COMPILE_DL_MONGODB)
ZEND_TSRMLS_CACHE_EXTERN()
#endif
-#else /* PHP_VERSION_ID >= 70000 */
-#ifdef ZTS
-#define MONGODB_G(v) TSRMG(mongodb_globals_id, zend_mongodb_globals*, v)
-#define mglo mongodb_globals_id
-#else /* ZTS */
-#define MONGODB_G(v) (mongodb_globals.v)
-#define mglo mongodb_globals
-#endif /* ZTS */
-#endif /* PHP_VERSION_ID >= 70000 */
#define PHONGO_WRITE_CONCERN_W_MAJORITY "majority"
/* This enum is necessary since mongoc_server_description_type_t is private and
* we need to translate strings returned by mongoc_server_description_type() to
* Server integer constants. */
typedef enum {
PHONGO_SERVER_UNKNOWN = 0,
PHONGO_SERVER_STANDALONE = 1,
PHONGO_SERVER_MONGOS = 2,
PHONGO_SERVER_POSSIBLE_PRIMARY = 3,
PHONGO_SERVER_RS_PRIMARY = 4,
PHONGO_SERVER_RS_SECONDARY = 5,
PHONGO_SERVER_RS_ARBITER = 6,
PHONGO_SERVER_RS_OTHER = 7,
PHONGO_SERVER_RS_GHOST = 8,
PHONGO_SERVER_DESCRIPTION_TYPES = 9,
} php_phongo_server_description_type_t;
typedef struct {
php_phongo_server_description_type_t type;
const char* name;
} php_phongo_server_description_type_map_t;
extern php_phongo_server_description_type_map_t php_phongo_server_description_type_map[];
typedef enum {
PHONGO_ERROR_INVALID_ARGUMENT = 1,
PHONGO_ERROR_RUNTIME = 2,
PHONGO_ERROR_UNEXPECTED_VALUE = 8,
PHONGO_ERROR_MONGOC_FAILED = 3,
PHONGO_ERROR_CONNECTION_FAILED = 7,
PHONGO_ERROR_LOGIC = 9
} php_phongo_error_domain_t;
/* This constant is used for determining if a server error for an exceeded query
* or command should select ExecutionTimeoutException. */
#define PHONGO_SERVER_ERROR_EXCEEDED_TIME_LIMIT 50
zend_class_entry* phongo_exception_from_mongoc_domain(uint32_t /* mongoc_error_domain_t */ domain, uint32_t /* mongoc_error_code_t */ code);
zend_class_entry* phongo_exception_from_phongo_domain(php_phongo_error_domain_t domain);
-void phongo_throw_exception(php_phongo_error_domain_t domain TSRMLS_DC, const char* format, ...)
-#if PHP_VERSION_ID < 70000
-#ifndef PHP_WIN32
-#ifdef ZTS
- __attribute__((format(printf, 3, 4)))
-#else
- __attribute__((format(printf, 2, 3)))
-#endif /* ZTS */
-#endif /* PHP_WIN32 */
-#endif /* PHP_VERSION_ID < 70000 */
- ;
-void phongo_throw_exception_from_bson_error_t(bson_error_t* error TSRMLS_DC);
-void phongo_throw_exception_from_bson_error_t_and_reply(bson_error_t* error, const bson_t* reply TSRMLS_DC);
+void phongo_throw_exception(php_phongo_error_domain_t domain, const char* format, ...);
+void phongo_throw_exception_from_bson_error_t(bson_error_t* error);
+void phongo_throw_exception_from_bson_error_t_and_reply(bson_error_t* error, const bson_t* reply);
/* This enum is used for processing options in phongo_execute_parse_options and
* selecting a libmongoc function to use in phongo_execute_command. The values
* are important, as READ and WRITE are also used as a bit field to determine
* whether readPreference, readConcern, and writeConcern options are parsed. */
typedef enum {
PHONGO_OPTION_READ_CONCERN = 0x01,
PHONGO_OPTION_READ_PREFERENCE = 0x02,
PHONGO_OPTION_WRITE_CONCERN = 0x04,
PHONGO_COMMAND_RAW = 0x07,
PHONGO_COMMAND_READ = 0x03,
PHONGO_COMMAND_WRITE = 0x04,
PHONGO_COMMAND_READ_WRITE = 0x05,
} php_phongo_command_type_t;
zend_object_handlers* phongo_get_std_object_handlers(void);
-void phongo_clientencryption_init(php_phongo_clientencryption_t* ce_obj, mongoc_client_t* client, zval* options TSRMLS_DC);
-void phongo_server_init(zval* return_value, mongoc_client_t* client, uint32_t server_id TSRMLS_DC);
-void phongo_session_init(zval* return_value, mongoc_client_session_t* client_session TSRMLS_DC);
-void phongo_readconcern_init(zval* return_value, const mongoc_read_concern_t* read_concern TSRMLS_DC);
-void phongo_readpreference_init(zval* return_value, const mongoc_read_prefs_t* read_prefs TSRMLS_DC);
-void phongo_writeconcern_init(zval* return_value, const mongoc_write_concern_t* write_concern TSRMLS_DC);
-bool phongo_execute_bulk_write(mongoc_client_t* client, const char* namespace, php_phongo_bulkwrite_t* bulk_write, zval* zwriteConcern, uint32_t server_id, zval* return_value, int return_value_used TSRMLS_DC);
-bool phongo_execute_command(mongoc_client_t* client, php_phongo_command_type_t type, const char* db, zval* zcommand, zval* zreadPreference, uint32_t server_id, zval* return_value, int return_value_used TSRMLS_DC);
-bool phongo_execute_query(mongoc_client_t* client, const char* namespace, zval* zquery, zval* zreadPreference, uint32_t server_id, zval* return_value, int return_value_used TSRMLS_DC);
+void phongo_clientencryption_init(php_phongo_clientencryption_t* ce_obj, mongoc_client_t* client, zval* options);
+void phongo_server_init(zval* return_value, mongoc_client_t* client, uint32_t server_id);
+void phongo_session_init(zval* return_value, mongoc_client_session_t* client_session);
+void phongo_readconcern_init(zval* return_value, const mongoc_read_concern_t* read_concern);
+void phongo_readpreference_init(zval* return_value, const mongoc_read_prefs_t* read_prefs);
+void phongo_writeconcern_init(zval* return_value, const mongoc_write_concern_t* write_concern);
+bool phongo_execute_bulk_write(mongoc_client_t* client, const char* namespace, php_phongo_bulkwrite_t* bulk_write, zval* zwriteConcern, uint32_t server_id, zval* return_value);
+bool phongo_execute_command(mongoc_client_t* client, php_phongo_command_type_t type, const char* db, zval* zcommand, zval* zreadPreference, uint32_t server_id, zval* return_value);
+bool phongo_execute_query(mongoc_client_t* client, const char* namespace, zval* zquery, zval* zreadPreference, uint32_t server_id, zval* return_value);
-bool phongo_cursor_advance_and_check_for_error(mongoc_cursor_t* cursor TSRMLS_DC);
+bool phongo_cursor_advance_and_check_for_error(mongoc_cursor_t* cursor);
-const mongoc_read_concern_t* phongo_read_concern_from_zval(zval* zread_concern TSRMLS_DC);
-const mongoc_read_prefs_t* phongo_read_preference_from_zval(zval* zread_preference TSRMLS_DC);
-const mongoc_write_concern_t* phongo_write_concern_from_zval(zval* zwrite_concern TSRMLS_DC);
+const mongoc_read_concern_t* phongo_read_concern_from_zval(zval* zread_concern);
+const mongoc_read_prefs_t* phongo_read_preference_from_zval(zval* zread_preference);
+const mongoc_write_concern_t* phongo_write_concern_from_zval(zval* zwrite_concern);
php_phongo_server_description_type_t php_phongo_server_description_type(mongoc_server_description_t* sd);
-bool phongo_parse_read_preference(zval* options, zval** zreadPreference TSRMLS_DC);
-bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession TSRMLS_DC);
+bool phongo_parse_read_preference(zval* options, zval** zreadPreference);
+bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession);
-zval* php_phongo_prep_legacy_option(zval* options, const char* key, bool* allocated TSRMLS_DC);
-void php_phongo_prep_legacy_option_free(zval* options TSRMLS_DC);
+zval* php_phongo_prep_legacy_option(zval* options, const char* key, bool* allocated);
+void php_phongo_prep_legacy_option_free(zval* options);
-void php_phongo_read_preference_prep_tagsets(zval* tagSets TSRMLS_DC);
+void php_phongo_read_preference_prep_tagsets(zval* tagSets);
bool php_phongo_read_preference_tags_are_valid(const bson_t* tags);
bool php_phongo_server_to_zval(zval* retval, mongoc_server_description_t* sd);
void php_phongo_read_concern_to_zval(zval* retval, const mongoc_read_concern_t* read_concern);
void php_phongo_write_concern_to_zval(zval* retval, const mongoc_write_concern_t* write_concern);
void php_phongo_cursor_to_zval(zval* retval, const mongoc_cursor_t* cursor);
-void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, zval* options, zval* driverOptions TSRMLS_DC);
+void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, zval* options, zval* driverOptions);
int php_phongo_set_monitoring_callbacks(mongoc_client_t* client);
-bool php_phongo_parse_int64(int64_t* retval, const char* data, phongo_zpp_char_len data_len);
+bool php_phongo_parse_int64(int64_t* retval, const char* data, size_t data_len);
-void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options TSRMLS_DC);
-void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options TSRMLS_DC);
-void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue TSRMLS_DC);
+void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options);
+void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options);
+void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue);
-zend_bool phongo_writeerror_init(zval* return_value, bson_t* bson TSRMLS_DC);
-zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson TSRMLS_DC);
+zend_bool phongo_writeerror_init(zval* return_value, bson_t* bson);
+zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson);
void php_phongo_client_reset_once(mongoc_client_t* client, int pid);
-#if PHP_VERSION_ID >= 70000
#define PHONGO_CE_FINAL(ce) \
do { \
ce->ce_flags |= ZEND_ACC_FINAL; \
} while (0);
-#else
-#define PHONGO_CE_FINAL(ce) \
- do { \
- ce->ce_flags |= ZEND_ACC_FINAL_CLASS; \
- } while (0);
-#endif
#define PHONGO_CE_DISABLE_SERIALIZATION(ce) \
do { \
ce->serialize = zend_class_serialize_deny; \
ce->unserialize = zend_class_unserialize_deny; \
} while (0);
#define PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, size) \
do { \
if (is_debug) { \
ALLOC_HASHTABLE(props); \
zend_hash_init((props), (size), NULL, ZVAL_PTR_DTOR, 0); \
} else if ((intern)->properties) { \
(props) = (intern)->properties; \
} else { \
ALLOC_HASHTABLE(props); \
zend_hash_init((props), (size), NULL, ZVAL_PTR_DTOR, 0); \
(intern)->properties = (props); \
} \
} while (0);
#define PHONGO_GET_PROPERTY_HASH_FREE_PROPS(is_debug, props) \
do { \
if (is_debug) { \
zend_hash_destroy((props)); \
FREE_HASHTABLE(props); \
} \
} while (0);
#define PHONGO_ZVAL_CLASS_OR_TYPE_NAME(zv) (Z_TYPE(zv) == IS_OBJECT ? ZSTR_VAL(Z_OBJCE(zv)->name) : zend_get_type_by_const(Z_TYPE(zv)))
#define PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zvp) PHONGO_ZVAL_CLASS_OR_TYPE_NAME(*(zvp))
-#if PHP_VERSION_ID >= 70000
#define PHONGO_ZVAL_EXCEPTION_NAME(e) (ZSTR_VAL(e->ce->name))
-#else
-#define PHONGO_ZVAL_EXCEPTION_NAME(e) (ZSTR_VAL(Z_OBJCE_P(e)->name))
-#endif
#define PHONGO_SET_CREATED_BY_PID(intern) \
do { \
(intern)->created_by_pid = (int) getpid(); \
} while (0);
#define PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern) \
do { \
int pid = (int) getpid(); \
if ((intern)->created_by_pid != pid) { \
php_phongo_client_reset_once((intern)->client, pid); \
} \
} while (0);
#endif /* PHONGO_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/php_phongo_classes.h b/mongodb-1.8.1/php_phongo_classes.h
similarity index 78%
rename from mongodb-1.7.4/php_phongo_classes.h
rename to mongodb-1.8.1/php_phongo_classes.h
index 5be3128c..e832319e 100644
--- a/mongodb-1.7.4/php_phongo_classes.h
+++ b/mongodb-1.8.1/php_phongo_classes.h
@@ -1,439 +1,369 @@
/*
* Copyright 2014-2017 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.
*/
#ifndef PHONGO_CLASSES_H
#define PHONGO_CLASSES_H
#include "php_phongo_structs.h"
/* Export zend_class_entry dependencies, which are initialized in MINIT */
extern zend_class_entry* php_phongo_date_immutable_ce;
extern zend_class_entry* php_phongo_json_serializable_ce;
-#if PHP_VERSION_ID >= 70000
-
static inline php_phongo_bulkwrite_t* php_bulkwrite_fetch_object(zend_object* obj)
{
return (php_phongo_bulkwrite_t*) ((char*) obj - XtOffsetOf(php_phongo_bulkwrite_t, std));
}
static inline php_phongo_clientencryption_t* php_clientencryption_fetch_object(zend_object* obj)
{
return (php_phongo_clientencryption_t*) ((char*) obj - XtOffsetOf(php_phongo_clientencryption_t, std));
}
static inline php_phongo_command_t* php_command_fetch_object(zend_object* obj)
{
return (php_phongo_command_t*) ((char*) obj - XtOffsetOf(php_phongo_command_t, std));
}
static inline php_phongo_cursor_t* php_cursor_fetch_object(zend_object* obj)
{
return (php_phongo_cursor_t*) ((char*) obj - XtOffsetOf(php_phongo_cursor_t, std));
}
static inline php_phongo_cursorid_t* php_cursorid_fetch_object(zend_object* obj)
{
return (php_phongo_cursorid_t*) ((char*) obj - XtOffsetOf(php_phongo_cursorid_t, std));
}
static inline php_phongo_manager_t* php_manager_fetch_object(zend_object* obj)
{
return (php_phongo_manager_t*) ((char*) obj - XtOffsetOf(php_phongo_manager_t, std));
}
static inline php_phongo_query_t* php_query_fetch_object(zend_object* obj)
{
return (php_phongo_query_t*) ((char*) obj - XtOffsetOf(php_phongo_query_t, std));
}
static inline php_phongo_readconcern_t* php_readconcern_fetch_object(zend_object* obj)
{
return (php_phongo_readconcern_t*) ((char*) obj - XtOffsetOf(php_phongo_readconcern_t, std));
}
static inline php_phongo_readpreference_t* php_readpreference_fetch_object(zend_object* obj)
{
return (php_phongo_readpreference_t*) ((char*) obj - XtOffsetOf(php_phongo_readpreference_t, std));
}
static inline php_phongo_server_t* php_server_fetch_object(zend_object* obj)
{
return (php_phongo_server_t*) ((char*) obj - XtOffsetOf(php_phongo_server_t, std));
}
static inline php_phongo_session_t* php_session_fetch_object(zend_object* obj)
{
return (php_phongo_session_t*) ((char*) obj - XtOffsetOf(php_phongo_session_t, std));
}
static inline php_phongo_writeconcern_t* php_writeconcern_fetch_object(zend_object* obj)
{
return (php_phongo_writeconcern_t*) ((char*) obj - XtOffsetOf(php_phongo_writeconcern_t, std));
}
static inline php_phongo_writeconcernerror_t* php_writeconcernerror_fetch_object(zend_object* obj)
{
return (php_phongo_writeconcernerror_t*) ((char*) obj - XtOffsetOf(php_phongo_writeconcernerror_t, std));
}
static inline php_phongo_writeerror_t* php_writeerror_fetch_object(zend_object* obj)
{
return (php_phongo_writeerror_t*) ((char*) obj - XtOffsetOf(php_phongo_writeerror_t, std));
}
static inline php_phongo_writeresult_t* php_writeresult_fetch_object(zend_object* obj)
{
return (php_phongo_writeresult_t*) ((char*) obj - XtOffsetOf(php_phongo_writeresult_t, std));
}
static inline php_phongo_binary_t* php_binary_fetch_object(zend_object* obj)
{
return (php_phongo_binary_t*) ((char*) obj - XtOffsetOf(php_phongo_binary_t, std));
}
static inline php_phongo_dbpointer_t* php_dbpointer_fetch_object(zend_object* obj)
{
return (php_phongo_dbpointer_t*) ((char*) obj - XtOffsetOf(php_phongo_dbpointer_t, std));
}
static inline php_phongo_decimal128_t* php_decimal128_fetch_object(zend_object* obj)
{
return (php_phongo_decimal128_t*) ((char*) obj - XtOffsetOf(php_phongo_decimal128_t, std));
}
static inline php_phongo_int64_t* php_int64_fetch_object(zend_object* obj)
{
return (php_phongo_int64_t*) ((char*) obj - XtOffsetOf(php_phongo_int64_t, std));
}
static inline php_phongo_javascript_t* php_javascript_fetch_object(zend_object* obj)
{
return (php_phongo_javascript_t*) ((char*) obj - XtOffsetOf(php_phongo_javascript_t, std));
}
static inline php_phongo_maxkey_t* php_maxkey_fetch_object(zend_object* obj)
{
return (php_phongo_maxkey_t*) ((char*) obj - XtOffsetOf(php_phongo_maxkey_t, std));
}
static inline php_phongo_minkey_t* php_minkey_fetch_object(zend_object* obj)
{
return (php_phongo_minkey_t*) ((char*) obj - XtOffsetOf(php_phongo_minkey_t, std));
}
static inline php_phongo_objectid_t* php_objectid_fetch_object(zend_object* obj)
{
return (php_phongo_objectid_t*) ((char*) obj - XtOffsetOf(php_phongo_objectid_t, std));
}
static inline php_phongo_regex_t* php_regex_fetch_object(zend_object* obj)
{
return (php_phongo_regex_t*) ((char*) obj - XtOffsetOf(php_phongo_regex_t, std));
}
static inline php_phongo_symbol_t* php_symbol_fetch_object(zend_object* obj)
{
return (php_phongo_symbol_t*) ((char*) obj - XtOffsetOf(php_phongo_symbol_t, std));
}
static inline php_phongo_timestamp_t* php_timestamp_fetch_object(zend_object* obj)
{
return (php_phongo_timestamp_t*) ((char*) obj - XtOffsetOf(php_phongo_timestamp_t, std));
}
static inline php_phongo_undefined_t* php_undefined_fetch_object(zend_object* obj)
{
return (php_phongo_undefined_t*) ((char*) obj - XtOffsetOf(php_phongo_undefined_t, std));
}
static inline php_phongo_utcdatetime_t* php_utcdatetime_fetch_object(zend_object* obj)
{
return (php_phongo_utcdatetime_t*) ((char*) obj - XtOffsetOf(php_phongo_utcdatetime_t, std));
}
static inline php_phongo_commandfailedevent_t* php_commandfailedevent_fetch_object(zend_object* obj)
{
return (php_phongo_commandfailedevent_t*) ((char*) obj - XtOffsetOf(php_phongo_commandfailedevent_t, std));
}
static inline php_phongo_commandstartedevent_t* php_commandstartedevent_fetch_object(zend_object* obj)
{
return (php_phongo_commandstartedevent_t*) ((char*) obj - XtOffsetOf(php_phongo_commandstartedevent_t, std));
}
static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetch_object(zend_object* obj)
{
return (php_phongo_commandsucceededevent_t*) ((char*) obj - XtOffsetOf(php_phongo_commandsucceededevent_t, std));
}
#define Z_CLIENTENCRYPTION_OBJ_P(zv) (php_clientencryption_fetch_object(Z_OBJ_P(zv)))
#define Z_COMMAND_OBJ_P(zv) (php_command_fetch_object(Z_OBJ_P(zv)))
#define Z_CURSOR_OBJ_P(zv) (php_cursor_fetch_object(Z_OBJ_P(zv)))
#define Z_CURSORID_OBJ_P(zv) (php_cursorid_fetch_object(Z_OBJ_P(zv)))
#define Z_MANAGER_OBJ_P(zv) (php_manager_fetch_object(Z_OBJ_P(zv)))
#define Z_QUERY_OBJ_P(zv) (php_query_fetch_object(Z_OBJ_P(zv)))
#define Z_READCONCERN_OBJ_P(zv) (php_readconcern_fetch_object(Z_OBJ_P(zv)))
#define Z_READPREFERENCE_OBJ_P(zv) (php_readpreference_fetch_object(Z_OBJ_P(zv)))
#define Z_SERVER_OBJ_P(zv) (php_server_fetch_object(Z_OBJ_P(zv)))
#define Z_SESSION_OBJ_P(zv) (php_session_fetch_object(Z_OBJ_P(zv)))
#define Z_BULKWRITE_OBJ_P(zv) (php_bulkwrite_fetch_object(Z_OBJ_P(zv)))
#define Z_WRITECONCERN_OBJ_P(zv) (php_writeconcern_fetch_object(Z_OBJ_P(zv)))
#define Z_WRITECONCERNERROR_OBJ_P(zv) (php_writeconcernerror_fetch_object(Z_OBJ_P(zv)))
#define Z_WRITEERROR_OBJ_P(zv) (php_writeerror_fetch_object(Z_OBJ_P(zv)))
#define Z_WRITERESULT_OBJ_P(zv) (php_writeresult_fetch_object(Z_OBJ_P(zv)))
#define Z_BINARY_OBJ_P(zv) (php_binary_fetch_object(Z_OBJ_P(zv)))
#define Z_DBPOINTER_OBJ_P(zv) (php_dbpointer_fetch_object(Z_OBJ_P(zv)))
#define Z_DECIMAL128_OBJ_P(zv) (php_decimal128_fetch_object(Z_OBJ_P(zv)))
#define Z_INT64_OBJ_P(zv) (php_int64_fetch_object(Z_OBJ_P(zv)))
#define Z_JAVASCRIPT_OBJ_P(zv) (php_javascript_fetch_object(Z_OBJ_P(zv)))
#define Z_MAXKEY_OBJ_P(zv) (php_maxkey_fetch_object(Z_OBJ_P(zv)))
#define Z_MINKEY_OBJ_P(zv) (php_minkey_fetch_object(Z_OBJ_P(zv)))
#define Z_OBJECTID_OBJ_P(zv) (php_objectid_fetch_object(Z_OBJ_P(zv)))
#define Z_REGEX_OBJ_P(zv) (php_regex_fetch_object(Z_OBJ_P(zv)))
#define Z_SYMBOL_OBJ_P(zv) (php_symbol_fetch_object(Z_OBJ_P(zv)))
#define Z_TIMESTAMP_OBJ_P(zv) (php_timestamp_fetch_object(Z_OBJ_P(zv)))
#define Z_UNDEFINED_OBJ_P(zv) (php_undefined_fetch_object(Z_OBJ_P(zv)))
#define Z_UTCDATETIME_OBJ_P(zv) (php_utcdatetime_fetch_object(Z_OBJ_P(zv)))
#define Z_COMMANDFAILEDEVENT_OBJ_P(zv) (php_commandfailedevent_fetch_object(Z_OBJ_P(zv)))
#define Z_COMMANDSTARTEDEVENT_OBJ_P(zv) (php_commandstartedevent_fetch_object(Z_OBJ_P(zv)))
#define Z_COMMANDSUCCEEDEDEVENT_OBJ_P(zv) (php_commandsucceededevent_fetch_object(Z_OBJ_P(zv)))
#define Z_OBJ_CLIENTENCRYPTION(zo) (php_clientencryption_fetch_object(zo))
#define Z_OBJ_COMMAND(zo) (php_command_fetch_object(zo))
#define Z_OBJ_CURSOR(zo) (php_cursor_fetch_object(zo))
#define Z_OBJ_CURSORID(zo) (php_cursorid_fetch_object(zo))
#define Z_OBJ_MANAGER(zo) (php_manager_fetch_object(zo))
#define Z_OBJ_QUERY(zo) (php_query_fetch_object(zo))
#define Z_OBJ_READCONCERN(zo) (php_readconcern_fetch_object(zo))
#define Z_OBJ_READPREFERENCE(zo) (php_readpreference_fetch_object(zo))
#define Z_OBJ_SERVER(zo) (php_server_fetch_object(zo))
#define Z_OBJ_SESSION(zo) (php_session_fetch_object(zo))
#define Z_OBJ_BULKWRITE(zo) (php_bulkwrite_fetch_object(zo))
#define Z_OBJ_WRITECONCERN(zo) (php_writeconcern_fetch_object(zo))
#define Z_OBJ_WRITECONCERNERROR(zo) (php_writeconcernerror_fetch_object(zo))
#define Z_OBJ_WRITEERROR(zo) (php_writeerror_fetch_object(zo))
#define Z_OBJ_WRITERESULT(zo) (php_writeresult_fetch_object(zo))
#define Z_OBJ_BINARY(zo) (php_binary_fetch_object(zo))
#define Z_OBJ_DBPOINTER(zo) (php_dbpointer_fetch_object(zo))
#define Z_OBJ_DECIMAL128(zo) (php_decimal128_fetch_object(zo))
#define Z_OBJ_INT64(zo) (php_int64_fetch_object(zo))
#define Z_OBJ_JAVASCRIPT(zo) (php_javascript_fetch_object(zo))
#define Z_OBJ_MAXKEY(zo) (php_maxkey_fetch_object(zo))
#define Z_OBJ_MINKEY(zo) (php_minkey_fetch_object(zo))
#define Z_OBJ_OBJECTID(zo) (php_objectid_fetch_object(zo))
#define Z_OBJ_REGEX(zo) (php_regex_fetch_object(zo))
#define Z_OBJ_SYMBOL(zo) (php_symbol_fetch_object(zo))
#define Z_OBJ_TIMESTAMP(zo) (php_timestamp_fetch_object(zo))
#define Z_OBJ_UNDEFINED(zo) (php_undefined_fetch_object(zo))
#define Z_OBJ_UTCDATETIME(zo) (php_utcdatetime_fetch_object(zo))
#define Z_OBJ_COMMANDFAILEDEVENT(zo) (php_commandfailedevent_fetch_object(zo))
#define Z_OBJ_COMMANDSTARTEDEVENT(zo) (php_commandstartedevent_fetch_object(zo))
#define Z_OBJ_COMMANDSUCCEEDEDEVENT(zo) (php_commandsucceededevent_fetch_object(zo))
-#else /* PHP_VERSION_ID >= 70000 */
-
-#define Z_CLIENTENCRYPTION_OBJ_P(zv) ((php_phongo_clientencryption_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_COMMAND_OBJ_P(zv) ((php_phongo_command_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_CURSOR_OBJ_P(zv) ((php_phongo_cursor_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_CURSORID_OBJ_P(zv) ((php_phongo_cursorid_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_MANAGER_OBJ_P(zv) ((php_phongo_manager_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_QUERY_OBJ_P(zv) ((php_phongo_query_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_READCONCERN_OBJ_P(zv) ((php_phongo_readconcern_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_READPREFERENCE_OBJ_P(zv) ((php_phongo_readpreference_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_SERVER_OBJ_P(zv) ((php_phongo_server_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_SESSION_OBJ_P(zv) ((php_phongo_session_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_BULKWRITE_OBJ_P(zv) ((php_phongo_bulkwrite_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_WRITECONCERN_OBJ_P(zv) ((php_phongo_writeconcern_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_WRITECONCERNERROR_OBJ_P(zv) ((php_phongo_writeconcernerror_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_WRITEERROR_OBJ_P(zv) ((php_phongo_writeerror_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_WRITERESULT_OBJ_P(zv) ((php_phongo_writeresult_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_BINARY_OBJ_P(zv) ((php_phongo_binary_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_DBPOINTER_OBJ_P(zv) ((php_phongo_dbpointer_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_DECIMAL128_OBJ_P(zv) ((php_phongo_decimal128_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_INT64_OBJ_P(zv) ((php_phongo_int64_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_JAVASCRIPT_OBJ_P(zv) ((php_phongo_javascript_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_MAXKEY_OBJ_P(zv) ((php_phongo_maxkey_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_MINKEY_OBJ_P(zv) ((php_phongo_minkey_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_OBJECTID_OBJ_P(zv) ((php_phongo_objectid_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_REGEX_OBJ_P(zv) ((php_phongo_regex_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_SYMBOL_OBJ_P(zv) ((php_phongo_symbol_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_TIMESTAMP_OBJ_P(zv) ((php_phongo_timestamp_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_UNDEFINED_OBJ_P(zv) ((php_phongo_undefined_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_UTCDATETIME_OBJ_P(zv) ((php_phongo_utcdatetime_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_COMMANDFAILEDEVENT_OBJ_P(zv) ((php_phongo_commandfailedevent_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_COMMANDSTARTEDEVENT_OBJ_P(zv) ((php_phongo_commandstartedevent_t*) zend_object_store_get_object(zv TSRMLS_CC))
-#define Z_COMMANDSUCCEEDEDEVENT_OBJ_P(zv) ((php_phongo_commandsucceededevent_t*) zend_object_store_get_object(zv TSRMLS_CC))
-
-#define Z_OBJ_CLIENTENCRYPTION(zo) ((php_phongo_clientencryption_t*) zo)
-#define Z_OBJ_COMMAND(zo) ((php_phongo_command_t*) zo)
-#define Z_OBJ_CURSOR(zo) ((php_phongo_cursor_t*) zo)
-#define Z_OBJ_CURSORID(zo) ((php_phongo_cursorid_t*) zo)
-#define Z_OBJ_MANAGER(zo) ((php_phongo_manager_t*) zo)
-#define Z_OBJ_QUERY(zo) ((php_phongo_query_t*) zo)
-#define Z_OBJ_READCONCERN(zo) ((php_phongo_readconcern_t*) zo)
-#define Z_OBJ_READPREFERENCE(zo) ((php_phongo_readpreference_t*) zo)
-#define Z_OBJ_SERVER(zo) ((php_phongo_server_t*) zo)
-#define Z_OBJ_SESSION(zo) ((php_phongo_session_t*) zo)
-#define Z_OBJ_BULKWRITE(zo) ((php_phongo_bulkwrite_t*) zo)
-#define Z_OBJ_WRITECONCERN(zo) ((php_phongo_writeconcern_t*) zo)
-#define Z_OBJ_WRITECONCERNERROR(zo) ((php_phongo_writeconcernerror_t*) zo)
-#define Z_OBJ_WRITEERROR(zo) ((php_phongo_writeerror_t*) zo)
-#define Z_OBJ_WRITERESULT(zo) ((php_phongo_writeresult_t*) zo)
-#define Z_OBJ_BINARY(zo) ((php_phongo_binary_t*) zo)
-#define Z_OBJ_DBPOINTER(zo) ((php_phongo_dbpointer_t*) zo)
-#define Z_OBJ_DECIMAL128(zo) ((php_phongo_decimal128_t*) zo)
-#define Z_OBJ_INT64(zo) ((php_phongo_int64_t*) zo)
-#define Z_OBJ_JAVASCRIPT(zo) ((php_phongo_javascript_t*) zo)
-#define Z_OBJ_MAXKEY(zo) ((php_phongo_maxkey_t*) zo)
-#define Z_OBJ_MINKEY(zo) ((php_phongo_minkey_t*) zo)
-#define Z_OBJ_OBJECTID(zo) ((php_phongo_objectid_t*) zo)
-#define Z_OBJ_REGEX(zo) ((php_phongo_regex_t*) zo)
-#define Z_OBJ_SYMBOL(zo) ((php_phongo_symbol_t*) zo)
-#define Z_OBJ_TIMESTAMP(zo) ((php_phongo_timestamp_t*) zo)
-#define Z_OBJ_UNDEFINED(zo) ((php_phongo_undefined_t*) zo)
-#define Z_OBJ_UTCDATETIME(zo) ((php_phongo_utcdatetime_t*) zo)
-#define Z_OBJ_COMMANDFAILEDEVENT(zo) ((php_phongo_commandfailedevent_t*) zo)
-#define Z_OBJ_COMMANDSTARTEDEVENT(zo) ((php_phongo_commandstartedevent_t*) zo)
-#define Z_OBJ_COMMANDSUCCEEDEDEVENT(zo) ((php_phongo_commandsucceededevent_t*) zo)
-
-#endif /* PHP_VERSION_ID >= 70000 */
-
typedef struct {
zend_object_iterator intern;
php_phongo_cursor_t* cursor;
} php_phongo_cursor_iterator;
extern zend_class_entry* php_phongo_clientencryption_ce;
extern zend_class_entry* php_phongo_command_ce;
extern zend_class_entry* php_phongo_cursor_ce;
extern zend_class_entry* php_phongo_cursorid_ce;
extern zend_class_entry* php_phongo_manager_ce;
extern zend_class_entry* php_phongo_query_ce;
extern zend_class_entry* php_phongo_readconcern_ce;
extern zend_class_entry* php_phongo_readpreference_ce;
extern zend_class_entry* php_phongo_server_ce;
extern zend_class_entry* php_phongo_session_ce;
extern zend_class_entry* php_phongo_bulkwrite_ce;
extern zend_class_entry* php_phongo_writeconcern_ce;
extern zend_class_entry* php_phongo_writeconcernerror_ce;
extern zend_class_entry* php_phongo_writeerror_ce;
extern zend_class_entry* php_phongo_writeresult_ce;
extern zend_class_entry* php_phongo_cursor_interface_ce;
extern zend_class_entry* php_phongo_exception_ce;
extern zend_class_entry* php_phongo_logicexception_ce;
extern zend_class_entry* php_phongo_runtimeexception_ce;
extern zend_class_entry* php_phongo_serverexception_ce;
extern zend_class_entry* php_phongo_commandexception_ce;
extern zend_class_entry* php_phongo_unexpectedvalueexception_ce;
extern zend_class_entry* php_phongo_invalidargumentexception_ce;
extern zend_class_entry* php_phongo_connectionexception_ce;
extern zend_class_entry* php_phongo_authenticationexception_ce;
extern zend_class_entry* php_phongo_sslconnectionexception_ce;
extern zend_class_entry* php_phongo_encryptionexception_ce;
extern zend_class_entry* php_phongo_executiontimeoutexception_ce;
extern zend_class_entry* php_phongo_connectiontimeoutexception_ce;
extern zend_class_entry* php_phongo_writeexception_ce;
extern zend_class_entry* php_phongo_bulkwriteexception_ce;
extern zend_class_entry* php_phongo_type_ce;
extern zend_class_entry* php_phongo_persistable_ce;
extern zend_class_entry* php_phongo_unserializable_ce;
extern zend_class_entry* php_phongo_serializable_ce;
extern zend_class_entry* php_phongo_binary_ce;
extern zend_class_entry* php_phongo_dbpointer_ce;
extern zend_class_entry* php_phongo_decimal128_ce;
extern zend_class_entry* php_phongo_int64_ce;
extern zend_class_entry* php_phongo_javascript_ce;
extern zend_class_entry* php_phongo_maxkey_ce;
extern zend_class_entry* php_phongo_minkey_ce;
extern zend_class_entry* php_phongo_objectid_ce;
extern zend_class_entry* php_phongo_regex_ce;
extern zend_class_entry* php_phongo_symbol_ce;
extern zend_class_entry* php_phongo_timestamp_ce;
extern zend_class_entry* php_phongo_undefined_ce;
extern zend_class_entry* php_phongo_utcdatetime_ce;
extern zend_class_entry* php_phongo_binary_interface_ce;
extern zend_class_entry* php_phongo_decimal128_interface_ce;
extern zend_class_entry* php_phongo_javascript_interface_ce;
extern zend_class_entry* php_phongo_maxkey_interface_ce;
extern zend_class_entry* php_phongo_minkey_interface_ce;
extern zend_class_entry* php_phongo_objectid_interface_ce;
extern zend_class_entry* php_phongo_regex_interface_ce;
extern zend_class_entry* php_phongo_timestamp_interface_ce;
extern zend_class_entry* php_phongo_utcdatetime_interface_ce;
extern zend_class_entry* php_phongo_commandfailedevent_ce;
extern zend_class_entry* php_phongo_commandstartedevent_ce;
extern zend_class_entry* php_phongo_commandsubscriber_ce;
extern zend_class_entry* php_phongo_commandsucceededevent_ce;
extern zend_class_entry* php_phongo_subscriber_ce;
extern void php_phongo_binary_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_dbpointer_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_decimal128_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_int64_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_javascript_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_maxkey_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_minkey_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_objectid_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_persistable_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_regex_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_serializable_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_symbol_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_timestamp_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_type_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_undefined_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_unserializable_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_utcdatetime_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_binary_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_decimal128_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_javascript_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_maxkey_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_minkey_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_objectid_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_regex_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_timestamp_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_utcdatetime_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_command_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_cursor_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_manager_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_query_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_readconcern_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_readpreference_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_server_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_session_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_writeconcern_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_writeerror_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_writeresult_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_cursor_interface_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_authenticationexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_bulkwriteexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_commandexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_connectionexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_connectiontimeoutexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_encryptionexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_exception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_executiontimeoutexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_invalidargumentexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_logicexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_runtimeexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_serverexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_sslconnectionexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_unexpectedvalueexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_writeexception_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_commandstartedevent_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_commandsubscriber_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_subscriber_init_ce(INIT_FUNC_ARGS);
/* Shared function entries for disabling constructors and unserialize() */
PHP_FUNCTION(MongoDB_disabled___construct);
PHP_FUNCTION(MongoDB_disabled___wakeup);
#endif /* PHONGO_CLASSES_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/php_phongo_structs.h b/mongodb-1.8.1/php_phongo_structs.h
similarity index 56%
rename from mongodb-1.7.4/php_phongo_structs.h
rename to mongodb-1.8.1/php_phongo_structs.h
index 283a11bc..267b3a66 100644
--- a/mongodb-1.7.4/php_phongo_structs.h
+++ b/mongodb-1.8.1/php_phongo_structs.h
@@ -1,317 +1,272 @@
/*
* Copyright 2015-2017 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.
*/
#ifndef PHONGO_STRUCTS_H
#define PHONGO_STRUCTS_H
#include <php.h>
#include "php_bson.h"
-#if PHP_VERSION_ID >= 70000
-#define PHONGO_ZEND_OBJECT_PRE
-#define PHONGO_ZEND_OBJECT_POST zend_object std;
-#define PHONGO_STRUCT_ZVAL zval
-#else
-#define PHONGO_ZEND_OBJECT_PRE zend_object std;
-#define PHONGO_ZEND_OBJECT_POST
-#define PHONGO_STRUCT_ZVAL zval*
-#endif
-
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_bulk_operation_t* bulk;
size_t num_ops;
bool ordered;
int bypass;
char* database;
char* collection;
bool executed;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_bulkwrite_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_client_encryption_t* client_encryption;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_clientencryption_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- bson_t* bson;
- uint32_t max_await_time_ms;
- uint32_t batch_size;
- PHONGO_ZEND_OBJECT_POST
+ bson_t* bson;
+ uint32_t max_await_time_ms;
+ uint32_t batch_size;
+ zend_object std;
} php_phongo_command_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_cursor_t* cursor;
mongoc_client_t* client;
int created_by_pid;
uint32_t server_id;
bool advanced;
php_phongo_bson_state visitor_data;
bool got_iterator;
long current;
char* database;
char* collection;
- PHONGO_STRUCT_ZVAL query;
- PHONGO_STRUCT_ZVAL command;
- PHONGO_STRUCT_ZVAL read_preference;
- PHONGO_STRUCT_ZVAL session;
- PHONGO_ZEND_OBJECT_POST
+ zval query;
+ zval command;
+ zval read_preference;
+ zval session;
+ zend_object std;
} php_phongo_cursor_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- int64_t id;
- PHONGO_ZEND_OBJECT_POST
+ int64_t id;
+ zend_object std;
} php_phongo_cursorid_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_client_t* client;
int created_by_pid;
char* client_hash;
size_t client_hash_len;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_manager_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
bson_t* filter;
bson_t* opts;
mongoc_read_concern_t* read_concern;
uint32_t max_await_time_ms;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_query_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_read_concern_t* read_concern;
HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_readconcern_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_read_prefs_t* read_preference;
HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_readpreference_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_client_t* client;
int created_by_pid;
uint32_t server_id;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_server_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_client_session_t* client_session;
mongoc_client_t* client;
int created_by_pid;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_session_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
HashTable* properties;
mongoc_write_concern_t* write_concern;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_writeconcern_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- int code;
- char* message;
- PHONGO_STRUCT_ZVAL info;
- PHONGO_ZEND_OBJECT_POST
+ int code;
+ char* message;
+ zval info;
+ zend_object std;
} php_phongo_writeconcernerror_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- int code;
- char* message;
- PHONGO_STRUCT_ZVAL info;
- uint32_t index;
- PHONGO_ZEND_OBJECT_POST
+ int code;
+ char* message;
+ zval info;
+ uint32_t index;
+ zend_object std;
} php_phongo_writeerror_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_write_concern_t* write_concern;
bson_t* reply;
mongoc_client_t* client;
uint32_t server_id;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_writeresult_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- char* data;
- int data_len;
- uint8_t type;
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ char* data;
+ int data_len;
+ uint8_t type;
+ HashTable* properties;
+ zend_object std;
} php_phongo_binary_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- char* ref;
- size_t ref_len;
- char id[25];
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ char* ref;
+ size_t ref_len;
+ char id[25];
+ HashTable* properties;
+ zend_object std;
} php_phongo_dbpointer_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
bool initialized;
bson_decimal128_t decimal;
HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_decimal128_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- bool initialized;
- int64_t integer;
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ bool initialized;
+ int64_t integer;
+ HashTable* properties;
+ zend_object std;
} php_phongo_int64_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- char* code;
- size_t code_len;
- bson_t* scope;
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ char* code;
+ size_t code_len;
+ bson_t* scope;
+ HashTable* properties;
+ zend_object std;
} php_phongo_javascript_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_maxkey_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_minkey_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- bool initialized;
- char oid[25];
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ bool initialized;
+ char oid[25];
+ HashTable* properties;
+ zend_object std;
} php_phongo_objectid_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- char* pattern;
- int pattern_len;
- char* flags;
- int flags_len;
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ char* pattern;
+ int pattern_len;
+ char* flags;
+ int flags_len;
+ HashTable* properties;
+ zend_object std;
} php_phongo_regex_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- char* symbol;
- size_t symbol_len;
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ char* symbol;
+ size_t symbol_len;
+ HashTable* properties;
+ zend_object std;
} php_phongo_symbol_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- bool initialized;
- uint32_t increment;
- uint32_t timestamp;
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ bool initialized;
+ uint32_t increment;
+ uint32_t timestamp;
+ HashTable* properties;
+ zend_object std;
} php_phongo_timestamp_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_undefined_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- bool initialized;
- int64_t milliseconds;
- HashTable* properties;
- PHONGO_ZEND_OBJECT_POST
+ bool initialized;
+ int64_t milliseconds;
+ HashTable* properties;
+ zend_object std;
} php_phongo_utcdatetime_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
- mongoc_client_t* client;
- char* command_name;
- uint32_t server_id;
- uint64_t operation_id;
- uint64_t request_id;
- uint64_t duration_micros;
- bson_t* reply;
- PHONGO_STRUCT_ZVAL z_error;
- PHONGO_ZEND_OBJECT_POST
+ mongoc_client_t* client;
+ char* command_name;
+ uint32_t server_id;
+ uint64_t operation_id;
+ uint64_t request_id;
+ uint64_t duration_micros;
+ bson_t* reply;
+ zval z_error;
+ zend_object std;
} php_phongo_commandfailedevent_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_client_t* client;
char* command_name;
uint32_t server_id;
uint64_t operation_id;
uint64_t request_id;
bson_t* command;
char* database_name;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_commandstartedevent_t;
typedef struct {
- PHONGO_ZEND_OBJECT_PRE
mongoc_client_t* client;
char* command_name;
uint32_t server_id;
uint64_t operation_id;
uint64_t request_id;
uint64_t duration_micros;
bson_t* reply;
- PHONGO_ZEND_OBJECT_POST
+ zend_object std;
} php_phongo_commandsucceededevent_t;
-#undef PHONGO_ZEND_OBJECT_PRE
-#undef PHONGO_ZEND_OBJECT_POST
-#undef PHONGO_STRUCT_ZVAL
-
#endif /* PHONGO_STRUCTS */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/scripts/autotools/CheckCompiler.m4 b/mongodb-1.8.1/scripts/autotools/CheckCompiler.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/CheckCompiler.m4
rename to mongodb-1.8.1/scripts/autotools/CheckCompiler.m4
diff --git a/mongodb-1.7.4/scripts/autotools/CheckHost.m4 b/mongodb-1.8.1/scripts/autotools/CheckHost.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/CheckHost.m4
rename to mongodb-1.8.1/scripts/autotools/CheckHost.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libbson/CheckAtomics.m4 b/mongodb-1.8.1/scripts/autotools/libbson/CheckAtomics.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libbson/CheckAtomics.m4
rename to mongodb-1.8.1/scripts/autotools/libbson/CheckAtomics.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libbson/CheckHeaders.m4 b/mongodb-1.8.1/scripts/autotools/libbson/CheckHeaders.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libbson/CheckHeaders.m4
rename to mongodb-1.8.1/scripts/autotools/libbson/CheckHeaders.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libbson/Endian.m4 b/mongodb-1.8.1/scripts/autotools/libbson/Endian.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libbson/Endian.m4
rename to mongodb-1.8.1/scripts/autotools/libbson/Endian.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libbson/FindDependencies.m4 b/mongodb-1.8.1/scripts/autotools/libbson/FindDependencies.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libbson/FindDependencies.m4
rename to mongodb-1.8.1/scripts/autotools/libbson/FindDependencies.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libbson/Versions.m4 b/mongodb-1.8.1/scripts/autotools/libbson/Versions.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libbson/Versions.m4
rename to mongodb-1.8.1/scripts/autotools/libbson/Versions.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/CheckCompression.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/CheckCompression.m4
similarity index 69%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/CheckCompression.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/CheckCompression.m4
index d07ce423..395ccd66 100644
--- a/mongodb-1.7.4/scripts/autotools/libmongoc/CheckCompression.m4
+++ b/mongodb-1.8.1/scripts/autotools/libmongoc/CheckCompression.m4
@@ -1,68 +1,93 @@
found_snappy="no"
found_zlib="no"
bundled_zlib="no"
+found_zstd="no"
PKG_CHECK_MODULES([PHP_MONGODB_SNAPPY],[snappy],[
PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS $PHP_MONGODB_SNAPPY_CFLAGS"
PHP_EVAL_LIBLINE([$PHP_MONGODB_SNAPPY_LIBS],[MONGODB_SHARED_LIBADD])
found_snappy="yes"
],[
PHP_CHECK_LIBRARY([snappy],
[snappy_uncompress],
[have_snappy_lib="yes"],
[have_snappy_lib="no"])
AC_CHECK_HEADER([snappy-c.h],
[have_snappy_headers=yes],
[have_snappy_headers=no])
if test "$have_snappy_lib" = "yes" -a "$have_snappy_headers" = "yes"; then
PHP_ADD_LIBRARY([snappy],,[MONGODB_SHARED_LIBADD])
found_snappy="yes"
fi
])
PKG_CHECK_MODULES([PHP_MONGODB_ZLIB],[zlib],[
PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS $PHP_MONGODB_ZLIB_CFLAGS"
PHP_EVAL_LIBLINE([$PHP_MONGODB_ZLIB_LIBS],[MONGODB_SHARED_LIBADD])
found_zlib="yes"
],[
PHP_CHECK_LIBRARY([zlib],
[compress2],
[have_zlib_lib="yes"],
[have_zlib_lib="no"])
AC_CHECK_HEADER([zlib.h],
[have_zlib_headers=yes],
[have_zlib_headers=no])
if test "$have_zlib_lib" = "yes" -a "$have_zlib_headers" = "yes"; then
PHP_ADD_LIBRARY([z],,[MONGODB_SHARED_LIBADD])
found_zlib="yes"
fi
])
dnl If zlib was not found, use libmongoc's bundled version
AS_IF([test "$found_zlib" != "yes"],[
bundled_zlib="yes"
])
-if test "$found_snappy" = "yes" -o "$found_zlib" = "yes" -o "$bundled_zlib" = "yes"; then
+PKG_CHECK_MODULES([PHP_MONGODB_ZSTD],[libzstd],[
+ PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS $PHP_MONGODB_ZSTD_CFLAGS"
+ PHP_EVAL_LIBLINE([$PHP_MONGODB_ZSTD_LIBS],[MONGODB_SHARED_LIBADD])
+ found_zstd="yes"
+],[
+ PHP_CHECK_LIBRARY([zstd],
+ [ZSTD_compress],
+ [have_zstd_lib="yes"],
+ [have_zstd_lib="no"])
+
+ AC_CHECK_HEADER([zstd.h],
+ [have_zstd_headers=yes],
+ [have_zstd_headers=no])
+
+ if test "$have_zstd_lib" = "yes" -a "$have_zstd_headers" = "yes"; then
+ PHP_ADD_LIBRARY([zstd],,[MONGODB_SHARED_LIBADD])
+ found_zstd="yes"
+ fi
+])
+
+if test "$found_snappy" = "yes" -o "$found_zlib" = "yes" -o "$bundled_zlib" = "yes" -o "$found_zstd" = "yes"; then
AC_SUBST(MONGOC_ENABLE_COMPRESSION, 1)
if test "$found_snappy" = "yes"; then
AC_SUBST(MONGOC_ENABLE_COMPRESSION_SNAPPY, 1)
else
AC_SUBST(MONGOC_ENABLE_COMPRESSION_SNAPPY, 0)
fi
if test "$found_zlib" = "yes" -o "$bundled_zlib" = "yes"; then
AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZLIB, 1)
else
AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZLIB, 0)
fi
+ if test "$found_zstd" = "yes"; then
+ AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZSTD, 1)
+ else
+ AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZSTD, 0)
+ fi
else
AC_SUBST(MONGOC_ENABLE_COMPRESSION, 0)
- AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZLIB, 0)
AC_SUBST(MONGOC_ENABLE_COMPRESSION_SNAPPY, 0)
+ AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZLIB, 0)
+ AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZSTD, 0)
fi
-
-AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZSTD, 0)
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/CheckICU.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/CheckICU.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/CheckICU.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/CheckICU.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/CheckResolv.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/CheckResolv.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/CheckResolv.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/CheckResolv.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/CheckSSL.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/CheckSSL.m4
similarity index 95%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/CheckSSL.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/CheckSSL.m4
index a62abcba..320b9214 100644
--- a/mongodb-1.7.4/scripts/autotools/libmongoc/CheckSSL.m4
+++ b/mongodb-1.8.1/scripts/autotools/libmongoc/CheckSSL.m4
@@ -1,243 +1,249 @@
PHP_ARG_WITH([mongodb-ssl],
[whether to enable crypto and TLS],
[AS_HELP_STRING([--with-mongodb-ssl=@<:@auto/no/openssl/libressl/darwin@:>@],
[MongoDB: Enable TLS connections and SCRAM-SHA-1 authentication [default=auto]])],
[auto],
[no])
PHP_ARG_WITH([openssl-dir],
[deprecated option for OpenSSL library path],
[AS_HELP_STRING([--with-openssl-dir=@<:@auto/DIR@:>@],
[MongoDB: OpenSSL library path (deprecated for pkg-config) [default=auto]])],
[auto],
[no])
dnl PHP_ARG_WITH without a value assigns "yes". Treat it like "auto" but required.
AS_IF([test "$PHP_MONGODB_SSL" = "yes"],[
crypto_required="yes"
PHP_MONGODB_SSL="auto"
])
AS_IF([test "$PHP_MONGODB_SSL" = "darwin" -o \( "$PHP_MONGODB_SSL" = "auto" -a "$os_darwin" = "yes" \)],[
AC_MSG_NOTICE([checking whether Darwin SSL is available])
if test "$os_darwin" = "no"; then
AC_MSG_ERROR([Darwin SSL is only supported on macOS])
fi
dnl PHP_FRAMEWORKS is only used for SAPI builds, so use MONGODB_SHARED_LIBADD for shared builds
if test "$ext_shared" = "yes"; then
MONGODB_SHARED_LIBADD="-framework Security -framework CoreFoundation $MONGODB_SHARED_LIBADD"
else
PHP_ADD_FRAMEWORK([Security])
PHP_ADD_FRAMEWORK([CoreFoundation])
fi
PHP_MONGODB_SSL="darwin"
])
AS_IF([test "$PHP_MONGODB_SSL" = "openssl" -o "$PHP_MONGODB_SSL" = "auto"],[
AC_MSG_NOTICE([checking whether OpenSSL is available])
found_openssl="no"
PKG_CHECK_MODULES([PHP_MONGODB_SSL],[openssl],[
PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS $PHP_MONGODB_SSL_CFLAGS"
PHP_EVAL_LIBLINE([$PHP_MONGODB_SSL_LIBS],[MONGODB_SHARED_LIBADD])
PHP_MONGODB_SSL="openssl"
found_openssl="yes"
old_CFLAGS="$CFLAGS"
CFLAGS="$PHP_MONGODB_SSL_CFLAGS $CFLAGS"
AC_CHECK_DECLS([ASN1_STRING_get0_data],
[have_ASN1_STRING_get0_data="yes"],
[have_ASN1_STRING_get0_data="no"],
[[#include <openssl/asn1.h>]])
CFLAGS="$old_CFLAGS"
],[
unset OPENSSL_INCDIR
unset OPENSSL_LIBDIR
dnl Use a list of directories from PHP_SETUP_OPENSSL by default.
dnl Support documented "auto" and older, undocumented "yes" options
if test "$PHP_OPENSSL_DIR" = "auto" -o "$PHP_OPENSSL_DIR" = "yes"; then
PHP_OPENSSL_DIR="/usr/local/ssl /usr/local /usr /usr/local/openssl"
fi
for i in $PHP_OPENSSL_DIR; do
if test -r $i/include/openssl/evp.h; then
OPENSSL_INCDIR="$i/include"
fi
if test -r $i/$PHP_LIBDIR/libssl.a -o -r $i/$PHP_LIBDIR/libssl.$SHLIB_SUFFIX_NAME; then
OPENSSL_LIBDIR="$i/$PHP_LIBDIR"
fi
test -n "$OPENSSL_INCDIR" && test -n "$OPENSSL_LIBDIR" && break
done
if test -n "$OPENSSL_LIBDIR"; then
OPENSSL_LIBDIR_LDFLAG="-L$OPENSSL_LIBDIR"
fi
PHP_CHECK_LIBRARY([crypto],
[EVP_DigestInit_ex],
[have_crypto_lib="yes"],
[have_crypto_lib="no"],
[$OPENSSL_LIBDIR_LDFLAG])
AC_MSG_NOTICE([checking whether OpenSSL >= 1.1.0 is available])
PHP_CHECK_LIBRARY([ssl],
[OPENSSL_init_ssl],
[have_ssl_lib="yes"],
[have_ssl_lib="no"],
[$OPENSSL_LIBDIR_LDFLAG -lcrypto])
if test "$have_ssl_lib" = "no"; then
AC_MSG_NOTICE([checking whether OpenSSL < 1.1.0 is available])
PHP_CHECK_LIBRARY([ssl],
[SSL_library_init],
[have_ssl_lib="yes"],
[have_ssl_lib="no"],
[$OPENSSL_LIBDIR_LDFLAG -lcrypto])
fi
if test "$have_ssl_lib" = "yes" -a "$have_crypto_lib" = "yes"; then
PHP_ADD_LIBRARY([ssl],,[MONGODB_SHARED_LIBADD])
PHP_ADD_LIBRARY([crypto],,[MONGODB_SHARED_LIBADD])
if test -n "$OPENSSL_LIBDIR"; then
PHP_ADD_LIBPATH([$OPENSSL_LIBDIR],[MONGODB_SHARED_LIBADD])
fi
if test -n "$OPENSSL_INCDIR"; then
PHP_ADD_INCLUDE($OPENSSL_INCDIR)
fi
old_CFLAGS="$CFLAGS"
CFLAGS="-I$OPENSSL_INCDIR $CFLAGS"
AC_CHECK_DECLS([ASN1_STRING_get0_data],
[have_ASN1_STRING_get0_data="yes"],
[have_ASN1_STRING_get0_data="no"],
[[#include <openssl/asn1.h>]])
CFLAGS="$old_CFLAGS"
PHP_MONGODB_SSL="openssl"
found_openssl="yes"
fi
])
if test "$PHP_MONGODB_SSL" = "openssl" -a "$found_openssl" != "yes"; then
AC_MSG_ERROR([OpenSSL libraries and development headers could not be found])
fi
])
AS_IF([test "$PHP_MONGODB_SSL" = "libressl" -o "$PHP_MONGODB_SSL" = "auto"],[
AC_MSG_NOTICE([checking whether LibreSSL is available])
found_libressl="no"
PKG_CHECK_MODULES([PHP_MONGODB_SSL],[libtls libcrypto],[
PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS $PHP_MONGODB_SSL_CFLAGS"
PHP_EVAL_LIBLINE([$PHP_MONGODB_SSL_LIBS],[MONGODB_SHARED_LIBADD])
PHP_MONGODB_SSL="libressl"
found_libressl="yes"
],[
PHP_CHECK_LIBRARY([crypto],
[EVP_DigestInit_ex],
[have_crypto_lib="yes"],
[have_crypto_lib="no"])
PHP_CHECK_LIBRARY([tls],
[tls_init],
[have_ssl_lib="yes"],
[have_ssl_lib="no"],
[-lcrypto])
if test "$have_ssl_lib" = "yes" -a "$have_crypto_lib" = "yes"; then
PHP_ADD_LIBRARY([tls],,[MONGODB_SHARED_LIBADD])
PHP_ADD_LIBRARY([crypto],,[MONGODB_SHARED_LIBADD])
PHP_MONGODB_SSL="libressl"
found_libressl="yes"
fi
])
if test "$PHP_MONGODB_SSL" = "libressl" -a "$found_libressl" != "yes"; then
AC_MSG_ERROR([LibreSSL libraries and development headers could not be found])
fi
])
AS_IF([test "$PHP_MONGODB_SSL" = "auto"],[
if test "x$crypto_required" = "xyes"; then
AC_MSG_ERROR([crypto and TLS libraries not found])
fi
PHP_MONGODB_SSL="no"
])
AC_MSG_CHECKING([which TLS library to use])
AC_MSG_RESULT([$PHP_MONGODB_SSL])
dnl Disable Windows SSL and crypto
AC_SUBST(MONGOC_ENABLE_SSL_SECURE_CHANNEL, 0)
AC_SUBST(MONGOC_ENABLE_CRYPTO_CNG, 0)
if test "$PHP_MONGODB_SSL" = "openssl" -o "$PHP_MONGODB_SSL" = "libressl" -o "$PHP_MONGODB_SSL" = "darwin"; then
AC_SUBST(MONGOC_ENABLE_SSL, 1)
AC_SUBST(MONGOC_ENABLE_CRYPTO, 1)
if test "$PHP_MONGODB_SSL" = "darwin"; then
AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 0)
AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 0)
AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 1)
AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 0)
AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 1)
+
+ PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS -DKMS_MESSAGE_ENABLE_CRYPTO=1 -DKMS_MESSAGE_ENABLE_CRYPTO_COMMON_CRYPTO=1"
elif test "$PHP_MONGODB_SSL" = "openssl"; then
AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 1)
AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 0)
AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 0)
AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 1)
AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 0)
+
+ PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS -DKMS_MESSAGE_ENABLE_CRYPTO=1 -DKMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO=1"
elif test "$PHP_MONGODB_SSL" = "libressl"; then
AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 0)
AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 1)
AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 0)
AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 1)
AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 0)
+
+ PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS -DKMS_MESSAGE_ENABLE_CRYPTO=1 -DKMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO=1"
fi
else
AC_SUBST(MONGOC_ENABLE_SSL, 0)
AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 0)
AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 0)
AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 0)
AC_SUBST(MONGOC_ENABLE_CRYPTO, 0)
AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 0)
AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 0)
fi
if test "x$have_ASN1_STRING_get0_data" = "xyes"; then
AC_SUBST(MONGOC_HAVE_ASN1_STRING_GET0_DATA, 1)
else
AC_SUBST(MONGOC_HAVE_ASN1_STRING_GET0_DATA, 0)
fi
PHP_ARG_ENABLE([mongodb-crypto-system-profile],
[whether to use system crypto profile],
[AS_HELP_STRING([--enable-mongodb-crypto-system-profile],
[MongoDB: Use system crypto profile (OpenSSL only) [default=no]])],
[no],
[no])
PHP_ARG_WITH([system-ciphers],
[deprecated option for whether to use system crypto profile],
AS_HELP_STRING([--enable-system-ciphers],
[MongoDB: whether to use system crypto profile (deprecated for --enable-mongodb-crypto-system-profile) [default=no]]),
[no],
[no])
dnl Also consider the deprecated --enable-system-ciphers option
if test "$PHP_MONGODB_CRYPTO_SYSTEM_PROFILE" = "yes" -o "$PHP_SYSTEM_CIPHERS" = "yes"; then
if test "$PHP_MONGODB_SSL" = "openssl"; then
AC_SUBST(MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE, 1)
else
AC_MSG_ERROR([System crypto profile is only available with OpenSSL])
fi
else
AC_SUBST(MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE, 0)
fi
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/CheckSasl.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/CheckSasl.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/CheckSasl.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/CheckSasl.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/FindDependencies.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/FindDependencies.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/FindDependencies.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/FindDependencies.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/PlatformFlags.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/PlatformFlags.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/PlatformFlags.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/PlatformFlags.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/Versions.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/Versions.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/Versions.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/Versions.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libmongoc/WeakSymbols.m4 b/mongodb-1.8.1/scripts/autotools/libmongoc/WeakSymbols.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libmongoc/WeakSymbols.m4
rename to mongodb-1.8.1/scripts/autotools/libmongoc/WeakSymbols.m4
diff --git a/mongodb-1.7.4/scripts/autotools/libmongocrypt/CheckSSL.m4 b/mongodb-1.8.1/scripts/autotools/libmongocrypt/CheckSSL.m4
similarity index 79%
rename from mongodb-1.7.4/scripts/autotools/libmongocrypt/CheckSSL.m4
rename to mongodb-1.8.1/scripts/autotools/libmongocrypt/CheckSSL.m4
index a7a4d5b7..704aedb6 100644
--- a/mongodb-1.7.4/scripts/autotools/libmongocrypt/CheckSSL.m4
+++ b/mongodb-1.8.1/scripts/autotools/libmongocrypt/CheckSSL.m4
@@ -1,31 +1,27 @@
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" != "no"; then
AC_MSG_CHECKING([which crypto library to use for libmongocrypt])
AC_MSG_RESULT([$PHP_MONGODB_SSL])
dnl Disable Windows crypto
AC_SUBST(MONGOCRYPT_ENABLE_CRYPTO_CNG, 0)
if test "$PHP_MONGODB_SSL" = "darwin"; then
PHP_MONGODB_CLIENT_SIDE_ENCRYPTION="yes"
AC_SUBST(MONGOCRYPT_ENABLE_CRYPTO, 1)
AC_SUBST(MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO, 0)
AC_SUBST(MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO, 1)
-
- PHP_MONGODB_LIBMONGOCRYPT_CFLAGS="$PHP_MONGODB_LIBMONGOCRYPT_CFLAGS -DKMS_MESSAGE_ENABLE_CRYPTO=1 -DKMS_MESSAGE_ENABLE_CRYPTO_COMMON_CRYPTO=1"
elif test "$PHP_MONGODB_SSL" = "openssl" -o "$PHP_MONGODB_SSL" = "libressl"; then
PHP_MONGODB_CLIENT_SIDE_ENCRYPTION="yes"
AC_SUBST(MONGOCRYPT_ENABLE_CRYPTO, 1)
AC_SUBST(MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO, 1)
AC_SUBST(MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO, 0)
-
- PHP_MONGODB_LIBMONGOCRYPT_CFLAGS="$PHP_MONGODB_LIBMONGOCRYPT_CFLAGS -DKMS_MESSAGE_ENABLE_CRYPTO=1 -DKMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO=1"
elif test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "auto"; then
PHP_MONGODB_CLIENT_SIDE_ENCRYPTION="no"
AC_MSG_RESULT(No SSL library found. Compiling without libmongocrypt. Please specify a library using the --with-mongodb-ssl option)
else
AC_MSG_ERROR(Need an SSL library to compile with libmongocrypt. Please specify it using the --with-mongodb-ssl option)
fi
fi
diff --git a/mongodb-1.7.4/scripts/autotools/libmongocrypt/Version.m4 b/mongodb-1.8.1/scripts/autotools/libmongocrypt/Version.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/libmongocrypt/Version.m4
rename to mongodb-1.8.1/scripts/autotools/libmongocrypt/Version.m4
diff --git a/mongodb-1.7.4/scripts/autotools/m4/as_var_copy.m4 b/mongodb-1.8.1/scripts/autotools/m4/as_var_copy.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/m4/as_var_copy.m4
rename to mongodb-1.8.1/scripts/autotools/m4/as_var_copy.m4
diff --git a/mongodb-1.7.4/scripts/autotools/m4/ax_check_compile_flag.m4 b/mongodb-1.8.1/scripts/autotools/m4/ax_check_compile_flag.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/m4/ax_check_compile_flag.m4
rename to mongodb-1.8.1/scripts/autotools/m4/ax_check_compile_flag.m4
diff --git a/mongodb-1.7.4/scripts/autotools/m4/ax_prototype.m4 b/mongodb-1.8.1/scripts/autotools/m4/ax_prototype.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/m4/ax_prototype.m4
rename to mongodb-1.8.1/scripts/autotools/m4/ax_prototype.m4
diff --git a/mongodb-1.7.4/scripts/autotools/m4/ax_pthread.m4 b/mongodb-1.8.1/scripts/autotools/m4/ax_pthread.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/m4/ax_pthread.m4
rename to mongodb-1.8.1/scripts/autotools/m4/ax_pthread.m4
diff --git a/mongodb-1.7.4/scripts/autotools/m4/php_mongodb.m4 b/mongodb-1.8.1/scripts/autotools/m4/php_mongodb.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/m4/php_mongodb.m4
rename to mongodb-1.8.1/scripts/autotools/m4/php_mongodb.m4
diff --git a/mongodb-1.7.4/scripts/autotools/m4/pkg.m4 b/mongodb-1.8.1/scripts/autotools/m4/pkg.m4
similarity index 100%
rename from mongodb-1.7.4/scripts/autotools/m4/pkg.m4
rename to mongodb-1.8.1/scripts/autotools/m4/pkg.m4
diff --git a/mongodb-1.7.4/scripts/centos/essentials.sh b/mongodb-1.8.1/scripts/centos/essentials.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/essentials.sh
rename to mongodb-1.8.1/scripts/centos/essentials.sh
diff --git a/mongodb-1.7.4/scripts/centos/ldap/Domain.ldif b/mongodb-1.8.1/scripts/centos/ldap/Domain.ldif
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/Domain.ldif
rename to mongodb-1.8.1/scripts/centos/ldap/Domain.ldif
diff --git a/mongodb-1.7.4/scripts/centos/ldap/Users.ldif b/mongodb-1.8.1/scripts/centos/ldap/Users.ldif
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/Users.ldif
rename to mongodb-1.8.1/scripts/centos/ldap/Users.ldif
diff --git a/mongodb-1.7.4/scripts/centos/ldap/basics.ldif b/mongodb-1.8.1/scripts/centos/ldap/basics.ldif
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/basics.ldif
rename to mongodb-1.8.1/scripts/centos/ldap/basics.ldif
diff --git a/mongodb-1.7.4/scripts/centos/ldap/install.sh b/mongodb-1.8.1/scripts/centos/ldap/install.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/install.sh
rename to mongodb-1.8.1/scripts/centos/ldap/install.sh
diff --git a/mongodb-1.7.4/scripts/centos/ldap/ldapconfig.py b/mongodb-1.8.1/scripts/centos/ldap/ldapconfig.py
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/ldapconfig.py
rename to mongodb-1.8.1/scripts/centos/ldap/ldapconfig.py
diff --git a/mongodb-1.7.4/scripts/centos/ldap/mongod.ldif b/mongodb-1.8.1/scripts/centos/ldap/mongod.ldif
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/mongod.ldif
rename to mongodb-1.8.1/scripts/centos/ldap/mongod.ldif
diff --git a/mongodb-1.7.4/scripts/centos/ldap/pw.ldif b/mongodb-1.8.1/scripts/centos/ldap/pw.ldif
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/pw.ldif
rename to mongodb-1.8.1/scripts/centos/ldap/pw.ldif
diff --git a/mongodb-1.7.4/scripts/centos/ldap/saslauthd.conf b/mongodb-1.8.1/scripts/centos/ldap/saslauthd.conf
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/saslauthd.conf
rename to mongodb-1.8.1/scripts/centos/ldap/saslauthd.conf
diff --git a/mongodb-1.7.4/scripts/centos/ldap/users b/mongodb-1.8.1/scripts/centos/ldap/users
similarity index 100%
rename from mongodb-1.7.4/scripts/centos/ldap/users
rename to mongodb-1.8.1/scripts/centos/ldap/users
diff --git a/mongodb-1.7.4/scripts/clang-format.sh b/mongodb-1.8.1/scripts/clang-format.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/clang-format.sh
rename to mongodb-1.8.1/scripts/clang-format.sh
diff --git a/mongodb-1.7.4/scripts/convert-bson-corpus-tests.php b/mongodb-1.8.1/scripts/convert-bson-corpus-tests.php
similarity index 100%
rename from mongodb-1.7.4/scripts/convert-bson-corpus-tests.php
rename to mongodb-1.8.1/scripts/convert-bson-corpus-tests.php
diff --git a/mongodb-1.7.4/scripts/freebsd/essentials.sh b/mongodb-1.8.1/scripts/freebsd/essentials.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/freebsd/essentials.sh
rename to mongodb-1.8.1/scripts/freebsd/essentials.sh
diff --git a/mongodb-1.7.4/scripts/freebsd/phongo.sh b/mongodb-1.8.1/scripts/freebsd/phongo.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/freebsd/phongo.sh
rename to mongodb-1.8.1/scripts/freebsd/phongo.sh
diff --git a/mongodb-1.7.4/scripts/list-servers.php b/mongodb-1.8.1/scripts/list-servers.php
similarity index 100%
rename from mongodb-1.7.4/scripts/list-servers.php
rename to mongodb-1.8.1/scripts/list-servers.php
diff --git a/mongodb-1.7.4/scripts/presets/replicaset-30.json b/mongodb-1.8.1/scripts/presets/replicaset-30.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/replicaset-30.json
rename to mongodb-1.8.1/scripts/presets/replicaset-30.json
diff --git a/mongodb-1.7.4/scripts/presets/replicaset-dns.json b/mongodb-1.8.1/scripts/presets/replicaset-dns.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/replicaset-dns.json
rename to mongodb-1.8.1/scripts/presets/replicaset-dns.json
diff --git a/mongodb-1.7.4/scripts/presets/replicaset.json b/mongodb-1.8.1/scripts/presets/replicaset.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/replicaset.json
rename to mongodb-1.8.1/scripts/presets/replicaset.json
diff --git a/mongodb-1.7.4/scripts/presets/standalone-30.json b/mongodb-1.8.1/scripts/presets/standalone-30.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/standalone-30.json
rename to mongodb-1.8.1/scripts/presets/standalone-30.json
diff --git a/mongodb-1.7.4/scripts/presets/standalone-auth.json b/mongodb-1.8.1/scripts/presets/standalone-auth.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/standalone-auth.json
rename to mongodb-1.8.1/scripts/presets/standalone-auth.json
diff --git a/mongodb-1.7.4/scripts/presets/standalone-plain.json b/mongodb-1.8.1/scripts/presets/standalone-plain.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/standalone-plain.json
rename to mongodb-1.8.1/scripts/presets/standalone-plain.json
diff --git a/mongodb-1.7.4/scripts/presets/standalone-ssl.json b/mongodb-1.8.1/scripts/presets/standalone-ssl.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/standalone-ssl.json
rename to mongodb-1.8.1/scripts/presets/standalone-ssl.json
diff --git a/mongodb-1.7.4/scripts/presets/standalone-x509.json b/mongodb-1.8.1/scripts/presets/standalone-x509.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/standalone-x509.json
rename to mongodb-1.8.1/scripts/presets/standalone-x509.json
diff --git a/mongodb-1.7.4/scripts/presets/standalone.json b/mongodb-1.8.1/scripts/presets/standalone.json
similarity index 100%
rename from mongodb-1.7.4/scripts/presets/standalone.json
rename to mongodb-1.8.1/scripts/presets/standalone.json
diff --git a/mongodb-1.7.4/scripts/run-tests-on.sh b/mongodb-1.8.1/scripts/run-tests-on.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/run-tests-on.sh
rename to mongodb-1.8.1/scripts/run-tests-on.sh
diff --git a/mongodb-1.7.4/scripts/ssl/ca.pem b/mongodb-1.8.1/scripts/ssl/ca.pem
similarity index 100%
rename from mongodb-1.7.4/scripts/ssl/ca.pem
rename to mongodb-1.8.1/scripts/ssl/ca.pem
diff --git a/mongodb-1.7.4/scripts/ssl/client.pem b/mongodb-1.8.1/scripts/ssl/client.pem
similarity index 100%
rename from mongodb-1.7.4/scripts/ssl/client.pem
rename to mongodb-1.8.1/scripts/ssl/client.pem
diff --git a/mongodb-1.7.4/scripts/ssl/crl.pem b/mongodb-1.8.1/scripts/ssl/crl.pem
similarity index 100%
rename from mongodb-1.7.4/scripts/ssl/crl.pem
rename to mongodb-1.8.1/scripts/ssl/crl.pem
diff --git a/mongodb-1.7.4/scripts/ssl/server.pem b/mongodb-1.8.1/scripts/ssl/server.pem
similarity index 100%
rename from mongodb-1.7.4/scripts/ssl/server.pem
rename to mongodb-1.8.1/scripts/ssl/server.pem
diff --git a/mongodb-1.7.4/scripts/start-servers.php b/mongodb-1.8.1/scripts/start-servers.php
similarity index 100%
rename from mongodb-1.7.4/scripts/start-servers.php
rename to mongodb-1.8.1/scripts/start-servers.php
diff --git a/mongodb-1.7.4/scripts/ubuntu/essentials.sh b/mongodb-1.8.1/scripts/ubuntu/essentials.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/ubuntu/essentials.sh
rename to mongodb-1.8.1/scripts/ubuntu/essentials.sh
diff --git a/mongodb-1.7.4/scripts/ubuntu/ldap/install.sh b/mongodb-1.8.1/scripts/ubuntu/ldap/install.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/ubuntu/ldap/install.sh
rename to mongodb-1.8.1/scripts/ubuntu/ldap/install.sh
diff --git a/mongodb-1.7.4/scripts/ubuntu/ldap/saslauthd.conf b/mongodb-1.8.1/scripts/ubuntu/ldap/saslauthd.conf
similarity index 100%
rename from mongodb-1.7.4/scripts/ubuntu/ldap/saslauthd.conf
rename to mongodb-1.8.1/scripts/ubuntu/ldap/saslauthd.conf
diff --git a/mongodb-1.7.4/scripts/ubuntu/mongo-orchestration.sh b/mongodb-1.8.1/scripts/ubuntu/mongo-orchestration.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/ubuntu/mongo-orchestration.sh
rename to mongodb-1.8.1/scripts/ubuntu/mongo-orchestration.sh
diff --git a/mongodb-1.7.4/scripts/ubuntu/phongo.sh b/mongodb-1.8.1/scripts/ubuntu/phongo.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/ubuntu/phongo.sh
rename to mongodb-1.8.1/scripts/ubuntu/phongo.sh
diff --git a/mongodb-1.7.4/scripts/vmware/kernel.sh b/mongodb-1.8.1/scripts/vmware/kernel.sh
similarity index 100%
rename from mongodb-1.7.4/scripts/vmware/kernel.sh
rename to mongodb-1.8.1/scripts/vmware/kernel.sh
diff --git a/mongodb-1.7.4/src/BSON/Binary.c b/mongodb-1.8.1/src/BSON/Binary.c
similarity index 60%
rename from mongodb-1.7.4/src/BSON/Binary.c
rename to mongodb-1.8.1/src/BSON/Binary.c
index 4d5089a5..44bf926f 100644
--- a/mongodb-1.7.4/src/BSON/Binary.c
+++ b/mongodb-1.8.1/src/BSON/Binary.c
@@ -1,518 +1,429 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <ext/standard/base64.h>
#include <Zend/zend_interfaces.h>
#include <Zend/zend_operators.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#define PHONGO_BINARY_UUID_SIZE 16
zend_class_entry* php_phongo_binary_ce;
/* Initialize the object and return whether it was successful. An exception will
* be thrown on error. */
-static bool php_phongo_binary_init(php_phongo_binary_t* intern, const char* data, phongo_zpp_char_len data_len, phongo_long type TSRMLS_DC) /* {{{ */
+static bool php_phongo_binary_init(php_phongo_binary_t* intern, const char* data, size_t data_len, zend_long type) /* {{{ */
{
if (type < 0 || type > UINT8_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected type to be an unsigned 8-bit integer, %" PHONGO_LONG_FORMAT " given", type);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected type to be an unsigned 8-bit integer, %" PHONGO_LONG_FORMAT " given", type);
return false;
}
if ((type == BSON_SUBTYPE_UUID_DEPRECATED || type == BSON_SUBTYPE_UUID) && data_len != PHONGO_BINARY_UUID_SIZE) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected UUID length to be %d bytes, %d given", PHONGO_BINARY_UUID_SIZE, data_len);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected UUID length to be %d bytes, %d given", PHONGO_BINARY_UUID_SIZE, data_len);
return false;
}
intern->data = estrndup(data, data_len);
intern->data_len = data_len;
intern->type = (uint8_t) type;
return true;
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_binary_init_from_hash(php_phongo_binary_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_binary_init_from_hash(php_phongo_binary_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval *data, *type;
if ((data = zend_hash_str_find(props, "data", sizeof("data") - 1)) && Z_TYPE_P(data) == IS_STRING &&
(type = zend_hash_str_find(props, "type", sizeof("type") - 1)) && Z_TYPE_P(type) == IS_LONG) {
- return php_phongo_binary_init(intern, Z_STRVAL_P(data), Z_STRLEN_P(data), Z_LVAL_P(type) TSRMLS_CC);
+ return php_phongo_binary_init(intern, Z_STRVAL_P(data), Z_STRLEN_P(data), Z_LVAL_P(type));
}
-#else
- zval **data, **type;
-
- if (zend_hash_find(props, "data", sizeof("data"), (void**) &data) == SUCCESS && Z_TYPE_PP(data) == IS_STRING &&
- zend_hash_find(props, "type", sizeof("type"), (void**) &type) == SUCCESS && Z_TYPE_PP(type) == IS_LONG) {
-
- return php_phongo_binary_init(intern, Z_STRVAL_PP(data), Z_STRLEN_PP(data), Z_LVAL_PP(type) TSRMLS_CC);
- }
-#endif
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"data\" string and \"type\" integer fields", ZSTR_VAL(php_phongo_binary_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"data\" string and \"type\" integer fields", ZSTR_VAL(php_phongo_binary_ce->name));
return false;
} /* }}} */
/* {{{ proto void MongoDB\BSON\Binary::__construct(string $data, int $type)
Construct a new BSON binary type */
static PHP_METHOD(Binary, __construct)
{
php_phongo_binary_t* intern;
zend_error_handling error_handling;
char* data;
- phongo_zpp_char_len data_len;
- phongo_long type;
+ size_t data_len;
+ zend_long type;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_BINARY_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &data, &data_len, &type) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl", &data, &data_len, &type) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- php_phongo_binary_init(intern, data, data_len, type TSRMLS_CC);
+ php_phongo_binary_init(intern, data, data_len, type);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Binary::__set_state(array $properties)
*/
static PHP_METHOD(Binary, __set_state)
{
php_phongo_binary_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_binary_ce);
intern = Z_BINARY_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_binary_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_binary_init_from_hash(intern, props);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Binary::__toString()
Return the Binary's data string. */
static PHP_METHOD(Binary, __toString)
{
php_phongo_binary_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_BINARY_OBJ_P(getThis());
- PHONGO_RETURN_STRINGL(intern->data, intern->data_len);
+ RETURN_STRINGL(intern->data, intern->data_len);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Binary::getData()
*/
static PHP_METHOD(Binary, getData)
{
php_phongo_binary_t* intern;
intern = Z_BINARY_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETURN_STRINGL(intern->data, intern->data_len);
+ RETURN_STRINGL(intern->data, intern->data_len);
} /* }}} */
/* {{{ proto integer MongoDB\BSON\Binary::getType()
*/
static PHP_METHOD(Binary, getType)
{
php_phongo_binary_t* intern;
intern = Z_BINARY_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(intern->type);
} /* }}} */
/* {{{ proto array MongoDB\BSON\Binary::jsonSerialize()
*/
static PHP_METHOD(Binary, jsonSerialize)
{
php_phongo_binary_t* intern;
char type[3];
int type_len;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_BINARY_OBJ_P(getThis());
array_init_size(return_value, 2);
-#if PHP_VERSION_ID >= 70000
{
zend_string* data = php_base64_encode((unsigned char*) intern->data, intern->data_len);
ADD_ASSOC_STRINGL(return_value, "$binary", ZSTR_VAL(data), ZSTR_LEN(data));
zend_string_free(data);
}
-#else
- {
- int data_len = 0;
- unsigned char* data = php_base64_encode((unsigned char*) intern->data, intern->data_len, &data_len);
- ADD_ASSOC_STRINGL(return_value, "$binary", (char*) data, data_len);
- efree(data);
- }
-#endif
type_len = snprintf(type, sizeof(type), "%02x", intern->type);
ADD_ASSOC_STRINGL(return_value, "$type", type, type_len);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Binary::serialize()
*/
static PHP_METHOD(Binary, serialize)
{
php_phongo_binary_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
intern = Z_BINARY_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 2);
ADD_ASSOC_STRINGL(&retval, "data", intern->data, intern->data_len);
ADD_ASSOC_LONG_EX(&retval, "type", intern->type);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 2);
- ADD_ASSOC_STRINGL(retval, "data", intern->data, intern->data_len);
- ADD_ASSOC_LONG_EX(retval, "type", intern->type);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Binary::unserialize(string $serialized)
*/
static PHP_METHOD(Binary, unserialize)
{
- php_phongo_binary_t* intern;
- zend_error_handling error_handling;
- char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
+ php_phongo_binary_t* intern;
+ zend_error_handling error_handling;
+ char* serialized;
+ size_t serialized_len;
+ zval props;
php_unserialize_data_t var_hash;
intern = Z_BINARY_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_binary_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_binary_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_binary_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_binary_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_binary_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\Binary function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Binary___construct, 0, 0, 2)
ZEND_ARG_INFO(0, data)
ZEND_ARG_INFO(0, type)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Binary___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Binary_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Binary_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_binary_me[] = {
/* clang-format off */
PHP_ME(Binary, __construct, ai_Binary___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Binary, __set_state, ai_Binary___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Binary, __toString, ai_Binary_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Binary, jsonSerialize, ai_Binary_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Binary, serialize, ai_Binary_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Binary, unserialize, ai_Binary_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Binary, getData, ai_Binary_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Binary, getType, ai_Binary_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\Binary object handlers */
static zend_object_handlers php_phongo_handler_binary;
-static void php_phongo_binary_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_binary_free_object(zend_object* object) /* {{{ */
{
php_phongo_binary_t* intern = Z_OBJ_BINARY(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->data) {
efree(intern->data);
}
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_binary_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_binary_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_binary_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_binary_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_binary;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_binary_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_binary;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_binary_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_binary_clone_object(zval* object) /* {{{ */
{
- php_phongo_binary_t* intern;
- php_phongo_binary_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_binary_t* intern;
+ php_phongo_binary_t* new_intern;
+ zend_object* new_object;
intern = Z_BINARY_OBJ_P(object);
- new_object = php_phongo_binary_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_binary_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_BINARY(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
+ zend_objects_clone_members(&new_intern->std, &intern->std);
- new_intern = (php_phongo_binary_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
-
- php_phongo_binary_init(new_intern, intern->data, intern->data_len, intern->type TSRMLS_CC);
+ php_phongo_binary_init(new_intern, intern->data, intern->data_len, intern->type);
return new_object;
} /* }}} */
-static int php_phongo_binary_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_binary_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_binary_t *intern1, *intern2;
intern1 = Z_BINARY_OBJ_P(o1);
intern2 = Z_BINARY_OBJ_P(o2);
/* MongoDB compares binary types first by the data length, then by the type
* byte, and finally by the binary data itself. */
if (intern1->data_len != intern2->data_len) {
return intern1->data_len < intern2->data_len ? -1 : 1;
}
if (intern1->type != intern2->type) {
return intern1->type < intern2->type ? -1 : 1;
}
return zend_binary_strcmp(intern1->data, intern1->data_len, intern2->data, intern2->data_len);
} /* }}} */
-static HashTable* php_phongo_binary_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_BINARY_OBJ_P(object)->properties;
-} /* }}} */
-
-static HashTable* php_phongo_binary_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_binary_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_binary_t* intern;
HashTable* props;
intern = Z_BINARY_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);
if (!intern->data) {
return props;
}
-#if PHP_VERSION_ID >= 70000
{
zval data, type;
ZVAL_STRINGL(&data, intern->data, intern->data_len);
zend_hash_str_update(props, "data", sizeof("data") - 1, &data);
ZVAL_LONG(&type, intern->type);
zend_hash_str_update(props, "type", sizeof("type") - 1, &type);
}
-#else
- {
- zval *data, *type;
-
- MAKE_STD_ZVAL(data);
- ZVAL_STRINGL(data, intern->data, intern->data_len, 1);
- zend_hash_update(props, "data", sizeof("data"), &data, sizeof(data), NULL);
-
- MAKE_STD_ZVAL(type);
- ZVAL_LONG(type, intern->type);
- zend_hash_update(props, "type", sizeof("type"), &type, sizeof(type), NULL);
- }
-#endif
return props;
} /* }}} */
-static HashTable* php_phongo_binary_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_binary_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_binary_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_binary_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_binary_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_binary_get_properties(zval* object) /* {{{ */
{
- return php_phongo_binary_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_binary_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_binary_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Binary", php_phongo_binary_me);
- php_phongo_binary_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_binary_ce = zend_register_internal_class(&ce);
php_phongo_binary_ce->create_object = php_phongo_binary_create_object;
PHONGO_CE_FINAL(php_phongo_binary_ce);
- zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_binary_interface_ce);
- zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_binary_ce, 1, php_phongo_binary_interface_ce);
+ zend_class_implements(php_phongo_binary_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_binary_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_binary_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_binary, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_binary.clone_obj = php_phongo_binary_clone_object;
php_phongo_handler_binary.compare_objects = php_phongo_binary_compare_objects;
php_phongo_handler_binary.get_debug_info = php_phongo_binary_get_debug_info;
- php_phongo_handler_binary.get_gc = php_phongo_binary_get_gc;
php_phongo_handler_binary.get_properties = php_phongo_binary_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_binary.free_obj = php_phongo_binary_free_object;
- php_phongo_handler_binary.offset = XtOffsetOf(php_phongo_binary_t, std);
-#endif
-
- zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_GENERIC"), BSON_SUBTYPE_BINARY TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_FUNCTION"), BSON_SUBTYPE_FUNCTION TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_OLD_BINARY"), BSON_SUBTYPE_BINARY_DEPRECATED TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_OLD_UUID"), BSON_SUBTYPE_UUID_DEPRECATED TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_UUID"), BSON_SUBTYPE_UUID TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_MD5"), BSON_SUBTYPE_MD5 TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_ENCRYPTED"), BSON_SUBTYPE_ENCRYPTED TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_USER_DEFINED"), BSON_SUBTYPE_USER TSRMLS_CC);
+ php_phongo_handler_binary.free_obj = php_phongo_binary_free_object;
+ php_phongo_handler_binary.offset = XtOffsetOf(php_phongo_binary_t, std);
+
+ zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_GENERIC"), BSON_SUBTYPE_BINARY);
+ zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_FUNCTION"), BSON_SUBTYPE_FUNCTION);
+ zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_OLD_BINARY"), BSON_SUBTYPE_BINARY_DEPRECATED);
+ zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_OLD_UUID"), BSON_SUBTYPE_UUID_DEPRECATED);
+ zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_UUID"), BSON_SUBTYPE_UUID);
+ zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_MD5"), BSON_SUBTYPE_MD5);
+ zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_ENCRYPTED"), BSON_SUBTYPE_ENCRYPTED);
+ zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_USER_DEFINED"), BSON_SUBTYPE_USER);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/BinaryInterface.c b/mongodb-1.8.1/src/BSON/BinaryInterface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/BinaryInterface.c
rename to mongodb-1.8.1/src/BSON/BinaryInterface.c
index 155daf88..30639bbc 100644
--- a/mongodb-1.7.4/src/BSON/BinaryInterface.c
+++ b/mongodb-1.8.1/src/BSON/BinaryInterface.c
@@ -1,57 +1,57 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_binary_interface_ce;
/* {{{ MongoDB\BSON\BinaryInterface function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_BinaryInterface_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_binary_interface_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(BinaryInterface, getData, ai_BinaryInterface_void)
ZEND_ABSTRACT_ME(BinaryInterface, getType, ai_BinaryInterface_void)
ZEND_ABSTRACT_ME(BinaryInterface, __toString, ai_BinaryInterface_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_binary_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "BinaryInterface", php_phongo_binary_interface_me);
- php_phongo_binary_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_binary_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/DBPointer.c b/mongodb-1.8.1/src/BSON/DBPointer.c
similarity index 58%
rename from mongodb-1.7.4/src/BSON/DBPointer.c
rename to mongodb-1.8.1/src/BSON/DBPointer.c
index 6a575799..6c506f95 100644
--- a/mongodb-1.7.4/src/BSON/DBPointer.c
+++ b/mongodb-1.8.1/src/BSON/DBPointer.c
@@ -1,423 +1,331 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_dbpointer_ce;
/* Initialize the object and return whether it was successful. An exception will
* be thrown on error. */
-static bool php_phongo_dbpointer_init(php_phongo_dbpointer_t* intern, const char* ref, phongo_zpp_char_len ref_len, const char* id, phongo_zpp_char_len id_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_dbpointer_init(php_phongo_dbpointer_t* intern, const char* ref, size_t ref_len, const char* id, size_t id_len) /* {{{ */
{
if (strlen(ref) != (size_t) ref_len) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Ref cannot contain null bytes");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Ref cannot contain null bytes");
return false;
}
if (!bson_oid_is_valid(id, id_len)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing ObjectId string: %s", id);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error parsing ObjectId string: %s", id);
return false;
}
intern->ref = estrndup(ref, ref_len);
intern->ref_len = ref_len;
strncpy(intern->id, id, sizeof(intern->id));
return true;
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_dbpointer_init_from_hash(php_phongo_dbpointer_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_dbpointer_init_from_hash(php_phongo_dbpointer_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval *ref, *id;
if ((ref = zend_hash_str_find(props, "ref", sizeof("ref") - 1)) && Z_TYPE_P(ref) == IS_STRING &&
(id = zend_hash_str_find(props, "id", sizeof("id") - 1)) && Z_TYPE_P(id) == IS_STRING) {
- return php_phongo_dbpointer_init(intern, Z_STRVAL_P(ref), Z_STRLEN_P(ref), Z_STRVAL_P(id), Z_STRLEN_P(id) TSRMLS_CC);
- }
-#else
- zval **ref, **id;
-
- if (zend_hash_find(props, "ref", sizeof("ref"), (void**) &ref) == SUCCESS && Z_TYPE_PP(ref) == IS_STRING &&
- zend_hash_find(props, "id", sizeof("id"), (void**) &id) == SUCCESS && Z_TYPE_PP(id) == IS_STRING) {
-
- return php_phongo_dbpointer_init(intern, Z_STRVAL_PP(ref), Z_STRLEN_PP(ref), Z_STRVAL_PP(id), Z_STRLEN_PP(id) TSRMLS_CC);
+ return php_phongo_dbpointer_init(intern, Z_STRVAL_P(ref), Z_STRLEN_P(ref), Z_STRVAL_P(id), Z_STRLEN_P(id));
}
-#endif
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"ref\" and \"id\" string fields", ZSTR_VAL(php_phongo_dbpointer_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"ref\" and \"id\" string fields", ZSTR_VAL(php_phongo_dbpointer_ce->name));
return false;
} /* }}} */
/* {{{ proto string MongoDB\BSON\DBPointer::__toString()
Return the DBPointer's namespace string and ObjectId. */
static PHP_METHOD(DBPointer, __toString)
{
php_phongo_dbpointer_t* intern;
char* retval;
int retval_len;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_DBPOINTER_OBJ_P(getThis());
retval_len = spprintf(&retval, 0, "[%s/%s]", intern->ref, intern->id);
- PHONGO_RETVAL_STRINGL(retval, retval_len);
+ RETVAL_STRINGL(retval, retval_len);
efree(retval);
} /* }}} */
/* {{{ proto array MongoDB\BSON\Symbol::jsonSerialize()
*/
static PHP_METHOD(DBPointer, jsonSerialize)
{
php_phongo_dbpointer_t* intern;
- ZVAL_RETVAL_TYPE zdb_pointer;
- ZVAL_RETVAL_TYPE zoid;
+ zval zdb_pointer;
+ zval zoid;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_DBPOINTER_OBJ_P(getThis());
-#if PHP_VERSION_ID >= 70000
array_init_size(&zdb_pointer, 2);
array_init_size(&zoid, 1);
ADD_ASSOC_STRINGL(&zdb_pointer, "$ref", intern->ref, intern->ref_len);
ADD_ASSOC_STRING(&zoid, "$oid", intern->id);
ADD_ASSOC_ZVAL(&zdb_pointer, "$id", &zoid);
array_init_size(return_value, 1);
ADD_ASSOC_ZVAL(return_value, "$dbPointer", &zdb_pointer);
-#else
- ALLOC_INIT_ZVAL(zdb_pointer);
- ALLOC_INIT_ZVAL(zoid);
- array_init_size(zdb_pointer, 2);
- array_init_size(zoid, 1);
- ADD_ASSOC_STRINGL(zdb_pointer, "$ref", intern->ref, intern->ref_len);
- ADD_ASSOC_STRING(zoid, "$oid", intern->id);
- ADD_ASSOC_ZVAL(zdb_pointer, "$id", zoid);
-
- array_init_size(return_value, 1);
- ADD_ASSOC_ZVAL(return_value, "$dbPointer", zdb_pointer);
-#endif
} /* }}} */
/* {{{ proto string MongoDB\BSON\DBPointer::serialize()
*/
static PHP_METHOD(DBPointer, serialize)
{
php_phongo_dbpointer_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
intern = Z_DBPOINTER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 2);
ADD_ASSOC_STRINGL(&retval, "ref", intern->ref, intern->ref_len);
ADD_ASSOC_STRING(&retval, "id", intern->id);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 2);
- ADD_ASSOC_STRINGL(retval, "ref", intern->ref, intern->ref_len);
- ADD_ASSOC_STRING(retval, "id", intern->id);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\DBPointer::unserialize(string $serialized)
*/
static PHP_METHOD(DBPointer, unserialize)
{
php_phongo_dbpointer_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
- php_unserialize_data_t var_hash;
+ size_t serialized_len;
+ zval props;
+ php_unserialize_data_t var_hash;
intern = Z_DBPOINTER_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_dbpointer_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_dbpointer_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_dbpointer_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_dbpointer_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_dbpointer_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\DBPointer function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_DBPointer_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_DBPointer_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_dbpointer_me[] = {
/* clang-format off */
/* __set_state intentionally missing */
PHP_ME(DBPointer, __toString, ai_DBPointer_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(DBPointer, jsonSerialize, ai_DBPointer_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(DBPointer, serialize, ai_DBPointer_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(DBPointer, unserialize, ai_DBPointer_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_DBPointer_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\DBPointer object handlers */
static zend_object_handlers php_phongo_handler_dbpointer;
-static void php_phongo_dbpointer_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_dbpointer_free_object(zend_object* object) /* {{{ */
{
php_phongo_dbpointer_t* intern = Z_OBJ_DBPOINTER(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->ref) {
efree(intern->ref);
}
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-phongo_create_object_retval php_phongo_dbpointer_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+zend_object* php_phongo_dbpointer_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_dbpointer_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_dbpointer_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_dbpointer;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_dbpointer_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_dbpointer;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_dbpointer_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_dbpointer_clone_object(zval* object) /* {{{ */
{
- php_phongo_dbpointer_t* intern;
- php_phongo_dbpointer_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_dbpointer_t* intern;
+ php_phongo_dbpointer_t* new_intern;
+ zend_object* new_object;
intern = Z_DBPOINTER_OBJ_P(object);
- new_object = php_phongo_dbpointer_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_dbpointer_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_DBPOINTER(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
-
- new_intern = (php_phongo_dbpointer_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
+ zend_objects_clone_members(&new_intern->std, &intern->std);
- php_phongo_dbpointer_init(new_intern, intern->ref, intern->ref_len, intern->id, 24 TSRMLS_CC);
+ php_phongo_dbpointer_init(new_intern, intern->ref, intern->ref_len, intern->id, 24);
return new_object;
} /* }}} */
-static int php_phongo_dbpointer_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_dbpointer_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_dbpointer_t *intern1, *intern2;
int retval;
intern1 = Z_DBPOINTER_OBJ_P(o1);
intern2 = Z_DBPOINTER_OBJ_P(o2);
retval = strcmp(intern1->ref, intern2->ref);
if (retval != 0) {
return retval;
}
return strcmp(intern1->id, intern2->id);
} /* }}} */
-static HashTable* php_phongo_dbpointer_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_DBPOINTER_OBJ_P(object)->properties;
-} /* }}} */
-
-HashTable* php_phongo_dbpointer_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+HashTable* php_phongo_dbpointer_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_dbpointer_t* intern;
HashTable* props;
intern = Z_DBPOINTER_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);
if (!intern->ref) {
return props;
}
-#if PHP_VERSION_ID >= 70000
{
zval ref, id;
ZVAL_STRING(&ref, intern->ref);
ZVAL_STRING(&id, intern->id);
zend_hash_str_update(props, "ref", sizeof("ref") - 1, &ref);
zend_hash_str_update(props, "id", sizeof("id") - 1, &id);
}
-#else
- {
- zval *ref, *id;
-
- MAKE_STD_ZVAL(ref);
- ZVAL_STRING(ref, intern->ref, 1);
- MAKE_STD_ZVAL(id);
- ZVAL_STRING(id, intern->id, 1);
- zend_hash_update(props, "ref", sizeof("ref"), &ref, sizeof(ref), NULL);
- zend_hash_update(props, "id", sizeof("id"), &id, sizeof(id), NULL);
- }
-#endif
return props;
} /* }}} */
-static HashTable* php_phongo_dbpointer_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_dbpointer_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_dbpointer_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_dbpointer_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_dbpointer_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_dbpointer_get_properties(zval* object) /* {{{ */
{
- return php_phongo_dbpointer_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_dbpointer_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_dbpointer_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "DBPointer", php_phongo_dbpointer_me);
- php_phongo_dbpointer_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_dbpointer_ce = zend_register_internal_class(&ce);
php_phongo_dbpointer_ce->create_object = php_phongo_dbpointer_create_object;
PHONGO_CE_FINAL(php_phongo_dbpointer_ce);
- zend_class_implements(php_phongo_dbpointer_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_dbpointer_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_dbpointer_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_dbpointer_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_dbpointer_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_dbpointer_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_dbpointer, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_dbpointer.clone_obj = php_phongo_dbpointer_clone_object;
php_phongo_handler_dbpointer.compare_objects = php_phongo_dbpointer_compare_objects;
php_phongo_handler_dbpointer.get_debug_info = php_phongo_dbpointer_get_debug_info;
- php_phongo_handler_dbpointer.get_gc = php_phongo_dbpointer_get_gc;
php_phongo_handler_dbpointer.get_properties = php_phongo_dbpointer_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_dbpointer.free_obj = php_phongo_dbpointer_free_object;
- php_phongo_handler_dbpointer.offset = XtOffsetOf(php_phongo_dbpointer_t, std);
-#endif
+ php_phongo_handler_dbpointer.free_obj = php_phongo_dbpointer_free_object;
+ php_phongo_handler_dbpointer.offset = XtOffsetOf(php_phongo_dbpointer_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Decimal128.c b/mongodb-1.8.1/src/BSON/Decimal128.c
similarity index 61%
rename from mongodb-1.7.4/src/BSON/Decimal128.c
rename to mongodb-1.8.1/src/BSON/Decimal128.c
index 851cbabc..86bdffe8 100644
--- a/mongodb-1.7.4/src/BSON/Decimal128.c
+++ b/mongodb-1.8.1/src/BSON/Decimal128.c
@@ -1,419 +1,346 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_decimal128_ce;
/* Initialize the object and return whether it was successful. An exception will
* be thrown on error. */
-static bool php_phongo_decimal128_init(php_phongo_decimal128_t* intern, const char* value TSRMLS_DC) /* {{{ */
+static bool php_phongo_decimal128_init(php_phongo_decimal128_t* intern, const char* value) /* {{{ */
{
if (!bson_decimal128_from_string(value, &intern->decimal)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing Decimal128 string: %s", value);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error parsing Decimal128 string: %s", value);
return false;
}
intern->initialized = true;
return true;
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_decimal128_init_from_hash(php_phongo_decimal128_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_decimal128_init_from_hash(php_phongo_decimal128_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval* dec;
if ((dec = zend_hash_str_find(props, "dec", sizeof("dec") - 1)) && Z_TYPE_P(dec) == IS_STRING) {
- return php_phongo_decimal128_init(intern, Z_STRVAL_P(dec) TSRMLS_CC);
- }
-#else
- zval** dec;
-
- if (zend_hash_find(props, "dec", sizeof("dec"), (void**) &dec) == SUCCESS && Z_TYPE_PP(dec) == IS_STRING) {
- return php_phongo_decimal128_init(intern, Z_STRVAL_PP(dec) TSRMLS_CC);
+ return php_phongo_decimal128_init(intern, Z_STRVAL_P(dec));
}
-#endif
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"dec\" string field", ZSTR_VAL(php_phongo_decimal128_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"dec\" string field", ZSTR_VAL(php_phongo_decimal128_ce->name));
return false;
} /* }}} */
/* {{{ proto void MongoDB\BSON\Decimal128::__construct(string $value)
Construct a new BSON Decimal128 type */
static PHP_METHOD(Decimal128, __construct)
{
php_phongo_decimal128_t* intern;
zend_error_handling error_handling;
char* value;
- phongo_zpp_char_len value_len;
+ size_t value_len;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_DECIMAL128_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &value, &value_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- php_phongo_decimal128_init(intern, value TSRMLS_CC);
+ php_phongo_decimal128_init(intern, value);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Decimal128::__set_state(array $properties)
*/
static PHP_METHOD(Decimal128, __set_state)
{
php_phongo_decimal128_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_decimal128_ce);
intern = Z_DECIMAL128_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_decimal128_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_decimal128_init_from_hash(intern, props);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Decimal128::__toString()
*/
static PHP_METHOD(Decimal128, __toString)
{
php_phongo_decimal128_t* intern;
char outbuf[BSON_DECIMAL128_STRING];
intern = Z_DECIMAL128_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
bson_decimal128_to_string(&intern->decimal, outbuf);
- PHONGO_RETURN_STRING(outbuf);
+ RETURN_STRING(outbuf);
} /* }}} */
/* {{{ proto array MongoDB\BSON\Decimal128::jsonSerialize()
*/
static PHP_METHOD(Decimal128, jsonSerialize)
{
php_phongo_decimal128_t* intern;
char outbuf[BSON_DECIMAL128_STRING] = "";
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_DECIMAL128_OBJ_P(getThis());
array_init_size(return_value, 1);
bson_decimal128_to_string(&intern->decimal, outbuf);
ADD_ASSOC_STRING(return_value, "$numberDecimal", outbuf);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Decimal128::serialize()
*/
static PHP_METHOD(Decimal128, serialize)
{
php_phongo_decimal128_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
char outbuf[BSON_DECIMAL128_STRING];
intern = Z_DECIMAL128_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
bson_decimal128_to_string(&intern->decimal, outbuf);
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 1);
ADD_ASSOC_STRING(&retval, "dec", outbuf);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 1);
- ADD_ASSOC_STRING(retval, "dec", outbuf);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Decimal128::unserialize(string $serialized)
*/
static PHP_METHOD(Decimal128, unserialize)
{
php_phongo_decimal128_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
- php_unserialize_data_t var_hash;
+ size_t serialized_len;
+ zval props;
+ php_unserialize_data_t var_hash;
intern = Z_DECIMAL128_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_decimal128_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_decimal128_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_decimal128_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_decimal128_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_decimal128_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\Decimal128 function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128___construct, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_decimal128_me[] = {
/* clang-format off */
PHP_ME(Decimal128, __construct, ai_Decimal128___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Decimal128, __set_state, ai_Decimal128___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Decimal128, __toString, ai_Decimal128_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Decimal128, jsonSerialize, ai_Decimal128_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Decimal128, serialize, ai_Decimal128_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Decimal128, unserialize, ai_Decimal128_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\Decimal128 object handlers */
static zend_object_handlers php_phongo_handler_decimal128;
-static void php_phongo_decimal128_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_decimal128_free_object(zend_object* object) /* {{{ */
{
php_phongo_decimal128_t* intern = Z_OBJ_DECIMAL128(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_decimal128_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_decimal128_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_decimal128_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_decimal128_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_decimal128;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_decimal128_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_decimal128;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_decimal128_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_decimal128_clone_object(zval* object) /* {{{ */
{
- php_phongo_decimal128_t* intern;
- php_phongo_decimal128_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_decimal128_t* intern;
+ php_phongo_decimal128_t* new_intern;
+ zend_object* new_object;
intern = Z_DECIMAL128_OBJ_P(object);
- new_object = php_phongo_decimal128_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_decimal128_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_DECIMAL128(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
-
- new_intern = (php_phongo_decimal128_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
+ zend_objects_clone_members(&new_intern->std, &intern->std);
// Use memcpy to copy bson value to avoid converting to string and back
memcpy(&new_intern->decimal, &intern->decimal, sizeof(bson_decimal128_t));
new_intern->initialized = true;
return new_object;
} /* }}} */
-static HashTable* php_phongo_decimal128_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_DECIMAL128_OBJ_P(object)->properties;
-} /* }}} */
-
-static HashTable* php_phongo_decimal128_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_decimal128_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_decimal128_t* intern;
HashTable* props;
char outbuf[BSON_DECIMAL128_STRING] = "";
intern = Z_DECIMAL128_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 1);
if (!intern->initialized) {
return props;
}
bson_decimal128_to_string(&intern->decimal, outbuf);
-#if PHP_VERSION_ID >= 70000
{
zval dec;
ZVAL_STRING(&dec, outbuf);
zend_hash_str_update(props, "dec", sizeof("dec") - 1, &dec);
}
-#else
- {
- zval* dec;
-
- MAKE_STD_ZVAL(dec);
- ZVAL_STRING(dec, outbuf, 1);
- zend_hash_update(props, "dec", sizeof("dec"), &dec, sizeof(dec), NULL);
- }
-#endif
return props;
} /* }}} */
-static HashTable* php_phongo_decimal128_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_decimal128_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_decimal128_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_decimal128_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_decimal128_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_decimal128_get_properties(zval* object) /* {{{ */
{
- return php_phongo_decimal128_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_decimal128_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_decimal128_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Decimal128", php_phongo_decimal128_me);
- php_phongo_decimal128_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_decimal128_ce = zend_register_internal_class(&ce);
php_phongo_decimal128_ce->create_object = php_phongo_decimal128_create_object;
PHONGO_CE_FINAL(php_phongo_decimal128_ce);
- zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_phongo_decimal128_interface_ce);
- zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_decimal128_ce, 1, php_phongo_decimal128_interface_ce);
+ zend_class_implements(php_phongo_decimal128_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_decimal128_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_decimal128_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_decimal128, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_decimal128.clone_obj = php_phongo_decimal128_clone_object;
php_phongo_handler_decimal128.get_debug_info = php_phongo_decimal128_get_debug_info;
- php_phongo_handler_decimal128.get_gc = php_phongo_decimal128_get_gc;
php_phongo_handler_decimal128.get_properties = php_phongo_decimal128_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_decimal128.free_obj = php_phongo_decimal128_free_object;
- php_phongo_handler_decimal128.offset = XtOffsetOf(php_phongo_decimal128_t, std);
-#endif
+ php_phongo_handler_decimal128.free_obj = php_phongo_decimal128_free_object;
+ php_phongo_handler_decimal128.offset = XtOffsetOf(php_phongo_decimal128_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Decimal128Interface.c b/mongodb-1.8.1/src/BSON/Decimal128Interface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/Decimal128Interface.c
rename to mongodb-1.8.1/src/BSON/Decimal128Interface.c
index f43b4e27..bcc0763c 100644
--- a/mongodb-1.7.4/src/BSON/Decimal128Interface.c
+++ b/mongodb-1.8.1/src/BSON/Decimal128Interface.c
@@ -1,55 +1,55 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_decimal128_interface_ce;
/* {{{ MongoDB\BSON\Decimal128Interface function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128Interface_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_decimal128_interface_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(Decimal128Interface, __toString, ai_Decimal128Interface_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_decimal128_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Decimal128Interface", php_phongo_decimal128_interface_me);
- php_phongo_decimal128_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_decimal128_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Int64.c b/mongodb-1.8.1/src/BSON/Int64.c
similarity index 59%
rename from mongodb-1.7.4/src/BSON/Int64.c
rename to mongodb-1.8.1/src/BSON/Int64.c
index bd229c7c..80904795 100644
--- a/mongodb-1.7.4/src/BSON/Int64.c
+++ b/mongodb-1.8.1/src/BSON/Int64.c
@@ -1,382 +1,309 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_int64_ce;
/* Initialize the object and return whether it was successful. */
static bool php_phongo_int64_init(php_phongo_int64_t* intern, int64_t integer) /* {{{ */
{
intern->integer = integer;
intern->initialized = true;
return true;
} /* }}} */
/* Initialize the object from a numeric string and return whether it was
* successful. An exception will be thrown on error. */
-static bool php_phongo_int64_init_from_string(php_phongo_int64_t* intern, const char* s_integer, phongo_zpp_char_len s_integer_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_int64_init_from_string(php_phongo_int64_t* intern, const char* s_integer, size_t s_integer_len) /* {{{ */
{
int64_t integer;
if (!php_phongo_parse_int64(&integer, s_integer, s_integer_len)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit integer for %s initialization", s_integer, ZSTR_VAL(php_phongo_int64_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error parsing \"%s\" as 64-bit integer for %s initialization", s_integer, ZSTR_VAL(php_phongo_int64_ce->name));
return false;
}
return php_phongo_int64_init(intern, integer);
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_int64_init_from_hash(php_phongo_int64_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_int64_init_from_hash(php_phongo_int64_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval* value;
if ((value = zend_hash_str_find(props, "integer", sizeof("integer") - 1)) && Z_TYPE_P(value) == IS_STRING) {
- return php_phongo_int64_init_from_string(intern, Z_STRVAL_P(value), Z_STRLEN_P(value) TSRMLS_CC);
- }
-#else
- zval** value;
-
- if (zend_hash_find(props, "integer", sizeof("integer"), (void**) &value) == SUCCESS && Z_TYPE_PP(value) == IS_STRING) {
- return php_phongo_int64_init_from_string(intern, Z_STRVAL_PP(value), Z_STRLEN_PP(value) TSRMLS_CC);
+ return php_phongo_int64_init_from_string(intern, Z_STRVAL_P(value), Z_STRLEN_P(value));
}
-#endif
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"integer\" string field", ZSTR_VAL(php_phongo_int64_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"integer\" string field", ZSTR_VAL(php_phongo_int64_ce->name));
return false;
} /* }}} */
/* {{{ proto string MongoDB\BSON\Int64::__toString()
Return the Int64's value as a string. */
static PHP_METHOD(Int64, __toString)
{
php_phongo_int64_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_INT64_OBJ_P(getThis());
ZVAL_INT64_STRING(return_value, intern->integer);
} /* }}} */
/* {{{ proto array MongoDB\BSON\Int64::jsonSerialize()
*/
static PHP_METHOD(Int64, jsonSerialize)
{
php_phongo_int64_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_INT64_OBJ_P(getThis());
array_init_size(return_value, 1);
ADD_ASSOC_INT64_AS_STRING(return_value, "$numberLong", intern->integer);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Int64::serialize()
*/
static PHP_METHOD(Int64, serialize)
{
php_phongo_int64_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_INT64_OBJ_P(getThis());
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 1);
ADD_ASSOC_INT64_AS_STRING(&retval, "integer", intern->integer);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 1);
- ADD_ASSOC_INT64_AS_STRING(retval, "integer", intern->integer);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Int64::unserialize(string $serialized)
*/
static PHP_METHOD(Int64, unserialize)
{
- php_phongo_int64_t* intern;
- zend_error_handling error_handling;
- char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
+ php_phongo_int64_t* intern;
+ zend_error_handling error_handling;
+ char* serialized;
+ size_t serialized_len;
+ zval props;
php_unserialize_data_t var_hash;
intern = Z_INT64_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_int64_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_int64_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_int64_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_int64_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_int64_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\Int64 function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Int64_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Int64_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_int64_me[] = {
/* clang-format off */
/* __set_state intentionally missing */
PHP_ME(Int64, __toString, ai_Int64_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Int64, jsonSerialize, ai_Int64_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Int64, serialize, ai_Int64_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Int64, unserialize, ai_Int64_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Int64_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\Int64 object handlers */
static zend_object_handlers php_phongo_handler_int64;
-static void php_phongo_int64_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_int64_free_object(zend_object* object) /* {{{ */
{
php_phongo_int64_t* intern = Z_OBJ_INT64(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-phongo_create_object_retval php_phongo_int64_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+zend_object* php_phongo_int64_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_int64_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_int64_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_int64;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_int64_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_int64;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_int64_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_int64_clone_object(zval* object) /* {{{ */
{
- php_phongo_int64_t* intern;
- php_phongo_int64_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_int64_t* intern;
+ php_phongo_int64_t* new_intern;
+ zend_object* new_object;
intern = Z_INT64_OBJ_P(object);
- new_object = php_phongo_int64_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_int64_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_INT64(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
-
- new_intern = (php_phongo_int64_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
+ zend_objects_clone_members(&new_intern->std, &intern->std);
php_phongo_int64_init(new_intern, intern->integer);
return new_object;
} /* }}} */
-static int php_phongo_int64_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_int64_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_int64_t *intern1, *intern2;
intern1 = Z_INT64_OBJ_P(o1);
intern2 = Z_INT64_OBJ_P(o2);
if (intern1->integer != intern2->integer) {
return intern1->integer < intern2->integer ? -1 : 1;
}
return 0;
} /* }}} */
-static HashTable* php_phongo_int64_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_INT64_OBJ_P(object)->properties;
-} /* }}} */
-
-HashTable* php_phongo_int64_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+HashTable* php_phongo_int64_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_int64_t* intern;
HashTable* props;
intern = Z_INT64_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);
if (!intern->initialized) {
return props;
}
-#if PHP_VERSION_ID >= 70000
{
zval value;
ZVAL_INT64_STRING(&value, intern->integer);
zend_hash_str_update(props, "integer", sizeof("integer") - 1, &value);
}
-#else
- {
- zval* value;
-
- MAKE_STD_ZVAL(value);
- ZVAL_INT64_STRING(value, intern->integer);
- zend_hash_update(props, "integer", sizeof("integer"), &value, sizeof(value), NULL);
- }
-#endif
return props;
} /* }}} */
-static HashTable* php_phongo_int64_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_int64_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_int64_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_int64_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_int64_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_int64_get_properties(zval* object) /* {{{ */
{
- return php_phongo_int64_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_int64_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_int64_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Int64", php_phongo_int64_me);
- php_phongo_int64_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_int64_ce = zend_register_internal_class(&ce);
php_phongo_int64_ce->create_object = php_phongo_int64_create_object;
PHONGO_CE_FINAL(php_phongo_int64_ce);
- zend_class_implements(php_phongo_int64_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_int64_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_int64_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_int64_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_int64_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_int64_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_int64, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_int64.clone_obj = php_phongo_int64_clone_object;
php_phongo_handler_int64.compare_objects = php_phongo_int64_compare_objects;
php_phongo_handler_int64.get_debug_info = php_phongo_int64_get_debug_info;
- php_phongo_handler_int64.get_gc = php_phongo_int64_get_gc;
php_phongo_handler_int64.get_properties = php_phongo_int64_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_int64.free_obj = php_phongo_int64_free_object;
- php_phongo_handler_int64.offset = XtOffsetOf(php_phongo_int64_t, std);
-#endif
+ php_phongo_handler_int64.free_obj = php_phongo_int64_free_object;
+ php_phongo_handler_int64.offset = XtOffsetOf(php_phongo_int64_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Javascript.c b/mongodb-1.8.1/src/BSON/Javascript.c
similarity index 63%
rename from mongodb-1.7.4/src/BSON/Javascript.c
rename to mongodb-1.8.1/src/BSON/Javascript.c
index c3abdcbf..fa182228 100644
--- a/mongodb-1.7.4/src/BSON/Javascript.c
+++ b/mongodb-1.8.1/src/BSON/Javascript.c
@@ -1,583 +1,469 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_javascript_ce;
/* Initialize the object and return whether it was successful. An exception will
* be thrown on error. */
-static bool php_phongo_javascript_init(php_phongo_javascript_t* intern, const char* code, phongo_zpp_char_len code_len, zval* scope TSRMLS_DC) /* {{{ */
+static bool php_phongo_javascript_init(php_phongo_javascript_t* intern, const char* code, size_t code_len, zval* scope) /* {{{ */
{
if (scope && Z_TYPE_P(scope) != IS_OBJECT && Z_TYPE_P(scope) != IS_ARRAY && Z_TYPE_P(scope) != IS_NULL) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected scope to be array or object, %s given", zend_get_type_by_const(Z_TYPE_P(scope)));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected scope to be array or object, %s given", zend_get_type_by_const(Z_TYPE_P(scope)));
return false;
}
if (strlen(code) != (size_t) code_len) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Code cannot contain null bytes");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Code cannot contain null bytes");
return false;
}
intern->code = estrndup(code, code_len);
intern->code_len = code_len;
if (scope && (Z_TYPE_P(scope) == IS_OBJECT || Z_TYPE_P(scope) == IS_ARRAY)) {
intern->scope = bson_new();
- php_phongo_zval_to_bson(scope, PHONGO_BSON_NONE, intern->scope, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(scope, PHONGO_BSON_NONE, intern->scope, NULL);
} else {
intern->scope = NULL;
}
return true;
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_javascript_init_from_hash(php_phongo_javascript_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_javascript_init_from_hash(php_phongo_javascript_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval *code, *scope;
if ((code = zend_hash_str_find(props, "code", sizeof("code") - 1)) && Z_TYPE_P(code) == IS_STRING) {
scope = zend_hash_str_find(props, "scope", sizeof("scope") - 1);
- return php_phongo_javascript_init(intern, Z_STRVAL_P(code), Z_STRLEN_P(code), scope TSRMLS_CC);
+ return php_phongo_javascript_init(intern, Z_STRVAL_P(code), Z_STRLEN_P(code), scope);
}
-#else
- zval **code, **scope;
-
- if (zend_hash_find(props, "code", sizeof("code"), (void**) &code) == SUCCESS && Z_TYPE_PP(code) == IS_STRING) {
- zval* tmp = zend_hash_find(props, "scope", sizeof("scope"), (void**) &scope) == SUCCESS ? *scope : NULL;
- return php_phongo_javascript_init(intern, Z_STRVAL_PP(code), Z_STRLEN_PP(code), tmp TSRMLS_CC);
- }
-#endif
-
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"code\" string field", ZSTR_VAL(php_phongo_javascript_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"code\" string field", ZSTR_VAL(php_phongo_javascript_ce->name));
return false;
} /* }}} */
/* {{{ proto void MongoDB\BSON\Javascript::__construct(string $code[, array|object $scope])
Construct a new BSON Javascript type. The scope is a document mapping
identifiers and values, representing the scope in which the code string will
be evaluated. Note that this type cannot be represented as Extended JSON. */
static PHP_METHOD(Javascript, __construct)
{
php_phongo_javascript_t* intern;
zend_error_handling error_handling;
char* code;
- phongo_zpp_char_len code_len;
+ size_t code_len;
zval* scope = NULL;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_JAVASCRIPT_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|A!", &code, &code_len, &scope) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|A!", &code, &code_len, &scope) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- php_phongo_javascript_init(intern, code, code_len, scope TSRMLS_CC);
+ php_phongo_javascript_init(intern, code, code_len, scope);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Javascript::__set_state(array $properties)
*/
static PHP_METHOD(Javascript, __set_state)
{
php_phongo_javascript_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_javascript_ce);
intern = Z_JAVASCRIPT_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_javascript_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_javascript_init_from_hash(intern, props);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Javascript::__toString()
Return the Javascript's code string. */
static PHP_METHOD(Javascript, __toString)
{
php_phongo_javascript_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_JAVASCRIPT_OBJ_P(getThis());
- PHONGO_RETURN_STRINGL(intern->code, intern->code_len);
+ RETURN_STRINGL(intern->code, intern->code_len);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Javascript::getCode()
*/
static PHP_METHOD(Javascript, getCode)
{
php_phongo_javascript_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_JAVASCRIPT_OBJ_P(getThis());
- PHONGO_RETURN_STRINGL(intern->code, intern->code_len);
+ RETURN_STRINGL(intern->code, intern->code_len);
} /* }}} */
/* {{{ proto object|null MongoDB\BSON\Javascript::getScope()
*/
static PHP_METHOD(Javascript, getScope)
{
php_phongo_javascript_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_JAVASCRIPT_OBJ_P(getThis());
if (!intern->scope) {
RETURN_NULL();
}
if (intern->scope->len) {
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
} else {
RETURN_NULL();
}
} /* }}} */
/* {{{ proto array MongoDB\BSON\Javascript::jsonSerialize()
*/
static PHP_METHOD(Javascript, jsonSerialize)
{
php_phongo_javascript_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_JAVASCRIPT_OBJ_P(getThis());
array_init_size(return_value, 2);
ADD_ASSOC_STRINGL(return_value, "$code", intern->code, intern->code_len);
if (intern->scope && intern->scope->len) {
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(return_value, "$scope", &state.zchild);
-#else
- ADD_ASSOC_ZVAL_EX(return_value, "$scope", state.zchild);
-#endif
}
} /* }}} */
/* {{{ proto string MongoDB\BSON\Javascript::serialize()
*/
static PHP_METHOD(Javascript, serialize)
{
php_phongo_javascript_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_phongo_bson_state state;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
PHONGO_BSON_INIT_STATE(state);
intern = Z_JAVASCRIPT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
if (intern->scope && intern->scope->len) {
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
} else {
ZVAL_NULL(&state.zchild);
}
-#else
- if (intern->scope && intern->scope->len) {
- if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) {
- zval_ptr_dtor(&state.zchild);
- return;
- }
- } else {
- MAKE_STD_ZVAL(state.zchild);
- ZVAL_NULL(state.zchild);
- }
-#endif
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 2);
ADD_ASSOC_STRINGL(&retval, "code", intern->code, intern->code_len);
ADD_ASSOC_ZVAL(&retval, "scope", &state.zchild);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 2);
- ADD_ASSOC_STRINGL(retval, "code", intern->code, intern->code_len);
- ADD_ASSOC_ZVAL(retval, "scope", state.zchild);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Javascript::unserialize(string $serialized)
*/
static PHP_METHOD(Javascript, unserialize)
{
php_phongo_javascript_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
- php_unserialize_data_t var_hash;
+ size_t serialized_len;
+ zval props;
+ php_unserialize_data_t var_hash;
intern = Z_JAVASCRIPT_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_javascript_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_javascript_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_javascript_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_javascript_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_javascript_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\Javascript function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Javascript___construct, 0, 0, 1)
ZEND_ARG_INFO(0, javascript)
ZEND_ARG_INFO(0, scope)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Javascript___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Javascript_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Javascript_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_javascript_me[] = {
/* clang-format off */
PHP_ME(Javascript, __construct, ai_Javascript___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Javascript, __set_state, ai_Javascript___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Javascript, __toString, ai_Javascript_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Javascript, jsonSerialize, ai_Javascript_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Javascript, serialize, ai_Javascript_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Javascript, unserialize, ai_Javascript_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Javascript, getCode, ai_Javascript_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Javascript, getScope, ai_Javascript_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\Javascript object handlers */
static zend_object_handlers php_phongo_handler_javascript;
-static void php_phongo_javascript_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_javascript_free_object(zend_object* object) /* {{{ */
{
php_phongo_javascript_t* intern = Z_OBJ_JAVASCRIPT(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->code) {
efree(intern->code);
}
if (intern->scope) {
bson_destroy(intern->scope);
intern->scope = NULL;
}
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-phongo_create_object_retval php_phongo_javascript_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+zend_object* php_phongo_javascript_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_javascript_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_javascript_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_javascript;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_javascript_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_javascript;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_javascript_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_javascript_clone_object(zval* object) /* {{{ */
{
- php_phongo_javascript_t* intern;
- php_phongo_javascript_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_javascript_t* intern;
+ php_phongo_javascript_t* new_intern;
+ zend_object* new_object;
intern = Z_JAVASCRIPT_OBJ_P(object);
- new_object = php_phongo_javascript_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_javascript_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_JAVASCRIPT(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
-
- new_intern = (php_phongo_javascript_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
+ zend_objects_clone_members(&new_intern->std, &intern->std);
- php_phongo_javascript_init(new_intern, intern->code, intern->code_len, NULL TSRMLS_CC);
+ php_phongo_javascript_init(new_intern, intern->code, intern->code_len, NULL);
new_intern->scope = bson_copy(intern->scope);
return new_object;
} /* }}} */
-static int php_phongo_javascript_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_javascript_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_javascript_t *intern1, *intern2;
intern1 = Z_JAVASCRIPT_OBJ_P(o1);
intern2 = Z_JAVASCRIPT_OBJ_P(o2);
/* Do not consider the scope document for comparisons */
return strcmp(intern1->code, intern2->code);
} /* }}} */
-static HashTable* php_phongo_javascript_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_JAVASCRIPT_OBJ_P(object)->properties;
-} /* }}} */
-
-HashTable* php_phongo_javascript_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+HashTable* php_phongo_javascript_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_javascript_t* intern;
HashTable* props;
intern = Z_JAVASCRIPT_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);
if (!intern->code) {
return props;
}
-#if PHP_VERSION_ID >= 70000
{
zval code;
ZVAL_STRING(&code, intern->code);
zend_hash_str_update(props, "code", sizeof("code") - 1, &code);
if (intern->scope) {
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) {
zval_ptr_dtor(&state.zchild);
goto failure;
}
zend_hash_str_update(props, "scope", sizeof("scope") - 1, &state.zchild);
} else {
zval scope;
ZVAL_NULL(&scope);
zend_hash_str_update(props, "scope", sizeof("scope") - 1, &scope);
}
}
-#else
- {
- zval* code;
-
- MAKE_STD_ZVAL(code);
- ZVAL_STRING(code, intern->code, 1);
- zend_hash_update(props, "code", sizeof("code"), &code, sizeof(code), NULL);
-
- if (intern->scope) {
- php_phongo_bson_state state;
-
- PHONGO_BSON_INIT_STATE(state);
- if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) {
- zval_ptr_dtor(&state.zchild);
- goto failure;
- }
-
- zend_hash_update(props, "scope", sizeof("scope"), &state.zchild, sizeof(state.zchild), NULL);
- } else {
- zval* scope;
-
- MAKE_STD_ZVAL(scope);
- ZVAL_NULL(scope);
- zend_hash_update(props, "scope", sizeof("scope"), &scope, sizeof(scope), NULL);
- }
- }
-#endif
return props;
failure:
PHONGO_GET_PROPERTY_HASH_FREE_PROPS(is_debug, props);
return NULL;
} /* }}} */
-static HashTable* php_phongo_javascript_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_javascript_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_javascript_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_javascript_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_javascript_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_javascript_get_properties(zval* object) /* {{{ */
{
- return php_phongo_javascript_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_javascript_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_javascript_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Javascript", php_phongo_javascript_me);
- php_phongo_javascript_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_javascript_ce = zend_register_internal_class(&ce);
php_phongo_javascript_ce->create_object = php_phongo_javascript_create_object;
PHONGO_CE_FINAL(php_phongo_javascript_ce);
- zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_phongo_javascript_interface_ce);
- zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_javascript_ce, 1, php_phongo_javascript_interface_ce);
+ zend_class_implements(php_phongo_javascript_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_javascript_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_javascript_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_javascript, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_javascript.clone_obj = php_phongo_javascript_clone_object;
php_phongo_handler_javascript.compare_objects = php_phongo_javascript_compare_objects;
php_phongo_handler_javascript.get_debug_info = php_phongo_javascript_get_debug_info;
- php_phongo_handler_javascript.get_gc = php_phongo_javascript_get_gc;
php_phongo_handler_javascript.get_properties = php_phongo_javascript_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_javascript.free_obj = php_phongo_javascript_free_object;
- php_phongo_handler_javascript.offset = XtOffsetOf(php_phongo_javascript_t, std);
-#endif
+ php_phongo_handler_javascript.free_obj = php_phongo_javascript_free_object;
+ php_phongo_handler_javascript.offset = XtOffsetOf(php_phongo_javascript_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/JavascriptInterface.c b/mongodb-1.8.1/src/BSON/JavascriptInterface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/JavascriptInterface.c
rename to mongodb-1.8.1/src/BSON/JavascriptInterface.c
index 673d7d5d..a7fd3e85 100644
--- a/mongodb-1.7.4/src/BSON/JavascriptInterface.c
+++ b/mongodb-1.8.1/src/BSON/JavascriptInterface.c
@@ -1,57 +1,57 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_javascript_interface_ce;
/* {{{ MongoDB\BSON\JavascriptInterface function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_JavascriptInterface_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_javascript_interface_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(JavascriptInterface, getCode, ai_JavascriptInterface_void)
ZEND_ABSTRACT_ME(JavascriptInterface, getScope, ai_JavascriptInterface_void)
ZEND_ABSTRACT_ME(JavascriptInterface, __toString, ai_JavascriptInterface_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_javascript_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "JavascriptInterface", php_phongo_javascript_interface_me);
- php_phongo_javascript_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_javascript_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/MaxKey.c b/mongodb-1.8.1/src/BSON/MaxKey.c
similarity index 67%
rename from mongodb-1.7.4/src/BSON/MaxKey.c
rename to mongodb-1.8.1/src/BSON/MaxKey.c
index cb0ec2d6..0ffa4200 100644
--- a/mongodb-1.7.4/src/BSON/MaxKey.c
+++ b/mongodb-1.8.1/src/BSON/MaxKey.c
@@ -1,175 +1,155 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_maxkey_ce;
/* {{{ proto void MongoDB\BSON\MaxKey::__set_state(array $properties)
*/
static PHP_METHOD(MaxKey, __set_state)
{
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_maxkey_ce);
} /* }}} */
/* {{{ proto array MongoDB\BSON\MaxKey::jsonSerialize()
*/
static PHP_METHOD(MaxKey, jsonSerialize)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
array_init_size(return_value, 1);
ADD_ASSOC_LONG_EX(return_value, "$maxKey", 1);
} /* }}} */
/* {{{ proto string MongoDB\BSON\MaxKey::serialize()
*/
static PHP_METHOD(MaxKey, serialize)
{
- PHONGO_RETURN_STRING("");
+ RETURN_STRING("");
} /* }}} */
/* {{{ proto void MongoDB\BSON\MaxKey::unserialize(string $serialized)
*/
static PHP_METHOD(MaxKey, unserialize)
{
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
+ size_t serialized_len;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
} /* }}} */
/* {{{ MongoDB\BSON\MaxKey function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_MaxKey___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_MaxKey_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_MaxKey_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_maxkey_me[] = {
/* clang-format off */
PHP_ME(MaxKey, __set_state, ai_MaxKey___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(MaxKey, jsonSerialize, ai_MaxKey_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(MaxKey, serialize, ai_MaxKey_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(MaxKey, unserialize, ai_MaxKey_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\MaxKey object handlers */
static zend_object_handlers php_phongo_handler_maxkey;
-static void php_phongo_maxkey_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_maxkey_free_object(zend_object* object) /* {{{ */
{
php_phongo_maxkey_t* intern = Z_OBJ_MAXKEY(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
+ zend_object_std_dtor(&intern->std);
} /* }}} */
-static phongo_create_object_retval php_phongo_maxkey_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_maxkey_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_maxkey_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_maxkey_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_maxkey;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_maxkey_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_maxkey;
-
- return retval;
- }
-#endif
} /* }}} */
/* }}} */
void php_phongo_maxkey_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "MaxKey", php_phongo_maxkey_me);
- php_phongo_maxkey_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_maxkey_ce = zend_register_internal_class(&ce);
php_phongo_maxkey_ce->create_object = php_phongo_maxkey_create_object;
PHONGO_CE_FINAL(php_phongo_maxkey_ce);
- zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_phongo_maxkey_interface_ce);
- zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_maxkey_ce, 1, php_phongo_maxkey_interface_ce);
+ zend_class_implements(php_phongo_maxkey_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_maxkey_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_maxkey_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_maxkey, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
/* Re-assign default handler previously removed in php_phongo.c */
php_phongo_handler_maxkey.clone_obj = zend_objects_clone_obj;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_maxkey.free_obj = php_phongo_maxkey_free_object;
- php_phongo_handler_maxkey.offset = XtOffsetOf(php_phongo_maxkey_t, std);
-#endif
+ php_phongo_handler_maxkey.free_obj = php_phongo_maxkey_free_object;
+ php_phongo_handler_maxkey.offset = XtOffsetOf(php_phongo_maxkey_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/MaxKeyInterface.c b/mongodb-1.8.1/src/BSON/MaxKeyInterface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/MaxKeyInterface.c
rename to mongodb-1.8.1/src/BSON/MaxKeyInterface.c
index e1301aac..40c42d7f 100644
--- a/mongodb-1.7.4/src/BSON/MaxKeyInterface.c
+++ b/mongodb-1.8.1/src/BSON/MaxKeyInterface.c
@@ -1,49 +1,49 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_maxkey_interface_ce;
/* {{{ MongoDB\BSON\MaxKeyInterface function entries */
static zend_function_entry php_phongo_maxkey_interface_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_maxkey_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "MaxKeyInterface", php_phongo_maxkey_interface_me);
- php_phongo_maxkey_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_maxkey_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/MinKey.c b/mongodb-1.8.1/src/BSON/MinKey.c
similarity index 67%
rename from mongodb-1.7.4/src/BSON/MinKey.c
rename to mongodb-1.8.1/src/BSON/MinKey.c
index f60d5db1..87564591 100644
--- a/mongodb-1.7.4/src/BSON/MinKey.c
+++ b/mongodb-1.8.1/src/BSON/MinKey.c
@@ -1,176 +1,156 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_minkey_ce;
/* {{{ proto void MongoDB\BSON\MinKey::__set_state(array $properties)
*/
static PHP_METHOD(MinKey, __set_state)
{
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_minkey_ce);
} /* }}} */
/* {{{ proto array MongoDB\BSON\MinKey::jsonSerialize()
*/
static PHP_METHOD(MinKey, jsonSerialize)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
array_init_size(return_value, 1);
ADD_ASSOC_LONG_EX(return_value, "$minKey", 1);
} /* }}} */
/* {{{ proto string MongoDB\BSON\MinKey::serialize()
*/
static PHP_METHOD(MinKey, serialize)
{
- PHONGO_RETURN_STRING("");
+ RETURN_STRING("");
} /* }}} */
/* {{{ proto void MongoDB\BSON\MinKey::unserialize(string $serialized)
*/
static PHP_METHOD(MinKey, unserialize)
{
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
+ size_t serialized_len;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
} /* }}} */
/* {{{ MongoDB\BSON\MinKey function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_MinKey___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_MinKey_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_MinKey_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_minkey_me[] = {
/* clang-format off */
PHP_ME(MinKey, __set_state, ai_MinKey___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(MinKey, jsonSerialize, ai_MinKey_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(MinKey, serialize, ai_MinKey_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(MinKey, unserialize, ai_MinKey_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\MinKey object handlers */
static zend_object_handlers php_phongo_handler_minkey;
-static void php_phongo_minkey_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_minkey_free_object(zend_object* object) /* {{{ */
{
php_phongo_minkey_t* intern = Z_OBJ_MINKEY(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
+ zend_object_std_dtor(&intern->std);
} /* }}} */
-static phongo_create_object_retval php_phongo_minkey_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_minkey_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_minkey_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_minkey_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_minkey;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_minkey_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_minkey;
-
- return retval;
- }
-#endif
} /* }}} */
/* }}} */
void php_phongo_minkey_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "MinKey", php_phongo_minkey_me);
- php_phongo_minkey_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_minkey_ce = zend_register_internal_class(&ce);
php_phongo_minkey_ce->create_object = php_phongo_minkey_create_object;
PHONGO_CE_FINAL(php_phongo_minkey_ce);
- zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_phongo_minkey_interface_ce);
- zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_minkey_ce, 1, php_phongo_minkey_interface_ce);
+ zend_class_implements(php_phongo_minkey_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_minkey_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_minkey_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_minkey, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
/* Re-assign default handler previously removed in php_phongo.c */
php_phongo_handler_minkey.clone_obj = zend_objects_clone_obj;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_minkey.free_obj = php_phongo_minkey_free_object;
- php_phongo_handler_minkey.offset = XtOffsetOf(php_phongo_minkey_t, std);
-#endif
+ php_phongo_handler_minkey.free_obj = php_phongo_minkey_free_object;
+ php_phongo_handler_minkey.offset = XtOffsetOf(php_phongo_minkey_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/MinKeyInterface.c b/mongodb-1.8.1/src/BSON/MinKeyInterface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/MinKeyInterface.c
rename to mongodb-1.8.1/src/BSON/MinKeyInterface.c
index 3504bc48..8804115e 100644
--- a/mongodb-1.7.4/src/BSON/MinKeyInterface.c
+++ b/mongodb-1.8.1/src/BSON/MinKeyInterface.c
@@ -1,49 +1,49 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_minkey_interface_ce;
/* {{{ MongoDB\BSON\MinKeyInterface function entries */
static zend_function_entry php_phongo_minkey_interface_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_minkey_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "MinKeyInterface", php_phongo_minkey_interface_me);
- php_phongo_minkey_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_minkey_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/ObjectId.c b/mongodb-1.8.1/src/BSON/ObjectId.c
similarity index 64%
rename from mongodb-1.7.4/src/BSON/ObjectId.c
rename to mongodb-1.8.1/src/BSON/ObjectId.c
index 751cc5d6..da54982c 100644
--- a/mongodb-1.7.4/src/BSON/ObjectId.c
+++ b/mongodb-1.8.1/src/BSON/ObjectId.c
@@ -1,467 +1,394 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#define PHONGO_OID_SIZE sizeof(((php_phongo_objectid_t*) 0)->oid)
#define PHONGO_OID_LEN (PHONGO_OID_SIZE - 1)
zend_class_entry* php_phongo_objectid_ce;
/* Initialize the object with a generated value and return whether it was
* successful. */
static bool php_phongo_objectid_init(php_phongo_objectid_t* intern)
{
bson_oid_t oid;
intern->initialized = true;
bson_oid_init(&oid, NULL);
bson_oid_to_string(&oid, intern->oid);
return true;
}
/* Initialize the object from a hex string and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_objectid_init_from_hex_string(php_phongo_objectid_t* intern, const char* hex, phongo_zpp_char_len hex_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_objectid_init_from_hex_string(php_phongo_objectid_t* intern, const char* hex, size_t hex_len) /* {{{ */
{
if (bson_oid_is_valid(hex, hex_len)) {
bson_oid_t oid;
bson_oid_init_from_string(&oid, hex);
bson_oid_to_string(&oid, intern->oid);
intern->initialized = true;
return true;
}
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing ObjectId string: %s", hex);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error parsing ObjectId string: %s", hex);
return false;
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_objectid_init_from_hash(php_phongo_objectid_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_objectid_init_from_hash(php_phongo_objectid_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval* z_oid;
z_oid = zend_hash_str_find(props, "oid", sizeof("oid") - 1);
if (z_oid && Z_TYPE_P(z_oid) == IS_STRING) {
- return php_phongo_objectid_init_from_hex_string(intern, Z_STRVAL_P(z_oid), Z_STRLEN_P(z_oid) TSRMLS_CC);
- }
-#else
- zval** z_oid;
-
- if (zend_hash_find(props, "oid", sizeof("oid"), (void**) &z_oid) == SUCCESS && Z_TYPE_PP(z_oid) == IS_STRING) {
- return php_phongo_objectid_init_from_hex_string(intern, Z_STRVAL_PP(z_oid), Z_STRLEN_PP(z_oid) TSRMLS_CC);
+ return php_phongo_objectid_init_from_hex_string(intern, Z_STRVAL_P(z_oid), Z_STRLEN_P(z_oid));
}
-#endif
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"oid\" string field", ZSTR_VAL(php_phongo_objectid_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"oid\" string field", ZSTR_VAL(php_phongo_objectid_ce->name));
return false;
} /* }}} */
/* {{{ proto void MongoDB\BSON\ObjectId::__construct([string $id])
Constructs a new BSON ObjectId type, optionally from a hex string. */
static PHP_METHOD(ObjectId, __construct)
{
php_phongo_objectid_t* intern;
zend_error_handling error_handling;
char* id = NULL;
- phongo_zpp_char_len id_len;
+ size_t id_len;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_OBJECTID_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &id, &id_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!", &id, &id_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
if (id) {
- php_phongo_objectid_init_from_hex_string(intern, id, id_len TSRMLS_CC);
+ php_phongo_objectid_init_from_hex_string(intern, id, id_len);
} else {
php_phongo_objectid_init(intern);
}
} /* }}} */
/* {{{ proto integer MongoDB\BSON\ObjectId::getTimestamp()
*/
static PHP_METHOD(ObjectId, getTimestamp)
{
php_phongo_objectid_t* intern;
bson_oid_t tmp_oid;
intern = Z_OBJECTID_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
bson_oid_init_from_string(&tmp_oid, intern->oid);
RETVAL_LONG(bson_oid_get_time_t(&tmp_oid));
} /* }}} */
/* {{{ proto MongoDB\BSON\ObjectId::__set_state(array $properties)
*/
static PHP_METHOD(ObjectId, __set_state)
{
php_phongo_objectid_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_objectid_ce);
intern = Z_OBJECTID_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_objectid_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_objectid_init_from_hash(intern, props);
} /* }}} */
/* {{{ proto string MongoDB\BSON\ObjectId::__toString()
*/
static PHP_METHOD(ObjectId, __toString)
{
php_phongo_objectid_t* intern;
intern = Z_OBJECTID_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETURN_STRINGL(intern->oid, PHONGO_OID_LEN);
+ RETURN_STRINGL(intern->oid, PHONGO_OID_LEN);
} /* }}} */
/* {{{ proto array MongoDB\BSON\ObjectId::jsonSerialize()
*/
static PHP_METHOD(ObjectId, jsonSerialize)
{
php_phongo_objectid_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_OBJECTID_OBJ_P(getThis());
array_init_size(return_value, 1);
ADD_ASSOC_STRINGL(return_value, "$oid", intern->oid, PHONGO_OID_LEN);
} /* }}} */
/* {{{ proto string MongoDB\BSON\ObjectId::serialize()
*/
static PHP_METHOD(ObjectId, serialize)
{
php_phongo_objectid_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
intern = Z_OBJECTID_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 1);
ADD_ASSOC_STRINGL(&retval, "oid", intern->oid, PHONGO_OID_LEN);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 1);
- ADD_ASSOC_STRINGL(retval, "oid", intern->oid, PHONGO_OID_LEN);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\ObjectId::unserialize(string $serialized)
*/
static PHP_METHOD(ObjectId, unserialize)
{
php_phongo_objectid_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
+ size_t serialized_len;
+ zval props;
php_unserialize_data_t var_hash;
intern = Z_OBJECTID_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_objectid_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_objectid_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_objectid_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_objectid_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_objectid_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\ObjectId function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_ObjectId___construct, 0, 0, 0)
ZEND_ARG_INFO(0, id)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ObjectId___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ObjectId_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ObjectId_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_objectid_me[] = {
/* clang-format off */
PHP_ME(ObjectId, __construct, ai_ObjectId___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ObjectId, getTimestamp, ai_ObjectId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ObjectId, __set_state, ai_ObjectId___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(ObjectId, __toString, ai_ObjectId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ObjectId, jsonSerialize, ai_ObjectId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ObjectId, serialize, ai_ObjectId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ObjectId, unserialize, ai_ObjectId_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\ObjectId object handlers */
static zend_object_handlers php_phongo_handler_objectid;
-static void php_phongo_objectid_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_objectid_free_object(zend_object* object) /* {{{ */
{
php_phongo_objectid_t* intern = Z_OBJ_OBJECTID(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_objectid_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_objectid_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_objectid_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_objectid_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_objectid;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_objectid_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_objectid;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_objectid_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_objectid_clone_object(zval* object) /* {{{ */
{
- php_phongo_objectid_t* intern;
- php_phongo_objectid_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_objectid_t* intern;
+ php_phongo_objectid_t* new_intern;
+ zend_object* new_object;
intern = Z_OBJECTID_OBJ_P(object);
- new_object = php_phongo_objectid_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_objectid_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_OBJECTID(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
-
- new_intern = (php_phongo_objectid_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
+ zend_objects_clone_members(&new_intern->std, &intern->std);
// Use memcpy to copy bson value to avoid converting to string and back
memcpy(&new_intern->oid, &intern->oid, PHONGO_OID_SIZE);
new_intern->initialized = true;
return new_object;
} /* }}} */
-static int php_phongo_objectid_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_objectid_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_objectid_t* intern1;
php_phongo_objectid_t* intern2;
intern1 = Z_OBJECTID_OBJ_P(o1);
intern2 = Z_OBJECTID_OBJ_P(o2);
return strcmp(intern1->oid, intern2->oid);
} /* }}} */
-static HashTable* php_phongo_objectid_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_OBJECTID_OBJ_P(object)->properties;
-} /* }}} */
-
-static HashTable* php_phongo_objectid_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_objectid_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_objectid_t* intern;
HashTable* props;
intern = Z_OBJECTID_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 1);
if (!intern->initialized) {
return props;
}
-#if PHP_VERSION_ID >= 70000
{
zval zv;
ZVAL_STRING(&zv, intern->oid);
zend_hash_str_update(props, "oid", sizeof("oid") - 1, &zv);
}
-#else
- {
- zval* zv;
-
- MAKE_STD_ZVAL(zv);
- ZVAL_STRING(zv, intern->oid, 1);
- zend_hash_update(props, "oid", sizeof("oid"), &zv, sizeof(zv), NULL);
- }
-#endif
return props;
} /* }}} */
-static HashTable* php_phongo_objectid_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_objectid_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_objectid_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_objectid_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_objectid_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_objectid_get_properties(zval* object) /* {{{ */
{
- return php_phongo_objectid_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_objectid_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_objectid_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "ObjectId", php_phongo_objectid_me);
- php_phongo_objectid_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_objectid_ce = zend_register_internal_class(&ce);
php_phongo_objectid_ce->create_object = php_phongo_objectid_create_object;
PHONGO_CE_FINAL(php_phongo_objectid_ce);
- zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_phongo_objectid_interface_ce);
- zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_objectid_ce, 1, php_phongo_objectid_interface_ce);
+ zend_class_implements(php_phongo_objectid_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_objectid_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_objectid_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_objectid, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_objectid.clone_obj = php_phongo_objectid_clone_object;
php_phongo_handler_objectid.compare_objects = php_phongo_objectid_compare_objects;
php_phongo_handler_objectid.get_debug_info = php_phongo_objectid_get_debug_info;
- php_phongo_handler_objectid.get_gc = php_phongo_objectid_get_gc;
php_phongo_handler_objectid.get_properties = php_phongo_objectid_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_objectid.free_obj = php_phongo_objectid_free_object;
- php_phongo_handler_objectid.offset = XtOffsetOf(php_phongo_objectid_t, std);
-#endif
+ php_phongo_handler_objectid.free_obj = php_phongo_objectid_free_object;
+ php_phongo_handler_objectid.offset = XtOffsetOf(php_phongo_objectid_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/ObjectIdInterface.c b/mongodb-1.8.1/src/BSON/ObjectIdInterface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/ObjectIdInterface.c
rename to mongodb-1.8.1/src/BSON/ObjectIdInterface.c
index e4cbef0f..863072dd 100644
--- a/mongodb-1.7.4/src/BSON/ObjectIdInterface.c
+++ b/mongodb-1.8.1/src/BSON/ObjectIdInterface.c
@@ -1,56 +1,56 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_objectid_interface_ce;
/* {{{ MongoDB\BSON\ObjectIdInterface function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_ObjectIdInterface_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_objectid_interface_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(ObjectIdInterface, getTimestamp, ai_ObjectIdInterface_void)
ZEND_ABSTRACT_ME(ObjectIdInterface, __toString, ai_ObjectIdInterface_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_objectid_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "ObjectIdInterface", php_phongo_objectid_interface_me);
- php_phongo_objectid_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_objectid_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Persistable.c b/mongodb-1.8.1/src/BSON/Persistable.c
similarity index 90%
rename from mongodb-1.7.4/src/BSON/Persistable.c
rename to mongodb-1.8.1/src/BSON/Persistable.c
index 55787e57..a882aef7 100644
--- a/mongodb-1.7.4/src/BSON/Persistable.c
+++ b/mongodb-1.8.1/src/BSON/Persistable.c
@@ -1,50 +1,50 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_persistable_ce;
/* {{{ MongoDB\BSON\Persistable function entries */
static zend_function_entry php_phongo_persistable_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_persistable_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Persistable", php_phongo_persistable_me);
- php_phongo_persistable_ce = zend_register_internal_interface(&ce TSRMLS_CC);
- zend_class_implements(php_phongo_persistable_ce TSRMLS_CC, 2, php_phongo_unserializable_ce, php_phongo_serializable_ce);
+ php_phongo_persistable_ce = zend_register_internal_interface(&ce);
+ zend_class_implements(php_phongo_persistable_ce, 2, php_phongo_unserializable_ce, php_phongo_serializable_ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Regex.c b/mongodb-1.8.1/src/BSON/Regex.c
similarity index 61%
rename from mongodb-1.7.4/src/BSON/Regex.c
rename to mongodb-1.8.1/src/BSON/Regex.c
index 8a0a50b6..dd689f85 100644
--- a/mongodb-1.7.4/src/BSON/Regex.c
+++ b/mongodb-1.8.1/src/BSON/Regex.c
@@ -1,511 +1,431 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_regex_ce;
/* qsort() compare callback for alphabetizing regex flags upon initialization */
static int php_phongo_regex_compare_flags(const void* f1, const void* f2) /* {{{ */
{
if (*(const char*) f1 == *(const char*) f2) {
return 0;
}
return (*(const char*) f1 > *(const char*) f2) ? 1 : -1;
} /* }}} */
/* Initialize the object and return whether it was successful. An exception will
* be thrown on error. */
-static bool php_phongo_regex_init(php_phongo_regex_t* intern, const char* pattern, phongo_zpp_char_len pattern_len, const char* flags, phongo_zpp_char_len flags_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_regex_init(php_phongo_regex_t* intern, const char* pattern, size_t pattern_len, const char* flags, size_t flags_len) /* {{{ */
{
if (strlen(pattern) != (size_t) pattern_len) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Pattern cannot contain null bytes");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Pattern cannot contain null bytes");
return false;
}
intern->pattern = estrndup(pattern, pattern_len);
intern->pattern_len = pattern_len;
if (flags) {
if (strlen(flags) != (size_t) flags_len) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Flags cannot contain null bytes");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Flags cannot contain null bytes");
return false;
}
intern->flags = estrndup(flags, flags_len);
intern->flags_len = flags_len;
/* Ensure flags are alphabetized upon initialization */
qsort((void*) intern->flags, flags_len, 1, php_phongo_regex_compare_flags);
} else {
intern->flags = estrdup("");
intern->flags_len = 0;
}
return true;
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_regex_init_from_hash(php_phongo_regex_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_regex_init_from_hash(php_phongo_regex_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval *pattern, *flags;
if ((pattern = zend_hash_str_find(props, "pattern", sizeof("pattern") - 1)) && Z_TYPE_P(pattern) == IS_STRING &&
(flags = zend_hash_str_find(props, "flags", sizeof("flags") - 1)) && Z_TYPE_P(flags) == IS_STRING) {
- return php_phongo_regex_init(intern, Z_STRVAL_P(pattern), Z_STRLEN_P(pattern), Z_STRVAL_P(flags), Z_STRLEN_P(flags) TSRMLS_CC);
+ return php_phongo_regex_init(intern, Z_STRVAL_P(pattern), Z_STRLEN_P(pattern), Z_STRVAL_P(flags), Z_STRLEN_P(flags));
}
-#else
- zval **pattern, **flags;
-
- if (zend_hash_find(props, "pattern", sizeof("pattern"), (void**) &pattern) == SUCCESS && Z_TYPE_PP(pattern) == IS_STRING &&
- zend_hash_find(props, "flags", sizeof("flags"), (void**) &flags) == SUCCESS && Z_TYPE_PP(flags) == IS_STRING) {
-
- return php_phongo_regex_init(intern, Z_STRVAL_PP(pattern), Z_STRLEN_PP(pattern), Z_STRVAL_PP(flags), Z_STRLEN_PP(flags) TSRMLS_CC);
- }
-#endif
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"pattern\" and \"flags\" string fields", ZSTR_VAL(php_phongo_regex_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"pattern\" and \"flags\" string fields", ZSTR_VAL(php_phongo_regex_ce->name));
return false;
} /* }}} */
/* {{{ proto void MongoDB\BSON\Regex::__construct(string $pattern [, string $flags])
Constructs a new BSON regular expression type. */
static PHP_METHOD(Regex, __construct)
{
php_phongo_regex_t* intern;
zend_error_handling error_handling;
char* pattern;
- phongo_zpp_char_len pattern_len;
+ size_t pattern_len;
char* flags = NULL;
- phongo_zpp_char_len flags_len = 0;
+ size_t flags_len = 0;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_REGEX_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &pattern, &pattern_len, &flags, &flags_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &pattern, &pattern_len, &flags, &flags_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- php_phongo_regex_init(intern, pattern, pattern_len, flags, flags_len TSRMLS_CC);
+ php_phongo_regex_init(intern, pattern, pattern_len, flags, flags_len);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Regex::getPattern()
*/
static PHP_METHOD(Regex, getPattern)
{
php_phongo_regex_t* intern;
intern = Z_REGEX_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETURN_STRINGL(intern->pattern, intern->pattern_len);
+ RETURN_STRINGL(intern->pattern, intern->pattern_len);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Regex::getFlags()
*/
static PHP_METHOD(Regex, getFlags)
{
php_phongo_regex_t* intern;
intern = Z_REGEX_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETURN_STRINGL(intern->flags, intern->flags_len);
+ RETURN_STRINGL(intern->flags, intern->flags_len);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Regex::__set_state(array $properties)
*/
static PHP_METHOD(Regex, __set_state)
{
php_phongo_regex_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_regex_ce);
intern = Z_REGEX_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_regex_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_regex_init_from_hash(intern, props);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Regex::__toString()
Returns a string in the form: /pattern/flags */
static PHP_METHOD(Regex, __toString)
{
php_phongo_regex_t* intern;
char* regex;
int regex_len;
intern = Z_REGEX_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
regex_len = spprintf(&regex, 0, "/%s/%s", intern->pattern, intern->flags);
- PHONGO_RETVAL_STRINGL(regex, regex_len);
+ RETVAL_STRINGL(regex, regex_len);
efree(regex);
} /* }}} */
/* {{{ proto array MongoDB\BSON\Regex::jsonSerialize()
*/
static PHP_METHOD(Regex, jsonSerialize)
{
php_phongo_regex_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_REGEX_OBJ_P(getThis());
array_init_size(return_value, 2);
ADD_ASSOC_STRINGL(return_value, "$regex", intern->pattern, intern->pattern_len);
ADD_ASSOC_STRINGL(return_value, "$options", intern->flags, intern->flags_len);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Regex::serialize()
*/
static PHP_METHOD(Regex, serialize)
{
php_phongo_regex_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
intern = Z_REGEX_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 2);
ADD_ASSOC_STRINGL(&retval, "pattern", intern->pattern, intern->pattern_len);
ADD_ASSOC_STRINGL(&retval, "flags", intern->flags, intern->flags_len);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 2);
- ADD_ASSOC_STRINGL(retval, "pattern", intern->pattern, intern->pattern_len);
- ADD_ASSOC_STRINGL(retval, "flags", intern->flags, intern->flags_len);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Regex::unserialize(string $serialized)
*/
static PHP_METHOD(Regex, unserialize)
{
- php_phongo_regex_t* intern;
- zend_error_handling error_handling;
- char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
+ php_phongo_regex_t* intern;
+ zend_error_handling error_handling;
+ char* serialized;
+ size_t serialized_len;
+ zval props;
php_unserialize_data_t var_hash;
intern = Z_REGEX_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_regex_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_regex_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_regex_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_regex_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_regex_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\Regex function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Regex___construct, 0, 0, 2)
ZEND_ARG_INFO(0, pattern)
ZEND_ARG_INFO(0, flags)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Regex___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Regex_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Regex_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_regex_me[] = {
/* clang-format off */
PHP_ME(Regex, __construct, ai_Regex___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Regex, __set_state, ai_Regex___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Regex, __toString, ai_Regex_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Regex, jsonSerialize, ai_Regex_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Regex, serialize, ai_Regex_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Regex, unserialize, ai_Regex_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Regex, getPattern, ai_Regex_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Regex, getFlags, ai_Regex_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\Regex object handlers */
static zend_object_handlers php_phongo_handler_regex;
-static void php_phongo_regex_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_regex_free_object(zend_object* object) /* {{{ */
{
php_phongo_regex_t* intern = Z_OBJ_REGEX(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->pattern) {
efree(intern->pattern);
}
if (intern->flags) {
efree(intern->flags);
}
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_regex_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_regex_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_regex_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_regex_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_regex;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_regex_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_regex;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_regex_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_regex_clone_object(zval* object) /* {{{ */
{
- php_phongo_regex_t* intern;
- php_phongo_regex_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_regex_t* intern;
+ php_phongo_regex_t* new_intern;
+ zend_object* new_object;
intern = Z_REGEX_OBJ_P(object);
- new_object = php_phongo_regex_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_regex_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_REGEX(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
-
- new_intern = (php_phongo_regex_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
+ zend_objects_clone_members(&new_intern->std, &intern->std);
- php_phongo_regex_init(new_intern, intern->pattern, intern->pattern_len, intern->flags, intern->flags_len TSRMLS_CC);
+ php_phongo_regex_init(new_intern, intern->pattern, intern->pattern_len, intern->flags, intern->flags_len);
return new_object;
} /* }}} */
-static int php_phongo_regex_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_regex_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_regex_t *intern1, *intern2;
int retval;
intern1 = Z_REGEX_OBJ_P(o1);
intern2 = Z_REGEX_OBJ_P(o2);
/* MongoDB compares the pattern string before the flags. */
retval = strcmp(intern1->pattern, intern2->pattern);
if (retval != 0) {
return retval;
}
return strcmp(intern1->flags, intern2->flags);
} /* }}} */
-static HashTable* php_phongo_regex_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_REGEX_OBJ_P(object)->properties;
-} /* }}} */
-
-static HashTable* php_phongo_regex_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_regex_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_regex_t* intern;
HashTable* props;
intern = Z_REGEX_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);
if (!intern->pattern) {
return props;
}
-#if PHP_VERSION_ID >= 70000
{
zval pattern, flags;
ZVAL_STRINGL(&pattern, intern->pattern, intern->pattern_len);
zend_hash_str_update(props, "pattern", sizeof("pattern") - 1, &pattern);
ZVAL_STRINGL(&flags, intern->flags, intern->flags_len);
zend_hash_str_update(props, "flags", sizeof("flags") - 1, &flags);
}
-#else
- {
- zval *pattern, *flags;
-
- MAKE_STD_ZVAL(pattern);
- ZVAL_STRINGL(pattern, intern->pattern, intern->pattern_len, 1);
- zend_hash_update(props, "pattern", sizeof("pattern"), &pattern, sizeof(pattern), NULL);
-
- MAKE_STD_ZVAL(flags);
- ZVAL_STRINGL(flags, intern->flags, intern->flags_len, 1);
- zend_hash_update(props, "flags", sizeof("flags"), &flags, sizeof(flags), NULL);
- }
-#endif
return props;
} /* }}} */
-static HashTable* php_phongo_regex_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_regex_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_regex_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_regex_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_regex_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_regex_get_properties(zval* object) /* {{{ */
{
- return php_phongo_regex_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_regex_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_regex_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Regex", php_phongo_regex_me);
- php_phongo_regex_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_regex_ce = zend_register_internal_class(&ce);
php_phongo_regex_ce->create_object = php_phongo_regex_create_object;
PHONGO_CE_FINAL(php_phongo_regex_ce);
- zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_regex_interface_ce);
- zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, zend_ce_serializable);
- zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_regex_ce, 1, php_phongo_regex_interface_ce);
+ zend_class_implements(php_phongo_regex_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_regex_ce, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_regex_ce, 1, php_phongo_json_serializable_ce);
memcpy(&php_phongo_handler_regex, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_regex.clone_obj = php_phongo_regex_clone_object;
php_phongo_handler_regex.compare_objects = php_phongo_regex_compare_objects;
php_phongo_handler_regex.get_debug_info = php_phongo_regex_get_debug_info;
- php_phongo_handler_regex.get_gc = php_phongo_regex_get_gc;
php_phongo_handler_regex.get_properties = php_phongo_regex_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_regex.free_obj = php_phongo_regex_free_object;
- php_phongo_handler_regex.offset = XtOffsetOf(php_phongo_regex_t, std);
-#endif
+ php_phongo_handler_regex.free_obj = php_phongo_regex_free_object;
+ php_phongo_handler_regex.offset = XtOffsetOf(php_phongo_regex_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/RegexInterface.c b/mongodb-1.8.1/src/BSON/RegexInterface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/RegexInterface.c
rename to mongodb-1.8.1/src/BSON/RegexInterface.c
index a8783ae3..476cb56e 100644
--- a/mongodb-1.7.4/src/BSON/RegexInterface.c
+++ b/mongodb-1.8.1/src/BSON/RegexInterface.c
@@ -1,57 +1,57 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_regex_interface_ce;
/* {{{ MongoDB\BSON\RegexInterface function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_RegexInterface_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_regex_interface_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(RegexInterface, getFlags, ai_RegexInterface_void)
ZEND_ABSTRACT_ME(RegexInterface, getPattern, ai_RegexInterface_void)
ZEND_ABSTRACT_ME(RegexInterface, __toString, ai_RegexInterface_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_regex_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "RegexInterface", php_phongo_regex_interface_me);
- php_phongo_regex_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_regex_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Serializable.c b/mongodb-1.8.1/src/BSON/Serializable.c
similarity index 93%
rename from mongodb-1.7.4/src/BSON/Serializable.c
rename to mongodb-1.8.1/src/BSON/Serializable.c
index 49d7349d..323f020d 100644
--- a/mongodb-1.7.4/src/BSON/Serializable.c
+++ b/mongodb-1.8.1/src/BSON/Serializable.c
@@ -1,56 +1,56 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_serializable_ce;
/* {{{ MongoDB\BSON\Serializable function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Serializable_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_serializable_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(Serializable, bsonSerialize, ai_Serializable_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_serializable_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Serializable", php_phongo_serializable_me);
- php_phongo_serializable_ce = zend_register_internal_interface(&ce TSRMLS_CC);
- zend_class_implements(php_phongo_serializable_ce TSRMLS_CC, 1, php_phongo_type_ce);
+ php_phongo_serializable_ce = zend_register_internal_interface(&ce);
+ zend_class_implements(php_phongo_serializable_ce, 1, php_phongo_type_ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Symbol.c b/mongodb-1.8.1/src/BSON/Symbol.c
similarity index 58%
rename from mongodb-1.7.4/src/BSON/Symbol.c
rename to mongodb-1.8.1/src/BSON/Symbol.c
index 4167b6a6..d3f4a8a6 100644
--- a/mongodb-1.7.4/src/BSON/Symbol.c
+++ b/mongodb-1.8.1/src/BSON/Symbol.c
@@ -1,373 +1,300 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_symbol_ce;
/* Initialize the object and return whether it was successful. An exception will
* be thrown on error. */
-static bool php_phongo_symbol_init(php_phongo_symbol_t* intern, const char* symbol, phongo_zpp_char_len symbol_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_symbol_init(php_phongo_symbol_t* intern, const char* symbol, size_t symbol_len) /* {{{ */
{
if (strlen(symbol) != (size_t) symbol_len) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Symbol cannot contain null bytes");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Symbol cannot contain null bytes");
return false;
}
intern->symbol = estrndup(symbol, symbol_len);
intern->symbol_len = symbol_len;
return true;
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_symbol_init_from_hash(php_phongo_symbol_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_symbol_init_from_hash(php_phongo_symbol_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval* symbol;
if ((symbol = zend_hash_str_find(props, "symbol", sizeof("symbol") - 1)) && Z_TYPE_P(symbol) == IS_STRING) {
- return php_phongo_symbol_init(intern, Z_STRVAL_P(symbol), Z_STRLEN_P(symbol) TSRMLS_CC);
- }
-#else
- zval** symbol;
-
- if (zend_hash_find(props, "symbol", sizeof("symbol"), (void**) &symbol) == SUCCESS && Z_TYPE_PP(symbol) == IS_STRING) {
- return php_phongo_symbol_init(intern, Z_STRVAL_PP(symbol), Z_STRLEN_PP(symbol) TSRMLS_CC);
+ return php_phongo_symbol_init(intern, Z_STRVAL_P(symbol), Z_STRLEN_P(symbol));
}
-#endif
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"symbol\" string field", ZSTR_VAL(php_phongo_symbol_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"symbol\" string field", ZSTR_VAL(php_phongo_symbol_ce->name));
return false;
} /* }}} */
/* {{{ proto string MongoDB\BSON\Symbol::__toString()
Return the Symbol's symbol string. */
static PHP_METHOD(Symbol, __toString)
{
php_phongo_symbol_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_SYMBOL_OBJ_P(getThis());
- PHONGO_RETURN_STRINGL(intern->symbol, intern->symbol_len);
+ RETURN_STRINGL(intern->symbol, intern->symbol_len);
} /* }}} */
/* {{{ proto array MongoDB\BSON\Symbol::jsonSerialize()
*/
static PHP_METHOD(Symbol, jsonSerialize)
{
php_phongo_symbol_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_SYMBOL_OBJ_P(getThis());
array_init_size(return_value, 1);
ADD_ASSOC_STRINGL(return_value, "$symbol", intern->symbol, intern->symbol_len);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Symbol::serialize()
*/
static PHP_METHOD(Symbol, serialize)
{
php_phongo_symbol_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
intern = Z_SYMBOL_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 1);
ADD_ASSOC_STRINGL(&retval, "symbol", intern->symbol, intern->symbol_len);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 1);
- ADD_ASSOC_STRINGL(retval, "symbol", intern->symbol, intern->symbol_len);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Symbol::unserialize(string $serialized)
*/
static PHP_METHOD(Symbol, unserialize)
{
- php_phongo_symbol_t* intern;
- zend_error_handling error_handling;
- char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
+ php_phongo_symbol_t* intern;
+ zend_error_handling error_handling;
+ char* serialized;
+ size_t serialized_len;
+ zval props;
php_unserialize_data_t var_hash;
intern = Z_SYMBOL_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_symbol_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_symbol_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_symbol_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_symbol_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_symbol_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\Symbol function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Symbol_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Symbol_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_symbol_me[] = {
/* clang-format off */
/* __set_state intentionally missing */
PHP_ME(Symbol, __toString, ai_Symbol_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Symbol, jsonSerialize, ai_Symbol_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Symbol, serialize, ai_Symbol_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Symbol, unserialize, ai_Symbol_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Symbol_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\Symbol object handlers */
static zend_object_handlers php_phongo_handler_symbol;
-static void php_phongo_symbol_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_symbol_free_object(zend_object* object) /* {{{ */
{
php_phongo_symbol_t* intern = Z_OBJ_SYMBOL(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->symbol) {
efree(intern->symbol);
}
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-phongo_create_object_retval php_phongo_symbol_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+zend_object* php_phongo_symbol_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_symbol_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_symbol_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_symbol;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_symbol_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_symbol;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_symbol_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_symbol_clone_object(zval* object) /* {{{ */
{
- php_phongo_symbol_t* intern;
- php_phongo_symbol_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_symbol_t* intern;
+ php_phongo_symbol_t* new_intern;
+ zend_object* new_object;
intern = Z_SYMBOL_OBJ_P(object);
- new_object = php_phongo_symbol_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_symbol_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_SYMBOL(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
+ zend_objects_clone_members(&new_intern->std, &intern->std);
- new_intern = (php_phongo_symbol_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
-
- php_phongo_symbol_init(new_intern, intern->symbol, intern->symbol_len TSRMLS_CC);
+ php_phongo_symbol_init(new_intern, intern->symbol, intern->symbol_len);
return new_object;
} /* }}} */
-static int php_phongo_symbol_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_symbol_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_symbol_t *intern1, *intern2;
intern1 = Z_SYMBOL_OBJ_P(o1);
intern2 = Z_SYMBOL_OBJ_P(o2);
return strcmp(intern1->symbol, intern2->symbol);
} /* }}} */
-static HashTable* php_phongo_symbol_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_SYMBOL_OBJ_P(object)->properties;
-} /* }}} */
-
-HashTable* php_phongo_symbol_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+HashTable* php_phongo_symbol_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_symbol_t* intern;
HashTable* props;
intern = Z_SYMBOL_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);
if (!intern->symbol) {
return props;
}
-#if PHP_VERSION_ID >= 70000
{
zval symbol;
ZVAL_STRING(&symbol, intern->symbol);
zend_hash_str_update(props, "symbol", sizeof("symbol") - 1, &symbol);
}
-#else
- {
- zval* symbol;
-
- MAKE_STD_ZVAL(symbol);
- ZVAL_STRING(symbol, intern->symbol, 1);
- zend_hash_update(props, "symbol", sizeof("symbol"), &symbol, sizeof(symbol), NULL);
- }
-#endif
return props;
} /* }}} */
-static HashTable* php_phongo_symbol_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_symbol_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_symbol_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_symbol_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_symbol_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_symbol_get_properties(zval* object) /* {{{ */
{
- return php_phongo_symbol_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_symbol_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_symbol_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Symbol", php_phongo_symbol_me);
- php_phongo_symbol_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_symbol_ce = zend_register_internal_class(&ce);
php_phongo_symbol_ce->create_object = php_phongo_symbol_create_object;
PHONGO_CE_FINAL(php_phongo_symbol_ce);
- zend_class_implements(php_phongo_symbol_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_symbol_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_symbol_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_symbol_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_symbol_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_symbol_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_symbol, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_symbol.clone_obj = php_phongo_symbol_clone_object;
php_phongo_handler_symbol.compare_objects = php_phongo_symbol_compare_objects;
php_phongo_handler_symbol.get_debug_info = php_phongo_symbol_get_debug_info;
- php_phongo_handler_symbol.get_gc = php_phongo_symbol_get_gc;
php_phongo_handler_symbol.get_properties = php_phongo_symbol_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_symbol.free_obj = php_phongo_symbol_free_object;
- php_phongo_handler_symbol.offset = XtOffsetOf(php_phongo_symbol_t, std);
-#endif
+ php_phongo_handler_symbol.free_obj = php_phongo_symbol_free_object;
+ php_phongo_handler_symbol.offset = XtOffsetOf(php_phongo_symbol_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Timestamp.c b/mongodb-1.8.1/src/BSON/Timestamp.c
similarity index 61%
rename from mongodb-1.7.4/src/BSON/Timestamp.c
rename to mongodb-1.8.1/src/BSON/Timestamp.c
index 0873e28e..3e77db90 100644
--- a/mongodb-1.7.4/src/BSON/Timestamp.c
+++ b/mongodb-1.8.1/src/BSON/Timestamp.c
@@ -1,570 +1,473 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_timestamp_ce;
/* Initialize the object and return whether it was successful. An exception will
* be thrown on error. */
-static bool php_phongo_timestamp_init(php_phongo_timestamp_t* intern, int64_t increment, int64_t timestamp TSRMLS_DC) /* {{{ */
+static bool php_phongo_timestamp_init(php_phongo_timestamp_t* intern, int64_t increment, int64_t timestamp) /* {{{ */
{
if (increment < 0 || increment > UINT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected increment to be an unsigned 32-bit integer, %" PRId64 " given", increment);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected increment to be an unsigned 32-bit integer, %" PRId64 " given", increment);
return false;
}
if (timestamp < 0 || timestamp > UINT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected timestamp to be an unsigned 32-bit integer, %" PRId64 " given", timestamp);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected timestamp to be an unsigned 32-bit integer, %" PRId64 " given", timestamp);
return false;
}
intern->increment = (uint32_t) increment;
intern->timestamp = (uint32_t) timestamp;
intern->initialized = true;
return true;
} /* }}} */
/* Initialize the object from numeric strings and return whether it was
* successful. An exception will be thrown on error. */
-static bool php_phongo_timestamp_init_from_string(php_phongo_timestamp_t* intern, const char* s_increment, phongo_zpp_char_len s_increment_len, const char* s_timestamp, phongo_zpp_char_len s_timestamp_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_timestamp_init_from_string(php_phongo_timestamp_t* intern, const char* s_increment, size_t s_increment_len, const char* s_timestamp, size_t s_timestamp_len) /* {{{ */
{
int64_t increment, timestamp;
if (!php_phongo_parse_int64(&increment, s_increment, s_increment_len)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit integer increment for %s initialization", s_increment, ZSTR_VAL(php_phongo_timestamp_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error parsing \"%s\" as 64-bit integer increment for %s initialization", s_increment, ZSTR_VAL(php_phongo_timestamp_ce->name));
return false;
}
if (!php_phongo_parse_int64(&timestamp, s_timestamp, s_timestamp_len)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit integer timestamp for %s initialization", s_timestamp, ZSTR_VAL(php_phongo_timestamp_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error parsing \"%s\" as 64-bit integer timestamp for %s initialization", s_timestamp, ZSTR_VAL(php_phongo_timestamp_ce->name));
return false;
}
- return php_phongo_timestamp_init(intern, increment, timestamp TSRMLS_CC);
+ return php_phongo_timestamp_init(intern, increment, timestamp);
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_timestamp_init_from_hash(php_phongo_timestamp_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_timestamp_init_from_hash(php_phongo_timestamp_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval *increment, *timestamp;
if ((increment = zend_hash_str_find(props, "increment", sizeof("increment") - 1)) && Z_TYPE_P(increment) == IS_LONG &&
(timestamp = zend_hash_str_find(props, "timestamp", sizeof("timestamp") - 1)) && Z_TYPE_P(timestamp) == IS_LONG) {
- return php_phongo_timestamp_init(intern, Z_LVAL_P(increment), Z_LVAL_P(timestamp) TSRMLS_CC);
+ return php_phongo_timestamp_init(intern, Z_LVAL_P(increment), Z_LVAL_P(timestamp));
}
if ((increment = zend_hash_str_find(props, "increment", sizeof("increment") - 1)) && Z_TYPE_P(increment) == IS_STRING &&
(timestamp = zend_hash_str_find(props, "timestamp", sizeof("timestamp") - 1)) && Z_TYPE_P(timestamp) == IS_STRING) {
- return php_phongo_timestamp_init_from_string(intern, Z_STRVAL_P(increment), Z_STRLEN_P(increment), Z_STRVAL_P(timestamp), Z_STRLEN_P(timestamp) TSRMLS_CC);
+ return php_phongo_timestamp_init_from_string(intern, Z_STRVAL_P(increment), Z_STRLEN_P(increment), Z_STRVAL_P(timestamp), Z_STRLEN_P(timestamp));
}
-#else
- zval **increment, **timestamp;
-
- if (zend_hash_find(props, "increment", sizeof("increment"), (void**) &increment) == SUCCESS && Z_TYPE_PP(increment) == IS_LONG &&
- zend_hash_find(props, "timestamp", sizeof("timestamp"), (void**) &timestamp) == SUCCESS && Z_TYPE_PP(timestamp) == IS_LONG) {
- return php_phongo_timestamp_init(intern, Z_LVAL_PP(increment), Z_LVAL_PP(timestamp) TSRMLS_CC);
- }
- if (zend_hash_find(props, "increment", sizeof("increment"), (void**) &increment) == SUCCESS && Z_TYPE_PP(increment) == IS_STRING &&
- zend_hash_find(props, "timestamp", sizeof("timestamp"), (void**) &timestamp) == SUCCESS && Z_TYPE_PP(timestamp) == IS_STRING) {
-
- return php_phongo_timestamp_init_from_string(intern, Z_STRVAL_PP(increment), Z_STRLEN_PP(increment), Z_STRVAL_PP(timestamp), Z_STRLEN_PP(timestamp) TSRMLS_CC);
- }
-#endif
-
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"increment\" and \"timestamp\" integer or numeric string fields", ZSTR_VAL(php_phongo_timestamp_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"increment\" and \"timestamp\" integer or numeric string fields", ZSTR_VAL(php_phongo_timestamp_ce->name));
return false;
} /* }}} */
/* {{{ proto void MongoDB\BSON\Timestamp::__construct(int|string $increment, int|string $timestamp)
Construct a new BSON timestamp type, which consists of a 4-byte increment and
4-byte timestamp. */
static PHP_METHOD(Timestamp, __construct)
{
php_phongo_timestamp_t* intern;
zend_error_handling error_handling;
zval * increment = NULL, *timestamp = NULL;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_TIMESTAMP_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &increment, &timestamp) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &increment, &timestamp) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
if (Z_TYPE_P(increment) == IS_LONG && Z_TYPE_P(timestamp) == IS_LONG) {
- php_phongo_timestamp_init(intern, Z_LVAL_P(increment), Z_LVAL_P(timestamp) TSRMLS_CC);
+ php_phongo_timestamp_init(intern, Z_LVAL_P(increment), Z_LVAL_P(timestamp));
return;
}
if (Z_TYPE_P(increment) == IS_LONG) {
convert_to_string(increment);
}
if (Z_TYPE_P(increment) != IS_STRING) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected increment to be an unsigned 32-bit integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(increment));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected increment to be an unsigned 32-bit integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(increment));
return;
}
if (Z_TYPE_P(timestamp) == IS_LONG) {
convert_to_string(timestamp);
}
if (Z_TYPE_P(timestamp) != IS_STRING) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected timestamp to be an unsigned 32-bit integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(timestamp));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected timestamp to be an unsigned 32-bit integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(timestamp));
return;
}
- php_phongo_timestamp_init_from_string(intern, Z_STRVAL_P(increment), Z_STRLEN_P(increment), Z_STRVAL_P(timestamp), Z_STRLEN_P(timestamp) TSRMLS_CC);
+ php_phongo_timestamp_init_from_string(intern, Z_STRVAL_P(increment), Z_STRLEN_P(increment), Z_STRVAL_P(timestamp), Z_STRLEN_P(timestamp));
} /* }}} */
/* {{{ proto integer MongoDB\BSON\Timestamp::getIncrement()
*/
static PHP_METHOD(Timestamp, getIncrement)
{
php_phongo_timestamp_t* intern;
intern = Z_TIMESTAMP_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETVAL_LONG(intern->increment);
} /* }}} */
/* {{{ proto integer MongoDB\BSON\Timestamp::getTimestamp()
*/
static PHP_METHOD(Timestamp, getTimestamp)
{
php_phongo_timestamp_t* intern;
intern = Z_TIMESTAMP_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETVAL_LONG(intern->timestamp);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Timestamp::__set_state(array $properties)
*/
static PHP_METHOD(Timestamp, __set_state)
{
php_phongo_timestamp_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_timestamp_ce);
intern = Z_TIMESTAMP_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_timestamp_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_timestamp_init_from_hash(intern, props);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Timestamp::__toString()
Returns a string in the form: [increment:timestamp] */
static PHP_METHOD(Timestamp, __toString)
{
php_phongo_timestamp_t* intern;
char* retval;
int retval_len;
intern = Z_TIMESTAMP_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
retval_len = spprintf(&retval, 0, "[%" PRIu32 ":%" PRIu32 "]", intern->increment, intern->timestamp);
- PHONGO_RETVAL_STRINGL(retval, retval_len);
+ RETVAL_STRINGL(retval, retval_len);
efree(retval);
} /* }}} */
/* {{{ proto array MongoDB\BSON\Timestamp::jsonSerialize()
*/
static PHP_METHOD(Timestamp, jsonSerialize)
{
php_phongo_timestamp_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_TIMESTAMP_OBJ_P(getThis());
array_init_size(return_value, 1);
-#if PHP_VERSION_ID >= 70000
{
zval ts;
array_init_size(&ts, 2);
ADD_ASSOC_LONG_EX(&ts, "t", intern->timestamp);
ADD_ASSOC_LONG_EX(&ts, "i", intern->increment);
ADD_ASSOC_ZVAL_EX(return_value, "$timestamp", &ts);
}
-#else
- {
- zval* ts;
-
- MAKE_STD_ZVAL(ts);
- array_init_size(ts, 2);
- ADD_ASSOC_LONG_EX(ts, "t", intern->timestamp);
- ADD_ASSOC_LONG_EX(ts, "i", intern->increment);
- ADD_ASSOC_ZVAL_EX(return_value, "$timestamp", ts);
- }
-#endif
} /* }}} */
/* {{{ proto string MongoDB\BSON\Timestamp::serialize()
*/
static PHP_METHOD(Timestamp, serialize)
{
php_phongo_timestamp_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
char s_increment[12];
char s_timestamp[12];
int s_increment_len;
int s_timestamp_len;
intern = Z_TIMESTAMP_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
s_increment_len = snprintf(s_increment, sizeof(s_increment), "%" PRIu32, intern->increment);
s_timestamp_len = snprintf(s_timestamp, sizeof(s_timestamp), "%" PRIu32, intern->timestamp);
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 2);
ADD_ASSOC_STRINGL(&retval, "increment", s_increment, s_increment_len);
ADD_ASSOC_STRINGL(&retval, "timestamp", s_timestamp, s_timestamp_len);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 2);
- ADD_ASSOC_STRINGL(retval, "increment", s_increment, s_increment_len);
- ADD_ASSOC_STRINGL(retval, "timestamp", s_timestamp, s_timestamp_len);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\Timestamp::unserialize(string $serialized)
*/
static PHP_METHOD(Timestamp, unserialize)
{
php_phongo_timestamp_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
- php_unserialize_data_t var_hash;
+ size_t serialized_len;
+ zval props;
+ php_unserialize_data_t var_hash;
intern = Z_TIMESTAMP_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_timestamp_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_timestamp_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_timestamp_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_timestamp_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_timestamp_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\Timestamp function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Timestamp___construct, 0, 0, 2)
ZEND_ARG_INFO(0, increment)
ZEND_ARG_INFO(0, timestamp)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Timestamp___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Timestamp_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Timestamp_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_timestamp_me[] = {
/* clang-format off */
PHP_ME(Timestamp, __construct, ai_Timestamp___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Timestamp, __set_state, ai_Timestamp___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Timestamp, __toString, ai_Timestamp_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Timestamp, jsonSerialize, ai_Timestamp_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Timestamp, serialize, ai_Timestamp_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Timestamp, unserialize, ai_Timestamp_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Timestamp, getIncrement, ai_Timestamp_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Timestamp, getTimestamp, ai_Timestamp_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\Timestamp object handlers */
static zend_object_handlers php_phongo_handler_timestamp;
-static void php_phongo_timestamp_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_timestamp_free_object(zend_object* object) /* {{{ */
{
php_phongo_timestamp_t* intern = Z_OBJ_TIMESTAMP(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_timestamp_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_timestamp_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_timestamp_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_timestamp_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_timestamp;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_timestamp_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_timestamp;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_timestamp_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_timestamp_clone_object(zval* object) /* {{{ */
{
- php_phongo_timestamp_t* intern;
- php_phongo_timestamp_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_timestamp_t* intern;
+ php_phongo_timestamp_t* new_intern;
+ zend_object* new_object;
intern = Z_TIMESTAMP_OBJ_P(object);
- new_object = php_phongo_timestamp_create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ new_object = php_phongo_timestamp_create_object(Z_OBJCE_P(object));
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_TIMESTAMP(new_object);
- zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
+ zend_objects_clone_members(&new_intern->std, &intern->std);
- new_intern = (php_phongo_timestamp_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
-
- php_phongo_timestamp_init(new_intern, intern->increment, intern->timestamp TSRMLS_CC);
+ php_phongo_timestamp_init(new_intern, intern->increment, intern->timestamp);
return new_object;
} /* }}} */
-static int php_phongo_timestamp_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_timestamp_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_timestamp_t *intern1, *intern2;
intern1 = Z_TIMESTAMP_OBJ_P(o1);
intern2 = Z_TIMESTAMP_OBJ_P(o2);
/* MongoDB compares the timestamp before the increment. */
if (intern1->timestamp != intern2->timestamp) {
return intern1->timestamp < intern2->timestamp ? -1 : 1;
}
if (intern1->increment != intern2->increment) {
return intern1->increment < intern2->increment ? -1 : 1;
}
return 0;
} /* }}} */
-static HashTable* php_phongo_timestamp_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_TIMESTAMP_OBJ_P(object)->properties;
-} /* }}} */
-
-static HashTable* php_phongo_timestamp_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_timestamp_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_timestamp_t* intern;
HashTable* props;
char s_increment[24];
char s_timestamp[24];
int s_increment_len;
int s_timestamp_len;
intern = Z_TIMESTAMP_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);
if (!intern->initialized) {
return props;
}
s_increment_len = snprintf(s_increment, sizeof(s_increment), "%" PRIu32, intern->increment);
s_timestamp_len = snprintf(s_timestamp, sizeof(s_timestamp), "%" PRIu32, intern->timestamp);
-#if PHP_VERSION_ID >= 70000
{
zval increment, timestamp;
ZVAL_STRINGL(&increment, s_increment, s_increment_len);
zend_hash_str_update(props, "increment", sizeof("increment") - 1, &increment);
ZVAL_STRINGL(&timestamp, s_timestamp, s_timestamp_len);
zend_hash_str_update(props, "timestamp", sizeof("timestamp") - 1, &timestamp);
}
-#else
- {
- zval *increment, *timestamp;
-
- MAKE_STD_ZVAL(increment);
- ZVAL_STRINGL(increment, s_increment, s_increment_len, 1);
- zend_hash_update(props, "increment", sizeof("increment"), &increment, sizeof(increment), NULL);
-
- MAKE_STD_ZVAL(timestamp);
- ZVAL_STRINGL(timestamp, s_timestamp, s_timestamp_len, 1);
- zend_hash_update(props, "timestamp", sizeof("timestamp"), &timestamp, sizeof(timestamp), NULL);
- }
-#endif
return props;
} /* }}} */
-static HashTable* php_phongo_timestamp_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_timestamp_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_timestamp_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_timestamp_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_timestamp_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_timestamp_get_properties(zval* object) /* {{{ */
{
- return php_phongo_timestamp_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_timestamp_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_timestamp_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Timestamp", php_phongo_timestamp_me);
- php_phongo_timestamp_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_timestamp_ce = zend_register_internal_class(&ce);
php_phongo_timestamp_ce->create_object = php_phongo_timestamp_create_object;
PHONGO_CE_FINAL(php_phongo_timestamp_ce);
- zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, php_phongo_timestamp_interface_ce);
- zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_timestamp_ce, 1, php_phongo_timestamp_interface_ce);
+ zend_class_implements(php_phongo_timestamp_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_timestamp_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_timestamp_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_timestamp, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_timestamp.clone_obj = php_phongo_timestamp_clone_object;
php_phongo_handler_timestamp.compare_objects = php_phongo_timestamp_compare_objects;
php_phongo_handler_timestamp.get_debug_info = php_phongo_timestamp_get_debug_info;
- php_phongo_handler_timestamp.get_gc = php_phongo_timestamp_get_gc;
php_phongo_handler_timestamp.get_properties = php_phongo_timestamp_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_timestamp.free_obj = php_phongo_timestamp_free_object;
- php_phongo_handler_timestamp.offset = XtOffsetOf(php_phongo_timestamp_t, std);
-#endif
+ php_phongo_handler_timestamp.free_obj = php_phongo_timestamp_free_object;
+ php_phongo_handler_timestamp.offset = XtOffsetOf(php_phongo_timestamp_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/TimestampInterface.c b/mongodb-1.8.1/src/BSON/TimestampInterface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/TimestampInterface.c
rename to mongodb-1.8.1/src/BSON/TimestampInterface.c
index 1ac345ef..bfa2137d 100644
--- a/mongodb-1.7.4/src/BSON/TimestampInterface.c
+++ b/mongodb-1.8.1/src/BSON/TimestampInterface.c
@@ -1,57 +1,57 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_timestamp_interface_ce;
/* {{{ MongoDB\BSON\TimestampInterface function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_TimestampInterface_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_timestamp_interface_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(TimestampInterface, getIncrement, ai_TimestampInterface_void)
ZEND_ABSTRACT_ME(TimestampInterface, getTimestamp, ai_TimestampInterface_void)
ZEND_ABSTRACT_ME(TimestampInterface, __toString, ai_TimestampInterface_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_timestamp_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "TimestampInterface", php_phongo_timestamp_interface_me);
- php_phongo_timestamp_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_timestamp_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Type.c b/mongodb-1.8.1/src/BSON/Type.c
similarity index 94%
rename from mongodb-1.7.4/src/BSON/Type.c
rename to mongodb-1.8.1/src/BSON/Type.c
index 54090dfe..c97ebbaa 100644
--- a/mongodb-1.7.4/src/BSON/Type.c
+++ b/mongodb-1.8.1/src/BSON/Type.c
@@ -1,49 +1,49 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_type_ce;
/* {{{ MongoDB\BSON\Type function entries */
static zend_function_entry php_phongo_type_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_type_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Type", php_phongo_type_me);
- php_phongo_type_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_type_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/UTCDateTime.c b/mongodb-1.8.1/src/BSON/UTCDateTime.c
similarity index 81%
rename from mongodb-1.7.4/src/BSON/UTCDateTime.c
rename to mongodb-1.8.1/src/BSON/UTCDateTime.c
index 91addd73..178ff0c7 100644
--- a/mongodb-1.7.4/src/BSON/UTCDateTime.c
+++ b/mongodb-1.8.1/src/BSON/UTCDateTime.c
@@ -1,568 +1,480 @@
/*
* Copyright 2014-2017 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.
*/
#include <math.h>
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/date/php_date.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef PHP_WIN32
#include "win32/time.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_utcdatetime_ce;
/* Initialize the object and return whether it was successful. */
static bool php_phongo_utcdatetime_init(php_phongo_utcdatetime_t* intern, int64_t milliseconds) /* {{{ */
{
intern->milliseconds = milliseconds;
intern->initialized = true;
return true;
} /* }}} */
/* Initialize the object from a numeric string and return whether it was
* successful. An exception will be thrown on error. */
-static bool php_phongo_utcdatetime_init_from_string(php_phongo_utcdatetime_t* intern, const char* s_milliseconds, phongo_zpp_char_len s_milliseconds_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_utcdatetime_init_from_string(php_phongo_utcdatetime_t* intern, const char* s_milliseconds, size_t s_milliseconds_len TSRMLS_DC) /* {{{ */
{
int64_t milliseconds;
if (!php_phongo_parse_int64(&milliseconds, s_milliseconds, s_milliseconds_len)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit integer for %s initialization", s_milliseconds, ZSTR_VAL(php_phongo_utcdatetime_ce->name));
return false;
}
return php_phongo_utcdatetime_init(intern, milliseconds);
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
static bool php_phongo_utcdatetime_init_from_hash(php_phongo_utcdatetime_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval* milliseconds;
if ((milliseconds = zend_hash_str_find(props, "milliseconds", sizeof("milliseconds") - 1)) && Z_TYPE_P(milliseconds) == IS_LONG) {
return php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds));
}
if ((milliseconds = zend_hash_str_find(props, "milliseconds", sizeof("milliseconds") - 1)) && Z_TYPE_P(milliseconds) == IS_STRING) {
return php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds) TSRMLS_CC);
}
-#else
- zval** milliseconds;
-
- if (zend_hash_find(props, "milliseconds", sizeof("milliseconds"), (void**) &milliseconds) == SUCCESS && Z_TYPE_PP(milliseconds) == IS_LONG) {
- return php_phongo_utcdatetime_init(intern, Z_LVAL_PP(milliseconds));
- }
-
- if (zend_hash_find(props, "milliseconds", sizeof("milliseconds"), (void**) &milliseconds) == SUCCESS && Z_TYPE_PP(milliseconds) == IS_STRING) {
- return php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_PP(milliseconds), Z_STRLEN_PP(milliseconds) TSRMLS_CC);
- }
-#endif
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"milliseconds\" integer or numeric string field", ZSTR_VAL(php_phongo_utcdatetime_ce->name));
return false;
} /* }}} */
/* Initialize the object from the current time and return whether it was
* successful. */
static bool php_phongo_utcdatetime_init_from_current_time(php_phongo_utcdatetime_t* intern) /* {{{ */
{
int64_t sec, usec;
struct timeval cur_time;
gettimeofday(&cur_time, NULL);
sec = cur_time.tv_sec;
usec = cur_time.tv_usec;
intern->milliseconds = (sec * 1000) + (usec / 1000);
intern->initialized = true;
return true;
} /* }}} */
/* Initialize the object from a DateTime object and return whether it was
* successful. */
static bool php_phongo_utcdatetime_init_from_date(php_phongo_utcdatetime_t* intern, php_date_obj* datetime_obj) /* {{{ */
{
int64_t sec, usec;
/* The following assignments use the same logic as date_format() in php_date.c */
sec = datetime_obj->time->sse;
#if PHP_VERSION_ID >= 70200
usec = (int64_t) floor(datetime_obj->time->us);
#else
- usec = (int64_t) floor(datetime_obj->time->f * 1000000 + 0.5);
+ usec = (int64_t) floor(datetime_obj->time->f * 1000000 + 0.5);
#endif
intern->milliseconds = (sec * 1000) + (usec / 1000);
intern->initialized = true;
return true;
} /* }}} */
/* {{{ proto void MongoDB\BSON\UTCDateTime::__construct([int|float|string|DateTimeInterface $milliseconds = null])
Construct a new BSON UTCDateTime type from either the current time,
milliseconds since the epoch, or a DateTimeInterface object. Defaults to the
current time. */
static PHP_METHOD(UTCDateTime, __construct)
{
php_phongo_utcdatetime_t* intern;
zend_error_handling error_handling;
zval* milliseconds = NULL;
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
intern = Z_UTCDATETIME_OBJ_P(getThis());
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &milliseconds) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}
zend_restore_error_handling(&error_handling TSRMLS_CC);
if (milliseconds == NULL) {
php_phongo_utcdatetime_init_from_current_time(intern);
return;
}
if (Z_TYPE_P(milliseconds) == IS_OBJECT) {
if (instanceof_function(Z_OBJCE_P(milliseconds), php_date_get_date_ce() TSRMLS_CC) ||
(php_phongo_date_immutable_ce && instanceof_function(Z_OBJCE_P(milliseconds), php_phongo_date_immutable_ce TSRMLS_CC))) {
php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(milliseconds));
} else {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected instance of DateTimeInterface, %s given", ZSTR_VAL(Z_OBJCE_P(milliseconds)->name));
}
return;
}
if (Z_TYPE_P(milliseconds) == IS_LONG) {
php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds));
return;
}
if (Z_TYPE_P(milliseconds) == IS_DOUBLE) {
char tmp[24];
int tmp_len;
tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", Z_DVAL_P(milliseconds) > 0 ? floor(Z_DVAL_P(milliseconds)) : ceil(Z_DVAL_P(milliseconds)));
php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len TSRMLS_CC);
return;
}
if (Z_TYPE_P(milliseconds) != IS_STRING) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(milliseconds));
return;
}
php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds) TSRMLS_CC);
} /* }}} */
/* {{{ proto void MongoDB\BSON\UTCDateTime::__set_state(array $properties)
*/
static PHP_METHOD(UTCDateTime, __set_state)
{
php_phongo_utcdatetime_t* intern;
HashTable* props;
zval* array;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_utcdatetime_ce);
intern = Z_UTCDATETIME_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
php_phongo_utcdatetime_init_from_hash(intern, props TSRMLS_CC);
} /* }}} */
/* {{{ proto string MongoDB\BSON\UTCDateTime::__toString()
Returns the UTCDateTime's milliseconds as a string */
static PHP_METHOD(UTCDateTime, __toString)
{
php_phongo_utcdatetime_t* intern;
intern = Z_UTCDATETIME_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
ZVAL_INT64_STRING(return_value, intern->milliseconds);
} /* }}} */
/* {{{ proto DateTime MongoDB\BSON\UTCDateTime::toDateTime()
Returns a DateTime object representing this UTCDateTime */
static PHP_METHOD(UTCDateTime, toDateTime)
{
php_phongo_utcdatetime_t* intern;
php_date_obj* datetime_obj;
char* sec;
size_t sec_len;
intern = Z_UTCDATETIME_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
object_init_ex(return_value, php_date_get_date_ce());
datetime_obj = Z_PHPDATE_P(return_value);
sec_len = spprintf(&sec, 0, "@%" PRId64, intern->milliseconds / 1000);
php_date_initialize(datetime_obj, sec, sec_len, NULL, NULL, 0 TSRMLS_CC);
efree(sec);
#if PHP_VERSION_ID >= 70200
datetime_obj->time->us = (intern->milliseconds % 1000) * 1000;
#else
datetime_obj->time->f = (double) (intern->milliseconds % 1000) / 1000;
#endif
}
/* }}} */
/* {{{ proto array MongoDB\BSON\UTCDateTime::jsonSerialize()
*/
static PHP_METHOD(UTCDateTime, jsonSerialize)
{
php_phongo_utcdatetime_t* intern;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_UTCDATETIME_OBJ_P(getThis());
array_init_size(return_value, 1);
-#if PHP_VERSION_ID >= 70000
{
zval udt;
array_init_size(&udt, 1);
ADD_ASSOC_INT64_AS_STRING(&udt, "$numberLong", intern->milliseconds);
ADD_ASSOC_ZVAL_EX(return_value, "$date", &udt);
}
-#else
- {
- zval* udt;
-
- MAKE_STD_ZVAL(udt);
- array_init_size(udt, 1);
- ADD_ASSOC_INT64_AS_STRING(udt, "$numberLong", intern->milliseconds);
- ADD_ASSOC_ZVAL_EX(return_value, "$date", udt);
- }
-#endif
} /* }}} */
/* {{{ proto string MongoDB\BSON\UTCDateTime::serialize()
*/
static PHP_METHOD(UTCDateTime, serialize)
{
php_phongo_utcdatetime_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
intern = Z_UTCDATETIME_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 1);
ADD_ASSOC_INT64_AS_STRING(&retval, "milliseconds", intern->milliseconds);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 1);
- ADD_ASSOC_INT64_AS_STRING(retval, "milliseconds", intern->milliseconds);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\BSON\UTCDateTime::unserialize(string $serialized)
*/
static PHP_METHOD(UTCDateTime, unserialize)
{
php_phongo_utcdatetime_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
- php_unserialize_data_t var_hash;
+ size_t serialized_len;
+ zval props;
+ php_unserialize_data_t var_hash;
intern = Z_UTCDATETIME_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}
zend_restore_error_handling(&error_handling TSRMLS_CC);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
zval_ptr_dtor(&props);
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_utcdatetime_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
php_phongo_utcdatetime_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_utcdatetime_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\BSON\UTCDateTime function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime___construct, 0, 0, 0)
ZEND_ARG_INFO(0, milliseconds)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_utcdatetime_me[] = {
/* clang-format off */
PHP_ME(UTCDateTime, __construct, ai_UTCDateTime___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(UTCDateTime, __set_state, ai_UTCDateTime___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(UTCDateTime, __toString, ai_UTCDateTime_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(UTCDateTime, jsonSerialize, ai_UTCDateTime_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(UTCDateTime, serialize, ai_UTCDateTime_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(UTCDateTime, unserialize, ai_UTCDateTime_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(UTCDateTime, toDateTime, ai_UTCDateTime_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\UTCDateTime object handlers */
static zend_object_handlers php_phongo_handler_utcdatetime;
-static void php_phongo_utcdatetime_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_utcdatetime_free_object(zend_object* object TSRMLS_DC) /* {{{ */
{
php_phongo_utcdatetime_t* intern = Z_OBJ_UTCDATETIME(object);
zend_object_std_dtor(&intern->std TSRMLS_CC);
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_utcdatetime_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_utcdatetime_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
{
php_phongo_utcdatetime_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_utcdatetime_t, class_type);
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_utcdatetime;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_utcdatetime_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_utcdatetime;
-
- return retval;
- }
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_utcdatetime_clone_object(zval* object TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_utcdatetime_clone_object(zval* object TSRMLS_DC) /* {{{ */
{
- php_phongo_utcdatetime_t* intern;
- php_phongo_utcdatetime_t* new_intern;
- phongo_create_object_retval new_object;
+ php_phongo_utcdatetime_t* intern;
+ php_phongo_utcdatetime_t* new_intern;
+ zend_object* new_object;
intern = Z_UTCDATETIME_OBJ_P(object);
new_object = php_phongo_utcdatetime_create_object(Z_OBJCE_P(object) TSRMLS_CC);
-#if PHP_VERSION_ID >= 70000
new_intern = Z_OBJ_UTCDATETIME(new_object);
zend_objects_clone_members(&new_intern->std, &intern->std TSRMLS_CC);
-#else
- {
- zend_object_handle handle = Z_OBJ_HANDLE_P(object);
-
- new_intern = (php_phongo_utcdatetime_t*) zend_object_store_get_object_by_handle(new_object.handle TSRMLS_CC);
- zend_objects_clone_members(&new_intern->std, new_object, &intern->std, handle TSRMLS_CC);
- }
-#endif
php_phongo_utcdatetime_init(new_intern, intern->milliseconds);
return new_object;
} /* }}} */
static int php_phongo_utcdatetime_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
{
php_phongo_utcdatetime_t *intern1, *intern2;
intern1 = Z_UTCDATETIME_OBJ_P(o1);
intern2 = Z_UTCDATETIME_OBJ_P(o2);
if (intern1->milliseconds != intern2->milliseconds) {
return intern1->milliseconds < intern2->milliseconds ? -1 : 1;
}
return 0;
} /* }}} */
-static HashTable* php_phongo_utcdatetime_get_gc(zval* object, phongo_get_gc_table table, int* n TSRMLS_DC) /* {{{ */
-{
- *table = NULL;
- *n = 0;
-
- return Z_UTCDATETIME_OBJ_P(object)->properties;
-} /* }}} */
-
static HashTable* php_phongo_utcdatetime_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
{
php_phongo_utcdatetime_t* intern;
HashTable* props;
intern = Z_UTCDATETIME_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 1);
if (!intern->initialized) {
return props;
}
-#if PHP_VERSION_ID >= 70000
{
zval milliseconds;
ZVAL_INT64_STRING(&milliseconds, intern->milliseconds);
zend_hash_str_update(props, "milliseconds", sizeof("milliseconds") - 1, &milliseconds);
}
-#else
- {
- zval* milliseconds;
-
- MAKE_STD_ZVAL(milliseconds);
- ZVAL_INT64_STRING(milliseconds, intern->milliseconds);
- zend_hash_update(props, "milliseconds", sizeof("milliseconds"), &milliseconds, sizeof(milliseconds), NULL);
- }
-#endif
return props;
} /* }}} */
static HashTable* php_phongo_utcdatetime_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
{
*is_temp = 1;
return php_phongo_utcdatetime_get_properties_hash(object, true TSRMLS_CC);
} /* }}} */
static HashTable* php_phongo_utcdatetime_get_properties(zval* object TSRMLS_DC) /* {{{ */
{
return php_phongo_utcdatetime_get_properties_hash(object, false TSRMLS_CC);
} /* }}} */
/* }}} */
void php_phongo_utcdatetime_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "UTCDateTime", php_phongo_utcdatetime_me);
php_phongo_utcdatetime_ce = zend_register_internal_class(&ce TSRMLS_CC);
php_phongo_utcdatetime_ce->create_object = php_phongo_utcdatetime_create_object;
PHONGO_CE_FINAL(php_phongo_utcdatetime_ce);
zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, php_phongo_utcdatetime_interface_ce);
zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, php_phongo_type_ce);
zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_utcdatetime, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_utcdatetime.clone_obj = php_phongo_utcdatetime_clone_object;
php_phongo_handler_utcdatetime.compare_objects = php_phongo_utcdatetime_compare_objects;
php_phongo_handler_utcdatetime.get_debug_info = php_phongo_utcdatetime_get_debug_info;
- php_phongo_handler_utcdatetime.get_gc = php_phongo_utcdatetime_get_gc;
php_phongo_handler_utcdatetime.get_properties = php_phongo_utcdatetime_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_utcdatetime.free_obj = php_phongo_utcdatetime_free_object;
- php_phongo_handler_utcdatetime.offset = XtOffsetOf(php_phongo_utcdatetime_t, std);
-#endif
+ php_phongo_handler_utcdatetime.free_obj = php_phongo_utcdatetime_free_object;
+ php_phongo_handler_utcdatetime.offset = XtOffsetOf(php_phongo_utcdatetime_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/UTCDateTimeInterface.c b/mongodb-1.8.1/src/BSON/UTCDateTimeInterface.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/UTCDateTimeInterface.c
rename to mongodb-1.8.1/src/BSON/UTCDateTimeInterface.c
index fbcddd02..0b077e14 100644
--- a/mongodb-1.7.4/src/BSON/UTCDateTimeInterface.c
+++ b/mongodb-1.8.1/src/BSON/UTCDateTimeInterface.c
@@ -1,56 +1,56 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_utcdatetime_interface_ce;
/* {{{ MongoDB\BSON\UTCDateTimeInterface function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTimeInterface_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_utcdatetime_interface_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(UTCDateTimeInterface, toDateTime, ai_UTCDateTimeInterface_void)
ZEND_ABSTRACT_ME(UTCDateTimeInterface, __toString, ai_UTCDateTimeInterface_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_utcdatetime_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "UTCDateTimeInterface", php_phongo_utcdatetime_interface_me);
- php_phongo_utcdatetime_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_utcdatetime_interface_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Undefined.c b/mongodb-1.8.1/src/BSON/Undefined.c
similarity index 69%
rename from mongodb-1.7.4/src/BSON/Undefined.c
rename to mongodb-1.8.1/src/BSON/Undefined.c
index 5fa337cc..7f76e6b9 100644
--- a/mongodb-1.7.4/src/BSON/Undefined.c
+++ b/mongodb-1.8.1/src/BSON/Undefined.c
@@ -1,166 +1,146 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_undefined_ce;
/* {{{ proto string MongoDB\BSON\Undefined::__toString()
Return the empty string. */
static PHP_METHOD(Undefined, __toString)
{
- PHONGO_RETURN_STRINGL("", 0);
+ RETURN_STRINGL("", 0);
} /* }}} */
/* {{{ proto array MongoDB\BSON\Undefined::jsonSerialize()
*/
static PHP_METHOD(Undefined, jsonSerialize)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
array_init_size(return_value, 1);
ADD_ASSOC_BOOL_EX(return_value, "$undefined", 1);
} /* }}} */
/* {{{ proto string MongoDB\BSON\Undefined::serialize()
*/
static PHP_METHOD(Undefined, serialize)
{
- PHONGO_RETURN_STRING("");
+ RETURN_STRING("");
} /* }}} */
/* {{{ proto void MongoDB\BSON\Undefined::unserialize(string $serialized)
*/
static PHP_METHOD(Undefined, unserialize)
{
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
+ size_t serialized_len;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
} /* }}} */
/* {{{ MongoDB\BSON\Undefined function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Undefined_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Undefined_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_undefined_me[] = {
/* clang-format off */
/* __set_state intentionally missing */
PHP_ME(Undefined, __toString, ai_Undefined_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Undefined, jsonSerialize, ai_Undefined_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Undefined, serialize, ai_Undefined_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Undefined, unserialize, ai_Undefined_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Undefined_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\BSON\Undefined object handlers */
static zend_object_handlers php_phongo_handler_undefined;
-static void php_phongo_undefined_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_undefined_free_object(zend_object* object) /* {{{ */
{
php_phongo_undefined_t* intern = Z_OBJ_UNDEFINED(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
+ zend_object_std_dtor(&intern->std);
} /* }}} */
-static phongo_create_object_retval php_phongo_undefined_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_undefined_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_undefined_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_undefined_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_undefined;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_undefined_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_undefined;
-
- return retval;
- }
-#endif
} /* }}} */
/* }}} */
void php_phongo_undefined_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Undefined", php_phongo_undefined_me);
- php_phongo_undefined_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_undefined_ce = zend_register_internal_class(&ce);
php_phongo_undefined_ce->create_object = php_phongo_undefined_create_object;
PHONGO_CE_FINAL(php_phongo_undefined_ce);
- zend_class_implements(php_phongo_undefined_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce);
- zend_class_implements(php_phongo_undefined_ce TSRMLS_CC, 1, php_phongo_type_ce);
- zend_class_implements(php_phongo_undefined_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_undefined_ce, 1, php_phongo_json_serializable_ce);
+ zend_class_implements(php_phongo_undefined_ce, 1, php_phongo_type_ce);
+ zend_class_implements(php_phongo_undefined_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_undefined, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
/* Re-assign default handler previously removed in php_phongo.c */
php_phongo_handler_undefined.clone_obj = zend_objects_clone_obj;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_undefined.free_obj = php_phongo_undefined_free_object;
- php_phongo_handler_undefined.offset = XtOffsetOf(php_phongo_undefined_t, std);
-#endif
+ php_phongo_handler_undefined.free_obj = php_phongo_undefined_free_object;
+ php_phongo_handler_undefined.offset = XtOffsetOf(php_phongo_undefined_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/Unserializable.c b/mongodb-1.8.1/src/BSON/Unserializable.c
similarity index 98%
rename from mongodb-1.7.4/src/BSON/Unserializable.c
rename to mongodb-1.8.1/src/BSON/Unserializable.c
index 21a96dca..3da37d8e 100644
--- a/mongodb-1.7.4/src/BSON/Unserializable.c
+++ b/mongodb-1.8.1/src/BSON/Unserializable.c
@@ -1,56 +1,56 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_unserializable_ce;
/* {{{ MongoDB\BSON\Unserializable function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Unserializable_bsonUnserialize, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, data, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_unserializable_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(Unserializable, bsonUnserialize, ai_Unserializable_bsonUnserialize)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_unserializable_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Unserializable", php_phongo_unserializable_me);
- php_phongo_unserializable_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_unserializable_ce = zend_register_internal_interface(&ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/functions.c b/mongodb-1.8.1/src/BSON/functions.c
similarity index 69%
rename from mongodb-1.7.4/src/BSON/functions.c
rename to mongodb-1.8.1/src/BSON/functions.c
index fe17ddf3..02ae6ecd 100644
--- a/mongodb-1.7.4/src/BSON/functions.c
+++ b/mongodb-1.8.1/src/BSON/functions.c
@@ -1,181 +1,177 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
typedef enum {
PHONGO_JSON_MODE_LEGACY,
PHONGO_JSON_MODE_CANONICAL,
PHONGO_JSON_MODE_RELAXED,
} php_phongo_json_mode_t;
/* {{{ proto string MongoDB\BSON\fromPHP(array|object $value)
Returns the BSON representation of a PHP value */
PHP_FUNCTION(MongoDB_BSON_fromPHP)
{
zval* data;
bson_t* bson;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A", &data) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "A", &data) == FAILURE) {
return;
}
bson = bson_new();
- php_phongo_zval_to_bson(data, PHONGO_BSON_NONE, bson, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(data, PHONGO_BSON_NONE, bson, NULL);
- PHONGO_RETVAL_STRINGL((const char*) bson_get_data(bson), bson->len);
+ RETVAL_STRINGL((const char*) bson_get_data(bson), bson->len);
bson_destroy(bson);
} /* }}} */
/* {{{ proto array|object MongoDB\BSON\toPHP(string $bson [, array $typemap = array()])
Returns the PHP representation of a BSON value, optionally converting it into a custom class */
PHP_FUNCTION(MongoDB_BSON_toPHP)
{
char* data;
- phongo_zpp_char_len data_len;
+ size_t data_len;
zval* typemap = NULL;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a!", &data, &data_len, &typemap) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|a!", &data, &data_len, &typemap) == FAILURE) {
return;
}
- if (!php_phongo_bson_typemap_to_state(typemap, &state.map TSRMLS_CC)) {
+ if (!php_phongo_bson_typemap_to_state(typemap, &state.map)) {
return;
}
if (!php_phongo_bson_to_zval_ex((const unsigned char*) data, data_len, &state)) {
zval_ptr_dtor(&state.zchild);
php_phongo_bson_typemap_dtor(&state.map);
RETURN_NULL();
}
php_phongo_bson_typemap_dtor(&state.map);
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
} /* }}} */
/* {{{ proto string MongoDB\BSON\fromJSON(string $json)
Returns the BSON representation of a JSON value */
PHP_FUNCTION(MongoDB_BSON_fromJSON)
{
- char* json;
- phongo_zpp_char_len json_len;
- bson_t bson = BSON_INITIALIZER;
- bson_error_t error = { 0 };
+ char* json;
+ size_t json_len;
+ bson_t bson = BSON_INITIALIZER;
+ bson_error_t error = { 0 };
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &json, &json_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &json, &json_len) == FAILURE) {
return;
}
if (bson_init_from_json(&bson, (const char*) json, json_len, &error)) {
- PHONGO_RETVAL_STRINGL((const char*) bson_get_data(&bson), bson.len);
+ RETVAL_STRINGL((const char*) bson_get_data(&bson), bson.len);
bson_destroy(&bson);
} else {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s", error.domain == BSON_ERROR_JSON ? error.message : "Error parsing JSON");
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s", error.domain == BSON_ERROR_JSON ? error.message : "Error parsing JSON");
}
} /* }}} */
static void phongo_bson_to_json(INTERNAL_FUNCTION_PARAMETERS, php_phongo_json_mode_t mode)
{
- char* data;
- phongo_zpp_char_len data_len;
- const bson_t* bson;
- bool eof = false;
- bson_reader_t* reader;
- char* json = NULL;
- size_t json_len;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == FAILURE) {
+ char* data;
+ size_t data_len;
+ const bson_t* bson;
+ bool eof = false;
+ bson_reader_t* reader;
+ char* json = NULL;
+ size_t json_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data, &data_len) == FAILURE) {
return;
}
reader = bson_reader_new_from_data((const unsigned char*) data, data_len);
bson = bson_reader_read(reader, NULL);
if (!bson) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not read document from BSON reader");
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Could not read document from BSON reader");
bson_reader_destroy(reader);
return;
}
if (mode == PHONGO_JSON_MODE_LEGACY) {
json = bson_as_json(bson, &json_len);
} else if (mode == PHONGO_JSON_MODE_CANONICAL) {
json = bson_as_canonical_extended_json(bson, &json_len);
} else if (mode == PHONGO_JSON_MODE_RELAXED) {
json = bson_as_relaxed_extended_json(bson, &json_len);
}
if (!json) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not convert BSON document to a JSON string");
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Could not convert BSON document to a JSON string");
bson_reader_destroy(reader);
return;
}
- PHONGO_RETVAL_STRINGL(json, json_len);
+ RETVAL_STRINGL(json, json_len);
bson_free(json);
if (bson_reader_read(reader, &eof) || !eof) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Reading document did not exhaust input buffer");
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Reading document did not exhaust input buffer");
}
bson_reader_destroy(reader);
} /* }}} */
/* {{{ proto string MongoDB\BSON\toJSON(string $bson)
Returns the legacy extended JSON representation of a BSON value */
PHP_FUNCTION(MongoDB_BSON_toJSON)
{
phongo_bson_to_json(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHONGO_JSON_MODE_LEGACY);
} /* }}} */
/* {{{ proto string MongoDB\BSON\toCanonicalExtendedJSON(string $bson)
Returns the canonical extended JSON representation of a BSON value */
PHP_FUNCTION(MongoDB_BSON_toCanonicalExtendedJSON)
{
phongo_bson_to_json(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHONGO_JSON_MODE_CANONICAL);
} /* }}} */
/* {{{ proto string MongoDB\BSON\toRelaxedExtendedJSON(string $bson)
Returns the relaxed extended JSON representation of a BSON value */
PHP_FUNCTION(MongoDB_BSON_toRelaxedExtendedJSON)
{
phongo_bson_to_json(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHONGO_JSON_MODE_RELAXED);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/BSON/functions.h b/mongodb-1.8.1/src/BSON/functions.h
similarity index 100%
rename from mongodb-1.7.4/src/BSON/functions.h
rename to mongodb-1.8.1/src/BSON/functions.h
diff --git a/mongodb-1.8.1/src/LIBMONGOCRYPT_VERSION_CURRENT b/mongodb-1.8.1/src/LIBMONGOCRYPT_VERSION_CURRENT
new file mode 100644
index 00000000..ee90284c
--- /dev/null
+++ b/mongodb-1.8.1/src/LIBMONGOCRYPT_VERSION_CURRENT
@@ -0,0 +1 @@
+1.0.4
diff --git a/mongodb-1.8.1/src/LIBMONGOC_VERSION_CURRENT b/mongodb-1.8.1/src/LIBMONGOC_VERSION_CURRENT
new file mode 100644
index 00000000..092afa15
--- /dev/null
+++ b/mongodb-1.8.1/src/LIBMONGOC_VERSION_CURRENT
@@ -0,0 +1 @@
+1.17.0
diff --git a/mongodb-1.7.4/src/MongoDB/BulkWrite.c b/mongodb-1.8.1/src/MongoDB/BulkWrite.c
similarity index 77%
rename from mongodb-1.7.4/src/MongoDB/BulkWrite.c
rename to mongodb-1.8.1/src/MongoDB/BulkWrite.c
index 26493fac..89e3e230 100644
--- a/mongodb-1.7.4/src/MongoDB/BulkWrite.c
+++ b/mongodb-1.8.1/src/MongoDB/BulkWrite.c
@@ -1,679 +1,655 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_array_api.h"
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
#define PHONGO_BULKWRITE_BYPASS_UNSET -1
zend_class_entry* php_phongo_bulkwrite_ce;
/* Extracts the "_id" field of a BSON document into a return value. */
static void php_phongo_bulkwrite_extract_id(bson_t* doc, zval** return_value) /* {{{ */
{
zval* id = NULL;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &state)) {
goto cleanup;
}
-#if PHP_VERSION_ID >= 70000
id = php_array_fetchc(&state.zchild, "_id");
-#else
- id = php_array_fetchc(state.zchild, "_id");
-#endif
if (id) {
ZVAL_ZVAL(*return_value, id, 1, 0);
}
cleanup:
zval_ptr_dtor(&state.zchild);
} /* }}} */
/* Returns whether any top-level field names in the document contain a "$". */
static inline bool php_phongo_bulkwrite_update_has_operators(bson_t* bupdate) /* {{{ */
{
bson_iter_t iter;
if (bson_iter_init(&iter, bupdate)) {
while (bson_iter_next(&iter)) {
if (strchr(bson_iter_key(&iter), '$')) {
return true;
}
}
}
return false;
} /* }}} */
/* Returns whether the update document is considered an aggregation pipeline */
static inline bool php_phongo_bulkwrite_update_is_pipeline(bson_t* bupdate) /* {{{ */
{
bson_iter_t iter;
bson_iter_t child;
const char* key;
int i = 0;
char* i_str;
if (!bson_iter_init(&iter, bupdate)) {
return false;
}
while (bson_iter_next(&iter)) {
key = bson_iter_key(&iter);
i_str = bson_strdup_printf("%d", i++);
if (strcmp(key, i_str)) {
bson_free(i_str);
return false;
}
bson_free(i_str);
if (BSON_ITER_HOLDS_DOCUMENT(&iter)) {
if (!bson_iter_recurse(&iter, &child)) {
return false;
}
if (!bson_iter_next(&child)) {
return false;
}
key = bson_iter_key(&child);
if (key[0] != '$') {
return false;
}
} else {
return false;
}
}
/* should return false when the document is empty */
return i != 0;
} /* }}} */
/* Returns whether the BSON array's keys are a sequence of integer strings
* starting with "0". BSON_APPEND_ARRAY considers it the caller's responsibility
* to ensure that the array's keys are properly formatted. */
static inline bool php_phongo_bulkwrite_bson_array_has_valid_keys(bson_t* array) /* {{{ */
{
bson_iter_t iter;
if (bson_empty(array)) {
return true;
}
if (bson_iter_init(&iter, array)) {
char key[12];
int count = 0;
while (bson_iter_next(&iter)) {
bson_snprintf(key, sizeof(key), "%d", count);
if (0 != strcmp(key, bson_iter_key(&iter))) {
return false;
}
count++;
}
}
return true;
} /* }}} */
/* Appends an array field for the given opts document and key. Returns true on
* success; otherwise, false is returned and an exception is thrown. */
-static bool php_phongo_bulkwrite_opts_append_array(bson_t* opts, const char* key, zval* zarr TSRMLS_DC) /* {{{ */
+static bool php_phongo_bulkwrite_opts_append_array(bson_t* opts, const char* key, zval* zarr) /* {{{ */
{
zval* value = php_array_fetch(zarr, key);
bson_t b = BSON_INITIALIZER;
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" option to be array or object, %s given", key, zend_get_type_by_const(Z_TYPE_P(value)));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" option to be array or object, %s given", key, zend_get_type_by_const(Z_TYPE_P(value)));
return false;
}
- php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL);
if (EG(exception)) {
bson_destroy(&b);
return false;
}
if (!php_phongo_bulkwrite_bson_array_has_valid_keys(&b)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"%s\" option has invalid keys for a BSON array", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"%s\" option has invalid keys for a BSON array", key);
bson_destroy(&b);
return false;
}
if (!BSON_APPEND_ARRAY(opts, key, &b)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", key);
bson_destroy(&b);
return false;
}
bson_destroy(&b);
return true;
} /* }}} */
/* Appends a document field for the given opts document and key. Returns true on
* success; otherwise, false is returned and an exception is thrown. */
-static bool php_phongo_bulkwrite_opts_append_document(bson_t* opts, const char* key, zval* zarr TSRMLS_DC) /* {{{ */
+static bool php_phongo_bulkwrite_opts_append_document(bson_t* opts, const char* key, zval* zarr) /* {{{ */
{
zval* value = php_array_fetch(zarr, key);
bson_t b = BSON_INITIALIZER;
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" option to be array or object, %s given", key, zend_get_type_by_const(Z_TYPE_P(value)));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" option to be array or object, %s given", key, zend_get_type_by_const(Z_TYPE_P(value)));
return false;
}
- php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL);
if (EG(exception)) {
bson_destroy(&b);
return false;
}
if (!BSON_APPEND_DOCUMENT(opts, key, &b)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", key);
bson_destroy(&b);
return false;
}
bson_destroy(&b);
return true;
} /* }}} */
-#define PHONGO_BULKWRITE_APPEND_BOOL(opt, value) \
- if (!BSON_APPEND_BOOL(boptions, (opt), (value))) { \
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", (opt)); \
- return false; \
+#define PHONGO_BULKWRITE_APPEND_BOOL(opt, value) \
+ if (!BSON_APPEND_BOOL(boptions, (opt), (value))) { \
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
+ return false; \
}
-#define PHONGO_BULKWRITE_APPEND_INT32(opt, value) \
- if (!BSON_APPEND_INT32(boptions, (opt), (value))) { \
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", (opt)); \
- return false; \
+#define PHONGO_BULKWRITE_APPEND_INT32(opt, value) \
+ if (!BSON_APPEND_INT32(boptions, (opt), (value))) { \
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
+ return false; \
}
-#define PHONGO_BULKWRITE_OPT_ARRAY(opt) \
- if (zoptions && php_array_existsc(zoptions, (opt))) { \
- if (!php_phongo_bulkwrite_opts_append_array(boptions, (opt), zoptions TSRMLS_CC)) { \
- return false; \
- } \
+#define PHONGO_BULKWRITE_OPT_ARRAY(opt) \
+ if (zoptions && php_array_existsc(zoptions, (opt))) { \
+ if (!php_phongo_bulkwrite_opts_append_array(boptions, (opt), zoptions)) { \
+ return false; \
+ } \
}
-#define PHONGO_BULKWRITE_OPT_DOCUMENT(opt) \
- if (zoptions && php_array_existsc(zoptions, (opt))) { \
- if (!php_phongo_bulkwrite_opts_append_document(boptions, (opt), zoptions TSRMLS_CC)) { \
- return false; \
- } \
+#define PHONGO_BULKWRITE_OPT_DOCUMENT(opt) \
+ if (zoptions && php_array_existsc(zoptions, (opt))) { \
+ if (!php_phongo_bulkwrite_opts_append_document(boptions, (opt), zoptions)) { \
+ return false; \
+ } \
}
/* Initialize the "hint" option. Returns true on success; otherwise, false is
* returned and an exception is thrown.
*
* The "hint" option must be a string or document. Check for both types and
* merge into BSON options accordingly. */
-static bool php_phongo_bulkwrite_opt_hint(bson_t* boptions, zval* zoptions TSRMLS_DC) /* {{{ */
+static bool php_phongo_bulkwrite_opt_hint(bson_t* boptions, zval* zoptions) /* {{{ */
{
/* The "hint" option (or "$hint" modifier) must be a string or document.
* Check for both types and merge into BSON options accordingly. */
if (zoptions && php_array_existsc(zoptions, "hint")) {
zend_uchar type = Z_TYPE_P(php_array_fetchc(zoptions, "hint"));
if (type == IS_STRING) {
zval* value = php_array_fetchc(zoptions, "hint");
if (!bson_append_utf8(boptions, "hint", 4, Z_STRVAL_P(value), Z_STRLEN_P(value))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"hint\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"hint\" option");
return false;
}
} else if (type == IS_OBJECT || type == IS_ARRAY) {
PHONGO_BULKWRITE_OPT_DOCUMENT("hint");
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(type));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(type));
return false;
}
}
return true;
} /* }}} */
/* Applies options (including defaults) for an update operation. */
-static bool php_phongo_bulkwrite_update_apply_options(bson_t* boptions, zval* zoptions TSRMLS_DC) /* {{{ */
+static bool php_phongo_bulkwrite_update_apply_options(bson_t* boptions, zval* zoptions) /* {{{ */
{
bool multi = false, upsert = false;
if (zoptions) {
multi = php_array_fetchc_bool(zoptions, "multi");
upsert = php_array_fetchc_bool(zoptions, "upsert");
}
PHONGO_BULKWRITE_APPEND_BOOL("multi", multi);
PHONGO_BULKWRITE_APPEND_BOOL("upsert", upsert);
PHONGO_BULKWRITE_OPT_ARRAY("arrayFilters");
PHONGO_BULKWRITE_OPT_DOCUMENT("collation");
- if (!php_phongo_bulkwrite_opt_hint(boptions, zoptions TSRMLS_CC)) {
+ if (!php_phongo_bulkwrite_opt_hint(boptions, zoptions)) {
return false;
}
return true;
} /* }}} */
/* Applies options (including defaults) for an delete operation. */
-static bool php_phongo_bulkwrite_delete_apply_options(bson_t* boptions, zval* zoptions TSRMLS_DC) /* {{{ */
+static bool php_phongo_bulkwrite_delete_apply_options(bson_t* boptions, zval* zoptions) /* {{{ */
{
int32_t limit = 0;
if (zoptions) {
limit = php_array_fetchc_bool(zoptions, "limit") ? 1 : 0;
}
PHONGO_BULKWRITE_APPEND_INT32("limit", limit);
PHONGO_BULKWRITE_OPT_DOCUMENT("collation");
+ if (!php_phongo_bulkwrite_opt_hint(boptions, zoptions)) {
+ return false;
+ }
+
return true;
} /* }}} */
#undef PHONGO_BULKWRITE_APPEND_BOOL
#undef PHONGO_BULKWRITE_APPEND_INT32
#undef PHONGO_BULKWRITE_OPT_DOCUMENT
/* {{{ proto void MongoDB\Driver\BulkWrite::__construct([array $options = array()])
Constructs a new BulkWrite */
static PHP_METHOD(BulkWrite, __construct)
{
php_phongo_bulkwrite_t* intern;
zend_error_handling error_handling;
zval* options = NULL;
zend_bool ordered = 1;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_BULKWRITE_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &options) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &options) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
if (options && php_array_existsc(options, "ordered")) {
ordered = php_array_fetchc_bool(options, "ordered");
}
intern->bulk = mongoc_bulk_operation_new(ordered);
intern->ordered = ordered;
intern->bypass = PHONGO_BULKWRITE_BYPASS_UNSET;
intern->num_ops = 0;
intern->executed = false;
if (options && php_array_existsc(options, "bypassDocumentValidation")) {
zend_bool bypass = php_array_fetchc_bool(options, "bypassDocumentValidation");
mongoc_bulk_operation_set_bypass_document_validation(intern->bulk, bypass);
intern->bypass = bypass;
}
} /* }}} */
/* {{{ proto mixed MongoDB\Driver\BulkWrite::insert(array|object $document)
Adds an insert operation to the BulkWrite */
static PHP_METHOD(BulkWrite, insert)
{
php_phongo_bulkwrite_t* intern;
zval* zdocument;
bson_t bdocument = BSON_INITIALIZER, boptions = BSON_INITIALIZER;
bson_t* bson_out = NULL;
int bson_flags = PHONGO_BSON_ADD_ID;
bson_error_t error = { 0 };
- DECLARE_RETURN_VALUE_USED
intern = Z_BULKWRITE_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A", &zdocument) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "A", &zdocument) == FAILURE) {
return;
}
- if (return_value_used) {
- bson_flags |= PHONGO_BSON_RETURN_ID;
- }
+ bson_flags |= PHONGO_BSON_RETURN_ID;
- php_phongo_zval_to_bson(zdocument, bson_flags, &bdocument, &bson_out TSRMLS_CC);
+ php_phongo_zval_to_bson(zdocument, bson_flags, &bdocument, &bson_out);
if (EG(exception)) {
goto cleanup;
}
if (!mongoc_bulk_operation_insert_with_opts(intern->bulk, &bdocument, &boptions, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
intern->num_ops++;
- if (bson_out && return_value_used) {
- php_phongo_bulkwrite_extract_id(bson_out, &return_value);
+ if (!bson_out) {
+ phongo_throw_exception(PHONGO_ERROR_LOGIC, "Did not receive result from bulk write. Please file a bug report.");
+ goto cleanup;
}
+ php_phongo_bulkwrite_extract_id(bson_out, &return_value);
+
cleanup:
bson_destroy(&bdocument);
bson_destroy(&boptions);
bson_clear(&bson_out);
} /* }}} */
/* {{{ proto void MongoDB\Driver\BulkWrite::update(array|object $query, array|object $newObj[, array $updateOptions = array()])
Adds an update operation to the BulkWrite */
static PHP_METHOD(BulkWrite, update)
{
php_phongo_bulkwrite_t* intern;
zval * zquery, *zupdate, *zoptions = NULL;
bson_t bquery = BSON_INITIALIZER, bupdate = BSON_INITIALIZER, boptions = BSON_INITIALIZER;
bson_error_t error = { 0 };
intern = Z_BULKWRITE_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "AA|a!", &zquery, &zupdate, &zoptions) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "AA|a!", &zquery, &zupdate, &zoptions) == FAILURE) {
return;
}
- php_phongo_zval_to_bson(zquery, PHONGO_BSON_NONE, &bquery, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(zquery, PHONGO_BSON_NONE, &bquery, NULL);
if (EG(exception)) {
goto cleanup;
}
- php_phongo_zval_to_bson(zupdate, PHONGO_BSON_NONE, &bupdate, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(zupdate, PHONGO_BSON_NONE, &bupdate, NULL);
if (EG(exception)) {
goto cleanup;
}
- if (!php_phongo_bulkwrite_update_apply_options(&boptions, zoptions TSRMLS_CC)) {
+ if (!php_phongo_bulkwrite_update_apply_options(&boptions, zoptions)) {
goto cleanup;
}
if (php_phongo_bulkwrite_update_has_operators(&bupdate) || php_phongo_bulkwrite_update_is_pipeline(&bupdate)) {
if (zoptions && php_array_fetchc_bool(zoptions, "multi")) {
if (!mongoc_bulk_operation_update_many_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
} else {
if (!mongoc_bulk_operation_update_one_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
}
} else {
if (zoptions && php_array_fetchc_bool(zoptions, "multi")) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Replacement document conflicts with true \"multi\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Replacement document conflicts with true \"multi\" option");
goto cleanup;
}
if (!mongoc_bulk_operation_replace_one_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
}
intern->num_ops++;
cleanup:
bson_destroy(&bquery);
bson_destroy(&bupdate);
bson_destroy(&boptions);
} /* }}} */
/* {{{ proto void MongoDB\Driver\BulkWrite::delete(array|object $query[, array $deleteOptions = array()])
Adds a delete operation to the BulkWrite */
static PHP_METHOD(BulkWrite, delete)
{
php_phongo_bulkwrite_t* intern;
zval * zquery, *zoptions = NULL;
bson_t bquery = BSON_INITIALIZER, boptions = BSON_INITIALIZER;
bson_error_t error = { 0 };
intern = Z_BULKWRITE_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A|a!", &zquery, &zoptions) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "A|a!", &zquery, &zoptions) == FAILURE) {
return;
}
- php_phongo_zval_to_bson(zquery, PHONGO_BSON_NONE, &bquery, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(zquery, PHONGO_BSON_NONE, &bquery, NULL);
if (EG(exception)) {
goto cleanup;
}
- if (!php_phongo_bulkwrite_delete_apply_options(&boptions, zoptions TSRMLS_CC)) {
+ if (!php_phongo_bulkwrite_delete_apply_options(&boptions, zoptions)) {
goto cleanup;
}
if (zoptions && php_array_fetchc_bool(zoptions, "limit")) {
if (!mongoc_bulk_operation_remove_one_with_opts(intern->bulk, &bquery, &boptions, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
} else {
if (!mongoc_bulk_operation_remove_many_with_opts(intern->bulk, &bquery, &boptions, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
}
intern->num_ops++;
cleanup:
bson_destroy(&bquery);
bson_destroy(&boptions);
} /* }}} */
/* {{{ proto integer MongoDB\Driver\BulkWrite::count()
Returns the number of operations that have been added to the BulkWrite */
static PHP_METHOD(BulkWrite, count)
{
php_phongo_bulkwrite_t* intern;
intern = Z_BULKWRITE_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(intern->num_ops);
} /* }}} */
/* {{{ MongoDB\Driver\BulkWrite function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite___construct, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_insert, 0, 0, 1)
ZEND_ARG_INFO(0, document)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_update, 0, 0, 2)
ZEND_ARG_INFO(0, query)
ZEND_ARG_INFO(0, newObj)
ZEND_ARG_ARRAY_INFO(0, updateOptions, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_delete, 0, 0, 1)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, deleteOptions, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_bulkwrite_me[] = {
/* clang-format off */
PHP_ME(BulkWrite, __construct, ai_BulkWrite___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(BulkWrite, insert, ai_BulkWrite_insert, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(BulkWrite, update, ai_BulkWrite_update, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(BulkWrite, delete, ai_BulkWrite_delete, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(BulkWrite, count, ai_BulkWrite_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_BulkWrite_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\BulkWrite object handlers */
static zend_object_handlers php_phongo_handler_bulkwrite;
-static void php_phongo_bulkwrite_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_bulkwrite_free_object(zend_object* object) /* {{{ */
{
php_phongo_bulkwrite_t* intern = Z_OBJ_BULKWRITE(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->bulk) {
mongoc_bulk_operation_destroy(intern->bulk);
}
if (intern->database) {
efree(intern->database);
}
if (intern->collection) {
efree(intern->collection);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_bulkwrite_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_bulkwrite_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_bulkwrite_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_bulkwrite_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_bulkwrite;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_bulkwrite_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_bulkwrite;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_bulkwrite_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_bulkwrite_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
zval retval = ZVAL_STATIC_INIT;
php_phongo_bulkwrite_t* intern = NULL;
*is_temp = 1;
intern = Z_BULKWRITE_OBJ_P(object);
array_init(&retval);
if (intern->database) {
ADD_ASSOC_STRING(&retval, "database", intern->database);
} else {
ADD_ASSOC_NULL_EX(&retval, "database");
}
if (intern->collection) {
ADD_ASSOC_STRING(&retval, "collection", intern->collection);
} else {
ADD_ASSOC_NULL_EX(&retval, "collection");
}
ADD_ASSOC_BOOL_EX(&retval, "ordered", intern->ordered);
if (intern->bypass != PHONGO_BULKWRITE_BYPASS_UNSET) {
ADD_ASSOC_BOOL_EX(&retval, "bypassDocumentValidation", intern->bypass);
} else {
ADD_ASSOC_NULL_EX(&retval, "bypassDocumentValidation");
}
ADD_ASSOC_BOOL_EX(&retval, "executed", intern->executed);
ADD_ASSOC_LONG_EX(&retval, "server_id", mongoc_bulk_operation_get_hint(intern->bulk));
if (mongoc_bulk_operation_get_write_concern(intern->bulk)) {
-#if PHP_VERSION_ID >= 70000
zval write_concern;
php_phongo_write_concern_to_zval(&write_concern, mongoc_bulk_operation_get_write_concern(intern->bulk));
ADD_ASSOC_ZVAL_EX(&retval, "write_concern", &write_concern);
-#else
- zval* write_concern = NULL;
- MAKE_STD_ZVAL(write_concern);
-
- php_phongo_write_concern_to_zval(write_concern, mongoc_bulk_operation_get_write_concern(intern->bulk));
- ADD_ASSOC_ZVAL_EX(&retval, "write_concern", write_concern);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "write_concern");
}
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "BulkWrite", php_phongo_bulkwrite_me);
- php_phongo_bulkwrite_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_bulkwrite_ce = zend_register_internal_class(&ce);
php_phongo_bulkwrite_ce->create_object = php_phongo_bulkwrite_create_object;
PHONGO_CE_FINAL(php_phongo_bulkwrite_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_bulkwrite_ce);
memcpy(&php_phongo_handler_bulkwrite, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_bulkwrite.get_debug_info = php_phongo_bulkwrite_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_bulkwrite.free_obj = php_phongo_bulkwrite_free_object;
- php_phongo_handler_bulkwrite.offset = XtOffsetOf(php_phongo_bulkwrite_t, std);
-#endif
+ php_phongo_handler_bulkwrite.free_obj = php_phongo_bulkwrite_free_object;
+ php_phongo_handler_bulkwrite.offset = XtOffsetOf(php_phongo_bulkwrite_t, std);
- zend_class_implements(php_phongo_bulkwrite_ce TSRMLS_CC, 1, spl_ce_Countable);
+ zend_class_implements(php_phongo_bulkwrite_ce, 1, spl_ce_Countable);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/ClientEncryption.c b/mongodb-1.8.1/src/MongoDB/ClientEncryption.c
similarity index 73%
rename from mongodb-1.7.4/src/MongoDB/ClientEncryption.c
rename to mongodb-1.8.1/src/MongoDB/ClientEncryption.c
index 7917f63b..2b60f258 100644
--- a/mongodb-1.7.4/src/MongoDB/ClientEncryption.c
+++ b/mongodb-1.8.1/src/MongoDB/ClientEncryption.c
@@ -1,208 +1,192 @@
/*
* Copyright 2019 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_clientencryption_ce;
/* {{{ proto MongoDB\BSON\Binary MongoDB\Driver\ClientEncryption::createDataKey(string $kmsProvider[, array $options])
Creates a new key document and inserts into the key vault collection. */
static PHP_METHOD(ClientEncryption, createDataKey)
{
char* kms_provider = NULL;
- phongo_zpp_char_len kms_provider_len = 0;
+ size_t kms_provider_len = 0;
zval* options = NULL;
zend_error_handling error_handling;
php_phongo_clientencryption_t* intern;
intern = Z_CLIENTENCRYPTION_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a!", &kms_provider, &kms_provider_len, &options) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|a!", &kms_provider, &kms_provider_len, &options) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- phongo_clientencryption_create_datakey(intern, return_value, kms_provider, options TSRMLS_CC);
+ phongo_clientencryption_create_datakey(intern, return_value, kms_provider, options);
} /* }}} */
/* {{{ proto MongoDB\BSON\Binary MongoDB\Driver\ClientEncryption::encrypt(mixed $value[, array $options])
Encrypts a value with a given key and algorithm */
static PHP_METHOD(ClientEncryption, encrypt)
{
zval* value = NULL;
zval* options = NULL;
zend_error_handling error_handling;
php_phongo_clientencryption_t* intern;
intern = Z_CLIENTENCRYPTION_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a!", &value, &options) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|a!", &value, &options) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- phongo_clientencryption_encrypt(intern, value, return_value, options TSRMLS_CC);
+ phongo_clientencryption_encrypt(intern, value, return_value, options);
} /* }}} */
/* {{{ proto mixed MongoDB\Driver\ClientEncryption::decrypt(MongoDB\BSON\BinaryInterface $value)
Decrypts an encrypted value (BSON binary of subtype 6). Returns the original BSON value */
static PHP_METHOD(ClientEncryption, decrypt)
{
zval* ciphertext;
zend_error_handling error_handling;
php_phongo_clientencryption_t* intern;
intern = Z_CLIENTENCRYPTION_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &ciphertext, php_phongo_binary_interface_ce) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &ciphertext, php_phongo_binary_interface_ce) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- phongo_clientencryption_decrypt(intern, ciphertext, return_value TSRMLS_CC);
+ phongo_clientencryption_decrypt(intern, ciphertext, return_value);
} /* }}} */
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_createDataKey, 0, 0, 1)
ZEND_ARG_INFO(0, kmsProvider)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_encrypt, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_decrypt, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, keyVaultClient, MongoDB\\BSON\\BinaryInterface, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_clientencryption_me[] = {
/* clang-format off */
PHP_ME(ClientEncryption, createDataKey, ai_ClientEncryption_createDataKey, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ClientEncryption, encrypt, ai_ClientEncryption_encrypt, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ClientEncryption, decrypt, ai_ClientEncryption_decrypt, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_ClientEncryption_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_ClientEncryption_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\ClientEncryption object handlers */
static zend_object_handlers php_phongo_handler_clientencryption;
-static void php_phongo_clientencryption_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_clientencryption_free_object(zend_object* object) /* {{{ */
{
php_phongo_clientencryption_t* intern = Z_OBJ_CLIENTENCRYPTION(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->client_encryption) {
mongoc_client_encryption_destroy(intern->client_encryption);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_clientencryption_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_clientencryption_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_clientencryption_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_clientencryption_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_clientencryption;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_clientencryption_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_clientencryption;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_clientencryption_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_clientencryption_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_clientencryption_t* intern = NULL;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_CLIENTENCRYPTION_OBJ_P(object);
array_init(&retval);
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "ClientEncryption", php_phongo_clientencryption_me);
- php_phongo_clientencryption_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_clientencryption_ce = zend_register_internal_class(&ce);
php_phongo_clientencryption_ce->create_object = php_phongo_clientencryption_create_object;
PHONGO_CE_FINAL(php_phongo_clientencryption_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_clientencryption_ce);
memcpy(&php_phongo_handler_clientencryption, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_clientencryption.get_debug_info = php_phongo_clientencryption_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_clientencryption.free_obj = php_phongo_clientencryption_free_object;
- php_phongo_handler_clientencryption.offset = XtOffsetOf(php_phongo_clientencryption_t, std);
-#endif
+ php_phongo_handler_clientencryption.free_obj = php_phongo_clientencryption_free_object;
+ php_phongo_handler_clientencryption.offset = XtOffsetOf(php_phongo_clientencryption_t, std);
- zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC"), MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM"), MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM TSRMLS_CC);
+ zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC"), MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
+ zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM"), MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Command.c b/mongodb-1.8.1/src/MongoDB/Command.c
similarity index 73%
rename from mongodb-1.7.4/src/MongoDB/Command.c
rename to mongodb-1.8.1/src/MongoDB/Command.c
index f712aad4..c352dba0 100644
--- a/mongodb-1.7.4/src/MongoDB/Command.c
+++ b/mongodb-1.8.1/src/MongoDB/Command.c
@@ -1,242 +1,218 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_array_api.h"
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_command_ce;
/* Initialize the "maxAwaitTimeMS" option. Returns true on success; otherwise,
* false is returned and an exception is thrown.
*
* The "maxAwaitTimeMS" option is assigned to the cursor after query execution
* via mongoc_cursor_set_max_await_time_ms(). */
-static bool php_phongo_command_init_max_await_time_ms(php_phongo_command_t* intern, zval* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_command_init_max_await_time_ms(php_phongo_command_t* intern, zval* options) /* {{{ */
{
int64_t max_await_time_ms;
if (!php_array_existsc(options, "maxAwaitTimeMS")) {
return true;
}
max_await_time_ms = php_array_fetchc_long(options, "maxAwaitTimeMS");
if (max_await_time_ms < 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"maxAwaitTimeMS\" option to be >= 0, %" PRId64 " given", max_await_time_ms);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"maxAwaitTimeMS\" option to be >= 0, %" PRId64 " given", max_await_time_ms);
return false;
}
if (max_await_time_ms > UINT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"maxAwaitTimeMS\" option to be <= %" PRIu32 ", %" PRId64 " given", UINT32_MAX, max_await_time_ms);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"maxAwaitTimeMS\" option to be <= %" PRIu32 ", %" PRId64 " given", UINT32_MAX, max_await_time_ms);
return false;
}
intern->max_await_time_ms = (uint32_t) max_await_time_ms;
return true;
} /* }}} */
/* Initializes the php_phongo_command_init from options argument. This
* function will fall back to a modifier in the absence of a top-level option
* (where applicable). */
-static bool php_phongo_command_init(php_phongo_command_t* intern, zval* filter, zval* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_command_init(php_phongo_command_t* intern, zval* filter, zval* options) /* {{{ */
{
bson_iter_t iter;
bson_iter_t sub_iter;
intern->bson = bson_new();
intern->batch_size = 0;
intern->max_await_time_ms = 0;
- php_phongo_zval_to_bson(filter, PHONGO_BSON_NONE, intern->bson, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(filter, PHONGO_BSON_NONE, intern->bson, NULL);
/* Note: if any exceptions are thrown, we can simply return as PHP will
* invoke php_phongo_query_free_object to destruct the object. */
if (EG(exception)) {
return false;
}
if (bson_iter_init(&iter, intern->bson) && bson_iter_find_descendant(&iter, "cursor.batchSize", &sub_iter) && BSON_ITER_HOLDS_INT(&sub_iter)) {
int64_t batch_size = bson_iter_as_int64(&sub_iter);
if (batch_size >= 0 && batch_size <= UINT32_MAX) {
intern->batch_size = (uint32_t) batch_size;
}
}
if (!options) {
return true;
}
- if (!php_phongo_command_init_max_await_time_ms(intern, options TSRMLS_CC)) {
+ if (!php_phongo_command_init_max_await_time_ms(intern, options)) {
return false;
}
return true;
} /* }}} */
/* {{{ proto void MongoDB\Driver\Command::__construct(array|object $document[, array $options = array()])
Constructs a new Command */
static PHP_METHOD(Command, __construct)
{
php_phongo_command_t* intern;
zend_error_handling error_handling;
zval* document;
zval* options = NULL;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_COMMAND_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A|a!", &document, &options) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "A|a!", &document, &options) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- php_phongo_command_init(intern, document, options TSRMLS_CC);
+ php_phongo_command_init(intern, document, options);
} /* }}} */
/* {{{ MongoDB\Driver\Command function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Command___construct, 0, 0, 1)
ZEND_ARG_INFO(0, document)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Command_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_command_me[] = {
/* clang-format off */
PHP_ME(Command, __construct, ai_Command___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Command_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Command object handlers */
static zend_object_handlers php_phongo_handler_command;
-static void php_phongo_command_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_command_free_object(zend_object* object) /* {{{ */
{
php_phongo_command_t* intern = Z_OBJ_COMMAND(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->bson) {
bson_clear(&intern->bson);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_command_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_command_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_command_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_command_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_command;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_command_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_command;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_command_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_command_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_command_t* intern;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_COMMAND_OBJ_P(object);
array_init_size(&retval, 1);
if (intern->bson) {
-#if PHP_VERSION_ID >= 70000
zval zv;
-#else
- zval* zv;
-#endif
if (!php_phongo_bson_to_zval(bson_get_data(intern->bson), intern->bson->len, &zv)) {
zval_ptr_dtor(&zv);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "command", &zv);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "command", zv);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "command");
}
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_command_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Command", php_phongo_command_me);
- php_phongo_command_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_command_ce = zend_register_internal_class(&ce);
php_phongo_command_ce->create_object = php_phongo_command_create_object;
PHONGO_CE_FINAL(php_phongo_command_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_command_ce);
memcpy(&php_phongo_handler_command, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_command.get_debug_info = php_phongo_command_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_command.free_obj = php_phongo_command_free_object;
- php_phongo_handler_command.offset = XtOffsetOf(php_phongo_command_t, std);
-#endif
+ php_phongo_handler_command.free_obj = php_phongo_command_free_object;
+ php_phongo_handler_command.offset = XtOffsetOf(php_phongo_command_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Cursor.c b/mongodb-1.8.1/src/MongoDB/Cursor.c
similarity index 78%
rename from mongodb-1.7.4/src/MongoDB/Cursor.c
rename to mongodb-1.8.1/src/MongoDB/Cursor.c
index 7afbbcb5..14b00437 100644
--- a/mongodb-1.7.4/src/MongoDB/Cursor.c
+++ b/mongodb-1.8.1/src/MongoDB/Cursor.c
@@ -1,610 +1,520 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_cursor_ce;
/* Check if the cursor is exhausted (i.e. ID is zero) and free any reference to
* the session. Calling this function during iteration will allow an implicit
* session to return to the pool immediately after a getMore indicates that the
* server has no more results to return. */
static void php_phongo_cursor_free_session_if_exhausted(php_phongo_cursor_t* cursor) /* {{{ */
{
if (mongoc_cursor_get_id(cursor->cursor)) {
return;
}
if (!Z_ISUNDEF(cursor->session)) {
zval_ptr_dtor(&cursor->session);
ZVAL_UNDEF(&cursor->session);
}
} /* }}} */
static void php_phongo_cursor_free_current(php_phongo_cursor_t* cursor) /* {{{ */
{
if (!Z_ISUNDEF(cursor->visitor_data.zchild)) {
zval_ptr_dtor(&cursor->visitor_data.zchild);
ZVAL_UNDEF(&cursor->visitor_data.zchild);
}
} /* }}} */
/* {{{ MongoDB\Driver\Cursor iterator handlers */
-static void php_phongo_cursor_iterator_dtor(zend_object_iterator* iter TSRMLS_DC) /* {{{ */
+static void php_phongo_cursor_iterator_dtor(zend_object_iterator* iter) /* {{{ */
{
php_phongo_cursor_iterator* cursor_it = (php_phongo_cursor_iterator*) iter;
if (!Z_ISUNDEF(cursor_it->intern.data)) {
-#if PHP_VERSION_ID >= 70000
zval_ptr_dtor(&cursor_it->intern.data);
-#else
- zval_ptr_dtor((zval**) &cursor_it->intern.data);
- cursor_it->intern.data = NULL;
-#endif
}
-
-#if PHP_VERSION_ID < 70000
- efree(cursor_it);
-#endif
} /* }}} */
-static int php_phongo_cursor_iterator_valid(zend_object_iterator* iter TSRMLS_DC) /* {{{ */
+static int php_phongo_cursor_iterator_valid(zend_object_iterator* iter) /* {{{ */
{
php_phongo_cursor_t* cursor = ((php_phongo_cursor_iterator*) iter)->cursor;
if (!Z_ISUNDEF(cursor->visitor_data.zchild)) {
return SUCCESS;
}
return FAILURE;
} /* }}} */
-static void php_phongo_cursor_iterator_get_current_key(zend_object_iterator* iter, zval* key TSRMLS_DC) /* {{{ */
+static void php_phongo_cursor_iterator_get_current_key(zend_object_iterator* iter, zval* key) /* {{{ */
{
php_phongo_cursor_t* cursor = ((php_phongo_cursor_iterator*) iter)->cursor;
ZVAL_LONG(key, cursor->current);
} /* }}} */
-#if PHP_VERSION_ID < 70000
-static void php_phongo_cursor_iterator_get_current_data(zend_object_iterator* iter, zval*** data TSRMLS_DC) /* {{{ */
-{
- php_phongo_cursor_t* cursor = ((php_phongo_cursor_iterator*) iter)->cursor;
-
- *data = &cursor->visitor_data.zchild;
-} /* }}} */
-#else
static zval* php_phongo_cursor_iterator_get_current_data(zend_object_iterator* iter) /* {{{ */
{
php_phongo_cursor_t* cursor = ((php_phongo_cursor_iterator*) iter)->cursor;
return &cursor->visitor_data.zchild;
} /* }}} */
-#endif
-static void php_phongo_cursor_iterator_move_forward(zend_object_iterator* iter TSRMLS_DC) /* {{{ */
+static void php_phongo_cursor_iterator_move_forward(zend_object_iterator* iter) /* {{{ */
{
php_phongo_cursor_iterator* cursor_it = (php_phongo_cursor_iterator*) iter;
php_phongo_cursor_t* cursor = cursor_it->cursor;
const bson_t* doc;
php_phongo_cursor_free_current(cursor);
/* If the cursor has already advanced, increment its position. Otherwise,
* the first call to mongoc_cursor_next() will be made below and we should
* leave its position at zero. */
if (cursor->advanced) {
cursor->current++;
} else {
cursor->advanced = true;
}
if (mongoc_cursor_next(cursor->cursor, &doc)) {
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data)) {
/* Free invalid result, but don't return as we want to free the
* session if the cursor is exhausted. */
php_phongo_cursor_free_current(cursor);
}
} else {
bson_error_t error = { 0 };
const bson_t* doc = NULL;
if (mongoc_cursor_error_document(cursor->cursor, &error, &doc)) {
/* Intentionally not destroying the cursor as it will happen
* naturally now that there are no more results */
- phongo_throw_exception_from_bson_error_t_and_reply(&error, doc TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t_and_reply(&error, doc);
}
}
php_phongo_cursor_free_session_if_exhausted(cursor);
} /* }}} */
-static void php_phongo_cursor_iterator_rewind(zend_object_iterator* iter TSRMLS_DC) /* {{{ */
+static void php_phongo_cursor_iterator_rewind(zend_object_iterator* iter) /* {{{ */
{
php_phongo_cursor_iterator* cursor_it = (php_phongo_cursor_iterator*) iter;
php_phongo_cursor_t* cursor = cursor_it->cursor;
const bson_t* doc;
/* If the cursor was never advanced (e.g. command cursor), do so now */
if (!cursor->advanced) {
cursor->advanced = true;
- if (!phongo_cursor_advance_and_check_for_error(cursor->cursor TSRMLS_CC)) {
+ if (!phongo_cursor_advance_and_check_for_error(cursor->cursor)) {
/* Exception should already have been thrown */
return;
}
}
if (cursor->current > 0) {
- phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Cursors cannot rewind after starting iteration");
+ phongo_throw_exception(PHONGO_ERROR_LOGIC, "Cursors cannot rewind after starting iteration");
return;
}
php_phongo_cursor_free_current(cursor);
doc = mongoc_cursor_current(cursor->cursor);
if (doc) {
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data)) {
/* Free invalid result, but don't return as we want to free the
* session if the cursor is exhausted. */
php_phongo_cursor_free_current(cursor);
}
}
php_phongo_cursor_free_session_if_exhausted(cursor);
} /* }}} */
static zend_object_iterator_funcs php_phongo_cursor_iterator_funcs = {
php_phongo_cursor_iterator_dtor,
php_phongo_cursor_iterator_valid,
php_phongo_cursor_iterator_get_current_data,
php_phongo_cursor_iterator_get_current_key,
php_phongo_cursor_iterator_move_forward,
php_phongo_cursor_iterator_rewind,
NULL /* invalidate_current is not used */
};
-static zend_object_iterator* php_phongo_cursor_get_iterator(zend_class_entry* ce, zval* object, int by_ref TSRMLS_DC) /* {{{ */
+static zend_object_iterator* php_phongo_cursor_get_iterator(zend_class_entry* ce, zval* object, int by_ref) /* {{{ */
{
php_phongo_cursor_iterator* cursor_it = NULL;
php_phongo_cursor_t* cursor = Z_CURSOR_OBJ_P(object);
if (by_ref) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
if (cursor->got_iterator) {
- phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Cursors cannot yield multiple iterators");
+ phongo_throw_exception(PHONGO_ERROR_LOGIC, "Cursors cannot yield multiple iterators");
return NULL;
}
cursor->got_iterator = true;
cursor_it = ecalloc(1, sizeof(php_phongo_cursor_iterator));
-#if PHP_VERSION_ID >= 70000
zend_iterator_init(&cursor_it->intern);
-#endif
-#if PHP_VERSION_ID >= 70000
ZVAL_COPY(&cursor_it->intern.data, object);
-#else
- Z_ADDREF_P(object);
- cursor_it->intern.data = (void*) object;
-#endif
cursor_it->intern.funcs = &php_phongo_cursor_iterator_funcs;
cursor_it->cursor = cursor;
/* cursor_it->current should already be allocated to zero */
php_phongo_cursor_free_current(cursor_it->cursor);
return &cursor_it->intern;
} /* }}} */
/* }}} */
/* {{{ proto void MongoDB\Driver\Cursor::setTypeMap(array $typemap)
Sets a type map to use for BSON unserialization */
static PHP_METHOD(Cursor, setTypeMap)
{
php_phongo_cursor_t* intern;
php_phongo_bson_state state;
zval* typemap = NULL;
bool restore_current_element = false;
PHONGO_BSON_INIT_STATE(state);
intern = Z_CURSOR_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!", &typemap) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!", &typemap) == FAILURE) {
return;
}
- if (!php_phongo_bson_typemap_to_state(typemap, &state.map TSRMLS_CC)) {
+ if (!php_phongo_bson_typemap_to_state(typemap, &state.map)) {
return;
}
/* Check if the existing element needs to be freed before we overwrite
* visitor_data, which contains the only reference to it. */
if (!Z_ISUNDEF(intern->visitor_data.zchild)) {
php_phongo_cursor_free_current(intern);
restore_current_element = true;
}
php_phongo_bson_typemap_dtor(&intern->visitor_data.map);
intern->visitor_data = state;
/* If the cursor has a current element, we just freed it and should restore
* it with a new type map applied. */
if (restore_current_element && mongoc_cursor_current(intern->cursor)) {
const bson_t* doc = mongoc_cursor_current(intern->cursor);
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &intern->visitor_data)) {
php_phongo_cursor_free_current(intern);
}
}
} /* }}} */
-static int php_phongo_cursor_to_array_apply(zend_object_iterator* iter, void* puser TSRMLS_DC) /* {{{ */
+static int php_phongo_cursor_to_array_apply(zend_object_iterator* iter, void* puser) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval* data;
zval* return_value = (zval*) puser;
- data = iter->funcs->get_current_data(iter TSRMLS_CC);
+ data = iter->funcs->get_current_data(iter);
if (EG(exception)) {
return ZEND_HASH_APPLY_STOP;
}
if (Z_ISUNDEF_P(data)) {
return ZEND_HASH_APPLY_STOP;
}
Z_TRY_ADDREF_P(data);
add_next_index_zval(return_value, data);
-#else
- zval** data;
- zval* return_value = (zval*) puser;
-
- iter->funcs->get_current_data(iter, &data TSRMLS_CC);
-
- if (EG(exception)) {
- return ZEND_HASH_APPLY_STOP;
- }
- if (data == NULL || *data == NULL) {
- return ZEND_HASH_APPLY_STOP;
- }
- Z_ADDREF_PP(data);
- add_next_index_zval(return_value, *data);
-#endif
return ZEND_HASH_APPLY_KEEP;
} /* }}} */
-static void php_phongo_cursor_id_new_from_id(zval* object, int64_t cursorid TSRMLS_DC) /* {{{ */
+static void php_phongo_cursor_id_new_from_id(zval* object, int64_t cursorid) /* {{{ */
{
php_phongo_cursorid_t* intern;
object_init_ex(object, php_phongo_cursorid_ce);
intern = Z_CURSORID_OBJ_P(object);
intern->id = cursorid;
} /* }}} */
/* {{{ proto array MongoDB\Driver\Cursor::toArray()
Returns an array of all result documents for this cursor */
static PHP_METHOD(Cursor, toArray)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
array_init(return_value);
- if (spl_iterator_apply(getThis(), php_phongo_cursor_to_array_apply, (void*) return_value TSRMLS_CC) != SUCCESS) {
+ if (spl_iterator_apply(getThis(), php_phongo_cursor_to_array_apply, (void*) return_value) != SUCCESS) {
zval_dtor(return_value);
RETURN_NULL();
}
} /* }}} */
/* {{{ proto MongoDB\Driver\CursorId MongoDB\Driver\Cursor::getId()
Returns the CursorId for this cursor */
static PHP_METHOD(Cursor, getId)
{
php_phongo_cursor_t* intern;
intern = Z_CURSOR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- php_phongo_cursor_id_new_from_id(return_value, mongoc_cursor_get_id(intern->cursor) TSRMLS_CC);
+ php_phongo_cursor_id_new_from_id(return_value, mongoc_cursor_get_id(intern->cursor));
} /* }}} */
/* {{{ proto MongoDB\Driver\Server MongoDB\Driver\Cursor::getServer()
Returns the Server object to which this cursor is attached */
static PHP_METHOD(Cursor, getServer)
{
php_phongo_cursor_t* intern;
intern = Z_CURSOR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(return_value, intern->client, intern->server_id);
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\Cursor::isDead()
Checks if a cursor is still alive */
static PHP_METHOD(Cursor, isDead)
{
php_phongo_cursor_t* intern;
intern = Z_CURSOR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_BOOL(!mongoc_cursor_more(intern->cursor));
} /* }}} */
/* {{{ MongoDB\Driver\Cursor function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Cursor_setTypeMap, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, typemap, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Cursor_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_cursor_me[] = {
/* clang-format off */
PHP_ME(Cursor, setTypeMap, ai_Cursor_setTypeMap, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Cursor, toArray, ai_Cursor_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Cursor, getId, ai_Cursor_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Cursor, getServer, ai_Cursor_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Cursor, isDead, ai_Cursor_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Cursor_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Cursor_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Cursor object handlers */
static zend_object_handlers php_phongo_handler_cursor;
-static void php_phongo_cursor_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_cursor_free_object(zend_object* object) /* {{{ */
{
php_phongo_cursor_t* intern = Z_OBJ_CURSOR(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
/* If this Cursor was created in a different process, reset the client so
* that mongoc_cursor_destroy does not issue a killCursors command for an
* active cursor owned by a parent process. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
if (intern->cursor) {
mongoc_cursor_destroy(intern->cursor);
}
if (intern->database) {
efree(intern->database);
}
if (intern->collection) {
efree(intern->collection);
}
if (!Z_ISUNDEF(intern->query)) {
zval_ptr_dtor(&intern->query);
}
if (!Z_ISUNDEF(intern->command)) {
zval_ptr_dtor(&intern->command);
}
if (!Z_ISUNDEF(intern->read_preference)) {
zval_ptr_dtor(&intern->read_preference);
}
if (!Z_ISUNDEF(intern->session)) {
zval_ptr_dtor(&intern->session);
}
php_phongo_bson_typemap_dtor(&intern->visitor_data.map);
php_phongo_cursor_free_current(intern);
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_cursor_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_cursor_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_cursor_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_cursor_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
PHONGO_SET_CREATED_BY_PID(intern);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_cursor;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_cursor_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_cursor;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_cursor_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_cursor_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_cursor_t* intern;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_CURSOR_OBJ_P(object);
array_init_size(&retval, 10);
if (intern->database) {
ADD_ASSOC_STRING(&retval, "database", intern->database);
} else {
ADD_ASSOC_NULL_EX(&retval, "database");
}
if (intern->collection) {
ADD_ASSOC_STRING(&retval, "collection", intern->collection);
} else {
ADD_ASSOC_NULL_EX(&retval, "collection");
}
if (!Z_ISUNDEF(intern->query)) {
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "query", &intern->query);
Z_ADDREF(intern->query);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "query", intern->query);
- Z_ADDREF_P(intern->query);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "query");
}
if (!Z_ISUNDEF(intern->command)) {
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "command", &intern->command);
Z_ADDREF(intern->command);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "command", intern->command);
- Z_ADDREF_P(intern->command);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "command");
}
if (!Z_ISUNDEF(intern->read_preference)) {
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "readPreference", &intern->read_preference);
Z_ADDREF(intern->read_preference);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "readPreference", intern->read_preference);
- Z_ADDREF_P(intern->read_preference);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "readPreference");
}
if (!Z_ISUNDEF(intern->session)) {
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "session", &intern->session);
Z_ADDREF(intern->session);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "session", intern->session);
- Z_ADDREF_P(intern->session);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "session");
}
ADD_ASSOC_BOOL_EX(&retval, "isDead", !mongoc_cursor_more(intern->cursor));
ADD_ASSOC_LONG_EX(&retval, "currentIndex", intern->current);
if (!Z_ISUNDEF(intern->visitor_data.zchild)) {
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "currentDocument", &intern->visitor_data.zchild);
Z_ADDREF(intern->visitor_data.zchild);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "currentDocument", intern->visitor_data.zchild);
- Z_ADDREF_P(intern->visitor_data.zchild);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "currentDocument");
}
{
-#if PHP_VERSION_ID >= 70000
zval server;
- phongo_server_init(&server, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(&server, intern->client, intern->server_id);
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
-#else
- zval* server = NULL;
-
- MAKE_STD_ZVAL(server);
- phongo_server_init(server, intern->client, intern->server_id TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "server", server);
-#endif
}
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_cursor_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Cursor", php_phongo_cursor_me);
- php_phongo_cursor_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_cursor_ce = zend_register_internal_class(&ce);
php_phongo_cursor_ce->create_object = php_phongo_cursor_create_object;
PHONGO_CE_FINAL(php_phongo_cursor_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_cursor_ce);
php_phongo_cursor_ce->get_iterator = php_phongo_cursor_get_iterator;
- zend_class_implements(php_phongo_cursor_ce TSRMLS_CC, 1, php_phongo_cursor_interface_ce);
+ zend_class_implements(php_phongo_cursor_ce, 1, php_phongo_cursor_interface_ce);
memcpy(&php_phongo_handler_cursor, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_cursor.get_debug_info = php_phongo_cursor_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_cursor.free_obj = php_phongo_cursor_free_object;
- php_phongo_handler_cursor.offset = XtOffsetOf(php_phongo_cursor_t, std);
-#endif
+ php_phongo_handler_cursor.free_obj = php_phongo_cursor_free_object;
+ php_phongo_handler_cursor.offset = XtOffsetOf(php_phongo_cursor_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/CursorId.c b/mongodb-1.8.1/src/MongoDB/CursorId.c
similarity index 64%
rename from mongodb-1.7.4/src/MongoDB/CursorId.c
rename to mongodb-1.8.1/src/MongoDB/CursorId.c
index 96f18152..5f519e99 100644
--- a/mongodb-1.7.4/src/MongoDB/CursorId.c
+++ b/mongodb-1.8.1/src/MongoDB/CursorId.c
@@ -1,276 +1,231 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_cursorid_ce;
/* Initialize the object from a numeric string and return whether it was
* successful. An exception will be thrown on error. */
-static bool php_phongo_cursorid_init_from_string(php_phongo_cursorid_t* intern, const char* s_id, phongo_zpp_char_len s_id_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_cursorid_init_from_string(php_phongo_cursorid_t* intern, const char* s_id, size_t s_id_len) /* {{{ */
{
int64_t id;
if (!php_phongo_parse_int64(&id, s_id, s_id_len)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit id for %s initialization", s_id, ZSTR_VAL(php_phongo_cursorid_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error parsing \"%s\" as 64-bit id for %s initialization", s_id, ZSTR_VAL(php_phongo_cursorid_ce->name));
return false;
}
intern->id = id;
return true;
} /* }}} */
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_cursorid_init_from_hash(php_phongo_cursorid_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_cursorid_init_from_hash(php_phongo_cursorid_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval* value;
if ((value = zend_hash_str_find(props, "id", sizeof("id") - 1)) && Z_TYPE_P(value) == IS_STRING) {
- return php_phongo_cursorid_init_from_string(intern, Z_STRVAL_P(value), Z_STRLEN_P(value) TSRMLS_CC);
- }
-#else
- zval** value;
-
- if (zend_hash_find(props, "id", sizeof("id"), (void**) &value) == SUCCESS && Z_TYPE_PP(value) == IS_STRING) {
- return php_phongo_cursorid_init_from_string(intern, Z_STRVAL_PP(value), Z_STRLEN_PP(value) TSRMLS_CC);
+ return php_phongo_cursorid_init_from_string(intern, Z_STRVAL_P(value), Z_STRLEN_P(value));
}
-#endif
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"id\" string field", ZSTR_VAL(php_phongo_cursorid_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"id\" string field", ZSTR_VAL(php_phongo_cursorid_ce->name));
return false;
} /* }}} */
/* {{{ proto string MongoDB\Driver\CursorId::__toString()
Returns the string representation of the CursorId */
static PHP_METHOD(CursorId, __toString)
{
php_phongo_cursorid_t* intern;
char* tmp;
int tmp_len;
intern = Z_CURSORID_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
tmp_len = spprintf(&tmp, 0, "%" PRId64, intern->id);
- PHONGO_RETVAL_STRINGL(tmp, tmp_len);
+ RETVAL_STRINGL(tmp, tmp_len);
efree(tmp);
} /* }}} */
/* {{{ proto string MongoDB\Driver\CursorId::serialize()
*/
static PHP_METHOD(CursorId, serialize)
{
php_phongo_cursorid_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
if (zend_parse_parameters_none() == FAILURE) {
return;
}
intern = Z_CURSORID_OBJ_P(getThis());
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 1);
ADD_ASSOC_INT64_AS_STRING(&retval, "id", intern->id);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 1);
- ADD_ASSOC_INT64_AS_STRING(retval, "id", intern->id);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\Driver\CursorId::unserialize(string $serialized)
*/
static PHP_METHOD(CursorId, unserialize)
{
php_phongo_cursorid_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
+ size_t serialized_len;
+ zval props;
php_unserialize_data_t var_hash;
intern = Z_CURSORID_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_cursorid_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_cursorid_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_cursorid_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_cursorid_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_cursorid_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\Driver\CursorId function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CursorId_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_CursorId_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_cursorid_me[] = {
/* clang-format off */
PHP_ME(CursorId, __toString, ai_CursorId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CursorId, serialize, ai_CursorId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CursorId, unserialize, ai_CursorId_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CursorId_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CursorId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\CursorId object handlers */
static zend_object_handlers php_phongo_handler_cursorid;
-static void php_phongo_cursorid_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_cursorid_free_object(zend_object* object) /* {{{ */
{
php_phongo_cursorid_t* intern = Z_OBJ_CURSORID(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
+ zend_object_std_dtor(&intern->std);
} /* }}} */
-static phongo_create_object_retval php_phongo_cursorid_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_cursorid_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_cursorid_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_cursorid_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_cursorid;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_cursorid_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_cursorid;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_cursorid_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_cursorid_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_cursorid_t* intern;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_CURSORID_OBJ_P(object);
array_init(&retval);
-#if SIZEOF_LONG == 4
+#if SIZEOF_ZEND_LONG == 4
ADD_ASSOC_INT64_AS_STRING(&retval, "id", intern->id);
#else
ADD_ASSOC_LONG_EX(&retval, "id", intern->id);
#endif
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "CursorId", php_phongo_cursorid_me);
- php_phongo_cursorid_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_cursorid_ce = zend_register_internal_class(&ce);
php_phongo_cursorid_ce->create_object = php_phongo_cursorid_create_object;
PHONGO_CE_FINAL(php_phongo_cursorid_ce);
- zend_class_implements(php_phongo_cursorid_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_cursorid_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_cursorid, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_cursorid.get_debug_info = php_phongo_cursorid_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_cursorid.free_obj = php_phongo_cursorid_free_object;
- php_phongo_handler_cursorid.offset = XtOffsetOf(php_phongo_cursorid_t, std);
-#endif
+ php_phongo_handler_cursorid.free_obj = php_phongo_cursorid_free_object;
+ php_phongo_handler_cursorid.offset = XtOffsetOf(php_phongo_cursorid_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/CursorInterface.c b/mongodb-1.8.1/src/MongoDB/CursorInterface.c
similarity index 94%
rename from mongodb-1.7.4/src/MongoDB/CursorInterface.c
rename to mongodb-1.8.1/src/MongoDB/CursorInterface.c
index e37cc1c3..622aa145 100644
--- a/mongodb-1.7.4/src/MongoDB/CursorInterface.c
+++ b/mongodb-1.8.1/src/MongoDB/CursorInterface.c
@@ -1,66 +1,66 @@
/*
* 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_cursor_interface_ce;
/* {{{ MongoDB\BSON\CursorInterface function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CursorInterface_setTypeMap, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, typemap, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_CursorInterface_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_cursor_interface_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(CursorInterface, getId, ai_CursorInterface_void)
ZEND_ABSTRACT_ME(CursorInterface, getServer, ai_CursorInterface_void)
ZEND_ABSTRACT_ME(CursorInterface, isDead, ai_CursorInterface_void)
ZEND_ABSTRACT_ME(CursorInterface, setTypeMap, ai_CursorInterface_setTypeMap)
ZEND_ABSTRACT_ME(CursorInterface, toArray, ai_CursorInterface_void)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_cursor_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "CursorInterface", php_phongo_cursor_interface_me);
- php_phongo_cursor_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_cursor_interface_ce = zend_register_internal_interface(&ce);
- zend_class_implements(php_phongo_cursor_interface_ce TSRMLS_CC, 1, zend_ce_traversable);
+ zend_class_implements(php_phongo_cursor_interface_ce, 1, zend_ce_traversable);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/AuthenticationException.c b/mongodb-1.8.1/src/MongoDB/Exception/AuthenticationException.c
similarity index 89%
rename from mongodb-1.7.4/src/MongoDB/Exception/AuthenticationException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/AuthenticationException.c
index d7fa0fb4..8c8da852 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/AuthenticationException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/AuthenticationException.c
@@ -1,53 +1,49 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_authenticationexception_ce;
/* {{{ MongoDB\Driver\Exception\AuthenticationException function entries */
static zend_function_entry php_phongo_authenticationexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_authenticationexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "AuthenticationException", php_phongo_authenticationexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_authenticationexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce);
-#else
- php_phongo_authenticationexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce, NULL TSRMLS_CC);
-#endif
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/BulkWriteException.c b/mongodb-1.8.1/src/MongoDB/Exception/BulkWriteException.c
similarity index 89%
rename from mongodb-1.7.4/src/MongoDB/Exception/BulkWriteException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/BulkWriteException.c
index fea95946..76772d5a 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/BulkWriteException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/BulkWriteException.c
@@ -1,53 +1,49 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_bulkwriteexception_ce;
/* {{{ MongoDB\Driver\Exception\BulkWriteException function entries */
static zend_function_entry php_phongo_bulkwriteexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_bulkwriteexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "BulkWriteException", php_phongo_bulkwriteexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_bulkwriteexception_ce = zend_register_internal_class_ex(&ce, php_phongo_writeexception_ce);
-#else
- php_phongo_bulkwriteexception_ce = zend_register_internal_class_ex(&ce, php_phongo_writeexception_ce, NULL TSRMLS_CC);
-#endif
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/CommandException.c b/mongodb-1.8.1/src/MongoDB/Exception/CommandException.c
similarity index 80%
rename from mongodb-1.7.4/src/MongoDB/Exception/CommandException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/CommandException.c
index 7e148c87..017adab2 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/CommandException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/CommandException.c
@@ -1,83 +1,73 @@
/*
* 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_commandexception_ce;
/* {{{ proto document MongoDB\Driver\Exception\CommandException::getResultDocument()
Returns the result document from the failed command. */
static PHP_METHOD(CommandException, getResultDocument)
{
zval* resultdocument;
-#if PHP_VERSION_ID >= 70000
- zval rv;
-#endif
+ zval rv;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
- resultdocument = zend_read_property(php_phongo_commandexception_ce, getThis(), ZEND_STRL("resultDocument"), 0, &rv TSRMLS_CC);
-#else
- resultdocument = zend_read_property(php_phongo_commandexception_ce, getThis(), ZEND_STRL("resultDocument"), 0 TSRMLS_CC);
-#endif
+ resultdocument = zend_read_property(php_phongo_commandexception_ce, getThis(), ZEND_STRL("resultDocument"), 0, &rv);
RETURN_ZVAL(resultdocument, 1, 0);
} /* }}} */
/* {{{ MongoDB\Driver\Exception\CommandException function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CommandException_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_commandexception_me[] = {
/* clang-format off */
PHP_ME(CommandException, getResultDocument, ai_CommandException_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_commandexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "CommandException", php_phongo_commandexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_commandexception_ce = zend_register_internal_class_ex(&ce, php_phongo_serverexception_ce);
-#else
- php_phongo_commandexception_ce = zend_register_internal_class_ex(&ce, php_phongo_serverexception_ce, NULL TSRMLS_CC);
-#endif
- zend_declare_property_null(php_phongo_commandexception_ce, ZEND_STRL("resultDocument"), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(php_phongo_commandexception_ce, ZEND_STRL("resultDocument"), ZEND_ACC_PROTECTED);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/ConnectionException.c b/mongodb-1.8.1/src/MongoDB/Exception/ConnectionException.c
similarity index 89%
rename from mongodb-1.7.4/src/MongoDB/Exception/ConnectionException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/ConnectionException.c
index 0325ad2c..fae855f3 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/ConnectionException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/ConnectionException.c
@@ -1,53 +1,49 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_connectionexception_ce;
/* {{{ MongoDB\Driver\Exception\ConnectionException function entries */
static zend_function_entry php_phongo_connectionexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_connectionexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "ConnectionException", php_phongo_connectionexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_connectionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce);
-#else
- php_phongo_connectionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce, NULL TSRMLS_CC);
-#endif
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/ConnectionTimeoutException.c b/mongodb-1.8.1/src/MongoDB/Exception/ConnectionTimeoutException.c
similarity index 89%
rename from mongodb-1.7.4/src/MongoDB/Exception/ConnectionTimeoutException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/ConnectionTimeoutException.c
index a2f26eb9..959259bf 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/ConnectionTimeoutException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/ConnectionTimeoutException.c
@@ -1,54 +1,50 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_connectiontimeoutexception_ce;
/* {{{ MongoDB\Driver\Exception\ConnectionTimeoutException function entries */
static zend_function_entry php_phongo_connectiontimeoutexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_connectiontimeoutexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "ConnectionTimeoutException", php_phongo_connectiontimeoutexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_connectiontimeoutexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce);
-#else
- php_phongo_connectiontimeoutexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce, NULL TSRMLS_CC);
-#endif
PHONGO_CE_FINAL(php_phongo_connectiontimeoutexception_ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/EncryptionException.c b/mongodb-1.8.1/src/MongoDB/Exception/EncryptionException.c
similarity index 89%
rename from mongodb-1.7.4/src/MongoDB/Exception/EncryptionException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/EncryptionException.c
index b9331b3b..6e7b8fc9 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/EncryptionException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/EncryptionException.c
@@ -1,53 +1,49 @@
/*
* Copyright 2014-2020 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_encryptionexception_ce;
/* {{{ MongoDB\Driver\Exception\EncryptionException function entries */
static zend_function_entry php_phongo_encryptionexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_encryptionexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "EncryptionException", php_phongo_encryptionexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_encryptionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce);
-#else
- php_phongo_encryptionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce, NULL TSRMLS_CC);
-#endif
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/Exception.c b/mongodb-1.8.1/src/MongoDB/Exception/Exception.c
similarity index 86%
rename from mongodb-1.7.4/src/MongoDB/Exception/Exception.c
rename to mongodb-1.8.1/src/MongoDB/Exception/Exception.c
index 45484be4..d81c0074 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/Exception.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/Exception.c
@@ -1,54 +1,51 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <zend_exceptions.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_exception_ce;
/* {{{ MongoDB\Driver\Exception\Exception function entries */
static zend_function_entry php_phongo_exception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_exception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "Exception", php_phongo_exception_me);
- php_phongo_exception_ce = zend_register_internal_interface(&ce TSRMLS_CC);
-
-#if PHP_VERSION_ID >= 70000
- zend_class_implements(php_phongo_exception_ce TSRMLS_CC, 1, zend_ce_throwable);
-#endif
+ php_phongo_exception_ce = zend_register_internal_interface(&ce);
+ zend_class_implements(php_phongo_exception_ce, 1, zend_ce_throwable);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/ExecutionTimeoutException.c b/mongodb-1.8.1/src/MongoDB/Exception/ExecutionTimeoutException.c
similarity index 89%
rename from mongodb-1.7.4/src/MongoDB/Exception/ExecutionTimeoutException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/ExecutionTimeoutException.c
index fa87b174..696a4f53 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/ExecutionTimeoutException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/ExecutionTimeoutException.c
@@ -1,54 +1,50 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_executiontimeoutexception_ce;
/* {{{ MongoDB\Driver\Exception\ExecutionTimeoutException function entries */
static zend_function_entry php_phongo_executiontimeoutexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_executiontimeoutexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "ExecutionTimeoutException", php_phongo_executiontimeoutexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_executiontimeoutexception_ce = zend_register_internal_class_ex(&ce, php_phongo_serverexception_ce);
-#else
- php_phongo_executiontimeoutexception_ce = zend_register_internal_class_ex(&ce, php_phongo_serverexception_ce, NULL TSRMLS_CC);
-#endif
PHONGO_CE_FINAL(php_phongo_executiontimeoutexception_ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/InvalidArgumentException.c b/mongodb-1.8.1/src/MongoDB/Exception/InvalidArgumentException.c
similarity index 84%
rename from mongodb-1.7.4/src/MongoDB/Exception/InvalidArgumentException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/InvalidArgumentException.c
index 6aacee65..cf2d5428 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/InvalidArgumentException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/InvalidArgumentException.c
@@ -1,55 +1,51 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#include <ext/spl/spl_exceptions.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_invalidargumentexception_ce;
/* {{{ MongoDB\Driver\Exception\InvalidArgumentException function entries */
static zend_function_entry php_phongo_invalidargumentexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_invalidargumentexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "InvalidArgumentException", php_phongo_invalidargumentexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_invalidargumentexception_ce = zend_register_internal_class_ex(&ce, spl_ce_InvalidArgumentException);
-#else
- php_phongo_invalidargumentexception_ce = zend_register_internal_class_ex(&ce, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
-#endif
- zend_class_implements(php_phongo_invalidargumentexception_ce TSRMLS_CC, 1, php_phongo_exception_ce);
+ zend_class_implements(php_phongo_invalidargumentexception_ce, 1, php_phongo_exception_ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/LogicException.c b/mongodb-1.8.1/src/MongoDB/Exception/LogicException.c
similarity index 85%
rename from mongodb-1.7.4/src/MongoDB/Exception/LogicException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/LogicException.c
index 94e76a59..51ee88ef 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/LogicException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/LogicException.c
@@ -1,55 +1,51 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#include <ext/spl/spl_exceptions.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_logicexception_ce;
/* {{{ MongoDB\Driver\Exception\LogicException function entries */
static zend_function_entry php_phongo_logicexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_logicexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "LogicException", php_phongo_logicexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_logicexception_ce = zend_register_internal_class_ex(&ce, spl_ce_LogicException);
-#else
- php_phongo_logicexception_ce = zend_register_internal_class_ex(&ce, spl_ce_LogicException, NULL TSRMLS_CC);
-#endif
- zend_class_implements(php_phongo_logicexception_ce TSRMLS_CC, 1, php_phongo_exception_ce);
+ zend_class_implements(php_phongo_logicexception_ce, 1, php_phongo_exception_ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/RuntimeException.c b/mongodb-1.8.1/src/MongoDB/Exception/RuntimeException.c
similarity index 67%
rename from mongodb-1.7.4/src/MongoDB/Exception/RuntimeException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/RuntimeException.c
index cec91d51..e5090ad8 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/RuntimeException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/RuntimeException.c
@@ -1,133 +1,104 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#include <ext/spl/spl_exceptions.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_array_api.h"
zend_class_entry* php_phongo_runtimeexception_ce;
-static bool php_phongo_has_string_array_element(zval* labels, char* label TSRMLS_DC)
+static bool php_phongo_has_string_array_element(zval* labels, char* label)
{
HashTable* ht_data;
if (Z_TYPE_P(labels) != IS_ARRAY) {
return false;
}
ht_data = HASH_OF(labels);
-#if PHP_VERSION_ID >= 70000
{
zval* z_label;
ZEND_HASH_FOREACH_VAL_IND(ht_data, z_label)
{
if ((Z_TYPE_P(z_label) == IS_STRING) && (strcmp(Z_STRVAL_P(z_label), label) == 0)) {
return true;
}
}
ZEND_HASH_FOREACH_END();
}
-#else
- {
- HashPosition pos;
- zval** z_label;
-
- for (
- zend_hash_internal_pointer_reset_ex(ht_data, &pos);
- zend_hash_get_current_data_ex(ht_data, (void**) &z_label, &pos) == SUCCESS;
- zend_hash_move_forward_ex(ht_data, &pos)) {
-
- if (Z_TYPE_PP(z_label) == IS_STRING) {
- if (strcmp(Z_STRVAL_PP(z_label), label) == 0) {
- return true;
- }
- }
- }
- }
-#endif
return false;
}
/* {{{ proto bool MongoDB\Driver\Exception\RuntimeException::hasErrorLabel(string $label)
Returns whether a specific error label has been set */
static PHP_METHOD(RuntimeException, hasErrorLabel)
{
- char* label;
- phongo_zpp_char_len label_len;
- zval* error_labels;
-#if PHP_VERSION_ID >= 70000
- zval rv;
-#endif
+ char* label;
+ size_t label_len;
+ zval* error_labels;
+ zval rv;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &label, &label_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &label, &label_len) == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
- error_labels = zend_read_property(php_phongo_runtimeexception_ce, getThis(), ZEND_STRL("errorLabels"), 0, &rv TSRMLS_CC);
-#else
- error_labels = zend_read_property(php_phongo_runtimeexception_ce, getThis(), ZEND_STRL("errorLabels"), 0 TSRMLS_CC);
-#endif
+ error_labels = zend_read_property(php_phongo_runtimeexception_ce, getThis(), ZEND_STRL("errorLabels"), 0, &rv);
- RETURN_BOOL(php_phongo_has_string_array_element(error_labels, label TSRMLS_CC));
+ RETURN_BOOL(php_phongo_has_string_array_element(error_labels, label));
} /* }}} */
ZEND_BEGIN_ARG_INFO_EX(ai_RuntimeException_hasErrorLabel, 0, 0, 1)
ZEND_ARG_INFO(0, label)
ZEND_END_ARG_INFO()
/* {{{ MongoDB\Driver\Exception\RuntimeException function entries */
static zend_function_entry php_phongo_runtimeexception_me[] = {
/* clang-format off */
PHP_ME(RuntimeException, hasErrorLabel, ai_RuntimeException_hasErrorLabel, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_runtimeexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "RuntimeException", php_phongo_runtimeexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_runtimeexception_ce = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException);
-#else
- php_phongo_runtimeexception_ce = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException, NULL TSRMLS_CC);
-#endif
- zend_class_implements(php_phongo_runtimeexception_ce TSRMLS_CC, 1, php_phongo_exception_ce);
+ zend_class_implements(php_phongo_runtimeexception_ce, 1, php_phongo_exception_ce);
- zend_declare_property_null(php_phongo_runtimeexception_ce, ZEND_STRL("errorLabels"), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(php_phongo_runtimeexception_ce, ZEND_STRL("errorLabels"), ZEND_ACC_PROTECTED);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/SSLConnectionException.c b/mongodb-1.8.1/src/MongoDB/Exception/SSLConnectionException.c
similarity index 89%
rename from mongodb-1.7.4/src/MongoDB/Exception/SSLConnectionException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/SSLConnectionException.c
index 2f17b0d1..ab2af3f4 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/SSLConnectionException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/SSLConnectionException.c
@@ -1,54 +1,50 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_sslconnectionexception_ce;
/* {{{ MongoDB\Driver\Exception\SSLConnectionException function entries */
static zend_function_entry php_phongo_sslconnectionexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_sslconnectionexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "SSLConnectionException", php_phongo_sslconnectionexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_sslconnectionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce);
-#else
- php_phongo_sslconnectionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce, NULL TSRMLS_CC);
-#endif
PHONGO_CE_FINAL(php_phongo_sslconnectionexception_ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/ServerException.c b/mongodb-1.8.1/src/MongoDB/Exception/ServerException.c
similarity index 89%
rename from mongodb-1.7.4/src/MongoDB/Exception/ServerException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/ServerException.c
index 5617e52b..70178a5e 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/ServerException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/ServerException.c
@@ -1,53 +1,49 @@
/*
* 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_serverexception_ce;
/* {{{ MongoDB\Driver\Exception\ServerException function entries */
static zend_function_entry php_phongo_serverexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_serverexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "ServerException", php_phongo_serverexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_serverexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce);
-#else
- php_phongo_serverexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce, NULL TSRMLS_CC);
-#endif
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/UnexpectedValueException.c b/mongodb-1.8.1/src/MongoDB/Exception/UnexpectedValueException.c
similarity index 84%
rename from mongodb-1.7.4/src/MongoDB/Exception/UnexpectedValueException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/UnexpectedValueException.c
index c13eaad7..ff685afb 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/UnexpectedValueException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/UnexpectedValueException.c
@@ -1,55 +1,51 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <ext/spl/spl_exceptions.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_unexpectedvalueexception_ce;
/* {{{ MongoDB\Driver\Exception\UnexpectedValueException function entries */
static zend_function_entry php_phongo_unexpectedvalueexception_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_unexpectedvalueexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "UnexpectedValueException", php_phongo_unexpectedvalueexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_unexpectedvalueexception_ce = zend_register_internal_class_ex(&ce, spl_ce_UnexpectedValueException);
-#else
- php_phongo_unexpectedvalueexception_ce = zend_register_internal_class_ex(&ce, spl_ce_UnexpectedValueException, NULL TSRMLS_CC);
-#endif
- zend_class_implements(php_phongo_unexpectedvalueexception_ce TSRMLS_CC, 1, php_phongo_exception_ce);
+ zend_class_implements(php_phongo_unexpectedvalueexception_ce, 1, php_phongo_exception_ce);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Exception/WriteException.c b/mongodb-1.8.1/src/MongoDB/Exception/WriteException.c
similarity index 81%
rename from mongodb-1.7.4/src/MongoDB/Exception/WriteException.c
rename to mongodb-1.8.1/src/MongoDB/Exception/WriteException.c
index cd3eb50e..72f4a017 100644
--- a/mongodb-1.7.4/src/MongoDB/Exception/WriteException.c
+++ b/mongodb-1.8.1/src/MongoDB/Exception/WriteException.c
@@ -1,84 +1,74 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_writeexception_ce;
/* {{{ proto MongoDB\Driver\WriteResult MongoDB\Driver\Exception\WriteException::getWriteResult()
Returns the WriteResult from the failed write operation. */
static PHP_METHOD(WriteException, getWriteResult)
{
zval* writeresult;
-#if PHP_VERSION_ID >= 70000
- zval rv;
-#endif
+ zval rv;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
- writeresult = zend_read_property(php_phongo_writeexception_ce, getThis(), ZEND_STRL("writeResult"), 0, &rv TSRMLS_CC);
-#else
- writeresult = zend_read_property(php_phongo_writeexception_ce, getThis(), ZEND_STRL("writeResult"), 0 TSRMLS_CC);
-#endif
+ writeresult = zend_read_property(php_phongo_writeexception_ce, getThis(), ZEND_STRL("writeResult"), 0, &rv);
RETURN_ZVAL(writeresult, 1, 0);
} /* }}} */
/* {{{ MongoDB\Driver\Exception\WriteException function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_WriteException_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_writeexception_me[] = {
/* clang-format off */
PHP_ME(WriteException, getWriteResult, ai_WriteException_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_writeexception_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "WriteException", php_phongo_writeexception_me);
-#if PHP_VERSION_ID >= 70000
php_phongo_writeexception_ce = zend_register_internal_class_ex(&ce, php_phongo_serverexception_ce);
-#else
- php_phongo_writeexception_ce = zend_register_internal_class_ex(&ce, php_phongo_serverexception_ce, NULL TSRMLS_CC);
-#endif
php_phongo_writeexception_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
- zend_declare_property_null(php_phongo_writeexception_ce, ZEND_STRL("writeResult"), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(php_phongo_writeexception_ce, ZEND_STRL("writeResult"), ZEND_ACC_PROTECTED);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Manager.c b/mongodb-1.8.1/src/MongoDB/Manager.c
similarity index 72%
rename from mongodb-1.7.4/src/MongoDB/Manager.c
rename to mongodb-1.8.1/src/MongoDB/Manager.c
index 5bb597e5..01cef7df 100644
--- a/mongodb-1.7.4/src/MongoDB/Manager.c
+++ b/mongodb-1.8.1/src/MongoDB/Manager.c
@@ -1,1025 +1,890 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_hash.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/file.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_array_api.h"
#include "phongo_compat.h"
#include "php_phongo.h"
#include "Session.h"
#define PHONGO_MANAGER_URI_DEFAULT "mongodb://127.0.0.1/"
/**
* Manager abstracts a cluster of Server objects (i.e. socket connections).
*
* Typically, users will connect to a cluster using a URI, and the Manager will
* perform tasks such as replica set discovery and create the necessary Server
* objects. That said, it is also possible to create a Manager with an arbitrary
* collection of Server objects using the static factory method (this can be
* useful for testing or administration).
*
* Operation methods do not take socket-level options (e.g. socketTimeoutMS).
* Those options should be specified during construction.
*/
zend_class_entry* php_phongo_manager_ce;
/* Checks if driverOptions contains a stream context resource in the "context"
* key and incorporates any of its SSL options into the base array that did not
* already exist (i.e. array union). The "context" key is then unset from the
* base array.
*
* This handles the merging of any legacy SSL context options and also makes
* driverOptions suitable for serialization by removing the resource zval. */
-static bool php_phongo_manager_merge_context_options(zval* zdriverOptions TSRMLS_DC) /* {{{ */
+static bool php_phongo_manager_merge_context_options(zval* zdriverOptions) /* {{{ */
{
php_stream_context* context;
zval * zcontext, *zcontextOptions;
if (!php_array_existsc(zdriverOptions, "context")) {
return true;
}
zcontext = php_array_fetchc(zdriverOptions, "context");
context = php_stream_context_from_zval(zcontext, 1);
if (!context) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"context\" driver option is not a valid Stream-Context resource");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"context\" driver option is not a valid Stream-Context resource");
return false;
}
-#if PHP_VERSION_ID >= 70000
zcontextOptions = php_array_fetchc_array(&context->options, "ssl");
-#else
- zcontextOptions = php_array_fetchc_array(context->options, "ssl");
-#endif
if (!zcontextOptions) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Stream-Context resource does not contain \"ssl\" options array");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Stream-Context resource does not contain \"ssl\" options array");
return false;
}
/* When running PHP in debug mode, php_error_docref duplicates the current
* scope, leading to a COW violation in zend_hash_merge and
* zend_symtable_str_del (called by php_array_unsetc). This macro allows
* that violation in debug mode and is a NOOP when in non-debug. */
#if PHP_VERSION_ID >= 70200
HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(zdriverOptions));
#endif
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"context\" driver option is deprecated.");
+ php_error_docref(NULL, E_DEPRECATED, "The \"context\" driver option is deprecated.");
/* Perform array union (see: add_function() in zend_operators.c) */
-#if PHP_VERSION_ID >= 70000
zend_hash_merge(Z_ARRVAL_P(zdriverOptions), Z_ARRVAL_P(zcontextOptions), zval_add_ref, 0);
-#else
- {
- zval* tmp;
- zend_hash_merge(Z_ARRVAL_P(zdriverOptions), Z_ARRVAL_P(zcontextOptions), (void (*)(void* pData)) zval_add_ref, (void*) &tmp, sizeof(zval*), 0);
- }
-#endif
php_array_unsetc(zdriverOptions, "context");
return true;
} /* }}} */
/* Prepare authMechanismProperties for BSON encoding by converting a boolean
* value for the "CANONICALIZE_HOST_NAME" option to a string.
*
* Note: URI options are case-insensitive, so we must iterate through the
* HashTable in order to detect options. */
-static void php_phongo_manager_prep_authmechanismproperties(zval* properties TSRMLS_DC) /* {{{ */
+static void php_phongo_manager_prep_authmechanismproperties(zval* properties) /* {{{ */
{
HashTable* ht_data;
if (Z_TYPE_P(properties) != IS_ARRAY && Z_TYPE_P(properties) != IS_OBJECT) {
return;
}
ht_data = HASH_OF(properties);
-#if PHP_VERSION_ID >= 70000
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* property;
ZEND_HASH_FOREACH_KEY_VAL_IND(ht_data, num_key, string_key, property)
{
if (!string_key) {
continue;
}
/* URI options are case-insensitive */
if (!strcasecmp(ZSTR_VAL(string_key), "CANONICALIZE_HOST_NAME")) {
ZVAL_DEREF(property);
if (Z_TYPE_P(property) != IS_STRING && zend_is_true(property)) {
SEPARATE_ZVAL_NOREF(property);
ZVAL_NEW_STR(property, zend_string_init(ZEND_STRL("true"), 0));
}
}
}
ZEND_HASH_FOREACH_END();
}
-#else
- {
- HashPosition pos;
- zval** property;
-
- for (
- zend_hash_internal_pointer_reset_ex(ht_data, &pos);
- zend_hash_get_current_data_ex(ht_data, (void**) &property, &pos) == SUCCESS;
- zend_hash_move_forward_ex(ht_data, &pos)) {
-
- char* string_key = NULL;
- uint string_key_len = 0;
- ulong num_key = 0;
-
- if (HASH_KEY_IS_STRING != zend_hash_get_current_key_ex(ht_data, &string_key, &string_key_len, &num_key, 0, &pos)) {
- continue;
- }
-
- /* URI options are case-insensitive */
- if (!strcasecmp(string_key, "CANONICALIZE_HOST_NAME")) {
- if (Z_TYPE_PP(property) != IS_STRING && zend_is_true(*property)) {
- SEPARATE_ZVAL_IF_NOT_REF(property);
- Z_TYPE_PP(property) = IS_STRING;
- Z_STRVAL_PP(property) = estrndup("true", sizeof("true") - 1);
- Z_STRLEN_PP(property) = sizeof("true") - 1;
- }
- }
- }
- }
-#endif /* PHP_VERSION_ID >= 70000 */
-
- return;
} /* }}} */
/* Prepare URI options for BSON encoding.
*
* Read preference tag sets must be an array of documents. In order to ensure
* that empty arrays serialize as empty documents, array elements will be
* converted to objects. php_phongo_read_preference_tags_are_valid() handles
* actual validation of the tag set structure.
*
* Auth mechanism properties must have string values, so a boolean true value
* for the "CANONICALIZE_HOST_NAME" property will be converted to "true".
*
* Note: URI options are case-insensitive, so we must iterate through the
* HashTable in order to detect options. */
-static void php_phongo_manager_prep_uri_options(zval* options TSRMLS_DC) /* {{{ */
+static void php_phongo_manager_prep_uri_options(zval* options) /* {{{ */
{
HashTable* ht_data;
if (Z_TYPE_P(options) != IS_ARRAY) {
return;
}
ht_data = HASH_OF(options);
-#if PHP_VERSION_ID >= 70000
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* option;
ZEND_HASH_FOREACH_KEY_VAL_IND(ht_data, num_key, string_key, option)
{
if (!string_key) {
continue;
}
if (!strcasecmp(ZSTR_VAL(string_key), MONGOC_URI_READPREFERENCETAGS)) {
ZVAL_DEREF(option);
SEPARATE_ZVAL_NOREF(option);
- php_phongo_read_preference_prep_tagsets(option TSRMLS_CC);
+ php_phongo_read_preference_prep_tagsets(option);
continue;
}
if (!strcasecmp(ZSTR_VAL(string_key), MONGOC_URI_AUTHMECHANISMPROPERTIES)) {
ZVAL_DEREF(option);
SEPARATE_ZVAL_NOREF(option);
- php_phongo_manager_prep_authmechanismproperties(option TSRMLS_CC);
+ php_phongo_manager_prep_authmechanismproperties(option);
continue;
}
}
ZEND_HASH_FOREACH_END();
}
-#else
- {
- HashPosition pos;
- zval** option;
-
- for (
- zend_hash_internal_pointer_reset_ex(ht_data, &pos);
- zend_hash_get_current_data_ex(ht_data, (void**) &option, &pos) == SUCCESS;
- zend_hash_move_forward_ex(ht_data, &pos)) {
-
- char* string_key = NULL;
- uint string_key_len = 0;
- ulong num_key = 0;
-
- if (HASH_KEY_IS_STRING != zend_hash_get_current_key_ex(ht_data, &string_key, &string_key_len, &num_key, 0, &pos)) {
- continue;
- }
-
- if (!strcasecmp(string_key, MONGOC_URI_READPREFERENCETAGS)) {
- SEPARATE_ZVAL_IF_NOT_REF(option);
- php_phongo_read_preference_prep_tagsets(*option TSRMLS_CC);
- continue;
- }
-
- if (!strcasecmp(string_key, MONGOC_URI_AUTHMECHANISMPROPERTIES)) {
- SEPARATE_ZVAL_IF_NOT_REF(option);
- php_phongo_manager_prep_authmechanismproperties(*option TSRMLS_CC);
- continue;
- }
- }
- }
-#endif
-
- return;
} /* }}} */
/* Selects a server for an execute method. If "for_writes" is true, a primary
* will be selected. Otherwise, a read preference will be used to select the
* server. If zreadPreference is NULL, the client's read preference will be
* used. If zsession is a session object in a sharded transaction, the session
* will be checked whether it is pinned to a server. If so, that server will be
* selected. Otherwise, server selection
*
* On success, server_id will be set and the function will return true;
* otherwise, false is returned and an exception is thrown. */
-static bool php_phongo_manager_select_server(bool for_writes, zval* zreadPreference, zval* zsession, mongoc_client_t* client, uint32_t* server_id TSRMLS_DC) /* {{{ */
+static bool php_phongo_manager_select_server(bool for_writes, bool inherit_read_preference, zval* zreadPreference, zval* zsession, mongoc_client_t* client, uint32_t* server_id) /* {{{ */
{
mongoc_server_description_t* selected_server;
const mongoc_read_prefs_t* read_preference = NULL;
bson_error_t error = { 0 };
if (zsession) {
const mongoc_client_session_t* session = Z_SESSION_OBJ_P(zsession)->client_session;
/* Attempt to fetch server pinned to session */
if (mongoc_client_session_get_server_id(session) > 0) {
*server_id = mongoc_client_session_get_server_id(session);
return true;
}
}
if (!for_writes) {
- read_preference = zreadPreference ? phongo_read_preference_from_zval(zreadPreference TSRMLS_CC) : mongoc_client_get_read_prefs(client);
+ if (zreadPreference) {
+ read_preference = phongo_read_preference_from_zval(zreadPreference);
+ } else if (inherit_read_preference) {
+ read_preference = mongoc_client_get_read_prefs(client);
+ }
}
selected_server = mongoc_client_select_server(client, for_writes, read_preference, &error);
if (selected_server) {
*server_id = mongoc_server_description_id(selected_server);
mongoc_server_description_destroy(selected_server);
return true;
}
/* Check for connection related exceptions */
if (!EG(exception)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
}
return false;
} /* }}} */
/* {{{ proto void MongoDB\Driver\Manager::__construct([string $uri = "mongodb://127.0.0.1/"[, array $options = array()[, array $driverOptions = array()]]])
Constructs a new Manager */
static PHP_METHOD(Manager, __construct)
{
php_phongo_manager_t* intern;
zend_error_handling error_handling;
char* uri_string = NULL;
- phongo_zpp_char_len uri_string_len = 0;
+ size_t uri_string_len = 0;
zval* options = NULL;
zval* driverOptions = NULL;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_MANAGER_OBJ_P(getThis());
/* Separate the options and driverOptions zvals, since we may end up
* modifying them in php_phongo_manager_prep_uri_options() and
* php_phongo_manager_merge_context_options() below, respectively. */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!a/!a/!", &uri_string, &uri_string_len, &options, &driverOptions) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!a/!a/!", &uri_string, &uri_string_len, &options, &driverOptions) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
if (options) {
- php_phongo_manager_prep_uri_options(options TSRMLS_CC);
+ php_phongo_manager_prep_uri_options(options);
}
- if (driverOptions && !php_phongo_manager_merge_context_options(driverOptions TSRMLS_CC)) {
+ if (driverOptions && !php_phongo_manager_merge_context_options(driverOptions)) {
/* Exception should already have been thrown */
return;
}
- phongo_manager_init(intern, uri_string ? uri_string : PHONGO_MANAGER_URI_DEFAULT, options, driverOptions TSRMLS_CC);
+ phongo_manager_init(intern, uri_string ? uri_string : PHONGO_MANAGER_URI_DEFAULT, options, driverOptions);
if (intern->client) {
php_phongo_set_monitoring_callbacks(intern->client);
}
} /* }}} */
/* {{{ proto MongoDB\Driver\ClientEncryption MongoDB\Driver\Manager::createClientEncryption(array $options)
Return a ClientEncryption instance */
static PHP_METHOD(Manager, createClientEncryption)
{
php_phongo_manager_t* intern;
php_phongo_clientencryption_t* clientencryption;
zval* options;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &options) == FAILURE) {
return;
}
intern = Z_MANAGER_OBJ_P(getThis());
object_init_ex(return_value, php_phongo_clientencryption_ce);
clientencryption = Z_CLIENTENCRYPTION_OBJ_P(return_value);
- phongo_clientencryption_init(clientencryption, intern->client, options TSRMLS_CC);
+ phongo_clientencryption_init(clientencryption, intern->client, options);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
Execute a Command */
static PHP_METHOD(Manager, executeCommand)
{
php_phongo_manager_t* intern;
char* db;
- phongo_zpp_char_len db_len;
+ size_t db_len;
zval* command;
zval* options = NULL;
bool free_options = false;
zval* zreadPreference = NULL;
zval* zsession = NULL;
uint32_t server_id = 0;
- DECLARE_RETURN_VALUE_USED
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|z!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
return;
}
intern = Z_MANAGER_OBJ_P(getThis());
- options = php_phongo_prep_legacy_option(options, "readPreference", &free_options TSRMLS_CC);
+ options = php_phongo_prep_legacy_option(options, "readPreference", &free_options);
- if (!phongo_parse_session(options, intern->client, NULL, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
goto cleanup;
}
- if (!phongo_parse_read_preference(options, &zreadPreference TSRMLS_CC)) {
+ if (!phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
goto cleanup;
}
- if (!php_phongo_manager_select_server(false, zreadPreference, zsession, intern->client, &server_id TSRMLS_CC)) {
+ if (!php_phongo_manager_select_server(false, false, zreadPreference, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
goto cleanup;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_command(intern->client, PHONGO_COMMAND_RAW, db, command, options, server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_command(intern->client, PHONGO_COMMAND_RAW, db, command, options, server_id, return_value);
cleanup:
if (free_options) {
- php_phongo_prep_legacy_option_free(options TSRMLS_CC);
+ php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeReadCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
Execute a ReadCommand */
static PHP_METHOD(Manager, executeReadCommand)
{
php_phongo_manager_t* intern;
char* db;
- phongo_zpp_char_len db_len;
+ size_t db_len;
zval* command;
zval* options = NULL;
zval* zreadPreference = NULL;
uint32_t server_id = 0;
zval* zsession = NULL;
- DECLARE_RETURN_VALUE_USED
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
return;
}
intern = Z_MANAGER_OBJ_P(getThis());
- if (!phongo_parse_session(options, intern->client, NULL, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
return;
}
- if (!phongo_parse_read_preference(options, &zreadPreference TSRMLS_CC)) {
+ if (!phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
return;
}
- if (!php_phongo_manager_select_server(false, zreadPreference, zsession, intern->client, &server_id TSRMLS_CC)) {
+ if (!php_phongo_manager_select_server(false, true, zreadPreference, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
return;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_command(intern->client, PHONGO_COMMAND_READ, db, command, options, server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_command(intern->client, PHONGO_COMMAND_READ, db, command, options, server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeWriteCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
Execute a WriteCommand */
static PHP_METHOD(Manager, executeWriteCommand)
{
php_phongo_manager_t* intern;
char* db;
- phongo_zpp_char_len db_len;
+ size_t db_len;
zval* command;
zval* options = NULL;
uint32_t server_id = 0;
zval* zsession = NULL;
- DECLARE_RETURN_VALUE_USED
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
return;
}
intern = Z_MANAGER_OBJ_P(getThis());
- if (!phongo_parse_session(options, intern->client, NULL, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
return;
}
- if (!php_phongo_manager_select_server(true, NULL, zsession, intern->client, &server_id TSRMLS_CC)) {
+ if (!php_phongo_manager_select_server(true, false, NULL, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
return;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_command(intern->client, PHONGO_COMMAND_WRITE, db, command, options, server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_command(intern->client, PHONGO_COMMAND_WRITE, db, command, options, server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeReadWriteCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
Execute a ReadWriteCommand */
static PHP_METHOD(Manager, executeReadWriteCommand)
{
php_phongo_manager_t* intern;
char* db;
- phongo_zpp_char_len db_len;
+ size_t db_len;
zval* command;
zval* options = NULL;
uint32_t server_id = 0;
zval* zsession = NULL;
- DECLARE_RETURN_VALUE_USED
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
return;
}
intern = Z_MANAGER_OBJ_P(getThis());
- if (!phongo_parse_session(options, intern->client, NULL, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
return;
}
- if (!php_phongo_manager_select_server(true, NULL, zsession, intern->client, &server_id TSRMLS_CC)) {
+ if (!php_phongo_manager_select_server(true, false, NULL, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
return;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_command(intern->client, PHONGO_COMMAND_READ_WRITE, db, command, options, server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_command(intern->client, PHONGO_COMMAND_READ_WRITE, db, command, options, server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeQuery(string $namespace, MongoDB\Driver\Query $query[, array $options = null])
Execute a Query */
static PHP_METHOD(Manager, executeQuery)
{
php_phongo_manager_t* intern;
char* namespace;
- phongo_zpp_char_len namespace_len;
- zval* query;
- zval* options = NULL;
- bool free_options = false;
- zval* zreadPreference = NULL;
- uint32_t server_id = 0;
- zval* zsession = NULL;
- DECLARE_RETURN_VALUE_USED
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|z!", &namespace, &namespace_len, &query, php_phongo_query_ce, &options) == FAILURE) {
+ size_t namespace_len;
+ zval* query;
+ zval* options = NULL;
+ bool free_options = false;
+ zval* zreadPreference = NULL;
+ uint32_t server_id = 0;
+ zval* zsession = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &namespace, &namespace_len, &query, php_phongo_query_ce, &options) == FAILURE) {
return;
}
intern = Z_MANAGER_OBJ_P(getThis());
- options = php_phongo_prep_legacy_option(options, "readPreference", &free_options TSRMLS_CC);
+ options = php_phongo_prep_legacy_option(options, "readPreference", &free_options);
- if (!phongo_parse_session(options, intern->client, NULL, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
goto cleanup;
}
- if (!phongo_parse_read_preference(options, &zreadPreference TSRMLS_CC)) {
+ if (!phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
goto cleanup;
}
- if (!php_phongo_manager_select_server(false, zreadPreference, zsession, intern->client, &server_id TSRMLS_CC)) {
+ if (!php_phongo_manager_select_server(false, true, zreadPreference, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
goto cleanup;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_query(intern->client, namespace, query, options, server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_query(intern->client, namespace, query, options, server_id, return_value);
cleanup:
if (free_options) {
- php_phongo_prep_legacy_option_free(options TSRMLS_CC);
+ php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
/* {{{ proto MongoDB\Driver\WriteResult MongoDB\Driver\Manager::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, array $options = null])
Executes a BulkWrite (i.e. any number of insert, update, and delete ops) */
static PHP_METHOD(Manager, executeBulkWrite)
{
php_phongo_manager_t* intern;
char* namespace;
- phongo_zpp_char_len namespace_len;
+ size_t namespace_len;
zval* zbulk;
php_phongo_bulkwrite_t* bulk;
zval* options = NULL;
bool free_options = false;
uint32_t server_id = 0;
zval* zsession = NULL;
- DECLARE_RETURN_VALUE_USED
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|z!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &options) == FAILURE) {
return;
}
intern = Z_MANAGER_OBJ_P(getThis());
bulk = Z_BULKWRITE_OBJ_P(zbulk);
- options = php_phongo_prep_legacy_option(options, "writeConcern", &free_options TSRMLS_CC);
+ options = php_phongo_prep_legacy_option(options, "writeConcern", &free_options);
- if (!phongo_parse_session(options, intern->client, NULL, &zsession TSRMLS_CC)) {
+ if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
return;
}
- if (!php_phongo_manager_select_server(true, NULL, zsession, intern->client, &server_id TSRMLS_CC)) {
+ if (!php_phongo_manager_select_server(true, false, NULL, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
goto cleanup;
}
/* If the Server was created in a different process, reset the client so
* that its session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_bulk_write(intern->client, namespace, bulk, options, server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_bulk_write(intern->client, namespace, bulk, options, server_id, return_value);
cleanup:
if (free_options) {
- php_phongo_prep_legacy_option_free(options TSRMLS_CC);
+ php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
/* {{{ proto MongoDB\Driver\ReadConcern MongoDB\Driver\Manager::getReadConcern()
Returns the ReadConcern associated with this Manager */
static PHP_METHOD(Manager, getReadConcern)
{
php_phongo_manager_t* intern;
- DECLARE_RETURN_VALUE_USED
intern = Z_MANAGER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if (return_value_used) {
- phongo_readconcern_init(return_value, mongoc_client_get_read_concern(intern->client) TSRMLS_CC);
- }
+ phongo_readconcern_init(return_value, mongoc_client_get_read_concern(intern->client));
} /* }}} */
/* {{{ proto MongoDB\Driver\ReadPreference MongoDB\Driver\Manager::getReadPreference()
Returns the ReadPreference associated with this Manager */
static PHP_METHOD(Manager, getReadPreference)
{
php_phongo_manager_t* intern;
- DECLARE_RETURN_VALUE_USED
intern = Z_MANAGER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if (return_value_used) {
- phongo_readpreference_init(return_value, mongoc_client_get_read_prefs(intern->client) TSRMLS_CC);
- }
+ phongo_readpreference_init(return_value, mongoc_client_get_read_prefs(intern->client));
} /* }}} */
/* {{{ proto MongoDB\Driver\Server[] MongoDB\Driver\Manager::getServers()
Returns the Servers associated with this Manager */
static PHP_METHOD(Manager, getServers)
{
php_phongo_manager_t* intern;
mongoc_server_description_t** sds;
size_t i, n = 0;
intern = Z_MANAGER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
sds = mongoc_client_get_server_descriptions(intern->client, &n);
array_init_size(return_value, n);
for (i = 0; i < n; i++) {
-#if PHP_VERSION_ID >= 70000
zval obj;
- phongo_server_init(&obj, intern->client, mongoc_server_description_id(sds[i]) TSRMLS_CC);
+ phongo_server_init(&obj, intern->client, mongoc_server_description_id(sds[i]));
add_next_index_zval(return_value, &obj);
-#else
- zval* obj = NULL;
-
- MAKE_STD_ZVAL(obj);
- phongo_server_init(obj, intern->client, mongoc_server_description_id(sds[i]) TSRMLS_CC);
- add_next_index_zval(return_value, obj);
-#endif
}
mongoc_server_descriptions_destroy_all(sds, n);
} /* }}} */
/* {{{ proto MongoDB\Driver\WriteConcern MongoDB\Driver\Manager::getWriteConcern()
Returns the WriteConcern associated with this Manager */
static PHP_METHOD(Manager, getWriteConcern)
{
php_phongo_manager_t* intern;
- DECLARE_RETURN_VALUE_USED
intern = Z_MANAGER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if (return_value_used) {
- phongo_writeconcern_init(return_value, mongoc_client_get_write_concern(intern->client) TSRMLS_CC);
- }
+ phongo_writeconcern_init(return_value, mongoc_client_get_write_concern(intern->client));
} /* }}} */
/* {{{ proto MongoDB\Driver\Server MongoDB\Driver\Manager::selectServers(MongoDB\Driver\ReadPreference $readPreference)
Returns a suitable Server for the given ReadPreference */
static PHP_METHOD(Manager, selectServer)
{
php_phongo_manager_t* intern;
zval* zreadPreference = NULL;
uint32_t server_id = 0;
intern = Z_MANAGER_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zreadPreference, php_phongo_readpreference_ce) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zreadPreference, php_phongo_readpreference_ce) == FAILURE) {
return;
}
- if (!php_phongo_manager_select_server(false, zreadPreference, NULL, intern->client, &server_id TSRMLS_CC)) {
+ if (!php_phongo_manager_select_server(false, true, zreadPreference, NULL, intern->client, &server_id)) {
/* Exception should already have been thrown */
return;
}
- phongo_server_init(return_value, intern->client, server_id TSRMLS_CC);
+ phongo_server_init(return_value, intern->client, server_id);
} /* }}} */
/* {{{ proto MongoDB\Driver\Session MongoDB\Driver\Manager::startSession([array $options = null])
Returns a new client session */
static PHP_METHOD(Manager, startSession)
{
php_phongo_manager_t* intern;
zval* options = NULL;
mongoc_session_opt_t* cs_opts = NULL;
mongoc_client_session_t* cs;
bson_error_t error = { 0 };
mongoc_transaction_opt_t* txn_opts = NULL;
intern = Z_MANAGER_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &options) == FAILURE) {
return;
}
if (options && php_array_existsc(options, "causalConsistency")) {
cs_opts = mongoc_session_opts_new();
mongoc_session_opts_set_causal_consistency(cs_opts, php_array_fetchc_bool(options, "causalConsistency"));
}
if (options && php_array_existsc(options, "defaultTransactionOptions")) {
zval* txn_options = php_array_fetchc(options, "defaultTransactionOptions");
/* Thrown exception and return if the defaultTransactionOptions is not an array */
if (Z_TYPE_P(txn_options) != IS_ARRAY) {
phongo_throw_exception(
- PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC,
+ PHONGO_ERROR_INVALID_ARGUMENT,
"Expected \"defaultTransactionOptions\" option to be an array, %s given",
PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(txn_options));
goto cleanup;
}
/* Parse transaction options */
- txn_opts = php_mongodb_session_parse_transaction_options(txn_options TSRMLS_CC);
+ txn_opts = php_mongodb_session_parse_transaction_options(txn_options);
/* If an exception is thrown while parsing, the txn_opts struct is also
* NULL, so no need to free it here */
if (EG(exception)) {
goto cleanup;
}
/* If the options are non-empty, add them to the client session opts struct */
if (txn_opts) {
if (!cs_opts) {
cs_opts = mongoc_session_opts_new();
}
mongoc_session_opts_set_default_transaction_opts(cs_opts, txn_opts);
mongoc_transaction_opts_destroy(txn_opts);
}
}
/* If the Manager was created in a different process, reset the client so
* that its session pool is cleared. This will ensure that we do not re-use
* a server session (i.e. LSID) created by a parent process. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
cs = mongoc_client_start_session(intern->client, cs_opts, &error);
if (cs) {
- phongo_session_init(return_value, cs TSRMLS_CC);
+ phongo_session_init(return_value, cs);
} else {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
}
cleanup:
if (cs_opts) {
mongoc_session_opts_destroy(cs_opts);
}
} /* }}} */
/* {{{ MongoDB\Driver\Manager function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Manager___construct, 0, 0, 0)
ZEND_ARG_INFO(0, uri)
ZEND_ARG_ARRAY_INFO(0, options, 0)
ZEND_ARG_ARRAY_INFO(0, driverOptions, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_createClientEncryption, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, options, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeCommand, 0, 0, 2)
ZEND_ARG_INFO(0, db)
ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeRWCommand, 0, 0, 2)
ZEND_ARG_INFO(0, db)
ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0)
ZEND_ARG_ARRAY_INFO(0, options, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeQuery, 0, 0, 2)
ZEND_ARG_INFO(0, namespace)
ZEND_ARG_OBJ_INFO(0, zquery, MongoDB\\Driver\\Query, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeBulkWrite, 0, 0, 2)
ZEND_ARG_INFO(0, namespace)
ZEND_ARG_OBJ_INFO(0, zbulk, MongoDB\\Driver\\BulkWrite, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_selectServer, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_startSession, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_manager_me[] = {
/* clang-format off */
PHP_ME(Manager, __construct, ai_Manager___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, createClientEncryption, ai_Manager_createClientEncryption, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeCommand, ai_Manager_executeCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeReadCommand, ai_Manager_executeRWCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeWriteCommand, ai_Manager_executeRWCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeReadWriteCommand, ai_Manager_executeCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeQuery, ai_Manager_executeQuery, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeBulkWrite, ai_Manager_executeBulkWrite, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, getReadConcern, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, getReadPreference, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, getServers, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, getWriteConcern, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, selectServer, ai_Manager_selectServer, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, startSession, ai_Manager_startSession, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Manager object handlers */
static zend_object_handlers php_phongo_handler_manager;
-static void php_phongo_manager_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_manager_free_object(zend_object* object) /* {{{ */
{
php_phongo_manager_t* intern = Z_OBJ_MANAGER(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->client) {
MONGOC_DEBUG("Not destroying persistent client for Manager");
intern->client = NULL;
}
if (intern->client_hash) {
efree(intern->client_hash);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_manager_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_manager_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_manager_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_manager_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
PHONGO_SET_CREATED_BY_PID(intern);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_manager;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_manager_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_manager;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_manager_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_manager_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_manager_t* intern;
mongoc_server_description_t** sds;
size_t i, n = 0;
zval retval = ZVAL_STATIC_INIT;
- ZVAL_RETVAL_TYPE cluster;
+ zval cluster;
*is_temp = 1;
intern = Z_MANAGER_OBJ_P(object);
array_init_size(&retval, 2);
ADD_ASSOC_STRING(&retval, "uri", mongoc_uri_get_string(mongoc_client_get_uri(intern->client)));
sds = mongoc_client_get_server_descriptions(intern->client, &n);
-#if PHP_VERSION_ID >= 70000
array_init_size(&cluster, n);
for (i = 0; i < n; i++) {
zval obj;
if (!php_phongo_server_to_zval(&obj, sds[i])) {
/* Exception already thrown */
zval_ptr_dtor(&obj);
zval_ptr_dtor(&cluster);
goto done;
}
add_next_index_zval(&cluster, &obj);
}
ADD_ASSOC_ZVAL_EX(&retval, "cluster", &cluster);
-#else
- MAKE_STD_ZVAL(cluster);
- array_init_size(cluster, n);
-
- for (i = 0; i < n; i++) {
- zval* obj = NULL;
-
- MAKE_STD_ZVAL(obj);
- if (!php_phongo_server_to_zval(obj, sds[i])) {
- /* Exception already thrown */
- zval_ptr_dtor(&obj);
- zval_ptr_dtor(&cluster);
- goto done;
- }
-
- add_next_index_zval(cluster, obj);
- }
-
- ADD_ASSOC_ZVAL_EX(&retval, "cluster", cluster);
-#endif
done:
mongoc_server_descriptions_destroy_all(sds, n);
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_manager_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Manager", php_phongo_manager_me);
- php_phongo_manager_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_manager_ce = zend_register_internal_class(&ce);
php_phongo_manager_ce->create_object = php_phongo_manager_create_object;
PHONGO_CE_FINAL(php_phongo_manager_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_manager_ce);
memcpy(&php_phongo_handler_manager, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_manager.get_debug_info = php_phongo_manager_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_manager.free_obj = php_phongo_manager_free_object;
- php_phongo_handler_manager.offset = XtOffsetOf(php_phongo_manager_t, std);
-#endif
+ php_phongo_handler_manager.free_obj = php_phongo_manager_free_object;
+ php_phongo_handler_manager.offset = XtOffsetOf(php_phongo_manager_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Monitoring/CommandFailedEvent.c b/mongodb-1.8.1/src/MongoDB/Monitoring/CommandFailedEvent.c
similarity index 81%
rename from mongodb-1.7.4/src/MongoDB/Monitoring/CommandFailedEvent.c
rename to mongodb-1.8.1/src/MongoDB/Monitoring/CommandFailedEvent.c
index 3b7ce45c..e865b1f0 100644
--- a/mongodb-1.7.4/src/MongoDB/Monitoring/CommandFailedEvent.c
+++ b/mongodb-1.8.1/src/MongoDB/Monitoring/CommandFailedEvent.c
@@ -1,320 +1,277 @@
/*
* Copyright 2016-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_commandfailedevent_ce;
/* {{{ proto string CommandFailedEvent::getCommandName()
Returns the command name for this event */
PHP_METHOD(CommandFailedEvent, getCommandName)
{
php_phongo_commandfailedevent_t* intern;
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETVAL_STRING(intern->command_name);
+ RETVAL_STRING(intern->command_name);
} /* }}} */
/* {{{ proto int CommandFailedEvent::getDurationMicros()
Returns the event's duration in microseconds */
PHP_METHOD(CommandFailedEvent, getDurationMicros)
{
php_phongo_commandfailedevent_t* intern;
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(intern->duration_micros);
} /* }}} */
/* {{{ proto Exception CommandFailedEvent::getError()
Returns the error document associated with the event */
PHP_METHOD(CommandFailedEvent, getError)
{
php_phongo_commandfailedevent_t* intern;
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&intern->z_error, 1, 0);
-#else
- RETURN_ZVAL(intern->z_error, 1, 0);
-#endif
} /* }}} */
/* {{{ proto string CommandFailedEvent::getOperationId()
Returns the event's operation ID */
PHP_METHOD(CommandFailedEvent, getOperationId)
{
php_phongo_commandfailedevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
sprintf(int_as_string, "%" PRIu64, intern->operation_id);
- PHONGO_RETVAL_STRING(int_as_string);
+ RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto stdClass CommandFailedEvent::getReply()
Returns the reply document associated with the event */
PHP_METHOD(CommandFailedEvent, getReply)
{
php_phongo_commandfailedevent_t* intern;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
} /* }}} */
/* {{{ proto string CommandFailedEvent::getRequestId()
Returns the event's request ID */
PHP_METHOD(CommandFailedEvent, getRequestId)
{
php_phongo_commandfailedevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
sprintf(int_as_string, "%" PRIu64, intern->request_id);
- PHONGO_RETVAL_STRING(int_as_string);
+ RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto MongoDB\Driver\Server CommandFailedEvent::getServer()
Returns the Server from which the event originated */
PHP_METHOD(CommandFailedEvent, getServer)
{
php_phongo_commandfailedevent_t* intern;
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(return_value, intern->client, intern->server_id);
} /* }}} */
/**
* Event thrown when a command has failed to execute.
*
* This class is only constructed internally.
*/
/* {{{ MongoDB\Driver\Monitoring\CommandFailedEvent function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CommandFailedEvent_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_commandfailedevent_me[] = {
/* clang-format off */
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandFailedEvent_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getCommandName, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getError, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getDurationMicros, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getOperationId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getReply, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getRequestId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getServer, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Monitoring\CommandFailedEvent object handlers */
static zend_object_handlers php_phongo_handler_commandfailedevent;
-static void php_phongo_commandfailedevent_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_commandfailedevent_free_object(zend_object* object) /* {{{ */
{
php_phongo_commandfailedevent_t* intern = Z_OBJ_COMMANDFAILEDEVENT(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (!Z_ISUNDEF(intern->z_error)) {
zval_ptr_dtor(&intern->z_error);
}
if (intern->reply) {
bson_destroy(intern->reply);
}
if (intern->command_name) {
efree(intern->command_name);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_commandfailedevent_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_commandfailedevent_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_commandfailedevent_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_commandfailedevent_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_commandfailedevent;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_commandfailedevent_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_commandfailedevent;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_commandfailedevent_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_commandfailedevent_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_commandfailedevent_t* intern;
zval retval = ZVAL_STATIC_INIT;
char operation_id[20], request_id[20];
php_phongo_bson_state reply_state;
PHONGO_BSON_INIT_STATE(reply_state);
intern = Z_COMMANDFAILEDEVENT_OBJ_P(object);
*is_temp = 1;
array_init_size(&retval, 6);
ADD_ASSOC_STRING(&retval, "commandName", intern->command_name);
ADD_ASSOC_INT64(&retval, "durationMicros", (int64_t) intern->duration_micros);
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "error", &intern->z_error);
Z_ADDREF(intern->z_error);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "error", intern->z_error);
- Z_ADDREF_P(intern->z_error);
-#endif
sprintf(operation_id, "%" PRIu64, intern->operation_id);
ADD_ASSOC_STRING(&retval, "operationId", operation_id);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &reply_state)) {
zval_ptr_dtor(&reply_state.zchild);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL(&retval, "reply", &reply_state.zchild);
-#else
- ADD_ASSOC_ZVAL(&retval, "reply", reply_state.zchild);
-#endif
sprintf(request_id, "%" PRIu64, intern->request_id);
ADD_ASSOC_STRING(&retval, "requestId", request_id);
{
-#if PHP_VERSION_ID >= 70000
zval server;
- phongo_server_init(&server, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(&server, intern->client, intern->server_id);
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
-#else
- zval* server = NULL;
-
- MAKE_STD_ZVAL(server);
- phongo_server_init(server, intern->client, intern->server_id TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "server", server);
-#endif
}
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandFailedEvent", php_phongo_commandfailedevent_me);
- php_phongo_commandfailedevent_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_commandfailedevent_ce = zend_register_internal_class(&ce);
php_phongo_commandfailedevent_ce->create_object = php_phongo_commandfailedevent_create_object;
PHONGO_CE_FINAL(php_phongo_commandfailedevent_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandfailedevent_ce);
memcpy(&php_phongo_handler_commandfailedevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_commandfailedevent.get_debug_info = php_phongo_commandfailedevent_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_commandfailedevent.free_obj = php_phongo_commandfailedevent_free_object;
- php_phongo_handler_commandfailedevent.offset = XtOffsetOf(php_phongo_commandfailedevent_t, std);
-#endif
-
- return;
+ php_phongo_handler_commandfailedevent.free_obj = php_phongo_commandfailedevent_free_object;
+ php_phongo_handler_commandfailedevent.offset = XtOffsetOf(php_phongo_commandfailedevent_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Monitoring/CommandStartedEvent.c b/mongodb-1.8.1/src/MongoDB/Monitoring/CommandStartedEvent.c
similarity index 81%
rename from mongodb-1.7.4/src/MongoDB/Monitoring/CommandStartedEvent.c
rename to mongodb-1.8.1/src/MongoDB/Monitoring/CommandStartedEvent.c
index aeed7753..980eea2e 100644
--- a/mongodb-1.7.4/src/MongoDB/Monitoring/CommandStartedEvent.c
+++ b/mongodb-1.8.1/src/MongoDB/Monitoring/CommandStartedEvent.c
@@ -1,290 +1,258 @@
/*
* Copyright 2016-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_commandstartedevent_ce;
/* {{{ proto stdClass CommandStartedEvent::getCommand()
Returns the command document associated with the event */
PHP_METHOD(CommandStartedEvent, getCommand)
{
php_phongo_commandstartedevent_t* intern;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->command), intern->command->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
} /* }}} */
/* {{{ proto string CommandStartedEvent::getCommandName()
Returns the command name for this event */
PHP_METHOD(CommandStartedEvent, getCommandName)
{
php_phongo_commandstartedevent_t* intern;
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETVAL_STRING(intern->command_name);
+ RETVAL_STRING(intern->command_name);
} /* }}} */
/* {{{ proto string CommandStartedEvent::getDatabaseName()
Returns the database name for this event */
PHP_METHOD(CommandStartedEvent, getDatabaseName)
{
php_phongo_commandstartedevent_t* intern;
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETVAL_STRING(intern->database_name);
+ RETVAL_STRING(intern->database_name);
} /* }}} */
/* {{{ proto string CommandStartedEvent::getOperationId()
Returns the event's operation ID */
PHP_METHOD(CommandStartedEvent, getOperationId)
{
php_phongo_commandstartedevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
sprintf(int_as_string, "%" PRIu64, intern->operation_id);
- PHONGO_RETVAL_STRING(int_as_string);
+ RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto string CommandStartedEvent::getRequestId()
Returns the event's request ID */
PHP_METHOD(CommandStartedEvent, getRequestId)
{
php_phongo_commandstartedevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
sprintf(int_as_string, "%" PRIu64, intern->request_id);
- PHONGO_RETVAL_STRING(int_as_string);
+ RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto MongoDB\Driver\Server CommandStartedEvent::getServer()
Returns the Server from which the event originated */
PHP_METHOD(CommandStartedEvent, getServer)
{
php_phongo_commandstartedevent_t* intern;
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(return_value, intern->client, intern->server_id);
} /* }}} */
/**
* Event thrown when a command has started to execute.
*
* This class is only constructed internally.
*/
/* {{{ MongoDB\Driver\Monitoring\CommandStartedEvent function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CommandStartedEvent_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_commandstartedevent_me[] = {
/* clang-format off */
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandStartedEvent_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getCommand, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getCommandName, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getDatabaseName, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getOperationId, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getRequestId, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getServer, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Monitoring\CommandStartedEvent object handlers */
static zend_object_handlers php_phongo_handler_commandstartedevent;
-static void php_phongo_commandstartedevent_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_commandstartedevent_free_object(zend_object* object) /* {{{ */
{
php_phongo_commandstartedevent_t* intern = Z_OBJ_COMMANDSTARTEDEVENT(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->command) {
bson_destroy(intern->command);
}
if (intern->command_name) {
efree(intern->command_name);
}
if (intern->database_name) {
efree(intern->database_name);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_commandstartedevent_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_commandstartedevent_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_commandstartedevent_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_commandstartedevent_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_commandstartedevent;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_commandstartedevent_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_commandstartedevent;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_commandstartedevent_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_commandstartedevent_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_commandstartedevent_t* intern;
zval retval = ZVAL_STATIC_INIT;
char operation_id[20], request_id[20];
php_phongo_bson_state command_state;
PHONGO_BSON_INIT_STATE(command_state);
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(object);
*is_temp = 1;
array_init_size(&retval, 6);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->command), intern->command->len, &command_state)) {
zval_ptr_dtor(&command_state.zchild);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL(&retval, "command", &command_state.zchild);
-#else
- ADD_ASSOC_ZVAL(&retval, "command", command_state.zchild);
-#endif
ADD_ASSOC_STRING(&retval, "commandName", intern->command_name);
ADD_ASSOC_STRING(&retval, "databaseName", intern->database_name);
sprintf(operation_id, "%" PRIu64, intern->operation_id);
ADD_ASSOC_STRING(&retval, "operationId", operation_id);
sprintf(request_id, "%" PRIu64, intern->request_id);
ADD_ASSOC_STRING(&retval, "requestId", request_id);
{
-#if PHP_VERSION_ID >= 70000
zval server;
- phongo_server_init(&server, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(&server, intern->client, intern->server_id);
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
-#else
- zval* server = NULL;
-
- MAKE_STD_ZVAL(server);
- phongo_server_init(server, intern->client, intern->server_id TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "server", server);
-#endif
}
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_commandstartedevent_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandStartedEvent", php_phongo_commandstartedevent_me);
- php_phongo_commandstartedevent_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_commandstartedevent_ce = zend_register_internal_class(&ce);
php_phongo_commandstartedevent_ce->create_object = php_phongo_commandstartedevent_create_object;
PHONGO_CE_FINAL(php_phongo_commandstartedevent_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandstartedevent_ce);
memcpy(&php_phongo_handler_commandstartedevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_commandstartedevent.get_debug_info = php_phongo_commandstartedevent_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_commandstartedevent.free_obj = php_phongo_commandstartedevent_free_object;
- php_phongo_handler_commandstartedevent.offset = XtOffsetOf(php_phongo_commandstartedevent_t, std);
-#endif
+ php_phongo_handler_commandstartedevent.free_obj = php_phongo_commandstartedevent_free_object;
+ php_phongo_handler_commandstartedevent.offset = XtOffsetOf(php_phongo_commandstartedevent_t, std);
return;
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Monitoring/CommandSubscriber.c b/mongodb-1.8.1/src/MongoDB/Monitoring/CommandSubscriber.c
similarity index 95%
rename from mongodb-1.7.4/src/MongoDB/Monitoring/CommandSubscriber.c
rename to mongodb-1.8.1/src/MongoDB/Monitoring/CommandSubscriber.c
index e709e103..6d7ee90a 100644
--- a/mongodb-1.7.4/src/MongoDB/Monitoring/CommandSubscriber.c
+++ b/mongodb-1.8.1/src/MongoDB/Monitoring/CommandSubscriber.c
@@ -1,72 +1,72 @@
/*
* Copyright 2016-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_commandsubscriber_ce;
/* {{{ MongoDB\Driver\Monitoring\CommandSubscriber function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CommandSubscriber_commandStarted, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, event, MongoDB\\Driver\\Monitoring\\CommandStartedEvent, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_CommandSubscriber_commandSucceeded, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, event, MongoDB\\Driver\\Monitoring\\CommandSucceededEvent, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_CommandSubscriber_commandFailed, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, event, MongoDB\\Driver\\Monitoring\\CommandFailedEvent, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_commandsubscriber_me[] = {
/* clang-format off */
ZEND_ABSTRACT_ME(CommandSubscriber, commandStarted, ai_CommandSubscriber_commandStarted)
ZEND_ABSTRACT_ME(CommandSubscriber, commandSucceeded, ai_CommandSubscriber_commandSucceeded)
ZEND_ABSTRACT_ME(CommandSubscriber, commandFailed, ai_CommandSubscriber_commandFailed)
PHP_FE_END
/* clang-format on */
};
/* }}} */
void php_phongo_commandsubscriber_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandSubscriber", php_phongo_commandsubscriber_me);
- php_phongo_commandsubscriber_ce = zend_register_internal_interface(&ce TSRMLS_CC);
- zend_class_implements(php_phongo_commandsubscriber_ce TSRMLS_CC, 1, php_phongo_subscriber_ce);
+ php_phongo_commandsubscriber_ce = zend_register_internal_interface(&ce);
+ zend_class_implements(php_phongo_commandsubscriber_ce, 1, php_phongo_subscriber_ce);
return;
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Monitoring/CommandSucceededEvent.c b/mongodb-1.8.1/src/MongoDB/Monitoring/CommandSucceededEvent.c
similarity index 81%
rename from mongodb-1.7.4/src/MongoDB/Monitoring/CommandSucceededEvent.c
rename to mongodb-1.8.1/src/MongoDB/Monitoring/CommandSucceededEvent.c
index df05564d..f826d204 100644
--- a/mongodb-1.7.4/src/MongoDB/Monitoring/CommandSucceededEvent.c
+++ b/mongodb-1.8.1/src/MongoDB/Monitoring/CommandSucceededEvent.c
@@ -1,287 +1,255 @@
/*
* Copyright 2016-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_commandsucceededevent_ce;
/* {{{ proto string CommandSucceededEvent::getCommandName()
Returns the command name for this event */
PHP_METHOD(CommandSucceededEvent, getCommandName)
{
php_phongo_commandsucceededevent_t* intern;
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETVAL_STRING(intern->command_name);
+ RETVAL_STRING(intern->command_name);
} /* }}} */
/* {{{ proto int CommandSucceededEvent::getDurationMicros()
Returns the event's duration in microseconds */
PHP_METHOD(CommandSucceededEvent, getDurationMicros)
{
php_phongo_commandsucceededevent_t* intern;
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(intern->duration_micros);
} /* }}} */
/* {{{ proto string CommandSucceededEvent::getOperationId()
Returns the event's operation ID */
PHP_METHOD(CommandSucceededEvent, getOperationId)
{
php_phongo_commandsucceededevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
sprintf(int_as_string, "%" PRIu64, intern->operation_id);
- PHONGO_RETVAL_STRING(int_as_string);
+ RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto stdClass CommandSucceededEvent::getReply()
Returns the reply document associated with the event */
PHP_METHOD(CommandSucceededEvent, getReply)
{
php_phongo_commandsucceededevent_t* intern;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
} /* }}} */
/* {{{ proto string CommandsucceededEvent::getRequestId()
Returns the event's request ID */
PHP_METHOD(CommandSucceededEvent, getRequestId)
{
php_phongo_commandsucceededevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
sprintf(int_as_string, "%" PRIu64, intern->request_id);
- PHONGO_RETVAL_STRING(int_as_string);
+ RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto MongoDB\Driver\Server CommandSucceededEvent::getServer()
Returns the Server from which the event originated */
PHP_METHOD(CommandSucceededEvent, getServer)
{
php_phongo_commandsucceededevent_t* intern;
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(return_value, intern->client, intern->server_id);
} /* }}} */
/**
* Event thrown when a command has succeeded to execute.
*
* This class is only constructed internally.
*/
/* {{{ MongoDB\Driver\Monitoring\CommandSucceededEvent function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CommandSucceededEvent_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_commandsucceededevent_me[] = {
/* clang-format off */
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandSucceededEvent_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getCommandName, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getDurationMicros, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getOperationId, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getReply, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getRequestId, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getServer, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Monitoring\CommandSucceededEvent object handlers */
static zend_object_handlers php_phongo_handler_commandsucceededevent;
-static void php_phongo_commandsucceededevent_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_commandsucceededevent_free_object(zend_object* object) /* {{{ */
{
php_phongo_commandsucceededevent_t* intern = Z_OBJ_COMMANDSUCCEEDEDEVENT(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->reply) {
bson_destroy(intern->reply);
}
if (intern->command_name) {
efree(intern->command_name);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_commandsucceededevent_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_commandsucceededevent_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_commandsucceededevent_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_commandsucceededevent_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_commandsucceededevent;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_commandsucceededevent_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_commandsucceededevent;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_commandsucceededevent_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_commandsucceededevent_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_commandsucceededevent_t* intern;
zval retval = ZVAL_STATIC_INIT;
char operation_id[20], request_id[20];
php_phongo_bson_state reply_state;
PHONGO_BSON_INIT_STATE(reply_state);
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(object);
*is_temp = 1;
array_init_size(&retval, 6);
ADD_ASSOC_STRING(&retval, "commandName", intern->command_name);
ADD_ASSOC_INT64(&retval, "durationMicros", (int64_t) intern->duration_micros);
sprintf(operation_id, "%" PRIu64, intern->operation_id);
ADD_ASSOC_STRING(&retval, "operationId", operation_id);
if (php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &reply_state)) {
zval_ptr_dtor(&reply_state.zchild);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL(&retval, "reply", &reply_state.zchild);
-#else
- ADD_ASSOC_ZVAL(&retval, "reply", reply_state.zchild);
-#endif
sprintf(request_id, "%" PRIu64, intern->request_id);
ADD_ASSOC_STRING(&retval, "requestId", request_id);
{
-#if PHP_VERSION_ID >= 70000
zval server;
- phongo_server_init(&server, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(&server, intern->client, intern->server_id);
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
-#else
- zval* server = NULL;
-
- MAKE_STD_ZVAL(server);
- phongo_server_init(server, intern->client, intern->server_id TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "server", server);
-#endif
}
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandSucceededEvent", php_phongo_commandsucceededevent_me);
- php_phongo_commandsucceededevent_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_commandsucceededevent_ce = zend_register_internal_class(&ce);
php_phongo_commandsucceededevent_ce->create_object = php_phongo_commandsucceededevent_create_object;
PHONGO_CE_FINAL(php_phongo_commandsucceededevent_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandsucceededevent_ce);
memcpy(&php_phongo_handler_commandsucceededevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_commandsucceededevent.get_debug_info = php_phongo_commandsucceededevent_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_commandsucceededevent.free_obj = php_phongo_commandsucceededevent_free_object;
- php_phongo_handler_commandsucceededevent.offset = XtOffsetOf(php_phongo_commandsucceededevent_t, std);
-#endif
+ php_phongo_handler_commandsucceededevent.free_obj = php_phongo_commandsucceededevent_free_object;
+ php_phongo_handler_commandsucceededevent.offset = XtOffsetOf(php_phongo_commandsucceededevent_t, std);
return;
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Monitoring/Subscriber.c b/mongodb-1.8.1/src/MongoDB/Monitoring/Subscriber.c
similarity index 99%
rename from mongodb-1.7.4/src/MongoDB/Monitoring/Subscriber.c
rename to mongodb-1.8.1/src/MongoDB/Monitoring/Subscriber.c
index cfd270b6..3d647a92 100644
--- a/mongodb-1.7.4/src/MongoDB/Monitoring/Subscriber.c
+++ b/mongodb-1.8.1/src/MongoDB/Monitoring/Subscriber.c
@@ -1,54 +1,54 @@
/*
* Copyright 2016-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_subscriber_ce;
/* {{{ MongoDB\Driver\Monitoring\Subscriber function entries */
static zend_function_entry php_phongo_subscriber_me[] = {
PHP_FE_END
};
/* }}} */
void php_phongo_subscriber_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "Subscriber", php_phongo_subscriber_me);
- php_phongo_subscriber_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+ php_phongo_subscriber_ce = zend_register_internal_interface(&ce);
return;
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Monitoring/functions.c b/mongodb-1.8.1/src/MongoDB/Monitoring/functions.c
similarity index 73%
rename from mongodb-1.7.4/src/MongoDB/Monitoring/functions.c
rename to mongodb-1.8.1/src/MongoDB/Monitoring/functions.c
index 22dc4dd3..d5ea791a 100644
--- a/mongodb-1.7.4/src/MongoDB/Monitoring/functions.c
+++ b/mongodb-1.8.1/src/MongoDB/Monitoring/functions.c
@@ -1,117 +1,100 @@
/*
* Copyright 2016-2017 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.
*/
#include <php.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
ZEND_EXTERN_MODULE_GLOBALS(mongodb)
-static char* php_phongo_make_subscriber_hash(zval* subscriber TSRMLS_DC)
+static char* php_phongo_make_subscriber_hash(zval* subscriber)
{
char* hash;
int hash_len;
hash_len = spprintf(&hash, 0, "SUBS-%09d", Z_OBJ_HANDLE_P(subscriber));
return hash;
}
/* {{{ proto void MongoDB\Driver\Monitoring\addSubscriber(MongoDB\Driver\Monitoring\Subscriber $subscriber)
Adds a monitoring subscriber to the set of subscribers */
PHP_FUNCTION(MongoDB_Driver_Monitoring_addSubscriber)
{
zval* zSubscriber = NULL;
char* hash;
-#if PHP_VERSION_ID >= 70000
zval* subscriber;
-#else
- zval** subscriber;
-#endif
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zSubscriber, php_phongo_subscriber_ce) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zSubscriber, php_phongo_subscriber_ce) == FAILURE) {
return;
}
/* The HashTable should never be NULL, as it's initialized during RINIT and
* destroyed during RSHUTDOWN. This is simply a defensive guard. */
if (!MONGODB_G(subscribers)) {
return;
}
- hash = php_phongo_make_subscriber_hash(zSubscriber TSRMLS_CC);
+ hash = php_phongo_make_subscriber_hash(zSubscriber);
/* If we have already stored the subscriber, bail out. Otherwise, add
* subscriber to list */
-#if PHP_VERSION_ID >= 70000
if ((subscriber = zend_hash_str_find(MONGODB_G(subscribers), hash, strlen(hash)))) {
efree(hash);
return;
}
zend_hash_str_update(MONGODB_G(subscribers), hash, strlen(hash), zSubscriber);
-#else
- if (zend_hash_find(MONGODB_G(subscribers), hash, strlen(hash) + 1, (void**) &subscriber) == SUCCESS) {
- efree(hash);
- return;
- }
-
- zend_hash_update(MONGODB_G(subscribers), hash, strlen(hash) + 1, (void*) &zSubscriber, sizeof(zval*), NULL);
-#endif
Z_ADDREF_P(zSubscriber);
efree(hash);
} /* }}} */
/* {{{ proto void MongoDB\Driver\Monitoring\removeSubscriber(MongoDB\Driver\Monitoring\Subscriber $subscriber)
Removes a monitoring subscriber from the set of subscribers */
PHP_FUNCTION(MongoDB_Driver_Monitoring_removeSubscriber)
{
zval* zSubscriber = NULL;
char* hash;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zSubscriber, php_phongo_subscriber_ce) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zSubscriber, php_phongo_subscriber_ce) == FAILURE) {
return;
}
/* The HashTable should never be NULL, as it's initialized during RINIT and
* destroyed during RSHUTDOWN. This is simply a defensive guard. */
if (!MONGODB_G(subscribers)) {
return;
}
- hash = php_phongo_make_subscriber_hash(zSubscriber TSRMLS_CC);
+ hash = php_phongo_make_subscriber_hash(zSubscriber);
-#if PHP_VERSION_ID >= 70000
zend_hash_str_del(MONGODB_G(subscribers), hash, strlen(hash));
-#else
- zend_hash_del(MONGODB_G(subscribers), hash, strlen(hash) + 1);
-#endif
efree(hash);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Monitoring/functions.h b/mongodb-1.8.1/src/MongoDB/Monitoring/functions.h
similarity index 100%
rename from mongodb-1.7.4/src/MongoDB/Monitoring/functions.h
rename to mongodb-1.8.1/src/MongoDB/Monitoring/functions.h
diff --git a/mongodb-1.7.4/src/MongoDB/Query.c b/mongodb-1.8.1/src/MongoDB/Query.c
similarity index 68%
rename from mongodb-1.7.4/src/MongoDB/Query.c
rename to mongodb-1.8.1/src/MongoDB/Query.c
index cc011bb3..415b083c 100644
--- a/mongodb-1.7.4/src/MongoDB/Query.c
+++ b/mongodb-1.8.1/src/MongoDB/Query.c
@@ -1,541 +1,502 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_array_api.h"
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_query_ce;
/* Appends a string field into the BSON options. Returns true on success;
* otherwise, false is returned and an exception is thrown. */
-static bool php_phongo_query_opts_append_string(bson_t* opts, const char* opts_key, zval* zarr, const char* zarr_key TSRMLS_DC) /* {{{ */
+static bool php_phongo_query_opts_append_string(bson_t* opts, const char* opts_key, zval* zarr, const char* zarr_key) /* {{{ */
{
zval* value = php_array_fetch(zarr, zarr_key);
if (Z_TYPE_P(value) != IS_STRING) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" %s to be string, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" %s to be string, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
return false;
}
if (!bson_append_utf8(opts, opts_key, strlen(opts_key), Z_STRVAL_P(value), Z_STRLEN_P(value))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", opts_key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", opts_key);
return false;
}
return true;
} /* }}} */
/* Appends a document field for the given opts document and key. Returns true on
* success; otherwise, false is returned and an exception is thrown. */
-static bool php_phongo_query_opts_append_document(bson_t* opts, const char* opts_key, zval* zarr, const char* zarr_key TSRMLS_DC) /* {{{ */
+static bool php_phongo_query_opts_append_document(bson_t* opts, const char* opts_key, zval* zarr, const char* zarr_key) /* {{{ */
{
zval* value = php_array_fetch(zarr, zarr_key);
bson_t b = BSON_INITIALIZER;
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" %s to be array or object, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" %s to be array or object, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
return false;
}
- php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL);
if (EG(exception)) {
bson_destroy(&b);
return false;
}
if (!bson_validate(&b, BSON_VALIDATE_EMPTY_KEYS, NULL)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot use empty keys in \"%s\" %s", zarr_key, zarr_key[0] == '$' ? "modifier" : "option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot use empty keys in \"%s\" %s", zarr_key, zarr_key[0] == '$' ? "modifier" : "option");
bson_destroy(&b);
return false;
}
if (!BSON_APPEND_DOCUMENT(opts, opts_key, &b)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", opts_key);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", opts_key);
bson_destroy(&b);
return false;
}
bson_destroy(&b);
return true;
} /* }}} */
-#define PHONGO_QUERY_OPT_BOOL_EX(opt, zarr, key, deprecated) \
- if ((zarr) && php_array_existsc((zarr), (key))) { \
- if ((deprecated)) { \
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"%s\" option is deprecated and will be removed in a future release", key); \
- } \
- if (!BSON_APPEND_BOOL(intern->opts, (opt), php_array_fetchc_bool((zarr), (key)))) { \
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", (opt)); \
- return false; \
- } \
+#define PHONGO_QUERY_OPT_BOOL_EX(opt, zarr, key, deprecated) \
+ if ((zarr) && php_array_existsc((zarr), (key))) { \
+ if ((deprecated)) { \
+ php_error_docref(NULL, E_DEPRECATED, "The \"%s\" option is deprecated and will be removed in a future release", key); \
+ } \
+ if (!BSON_APPEND_BOOL(intern->opts, (opt), php_array_fetchc_bool((zarr), (key)))) { \
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
+ return false; \
+ } \
}
#define PHONGO_QUERY_OPT_BOOL(opt, zarr, key) PHONGO_QUERY_OPT_BOOL_EX((opt), (zarr), (key), 0)
#define PHONGO_QUERY_OPT_BOOL_DEPRECATED(opt, zarr, key) PHONGO_QUERY_OPT_BOOL_EX((opt), (zarr), (key), 1)
-#define PHONGO_QUERY_OPT_DOCUMENT(opt, zarr, key) \
- if ((zarr) && php_array_existsc((zarr), (key))) { \
- if (!php_phongo_query_opts_append_document(intern->opts, (opt), (zarr), (key) TSRMLS_CC)) { \
- return false; \
- } \
+#define PHONGO_QUERY_OPT_DOCUMENT(opt, zarr, key) \
+ if ((zarr) && php_array_existsc((zarr), (key))) { \
+ if (!php_phongo_query_opts_append_document(intern->opts, (opt), (zarr), (key))) { \
+ return false; \
+ } \
}
/* Note: handling of integer options will depend on SIZEOF_ZEND_LONG and we
* are not converting strings to 64-bit integers for 32-bit platforms. */
-#define PHONGO_QUERY_OPT_INT64_EX(opt, zarr, key, deprecated) \
- if ((zarr) && php_array_existsc((zarr), (key))) { \
- if ((deprecated)) { \
- php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The \"%s\" option is deprecated and will be removed in a future release", key); \
- } \
- if (!BSON_APPEND_INT64(intern->opts, (opt), php_array_fetchc_long((zarr), (key)))) { \
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", (opt)); \
- return false; \
- } \
+#define PHONGO_QUERY_OPT_INT64_EX(opt, zarr, key, deprecated) \
+ if ((zarr) && php_array_existsc((zarr), (key))) { \
+ if ((deprecated)) { \
+ php_error_docref(NULL, E_DEPRECATED, "The \"%s\" option is deprecated and will be removed in a future release", key); \
+ } \
+ if (!BSON_APPEND_INT64(intern->opts, (opt), php_array_fetchc_long((zarr), (key)))) { \
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
+ return false; \
+ } \
}
#define PHONGO_QUERY_OPT_INT64(opt, zarr, key) PHONGO_QUERY_OPT_INT64_EX((opt), (zarr), (key), 0)
#define PHONGO_QUERY_OPT_INT64_DEPRECATED(opt, zarr, key) PHONGO_QUERY_OPT_INT64_EX((opt), (zarr), (key), 1)
-#define PHONGO_QUERY_OPT_STRING(opt, zarr, key) \
- if ((zarr) && php_array_existsc((zarr), (key))) { \
- if (!php_phongo_query_opts_append_string(intern->opts, (opt), (zarr), (key) TSRMLS_CC)) { \
- return false; \
- } \
+#define PHONGO_QUERY_OPT_STRING(opt, zarr, key) \
+ if ((zarr) && php_array_existsc((zarr), (key))) { \
+ if (!php_phongo_query_opts_append_string(intern->opts, (opt), (zarr), (key))) { \
+ return false; \
+ } \
}
/* Initialize the "hint" option. Returns true on success; otherwise, false is
* returned and an exception is thrown.
*
* The "hint" option (or "$hint" modifier) must be a string or document. Check
* for both types and merge into BSON options accordingly. */
-static bool php_phongo_query_init_hint(php_phongo_query_t* intern, zval* options, zval* modifiers TSRMLS_DC) /* {{{ */
+static bool php_phongo_query_init_hint(php_phongo_query_t* intern, zval* options, zval* modifiers) /* {{{ */
{
/* The "hint" option (or "$hint" modifier) must be a string or document.
* Check for both types and merge into BSON options accordingly. */
if (php_array_existsc(options, "hint")) {
zend_uchar type = Z_TYPE_P(php_array_fetchc(options, "hint"));
if (type == IS_STRING) {
PHONGO_QUERY_OPT_STRING("hint", options, "hint");
} else if (type == IS_OBJECT || type == IS_ARRAY) {
PHONGO_QUERY_OPT_DOCUMENT("hint", options, "hint");
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(type));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(type));
return false;
}
} else if (modifiers && php_array_existsc(modifiers, "$hint")) {
zend_uchar type = Z_TYPE_P(php_array_fetchc(modifiers, "$hint"));
if (type == IS_STRING) {
PHONGO_QUERY_OPT_STRING("hint", modifiers, "$hint");
} else if (type == IS_OBJECT || type == IS_ARRAY) {
PHONGO_QUERY_OPT_DOCUMENT("hint", modifiers, "$hint");
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"$hint\" modifier to be string, array, or object, %s given", zend_get_type_by_const(type));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"$hint\" modifier to be string, array, or object, %s given", zend_get_type_by_const(type));
return false;
}
}
return true;
} /* }}} */
/* Initialize the "limit" and "singleBatch" options. Returns true on success;
* otherwise, false is returned and an exception is thrown.
*
* mongoc_collection_find_with_opts() requires a non-negative limit. For
* backwards compatibility, a negative limit should be set as a positive value
* and default singleBatch to true. */
-static bool php_phongo_query_init_limit_and_singlebatch(php_phongo_query_t* intern, zval* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_query_init_limit_and_singlebatch(php_phongo_query_t* intern, zval* options) /* {{{ */
{
if (php_array_fetchc_long(options, "limit") < 0) {
- phongo_long limit = php_array_fetchc_long(options, "limit");
+ zend_long limit = php_array_fetchc_long(options, "limit");
if (!BSON_APPEND_INT64(intern->opts, "limit", -limit)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"limit\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"limit\" option");
return false;
}
if (php_array_existsc(options, "singleBatch") && !php_array_fetchc_bool(options, "singleBatch")) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Negative \"limit\" option conflicts with false \"singleBatch\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Negative \"limit\" option conflicts with false \"singleBatch\" option");
return false;
} else {
if (!BSON_APPEND_BOOL(intern->opts, "singleBatch", true)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"singleBatch\" option");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"singleBatch\" option");
return false;
}
}
} else {
PHONGO_QUERY_OPT_INT64("limit", options, "limit");
PHONGO_QUERY_OPT_BOOL("singleBatch", options, "singleBatch");
}
return true;
} /* }}} */
/* Initialize the "readConcern" option. Returns true on success; otherwise,
* false is returned and an exception is thrown.
*
* The "readConcern" option should be a MongoDB\Driver\ReadConcern instance,
* which must be converted to a mongoc_read_concern_t. */
-static bool php_phongo_query_init_readconcern(php_phongo_query_t* intern, zval* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_query_init_readconcern(php_phongo_query_t* intern, zval* options) /* {{{ */
{
zval* read_concern;
if (!php_array_existsc(options, "readConcern")) {
return true;
}
read_concern = php_array_fetchc(options, "readConcern");
- if (Z_TYPE_P(read_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(read_concern), php_phongo_readconcern_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(read_concern));
+ if (Z_TYPE_P(read_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(read_concern), php_phongo_readconcern_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(read_concern));
return false;
}
- intern->read_concern = mongoc_read_concern_copy(phongo_read_concern_from_zval(read_concern TSRMLS_CC));
+ intern->read_concern = mongoc_read_concern_copy(phongo_read_concern_from_zval(read_concern));
return true;
} /* }}} */
/* Initialize the "maxAwaitTimeMS" option. Returns true on success; otherwise,
* false is returned and an exception is thrown.
*
* The "maxAwaitTimeMS" option is assigned to the cursor after query execution
* via mongoc_cursor_set_max_await_time_ms(). */
-static bool php_phongo_query_init_max_await_time_ms(php_phongo_query_t* intern, zval* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_query_init_max_await_time_ms(php_phongo_query_t* intern, zval* options) /* {{{ */
{
int64_t max_await_time_ms;
if (!php_array_existsc(options, "maxAwaitTimeMS")) {
return true;
}
max_await_time_ms = php_array_fetchc_long(options, "maxAwaitTimeMS");
if (max_await_time_ms < 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"maxAwaitTimeMS\" option to be >= 0, %" PRId64 " given", max_await_time_ms);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"maxAwaitTimeMS\" option to be >= 0, %" PRId64 " given", max_await_time_ms);
return false;
}
if (max_await_time_ms > UINT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"maxAwaitTimeMS\" option to be <= %" PRIu32 ", %" PRId64 " given", UINT32_MAX, max_await_time_ms);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"maxAwaitTimeMS\" option to be <= %" PRIu32 ", %" PRId64 " given", UINT32_MAX, max_await_time_ms);
return false;
}
intern->max_await_time_ms = (uint32_t) max_await_time_ms;
return true;
} /* }}} */
/* Initializes the php_phongo_query_t from filter and options arguments. This
* function will fall back to a modifier in the absence of a top-level option
* (where applicable). */
-static bool php_phongo_query_init(php_phongo_query_t* intern, zval* filter, zval* options TSRMLS_DC) /* {{{ */
+static bool php_phongo_query_init(php_phongo_query_t* intern, zval* filter, zval* options) /* {{{ */
{
zval* modifiers = NULL;
intern->filter = bson_new();
intern->opts = bson_new();
intern->max_await_time_ms = 0;
- php_phongo_zval_to_bson(filter, PHONGO_BSON_NONE, intern->filter, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(filter, PHONGO_BSON_NONE, intern->filter, NULL);
/* Note: if any exceptions are thrown, we can simply return as PHP will
* invoke php_phongo_query_free_object to destruct the object. */
if (EG(exception)) {
return false;
}
if (!bson_validate(intern->filter, BSON_VALIDATE_EMPTY_KEYS, NULL)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot use empty keys in filter document");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot use empty keys in filter document");
return false;
}
if (!options) {
return true;
}
if (php_array_existsc(options, "modifiers")) {
modifiers = php_array_fetchc(options, "modifiers");
if (Z_TYPE_P(modifiers) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"modifiers\" option to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(modifiers));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"modifiers\" option to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(modifiers));
return false;
}
}
+ PHONGO_QUERY_OPT_BOOL("allowDiskUse", options, "allowDiskUse")
PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "allowPartialResults")
else PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "partial");
PHONGO_QUERY_OPT_BOOL("awaitData", options, "awaitData");
PHONGO_QUERY_OPT_INT64("batchSize", options, "batchSize");
PHONGO_QUERY_OPT_DOCUMENT("collation", options, "collation");
PHONGO_QUERY_OPT_STRING("comment", options, "comment")
else PHONGO_QUERY_OPT_STRING("comment", modifiers, "$comment");
PHONGO_QUERY_OPT_BOOL("exhaust", options, "exhaust");
PHONGO_QUERY_OPT_DOCUMENT("max", options, "max")
else PHONGO_QUERY_OPT_DOCUMENT("max", modifiers, "$max");
PHONGO_QUERY_OPT_INT64_DEPRECATED("maxScan", options, "maxScan")
else PHONGO_QUERY_OPT_INT64_DEPRECATED("maxScan", modifiers, "$maxScan");
PHONGO_QUERY_OPT_INT64("maxTimeMS", options, "maxTimeMS")
else PHONGO_QUERY_OPT_INT64("maxTimeMS", modifiers, "$maxTimeMS");
PHONGO_QUERY_OPT_DOCUMENT("min", options, "min")
else PHONGO_QUERY_OPT_DOCUMENT("min", modifiers, "$min");
PHONGO_QUERY_OPT_BOOL("noCursorTimeout", options, "noCursorTimeout");
- PHONGO_QUERY_OPT_BOOL("oplogReplay", options, "oplogReplay");
+ PHONGO_QUERY_OPT_BOOL_DEPRECATED("oplogReplay", options, "oplogReplay");
PHONGO_QUERY_OPT_DOCUMENT("projection", options, "projection");
PHONGO_QUERY_OPT_BOOL("returnKey", options, "returnKey")
else PHONGO_QUERY_OPT_BOOL("returnKey", modifiers, "$returnKey");
PHONGO_QUERY_OPT_BOOL("showRecordId", options, "showRecordId")
else PHONGO_QUERY_OPT_BOOL("showRecordId", modifiers, "$showDiskLoc");
PHONGO_QUERY_OPT_INT64("skip", options, "skip");
PHONGO_QUERY_OPT_DOCUMENT("sort", options, "sort")
else PHONGO_QUERY_OPT_DOCUMENT("sort", modifiers, "$orderby");
PHONGO_QUERY_OPT_BOOL_DEPRECATED("snapshot", options, "snapshot")
else PHONGO_QUERY_OPT_BOOL_DEPRECATED("snapshot", modifiers, "$snapshot");
PHONGO_QUERY_OPT_BOOL("tailable", options, "tailable");
/* The "$explain" modifier should be converted to an "explain" option, which
* libmongoc will later convert back to a modifier for the OP_QUERY code
* path. This modifier will be ignored for the find command code path. */
PHONGO_QUERY_OPT_BOOL("explain", modifiers, "$explain");
- if (!php_phongo_query_init_hint(intern, options, modifiers TSRMLS_CC)) {
+ if (!php_phongo_query_init_hint(intern, options, modifiers)) {
return false;
}
- if (!php_phongo_query_init_limit_and_singlebatch(intern, options TSRMLS_CC)) {
+ if (!php_phongo_query_init_limit_and_singlebatch(intern, options)) {
return false;
}
- if (!php_phongo_query_init_readconcern(intern, options TSRMLS_CC)) {
+ if (!php_phongo_query_init_readconcern(intern, options)) {
return false;
}
- if (!php_phongo_query_init_max_await_time_ms(intern, options TSRMLS_CC)) {
+ if (!php_phongo_query_init_max_await_time_ms(intern, options)) {
return false;
}
return true;
} /* }}} */
#undef PHONGO_QUERY_OPT_BOOL
#undef PHONGO_QUERY_OPT_DOCUMENT
#undef PHONGO_QUERY_OPT_INT64
#undef PHONGO_QUERY_OPT_STRING
/* {{{ proto void MongoDB\Driver\Query::__construct(array|object $filter[, array $options = array()])
Constructs a new Query */
static PHP_METHOD(Query, __construct)
{
php_phongo_query_t* intern;
zend_error_handling error_handling;
zval* filter;
zval* options = NULL;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_QUERY_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A|a!", &filter, &options) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "A|a!", &filter, &options) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
- php_phongo_query_init(intern, filter, options TSRMLS_CC);
+ php_phongo_query_init(intern, filter, options);
} /* }}} */
/* {{{ MongoDB\Driver\Query function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Query___construct, 0, 0, 1)
ZEND_ARG_INFO(0, filter)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Query_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_query_me[] = {
/* clang-format off */
PHP_ME(Query, __construct, ai_Query___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Query_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Query object handlers */
static zend_object_handlers php_phongo_handler_query;
-static void php_phongo_query_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_query_free_object(zend_object* object) /* {{{ */
{
php_phongo_query_t* intern = Z_OBJ_QUERY(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->filter) {
bson_clear(&intern->filter);
}
if (intern->opts) {
bson_clear(&intern->opts);
}
if (intern->read_concern) {
mongoc_read_concern_destroy(intern->read_concern);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_query_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_query_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_query_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_query_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_query;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_query_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_query;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_query_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_query_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_query_t* intern;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_QUERY_OBJ_P(object);
array_init_size(&retval, 3);
/* Avoid using PHONGO_TYPEMAP_NATIVE_ARRAY for decoding filter and opts
* documents so that users can differentiate BSON arrays and documents. */
if (intern->filter) {
-#if PHP_VERSION_ID >= 70000
zval zv;
-#else
- zval* zv;
-#endif
if (!php_phongo_bson_to_zval(bson_get_data(intern->filter), intern->filter->len, &zv)) {
zval_ptr_dtor(&zv);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "filter", &zv);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "filter", zv);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "filter");
}
if (intern->opts) {
-#if PHP_VERSION_ID >= 70000
zval zv;
-#else
- zval* zv;
-#endif
if (!php_phongo_bson_to_zval(bson_get_data(intern->opts), intern->opts->len, &zv)) {
zval_ptr_dtor(&zv);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "options", &zv);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "options", zv);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "options");
}
if (intern->read_concern) {
-#if PHP_VERSION_ID >= 70000
zval read_concern;
php_phongo_read_concern_to_zval(&read_concern, intern->read_concern);
ADD_ASSOC_ZVAL_EX(&retval, "readConcern", &read_concern);
-#else
- zval* read_concern = NULL;
- MAKE_STD_ZVAL(read_concern);
-
- php_phongo_read_concern_to_zval(read_concern, intern->read_concern);
- ADD_ASSOC_ZVAL_EX(&retval, "readConcern", read_concern);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "readConcern");
}
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_query_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Query", php_phongo_query_me);
- php_phongo_query_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_query_ce = zend_register_internal_class(&ce);
php_phongo_query_ce->create_object = php_phongo_query_create_object;
PHONGO_CE_FINAL(php_phongo_query_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_query_ce);
memcpy(&php_phongo_handler_query, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_query.get_debug_info = php_phongo_query_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_query.free_obj = php_phongo_query_free_object;
- php_phongo_handler_query.offset = XtOffsetOf(php_phongo_query_t, std);
-#endif
+ php_phongo_handler_query.free_obj = php_phongo_query_free_object;
+ php_phongo_handler_query.offset = XtOffsetOf(php_phongo_query_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/ReadConcern.c b/mongodb-1.8.1/src/MongoDB/ReadConcern.c
similarity index 68%
rename from mongodb-1.7.4/src/MongoDB/ReadConcern.c
rename to mongodb-1.8.1/src/MongoDB/ReadConcern.c
index 5cdd945c..7995001b 100644
--- a/mongodb-1.7.4/src/MongoDB/ReadConcern.c
+++ b/mongodb-1.8.1/src/MongoDB/ReadConcern.c
@@ -1,423 +1,362 @@
/*
* Copyright 2015-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_readconcern_ce;
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_readconcern_init_from_hash(php_phongo_readconcern_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_readconcern_init_from_hash(php_phongo_readconcern_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval* level;
intern->read_concern = mongoc_read_concern_new();
if ((level = zend_hash_str_find(props, "level", sizeof("level") - 1))) {
if (Z_TYPE_P(level) == IS_STRING) {
mongoc_read_concern_set_level(intern->read_concern, Z_STRVAL_P(level));
return true;
}
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"level\" string field", ZSTR_VAL(php_phongo_readconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"level\" string field", ZSTR_VAL(php_phongo_readconcern_ce->name));
goto failure;
}
-#else
- zval** level;
-
- intern->read_concern = mongoc_read_concern_new();
-
- if (zend_hash_find(props, "level", sizeof("level"), (void**) &level) == SUCCESS) {
- if (Z_TYPE_PP(level) == IS_STRING) {
- mongoc_read_concern_set_level(intern->read_concern, Z_STRVAL_PP(level));
- return true;
- }
-
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"level\" string field", ZSTR_VAL(php_phongo_readconcern_ce->name));
- goto failure;
- }
-#endif
return true;
failure:
mongoc_read_concern_destroy(intern->read_concern);
intern->read_concern = NULL;
return false;
} /* }}} */
/* {{{ proto void MongoDB\Driver\ReadConcern::__construct([string $level])
Constructs a new ReadConcern */
static PHP_METHOD(ReadConcern, __construct)
{
php_phongo_readconcern_t* intern;
zend_error_handling error_handling;
char* level = NULL;
- phongo_zpp_char_len level_len = 0;
+ size_t level_len = 0;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_READCONCERN_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &level, &level_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!", &level, &level_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
intern->read_concern = mongoc_read_concern_new();
if (level) {
mongoc_read_concern_set_level(intern->read_concern, level);
}
} /* }}} */
/* {{{ proto void MongoDB\BSON\ReadConcern::__set_state(array $properties)
*/
static PHP_METHOD(ReadConcern, __set_state)
{
php_phongo_readconcern_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_readconcern_ce);
intern = Z_READCONCERN_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_readconcern_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_readconcern_init_from_hash(intern, props);
} /* }}} */
/* {{{ proto string|null MongoDB\Driver\ReadConcern::getLevel()
Returns the ReadConcern "level" option */
static PHP_METHOD(ReadConcern, getLevel)
{
php_phongo_readconcern_t* intern;
const char* level;
intern = Z_READCONCERN_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
level = mongoc_read_concern_get_level(intern->read_concern);
if (level) {
- PHONGO_RETURN_STRING(level);
+ RETURN_STRING(level);
}
RETURN_NULL();
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\ReadConcern::isDefault()
Returns whether the read concern has not been modified (i.e. constructed
without a level or from a Manager with no read concern URI options). */
static PHP_METHOD(ReadConcern, isDefault)
{
php_phongo_readconcern_t* intern;
intern = Z_READCONCERN_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_BOOL(mongoc_read_concern_is_default(intern->read_concern));
} /* }}} */
-static HashTable* php_phongo_read_concern_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_read_concern_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_readconcern_t* intern;
HashTable* props;
const char* level;
intern = Z_READCONCERN_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 1);
if (!intern->read_concern) {
return props;
}
level = mongoc_read_concern_get_level(intern->read_concern);
if (level) {
-#if PHP_VERSION_ID >= 70000
zval z_level;
ZVAL_STRING(&z_level, level);
zend_hash_str_update(props, "level", sizeof("level") - 1, &z_level);
-#else
- zval* z_level;
-
- MAKE_STD_ZVAL(z_level);
- ZVAL_STRING(z_level, level, 1);
- zend_hash_update(props, "level", sizeof("level"), &z_level, sizeof(z_level), NULL);
-#endif
}
return props;
} /* }}} */
/* {{{ proto array MongoDB\Driver\ReadConcern::bsonSerialize()
*/
static PHP_METHOD(ReadConcern, bsonSerialize)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- ZVAL_ARR(return_value, php_phongo_read_concern_get_properties_hash(getThis(), true TSRMLS_CC));
+ ZVAL_ARR(return_value, php_phongo_read_concern_get_properties_hash(getThis(), true));
convert_to_object(return_value);
} /* }}} */
/* {{{ proto string MongoDB\Driver\ReadConcern::serialize()
*/
static PHP_METHOD(ReadConcern, serialize)
{
php_phongo_readconcern_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
const char* level;
intern = Z_READCONCERN_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!intern->read_concern) {
return;
}
level = mongoc_read_concern_get_level(intern->read_concern);
if (!level) {
- PHONGO_RETURN_STRING("");
+ RETURN_STRING("");
}
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 1);
ADD_ASSOC_STRING(&retval, "level", level);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 1);
- ADD_ASSOC_STRING(retval, "level", level);
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\Driver\ReadConcern::unserialize(string $serialized)
*/
static PHP_METHOD(ReadConcern, unserialize)
{
php_phongo_readconcern_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
- php_unserialize_data_t var_hash;
+ size_t serialized_len;
+ zval props;
+ php_unserialize_data_t var_hash;
intern = Z_READCONCERN_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
if (!serialized_len) {
return;
}
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_readconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_readconcern_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_readconcern_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_readconcern_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_readconcern_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\Driver\ReadConcern function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern___construct, 0, 0, 0)
ZEND_ARG_INFO(0, level)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_readconcern_me[] = {
/* clang-format off */
PHP_ME(ReadConcern, __construct, ai_ReadConcern___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadConcern, __set_state, ai_ReadConcern___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(ReadConcern, getLevel, ai_ReadConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadConcern, isDefault, ai_ReadConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadConcern, bsonSerialize, ai_ReadConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadConcern, serialize, ai_ReadConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadConcern, unserialize, ai_ReadConcern_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\ReadConcern object handlers */
static zend_object_handlers php_phongo_handler_readconcern;
-static void php_phongo_readconcern_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_readconcern_free_object(zend_object* object) /* {{{ */
{
php_phongo_readconcern_t* intern = Z_OBJ_READCONCERN(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
if (intern->read_concern) {
mongoc_read_concern_destroy(intern->read_concern);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
}
-static phongo_create_object_retval php_phongo_readconcern_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_readconcern_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_readconcern_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_readconcern_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_readconcern;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_readconcern_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_readconcern;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_readconcern_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_readconcern_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_read_concern_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_read_concern_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_readconcern_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_readconcern_get_properties(zval* object) /* {{{ */
{
- return php_phongo_read_concern_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_read_concern_get_properties_hash(object, false);
} /* }}} */
void php_phongo_readconcern_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "ReadConcern", php_phongo_readconcern_me);
- php_phongo_readconcern_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_readconcern_ce = zend_register_internal_class(&ce);
php_phongo_readconcern_ce->create_object = php_phongo_readconcern_create_object;
PHONGO_CE_FINAL(php_phongo_readconcern_ce);
- zend_class_implements(php_phongo_readconcern_ce TSRMLS_CC, 1, php_phongo_serializable_ce);
- zend_class_implements(php_phongo_readconcern_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_readconcern_ce, 1, php_phongo_serializable_ce);
+ zend_class_implements(php_phongo_readconcern_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_readconcern, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_readconcern.get_debug_info = php_phongo_readconcern_get_debug_info;
php_phongo_handler_readconcern.get_properties = php_phongo_readconcern_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_readconcern.free_obj = php_phongo_readconcern_free_object;
- php_phongo_handler_readconcern.offset = XtOffsetOf(php_phongo_readconcern_t, std);
-#endif
+ php_phongo_handler_readconcern.free_obj = php_phongo_readconcern_free_object;
+ php_phongo_handler_readconcern.offset = XtOffsetOf(php_phongo_readconcern_t, std);
- zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("LOCAL"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_LOCAL) TSRMLS_CC);
- zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("MAJORITY"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_MAJORITY) TSRMLS_CC);
- zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("LINEARIZABLE"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE) TSRMLS_CC);
- zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("AVAILABLE"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_AVAILABLE) TSRMLS_CC);
+ zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("LOCAL"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_LOCAL));
+ zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("MAJORITY"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_MAJORITY));
+ zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("LINEARIZABLE"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE));
+ zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("AVAILABLE"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_AVAILABLE));
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/ReadPreference.c b/mongodb-1.8.1/src/MongoDB/ReadPreference.c
similarity index 59%
rename from mongodb-1.7.4/src/MongoDB/ReadPreference.c
rename to mongodb-1.8.1/src/MongoDB/ReadPreference.c
index 1f9bffbb..87acb4d0 100644
--- a/mongodb-1.7.4/src/MongoDB/ReadPreference.c
+++ b/mongodb-1.8.1/src/MongoDB/ReadPreference.c
@@ -1,782 +1,758 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_array_api.h"
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_readpreference_ce;
#define PHONGO_READ_PRIMARY "primary"
#define PHONGO_READ_PRIMARY_PREFERRED "primaryPreferred"
#define PHONGO_READ_SECONDARY "secondary"
#define PHONGO_READ_SECONDARY_PREFERRED "secondaryPreferred"
#define PHONGO_READ_NEAREST "nearest"
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_readpreference_init_from_hash(php_phongo_readpreference_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_readpreference_init_from_hash(php_phongo_readpreference_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
- zval *mode, *tagSets, *maxStalenessSeconds;
+ zval *mode, *tagSets, *maxStalenessSeconds, *hedge;
if ((mode = zend_hash_str_find(props, "mode", sizeof("mode") - 1)) && Z_TYPE_P(mode) == IS_STRING) {
if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_PRIMARY) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY);
} else if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_PRIMARY_PREFERRED) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY_PREFERRED);
} else if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_SECONDARY) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY);
} else if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_SECONDARY_PREFERRED) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY_PREFERRED);
} else if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_NEAREST) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_NEAREST);
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires specific values for \"mode\" string field", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires specific values for \"mode\" string field", ZSTR_VAL(php_phongo_readpreference_ce->name));
return false;
}
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"mode\" field to be string", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"mode\" field to be string", ZSTR_VAL(php_phongo_readpreference_ce->name));
return false;
}
if ((tagSets = zend_hash_str_find(props, "tags", sizeof("tags") - 1))) {
if (Z_TYPE_P(tagSets) == IS_ARRAY) {
bson_t* tags = bson_new();
- php_phongo_read_preference_prep_tagsets(tagSets TSRMLS_CC);
- php_phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t*) tags, NULL TSRMLS_CC);
+ php_phongo_read_preference_prep_tagsets(tagSets);
+ php_phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t*) tags, NULL);
if (!php_phongo_read_preference_tags_are_valid(tags)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" array field to have zero or more documents", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"tags\" array field to have zero or more documents", ZSTR_VAL(php_phongo_readpreference_ce->name));
bson_destroy(tags);
goto failure;
}
if (!bson_empty(tags) && (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"tags\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_readpreference_ce->name));
bson_destroy(tags);
goto failure;
}
mongoc_read_prefs_set_tags(intern->read_preference, tags);
bson_destroy(tags);
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" field to be array", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"tags\" field to be array", ZSTR_VAL(php_phongo_readpreference_ce->name));
goto failure;
}
}
if ((maxStalenessSeconds = zend_hash_str_find(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds") - 1))) {
if (Z_TYPE_P(maxStalenessSeconds) == IS_LONG) {
- if (Z_LVAL_P(maxStalenessSeconds) < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" integer field to be >= %d", ZSTR_VAL(php_phongo_readpreference_ce->name), MONGOC_SMALLEST_MAX_STALENESS_SECONDS);
- goto failure;
- }
- if (Z_LVAL_P(maxStalenessSeconds) > INT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" integer field to be <= %" PRId32, ZSTR_VAL(php_phongo_readpreference_ce->name), INT32_MAX);
- goto failure;
- }
- if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_readpreference_ce->name));
- goto failure;
+ if (Z_LVAL_P(maxStalenessSeconds) != MONGOC_NO_MAX_STALENESS) {
+ if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"maxStalenessSeconds\" field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ goto failure;
+ }
+ if (Z_LVAL_P(maxStalenessSeconds) < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"maxStalenessSeconds\" integer field to be >= %d", ZSTR_VAL(php_phongo_readpreference_ce->name), MONGOC_SMALLEST_MAX_STALENESS_SECONDS);
+ goto failure;
+ }
+ if (Z_LVAL_P(maxStalenessSeconds) > INT32_MAX) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"maxStalenessSeconds\" integer field to be <= %" PRId32, ZSTR_VAL(php_phongo_readpreference_ce->name), INT32_MAX);
+ goto failure;
+ }
}
mongoc_read_prefs_set_max_staleness_seconds(intern->read_preference, Z_LVAL_P(maxStalenessSeconds));
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" field to be integer", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"maxStalenessSeconds\" field to be integer", ZSTR_VAL(php_phongo_readpreference_ce->name));
goto failure;
}
}
-#else
- zval **mode, **tagSets, **maxStalenessSeconds;
-
- if (zend_hash_find(props, "mode", sizeof("mode"), (void**) &mode) == SUCCESS && Z_TYPE_PP(mode) == IS_STRING) {
- if (strcasecmp(Z_STRVAL_PP(mode), PHONGO_READ_PRIMARY) == 0) {
- intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY);
- } else if (strcasecmp(Z_STRVAL_PP(mode), PHONGO_READ_PRIMARY_PREFERRED) == 0) {
- intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY_PREFERRED);
- } else if (strcasecmp(Z_STRVAL_PP(mode), PHONGO_READ_SECONDARY) == 0) {
- intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY);
- } else if (strcasecmp(Z_STRVAL_PP(mode), PHONGO_READ_SECONDARY_PREFERRED) == 0) {
- intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY_PREFERRED);
- } else if (strcasecmp(Z_STRVAL_PP(mode), PHONGO_READ_NEAREST) == 0) {
- intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_NEAREST);
- } else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires specific values for \"mode\" string field", ZSTR_VAL(php_phongo_readpreference_ce->name));
- return false;
- }
- } else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"mode\" field to be string", ZSTR_VAL(php_phongo_readpreference_ce->name));
- return false;
- }
- if (zend_hash_find(props, "tags", sizeof("tags"), (void**) &tagSets) == SUCCESS) {
- if (Z_TYPE_PP(tagSets) == IS_ARRAY) {
- bson_t* tags = bson_new();
-
- php_phongo_read_preference_prep_tagsets(*tagSets TSRMLS_CC);
- php_phongo_zval_to_bson(*tagSets, PHONGO_BSON_NONE, (bson_t*) tags, NULL TSRMLS_CC);
+ if ((hedge = zend_hash_str_find(props, "hedge", sizeof("hedge") - 1))) {
+ if (Z_TYPE_P(hedge) == IS_ARRAY || Z_TYPE_P(hedge) == IS_OBJECT) {
+ bson_t* hedge_doc = bson_new();
- if (!php_phongo_read_preference_tags_are_valid(tags)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" array field to have zero or more documents", ZSTR_VAL(php_phongo_readpreference_ce->name));
- bson_destroy(tags);
+ if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"hedge\" field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ bson_destroy(hedge_doc);
goto failure;
}
- if (!bson_empty(tags) && (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_readpreference_ce->name));
- bson_destroy(tags);
+ php_phongo_zval_to_bson(hedge, PHONGO_BSON_NONE, hedge_doc, NULL);
+
+ if (EG(exception)) {
+ bson_destroy(hedge_doc);
goto failure;
}
- mongoc_read_prefs_set_tags(intern->read_preference, tags);
- bson_destroy(tags);
+ mongoc_read_prefs_set_hedge(intern->read_preference, hedge_doc);
+ bson_destroy(hedge_doc);
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" field to be array", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"hedge\" field to be an array or object", ZSTR_VAL(php_phongo_readpreference_ce->name));
goto failure;
}
}
- if (zend_hash_find(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds"), (void**) &maxStalenessSeconds) == SUCCESS) {
- if (Z_TYPE_PP(maxStalenessSeconds) == IS_LONG) {
- if (Z_LVAL_PP(maxStalenessSeconds) < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" integer field to be >= %d", ZSTR_VAL(php_phongo_readpreference_ce->name), MONGOC_SMALLEST_MAX_STALENESS_SECONDS);
- goto failure;
- }
- if (Z_LVAL_PP(maxStalenessSeconds) > INT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" integer field to be <= %" PRId32, ZSTR_VAL(php_phongo_readpreference_ce->name), INT32_MAX);
- goto failure;
- }
- if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_readpreference_ce->name));
- goto failure;
- }
-
- mongoc_read_prefs_set_max_staleness_seconds(intern->read_preference, Z_LVAL_PP(maxStalenessSeconds));
- } else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" field to be integer", ZSTR_VAL(php_phongo_readpreference_ce->name));
- goto failure;
- }
+ if (!mongoc_read_prefs_is_valid(intern->read_preference)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Read preference is not valid");
+ goto failure;
}
-#endif
return true;
failure:
mongoc_read_prefs_destroy(intern->read_preference);
intern->read_preference = NULL;
return false;
} /* }}} */
-static const char* php_phongo_readpreference_get_mode_string(mongoc_read_mode_t mode TSRMLS_DC) /* {{{ */
+static const char* php_phongo_readpreference_get_mode_string(mongoc_read_mode_t mode) /* {{{ */
{
switch (mode) {
case MONGOC_READ_PRIMARY:
return PHONGO_READ_PRIMARY;
case MONGOC_READ_PRIMARY_PREFERRED:
return PHONGO_READ_PRIMARY_PREFERRED;
case MONGOC_READ_SECONDARY:
return PHONGO_READ_SECONDARY;
case MONGOC_READ_SECONDARY_PREFERRED:
return PHONGO_READ_SECONDARY_PREFERRED;
case MONGOC_READ_NEAREST:
return PHONGO_READ_NEAREST;
default:
/* Should never happen, but if it does: exception */
- phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Mode '%d' should never have been passed to php_phongo_readpreference_get_mode_string, please file a bug report", mode);
+ phongo_throw_exception(PHONGO_ERROR_LOGIC, "Mode '%d' should never have been passed to php_phongo_readpreference_get_mode_string, please file a bug report", mode);
break;
}
return NULL;
} /* }}} */
/* {{{ proto void MongoDB\Driver\ReadPreference::__construct(int|string $mode[, array $tagSets = array()[, array $options = array()]])
Constructs a new ReadPreference */
static PHP_METHOD(ReadPreference, __construct)
{
php_phongo_readpreference_t* intern;
zend_error_handling error_handling;
zval* mode;
zval* tagSets = NULL;
zval* options = NULL;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_READPREFERENCE_OBJ_P(getThis());
/* Separate the tagSets zval, since we may end up modifying it in
* php_phongo_read_preference_prep_tagsets() below. */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a/!a!", &mode, &tagSets, &options) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|a/!a!", &mode, &tagSets, &options) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
if (Z_TYPE_P(mode) == IS_LONG) {
switch (Z_LVAL_P(mode)) {
case MONGOC_READ_PRIMARY:
case MONGOC_READ_SECONDARY:
case MONGOC_READ_PRIMARY_PREFERRED:
case MONGOC_READ_SECONDARY_PREFERRED:
case MONGOC_READ_NEAREST:
intern->read_preference = mongoc_read_prefs_new(Z_LVAL_P(mode));
break;
default:
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid mode: %" PHONGO_LONG_FORMAT, Z_LVAL_P(mode));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Invalid mode: %" PHONGO_LONG_FORMAT, Z_LVAL_P(mode));
return;
}
} else if (Z_TYPE_P(mode) == IS_STRING) {
if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_PRIMARY) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY);
} else if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_PRIMARY_PREFERRED) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY_PREFERRED);
} else if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_SECONDARY) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY);
} else if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_SECONDARY_PREFERRED) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY_PREFERRED);
} else if (strcasecmp(Z_STRVAL_P(mode), PHONGO_READ_NEAREST) == 0) {
intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_NEAREST);
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid mode: '%s'", Z_STRVAL_P(mode));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Invalid mode: '%s'", Z_STRVAL_P(mode));
return;
}
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected mode to be integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(mode));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected mode to be integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(mode));
return;
}
if (tagSets) {
bson_t* tags = bson_new();
- php_phongo_read_preference_prep_tagsets(tagSets TSRMLS_CC);
- php_phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t*) tags, NULL TSRMLS_CC);
+ php_phongo_read_preference_prep_tagsets(tagSets);
+ php_phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t*) tags, NULL);
if (!php_phongo_read_preference_tags_are_valid(tags)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets must be an array of zero or more documents");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "tagSets must be an array of zero or more documents");
bson_destroy(tags);
return;
}
if (!bson_empty(tags) && (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets may not be used with primary mode");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "tagSets may not be used with primary mode");
bson_destroy(tags);
return;
}
mongoc_read_prefs_set_tags(intern->read_preference, tags);
bson_destroy(tags);
}
if (options && php_array_exists(options, "maxStalenessSeconds")) {
- phongo_long maxStalenessSeconds = php_array_fetchc_long(options, "maxStalenessSeconds");
+ zend_long maxStalenessSeconds = php_array_fetchc_long(options, "maxStalenessSeconds");
if (maxStalenessSeconds != MONGOC_NO_MAX_STALENESS) {
if (maxStalenessSeconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be >= %d, %" PHONGO_LONG_FORMAT " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, maxStalenessSeconds);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected maxStalenessSeconds to be >= %d, %" PHONGO_LONG_FORMAT " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, maxStalenessSeconds);
return;
}
if (maxStalenessSeconds > INT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be <= %" PRId32 ", %" PHONGO_LONG_FORMAT " given", INT32_MAX, maxStalenessSeconds);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected maxStalenessSeconds to be <= %" PRId32 ", %" PHONGO_LONG_FORMAT " given", INT32_MAX, maxStalenessSeconds);
return;
}
if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "maxStalenessSeconds may not be used with primary mode");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "maxStalenessSeconds may not be used with primary mode");
return;
}
}
mongoc_read_prefs_set_max_staleness_seconds(intern->read_preference, maxStalenessSeconds);
}
+ if (options && php_array_exists(options, "hedge")) {
+ zval* hedge = php_array_fetchc(options, "hedge");
+
+ if (Z_TYPE_P(hedge) == IS_ARRAY || Z_TYPE_P(hedge) == IS_OBJECT) {
+ bson_t* hedge_doc = bson_new();
+
+ if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "hedge may not be used with primary mode");
+ bson_destroy(hedge_doc);
+ return;
+ }
+
+ php_phongo_zval_to_bson(hedge, PHONGO_BSON_NONE, hedge_doc, NULL);
+
+ if (EG(exception)) {
+ bson_destroy(hedge_doc);
+ return;
+ }
+
+ mongoc_read_prefs_set_hedge(intern->read_preference, hedge_doc);
+ bson_destroy(hedge_doc);
+ } else {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"hedge\" field to be an array or object", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ return;
+ }
+ }
+
if (!mongoc_read_prefs_is_valid(intern->read_preference)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference is not valid");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Read preference is not valid");
return;
}
} /* }}} */
/* {{{ proto void MongoDB\BSON\ReadPreference::__set_state(array $properties)
*/
static PHP_METHOD(ReadPreference, __set_state)
{
php_phongo_readpreference_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_readpreference_ce);
intern = Z_READPREFERENCE_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_readpreference_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_readpreference_init_from_hash(intern, props);
+} /* }}} */
+
+/* {{{ proto array|null MongoDB\Driver\ReadPreference::getHedge()
+ Returns the ReadPreference hedge document */
+static PHP_METHOD(ReadPreference, getHedge)
+{
+ php_phongo_readpreference_t* intern;
+ const bson_t* hedge;
+
+ intern = Z_READPREFERENCE_OBJ_P(getThis());
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ hedge = mongoc_read_prefs_get_hedge(intern->read_preference);
+
+ if (!bson_empty0(hedge)) {
+ php_phongo_bson_state state;
+
+ PHONGO_BSON_INIT_STATE(state);
+
+ if (!php_phongo_bson_to_zval_ex(bson_get_data(hedge), hedge->len, &state)) {
+ zval_ptr_dtor(&state.zchild);
+ return;
+ }
+
+ RETURN_ZVAL(&state.zchild, 0, 1);
+ } else {
+ RETURN_NULL();
+ }
} /* }}} */
/* {{{ proto integer MongoDB\Driver\ReadPreference::getMaxStalenessSeconds()
Returns the ReadPreference maxStalenessSeconds value */
static PHP_METHOD(ReadPreference, getMaxStalenessSeconds)
{
php_phongo_readpreference_t* intern;
intern = Z_READPREFERENCE_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference));
} /* }}} */
/* {{{ proto integer MongoDB\Driver\ReadPreference::getMode()
Returns the ReadPreference mode */
static PHP_METHOD(ReadPreference, getMode)
{
php_phongo_readpreference_t* intern;
intern = Z_READPREFERENCE_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(mongoc_read_prefs_get_mode(intern->read_preference));
} /* }}} */
/* {{{ proto string MongoDB\Driver\ReadPreference::getModeString()
Returns the ReadPreference mode as string */
static PHP_METHOD(ReadPreference, getModeString)
{
php_phongo_readpreference_t* intern;
const char* mode_string;
intern = Z_READPREFERENCE_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- mode_string = php_phongo_readpreference_get_mode_string(mongoc_read_prefs_get_mode(intern->read_preference) TSRMLS_CC);
+ mode_string = php_phongo_readpreference_get_mode_string(mongoc_read_prefs_get_mode(intern->read_preference));
if (!mode_string) {
/* Exception already thrown */
return;
}
- PHONGO_RETURN_STRING(mode_string);
+ RETURN_STRING(mode_string);
} /* }}} */
/* {{{ proto array MongoDB\Driver\ReadPreference::getTagSets()
Returns the ReadPreference tag sets */
static PHP_METHOD(ReadPreference, getTagSets)
{
php_phongo_readpreference_t* intern;
const bson_t* tags;
intern = Z_READPREFERENCE_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
tags = mongoc_read_prefs_get_tags(intern->read_preference);
if (tags->len) {
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
if (!php_phongo_bson_to_zval_ex(bson_get_data(tags), tags->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
} else {
RETURN_NULL();
}
} /* }}} */
-static HashTable* php_phongo_readpreference_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_readpreference_get_properties_hash(zval* object, bool is_debug) /* {{{ */
{
php_phongo_readpreference_t* intern;
HashTable* props;
const char* modeString = NULL;
const bson_t* tags;
+ const bson_t* hedge;
mongoc_read_mode_t mode;
intern = Z_READPREFERENCE_OBJ_P(object);
- PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 3);
+ PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 4);
if (!intern->read_preference) {
return props;
}
tags = mongoc_read_prefs_get_tags(intern->read_preference);
mode = mongoc_read_prefs_get_mode(intern->read_preference);
- modeString = php_phongo_readpreference_get_mode_string(mode TSRMLS_CC);
+ modeString = php_phongo_readpreference_get_mode_string(mode);
+ hedge = mongoc_read_prefs_get_hedge(intern->read_preference);
if (modeString) {
-#if PHP_VERSION_ID >= 70000
zval z_mode;
ZVAL_STRING(&z_mode, modeString);
zend_hash_str_update(props, "mode", sizeof("mode") - 1, &z_mode);
-#else
- zval* z_mode;
-
- MAKE_STD_ZVAL(z_mode);
- ZVAL_STRING(z_mode, modeString, 1);
- zend_hash_update(props, "mode", sizeof("mode"), &z_mode, sizeof(z_mode), NULL);
-#endif
}
if (!bson_empty0(tags)) {
php_phongo_bson_state state;
/* Use PHONGO_TYPEMAP_NATIVE_ARRAY for the root type since tags is an
* array; however, inner documents and arrays can use the default. */
PHONGO_BSON_INIT_STATE(state);
state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
if (!php_phongo_bson_to_zval_ex(bson_get_data(tags), tags->len, &state)) {
zval_ptr_dtor(&state.zchild);
goto done;
}
-#if PHP_VERSION_ID >= 70000
zend_hash_str_update(props, "tags", sizeof("tags") - 1, &state.zchild);
-#else
- zend_hash_update(props, "tags", sizeof("tags"), &state.zchild, sizeof(state.zchild), NULL);
-#endif
}
if (mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference) != MONGOC_NO_MAX_STALENESS) {
long maxStalenessSeconds = mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference);
-#if PHP_VERSION_ID >= 70000
zval z_max_ss;
ZVAL_LONG(&z_max_ss, maxStalenessSeconds);
zend_hash_str_update(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds") - 1, &z_max_ss);
-#else
- zval* z_max_ss;
+ }
- MAKE_STD_ZVAL(z_max_ss);
- ZVAL_LONG(z_max_ss, maxStalenessSeconds);
- zend_hash_update(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds"), &z_max_ss, sizeof(z_max_ss), NULL);
-#endif
+ if (!bson_empty0(hedge)) {
+ php_phongo_bson_state state;
+
+ PHONGO_BSON_INIT_STATE(state);
+
+ if (!php_phongo_bson_to_zval_ex(bson_get_data(hedge), hedge->len, &state)) {
+ zval_ptr_dtor(&state.zchild);
+ goto done;
+ }
+
+ zend_hash_str_update(props, "hedge", sizeof("hedge") - 1, &state.zchild);
}
done:
return props;
} /* }}} */
/* {{{ proto array MongoDB\Driver\ReadPreference::bsonSerialize()
*/
static PHP_METHOD(ReadPreference, bsonSerialize)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- ZVAL_ARR(return_value, php_phongo_readpreference_get_properties_hash(getThis(), true TSRMLS_CC));
+ ZVAL_ARR(return_value, php_phongo_readpreference_get_properties_hash(getThis(), true));
convert_to_object(return_value);
} /* }}} */
/* {{{ proto string MongoDB\Driver\ReadPreference::serialize()
*/
static PHP_METHOD(ReadPreference, serialize)
{
php_phongo_readpreference_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
const char* modeString = NULL;
const bson_t* tags;
+ const bson_t* hedge;
int64_t maxStalenessSeconds;
mongoc_read_mode_t mode;
intern = Z_READPREFERENCE_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!intern->read_preference) {
return;
}
tags = mongoc_read_prefs_get_tags(intern->read_preference);
mode = mongoc_read_prefs_get_mode(intern->read_preference);
- modeString = php_phongo_readpreference_get_mode_string(mode TSRMLS_CC);
+ modeString = php_phongo_readpreference_get_mode_string(mode);
maxStalenessSeconds = mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference);
+ hedge = mongoc_read_prefs_get_hedge(intern->read_preference);
-#if PHP_VERSION_ID >= 70000
- array_init_size(&retval, 3);
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 3);
-#endif
+ array_init_size(&retval, 4);
if (modeString) {
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_STRING(&retval, "mode", modeString);
-#else
- ADD_ASSOC_STRING(retval, "mode", modeString);
-#endif
}
if (!bson_empty0(tags)) {
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
if (!php_phongo_bson_to_zval_ex(bson_get_data(tags), tags->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "tags", &state.zchild);
-#else
- ADD_ASSOC_ZVAL_EX(retval, "tags", state.zchild);
-#endif
}
if (maxStalenessSeconds != MONGOC_NO_MAX_STALENESS) {
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_LONG_EX(&retval, "maxStalenessSeconds", maxStalenessSeconds);
-#else
- ADD_ASSOC_LONG_EX(retval, "maxStalenessSeconds", maxStalenessSeconds);
-#endif
+ }
+
+ if (!bson_empty0(hedge)) {
+ php_phongo_bson_state state;
+
+ PHONGO_BSON_INIT_STATE(state);
+
+ if (!php_phongo_bson_to_zval_ex(bson_get_data(hedge), hedge->len, &state)) {
+ zval_ptr_dtor(&state.zchild);
+ return;
+ }
+
+ ADD_ASSOC_ZVAL_EX(&retval, "hedge", &state.zchild);
}
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\Driver\ReadPreference::unserialize(string $serialized)
*/
static PHP_METHOD(ReadPreference, unserialize)
{
php_phongo_readpreference_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
- php_unserialize_data_t var_hash;
+ size_t serialized_len;
+ zval props;
+ php_unserialize_data_t var_hash;
intern = Z_READPREFERENCE_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
if (!serialized_len) {
return;
}
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_readpreference_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_readpreference_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_readpreference_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_readpreference_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_readpreference_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\Driver\ReadPreference function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference___construct, 0, 0, 1)
ZEND_ARG_INFO(0, mode)
ZEND_ARG_ARRAY_INFO(0, tagSets, 1)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_readpreference_me[] = {
/* clang-format off */
PHP_ME(ReadPreference, __construct, ai_ReadPreference___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadPreference, __set_state, ai_ReadPreference___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME(ReadPreference, getHedge, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadPreference, getMaxStalenessSeconds, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadPreference, getMode, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadPreference, getModeString, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadPreference, getTagSets, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadPreference, bsonSerialize, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadPreference, serialize, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ReadPreference, unserialize, ai_ReadPreference_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\ReadPreference object handlers */
static zend_object_handlers php_phongo_handler_readpreference;
-static void php_phongo_readpreference_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_readpreference_free_object(zend_object* object) /* {{{ */
{
php_phongo_readpreference_t* intern = Z_OBJ_READPREFERENCE(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
if (intern->read_preference) {
mongoc_read_prefs_destroy(intern->read_preference);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_readpreference_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_readpreference_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_readpreference_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_readpreference_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_readpreference;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_readpreference_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_readpreference;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_readpreference_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_readpreference_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_readpreference_get_properties_hash(object, true TSRMLS_CC);
+ return php_phongo_readpreference_get_properties_hash(object, true);
} /* }}} */
-static HashTable* php_phongo_readpreference_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_readpreference_get_properties(zval* object) /* {{{ */
{
- return php_phongo_readpreference_get_properties_hash(object, false TSRMLS_CC);
+ return php_phongo_readpreference_get_properties_hash(object, false);
} /* }}} */
/* }}} */
void php_phongo_readpreference_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "ReadPreference", php_phongo_readpreference_me);
- php_phongo_readpreference_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_readpreference_ce = zend_register_internal_class(&ce);
php_phongo_readpreference_ce->create_object = php_phongo_readpreference_create_object;
PHONGO_CE_FINAL(php_phongo_readpreference_ce);
- zend_class_implements(php_phongo_readpreference_ce TSRMLS_CC, 1, php_phongo_serializable_ce);
- zend_class_implements(php_phongo_readpreference_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_readpreference_ce, 1, php_phongo_serializable_ce);
+ zend_class_implements(php_phongo_readpreference_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_readpreference, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_readpreference.get_debug_info = php_phongo_readpreference_get_debug_info;
php_phongo_handler_readpreference.get_properties = php_phongo_readpreference_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_readpreference.free_obj = php_phongo_readpreference_free_object;
- php_phongo_handler_readpreference.offset = XtOffsetOf(php_phongo_readpreference_t, std);
-#endif
-
- zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_PRIMARY"), MONGOC_READ_PRIMARY TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_PRIMARY_PREFERRED"), MONGOC_READ_PRIMARY_PREFERRED TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_SECONDARY"), MONGOC_READ_SECONDARY TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_SECONDARY_PREFERRED"), MONGOC_READ_SECONDARY_PREFERRED TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_NEAREST"), MONGOC_READ_NEAREST TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("NO_MAX_STALENESS"), MONGOC_NO_MAX_STALENESS TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("SMALLEST_MAX_STALENESS_SECONDS"), MONGOC_SMALLEST_MAX_STALENESS_SECONDS TSRMLS_CC);
-
- zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("PRIMARY"), PHONGO_READ_PRIMARY TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("PRIMARY_PREFERRED"), PHONGO_READ_PRIMARY_PREFERRED TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("SECONDARY"), PHONGO_READ_SECONDARY TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("SECONDARY_PREFERRED"), PHONGO_READ_SECONDARY_PREFERRED TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("NEAREST"), PHONGO_READ_NEAREST TSRMLS_CC);
+ php_phongo_handler_readpreference.free_obj = php_phongo_readpreference_free_object;
+ php_phongo_handler_readpreference.offset = XtOffsetOf(php_phongo_readpreference_t, std);
+
+ zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_PRIMARY"), MONGOC_READ_PRIMARY);
+ zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_PRIMARY_PREFERRED"), MONGOC_READ_PRIMARY_PREFERRED);
+ zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_SECONDARY"), MONGOC_READ_SECONDARY);
+ zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_SECONDARY_PREFERRED"), MONGOC_READ_SECONDARY_PREFERRED);
+ zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_NEAREST"), MONGOC_READ_NEAREST);
+ zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("NO_MAX_STALENESS"), MONGOC_NO_MAX_STALENESS);
+ zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("SMALLEST_MAX_STALENESS_SECONDS"), MONGOC_SMALLEST_MAX_STALENESS_SECONDS);
+
+ zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("PRIMARY"), PHONGO_READ_PRIMARY);
+ zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("PRIMARY_PREFERRED"), PHONGO_READ_PRIMARY_PREFERRED);
+ zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("SECONDARY"), PHONGO_READ_SECONDARY);
+ zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("SECONDARY_PREFERRED"), PHONGO_READ_SECONDARY_PREFERRED);
+ zend_declare_class_constant_string(php_phongo_readpreference_ce, ZEND_STRL("NEAREST"), PHONGO_READ_NEAREST);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Server.c b/mongodb-1.8.1/src/MongoDB/Server.c
similarity index 78%
rename from mongodb-1.7.4/src/MongoDB/Server.c
rename to mongodb-1.8.1/src/MongoDB/Server.c
index 15692896..83236396 100644
--- a/mongodb-1.7.4/src/MongoDB/Server.c
+++ b/mongodb-1.8.1/src/MongoDB/Server.c
@@ -1,674 +1,644 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
zend_class_entry* php_phongo_server_ce;
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Server::executeCommand(string $db, MongoDB\Driver\Command $command[, array $options = null]))
Executes a Command on this Server */
static PHP_METHOD(Server, executeCommand)
{
php_phongo_server_t* intern;
char* db;
- phongo_zpp_char_len db_len;
+ size_t db_len;
zval* command;
zval* options = NULL;
bool free_options = false;
- DECLARE_RETURN_VALUE_USED
intern = Z_SERVER_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|z!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
return;
}
- options = php_phongo_prep_legacy_option(options, "readPreference", &free_options TSRMLS_CC);
+ options = php_phongo_prep_legacy_option(options, "readPreference", &free_options);
/* If the Server was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_command(intern->client, PHONGO_COMMAND_RAW, db, command, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_command(intern->client, PHONGO_COMMAND_RAW, db, command, options, intern->server_id, return_value);
if (free_options) {
- php_phongo_prep_legacy_option_free(options TSRMLS_CC);
+ php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Server::executeReadCommand(string $db, MongoDB\Driver\Command $command[, array $options = null]))
Executes a ReadCommand on this Server */
static PHP_METHOD(Server, executeReadCommand)
{
php_phongo_server_t* intern;
char* db;
- phongo_zpp_char_len db_len;
+ size_t db_len;
zval* command;
zval* options = NULL;
- DECLARE_RETURN_VALUE_USED
intern = Z_SERVER_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
return;
}
/* If the Server was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_command(intern->client, PHONGO_COMMAND_READ, db, command, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_command(intern->client, PHONGO_COMMAND_READ, db, command, options, intern->server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Server::executeWriteCommand(string $db, MongoDB\Driver\Command $command[, array $options = null]))
Executes a WriteCommand on this Server */
static PHP_METHOD(Server, executeWriteCommand)
{
php_phongo_server_t* intern;
char* db;
- phongo_zpp_char_len db_len;
+ size_t db_len;
zval* command;
zval* options = NULL;
- DECLARE_RETURN_VALUE_USED
intern = Z_SERVER_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
return;
}
/* If the Server was created in a different process, reset the client so
* that cursors created by this process can be differentiated. and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_command(intern->client, PHONGO_COMMAND_WRITE, db, command, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_command(intern->client, PHONGO_COMMAND_WRITE, db, command, options, intern->server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Server::executeReadWriteCommand(string $db, MongoDB\Driver\Command $command[, array $options = null]))
Executes a ReadWriteCommand on this Server */
static PHP_METHOD(Server, executeReadWriteCommand)
{
php_phongo_server_t* intern;
char* db;
- phongo_zpp_char_len db_len;
+ size_t db_len;
zval* command;
zval* options = NULL;
- DECLARE_RETURN_VALUE_USED
intern = Z_SERVER_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
return;
}
/* If the Server was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_command(intern->client, PHONGO_COMMAND_READ_WRITE, db, command, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_command(intern->client, PHONGO_COMMAND_READ_WRITE, db, command, options, intern->server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Server::executeQuery(string $namespace, MongoDB\Driver\Query $query[, array $options = null]))
Executes a Query on this Server */
static PHP_METHOD(Server, executeQuery)
{
php_phongo_server_t* intern;
char* namespace;
- phongo_zpp_char_len namespace_len;
- zval* query;
- zval* options = NULL;
- bool free_options = false;
- DECLARE_RETURN_VALUE_USED
+ size_t namespace_len;
+ zval* query;
+ zval* options = NULL;
+ bool free_options = false;
intern = Z_SERVER_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|z!", &namespace, &namespace_len, &query, php_phongo_query_ce, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &namespace, &namespace_len, &query, php_phongo_query_ce, &options) == FAILURE) {
return;
}
- options = php_phongo_prep_legacy_option(options, "readPreference", &free_options TSRMLS_CC);
+ options = php_phongo_prep_legacy_option(options, "readPreference", &free_options);
/* If the Server was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_query(intern->client, namespace, query, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_query(intern->client, namespace, query, options, intern->server_id, return_value);
if (free_options) {
- php_phongo_prep_legacy_option_free(options TSRMLS_CC);
+ php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
/* {{{ proto MongoDB\Driver\WriteResult MongoDB\Driver\Server::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, array $options = null])
Executes a BulkWrite (i.e. any number of insert, update, and delete ops) on
this Server */
static PHP_METHOD(Server, executeBulkWrite)
{
php_phongo_server_t* intern;
char* namespace;
- phongo_zpp_char_len namespace_len;
+ size_t namespace_len;
zval* zbulk;
php_phongo_bulkwrite_t* bulk;
zval* options = NULL;
bool free_options = false;
- DECLARE_RETURN_VALUE_USED
intern = Z_SERVER_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|z!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &options, php_phongo_writeconcern_ce) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &options, php_phongo_writeconcern_ce) == FAILURE) {
return;
}
bulk = Z_BULKWRITE_OBJ_P(zbulk);
- options = php_phongo_prep_legacy_option(options, "writeConcern", &free_options TSRMLS_CC);
+ options = php_phongo_prep_legacy_option(options, "writeConcern", &free_options);
/* If the Server was created in a different process, reset the client so
* that its session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
- phongo_execute_bulk_write(intern->client, namespace, bulk, options, intern->server_id, return_value, return_value_used TSRMLS_CC);
+ phongo_execute_bulk_write(intern->client, namespace, bulk, options, intern->server_id, return_value);
if (free_options) {
- php_phongo_prep_legacy_option_free(options TSRMLS_CC);
+ php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
/* {{{ proto string MongoDB\Driver\Server::getHost()
Returns the hostname for this Server */
static PHP_METHOD(Server, getHost)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
- PHONGO_RETVAL_STRING(mongoc_server_description_host(sd)->host);
+ RETVAL_STRING(mongoc_server_description_host(sd)->host);
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto array MongoDB\Driver\Server::getTags()
Returns the currently configured tags for this Server */
static PHP_METHOD(Server, getTags)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
const bson_t* is_master = mongoc_server_description_ismaster(sd);
bson_iter_t iter;
if (bson_iter_init_find(&iter, is_master, "tags") && BSON_ITER_HOLDS_DOCUMENT(&iter)) {
const uint8_t* bytes;
uint32_t len;
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
bson_iter_document(&iter, &len, &bytes);
if (!php_phongo_bson_to_zval_ex(bytes, len, &state)) {
/* Exception should already have been thrown */
zval_ptr_dtor(&state.zchild);
mongoc_server_description_destroy(sd);
return;
}
mongoc_server_description_destroy(sd);
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
}
array_init(return_value);
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto array MongoDB\Driver\Server::getInfo()
Returns the last isMaster result document for this Server */
static PHP_METHOD(Server, getInfo)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
const bson_t* is_master = mongoc_server_description_ismaster(sd);
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
if (!php_phongo_bson_to_zval_ex(bson_get_data(is_master), is_master->len, &state)) {
/* Exception should already have been thrown */
zval_ptr_dtor(&state.zchild);
mongoc_server_description_destroy(sd);
return;
}
mongoc_server_description_destroy(sd);
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto integer MongoDB\Driver\Server::getLatency()
Returns the last measured latency for this Server */
static PHP_METHOD(Server, getLatency)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
- RETVAL_LONG((phongo_long) mongoc_server_description_round_trip_time(sd));
+ RETVAL_LONG((zend_long) mongoc_server_description_round_trip_time(sd));
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto integer MongoDB\Driver\Server::getPort()
Returns the port for this Server */
static PHP_METHOD(Server, getPort)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
RETVAL_LONG(mongoc_server_description_host(sd)->port);
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto integer MongoDB\Driver\Server::getType()
Returns the node type of this Server */
static PHP_METHOD(Server, getType)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
RETVAL_LONG(php_phongo_server_description_type(sd));
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\Server::isPrimary()
Returns whether this Server is a primary member of a replica set */
static PHP_METHOD(Server, isPrimary)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_PRIMARY].name));
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\Server::isSecondary()
Returns whether this Server is a secondary member of a replica set */
static PHP_METHOD(Server, isSecondary)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_SECONDARY].name));
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\Server::isArbiter()
Returns whether this Server is an arbiter member of a replica set */
static PHP_METHOD(Server, isArbiter)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_ARBITER].name));
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\Server::isHidden()
Returns whether this Server is a hidden member of a replica set */
static PHP_METHOD(Server, isHidden)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
bson_iter_t iter;
RETVAL_BOOL(bson_iter_init_find_case(&iter, mongoc_server_description_ismaster(sd), "hidden") && bson_iter_as_bool(&iter));
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\Server::isPassive()
Returns whether this Server is a passive member of a replica set */
static PHP_METHOD(Server, isPassive)
{
php_phongo_server_t* intern;
mongoc_server_description_t* sd;
intern = Z_SERVER_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
bson_iter_t iter;
RETVAL_BOOL(bson_iter_init_find_case(&iter, mongoc_server_description_ismaster(sd), "passive") && bson_iter_as_bool(&iter));
mongoc_server_description_destroy(sd);
return;
}
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
} /* }}} */
/* {{{ MongoDB\Driver\Server function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeCommand, 0, 0, 2)
ZEND_ARG_INFO(0, db)
ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeRWCommand, 0, 0, 2)
ZEND_ARG_INFO(0, db)
ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0)
ZEND_ARG_ARRAY_INFO(0, options, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeQuery, 0, 0, 2)
ZEND_ARG_INFO(0, namespace)
ZEND_ARG_OBJ_INFO(0, zquery, MongoDB\\Driver\\Query, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeBulkWrite, 0, 0, 2)
ZEND_ARG_INFO(0, namespace)
ZEND_ARG_OBJ_INFO(0, zbulk, MongoDB\\Driver\\BulkWrite, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Server_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_server_me[] = {
/* clang-format off */
PHP_ME(Server, executeCommand, ai_Server_executeCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, executeReadCommand, ai_Server_executeRWCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, executeWriteCommand, ai_Server_executeRWCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, executeReadWriteCommand, ai_Server_executeRWCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, executeQuery, ai_Server_executeQuery, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, executeBulkWrite, ai_Server_executeBulkWrite, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, getHost, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, getTags, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, getInfo, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, getLatency, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, getPort, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, getType, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, isPrimary, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, isSecondary, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, isArbiter, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, isHidden, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Server, isPassive, ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Server_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Server_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Server object handlers */
static zend_object_handlers php_phongo_handler_server;
-static int php_phongo_server_compare_objects(zval* o1, zval* o2 TSRMLS_DC) /* {{{ */
+static int php_phongo_server_compare_objects(zval* o1, zval* o2) /* {{{ */
{
php_phongo_server_t* intern1;
php_phongo_server_t* intern2;
mongoc_server_description_t *sd1, *sd2;
int retval = 0;
intern1 = Z_SERVER_OBJ_P(o1);
intern2 = Z_SERVER_OBJ_P(o2);
sd1 = mongoc_client_get_server_description(intern1->client, intern1->server_id);
sd2 = mongoc_client_get_server_description(intern2->client, intern2->server_id);
if (sd1 && sd2) {
retval = strcasecmp(mongoc_server_description_host(sd1)->host_and_port, mongoc_server_description_host(sd2)->host_and_port);
} else {
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description(s)");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description(s)");
}
if (sd1) {
mongoc_server_description_destroy(sd1);
}
if (sd2) {
mongoc_server_description_destroy(sd2);
}
return retval;
} /* }}} */
-static void php_phongo_server_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_server_free_object(zend_object* object) /* {{{ */
{
php_phongo_server_t* intern = Z_OBJ_SERVER(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
+ zend_object_std_dtor(&intern->std);
} /* }}} */
-static phongo_create_object_retval php_phongo_server_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_server_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_server_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_server_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
PHONGO_SET_CREATED_BY_PID(intern);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_server;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_server_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_server;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_server_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_server_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_server_t* intern = NULL;
zval retval = ZVAL_STATIC_INIT;
mongoc_server_description_t* sd;
*is_temp = 1;
intern = Z_SERVER_OBJ_P(object);
if (!(sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
- phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
+ phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Failed to get server description");
return NULL;
}
php_phongo_server_to_zval(&retval, sd);
mongoc_server_description_destroy(sd);
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_server_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Server", php_phongo_server_me);
- php_phongo_server_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_server_ce = zend_register_internal_class(&ce);
php_phongo_server_ce->create_object = php_phongo_server_create_object;
PHONGO_CE_FINAL(php_phongo_server_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_server_ce);
memcpy(&php_phongo_handler_server, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_server.compare_objects = php_phongo_server_compare_objects;
php_phongo_handler_server.get_debug_info = php_phongo_server_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_server.free_obj = php_phongo_server_free_object;
- php_phongo_handler_server.offset = XtOffsetOf(php_phongo_server_t, std);
-#endif
-
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_UNKNOWN"), PHONGO_SERVER_UNKNOWN TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_STANDALONE"), PHONGO_SERVER_STANDALONE TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_MONGOS"), PHONGO_SERVER_MONGOS TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_POSSIBLE_PRIMARY"), PHONGO_SERVER_POSSIBLE_PRIMARY TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_PRIMARY"), PHONGO_SERVER_RS_PRIMARY TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_SECONDARY"), PHONGO_SERVER_RS_SECONDARY TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_ARBITER"), PHONGO_SERVER_RS_ARBITER TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_OTHER"), PHONGO_SERVER_RS_OTHER TSRMLS_CC);
- zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_GHOST"), PHONGO_SERVER_RS_GHOST TSRMLS_CC);
+ php_phongo_handler_server.free_obj = php_phongo_server_free_object;
+ php_phongo_handler_server.offset = XtOffsetOf(php_phongo_server_t, std);
+
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_UNKNOWN"), PHONGO_SERVER_UNKNOWN);
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_STANDALONE"), PHONGO_SERVER_STANDALONE);
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_MONGOS"), PHONGO_SERVER_MONGOS);
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_POSSIBLE_PRIMARY"), PHONGO_SERVER_POSSIBLE_PRIMARY);
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_PRIMARY"), PHONGO_SERVER_RS_PRIMARY);
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_SECONDARY"), PHONGO_SERVER_RS_SECONDARY);
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_ARBITER"), PHONGO_SERVER_RS_ARBITER);
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_OTHER"), PHONGO_SERVER_RS_OTHER);
+ zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_GHOST"), PHONGO_SERVER_RS_GHOST);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Session.c b/mongodb-1.8.1/src/MongoDB/Session.c
similarity index 77%
rename from mongodb-1.7.4/src/MongoDB/Session.c
rename to mongodb-1.8.1/src/MongoDB/Session.c
index 4dd570e9..53d51e20 100644
--- a/mongodb-1.7.4/src/MongoDB/Session.c
+++ b/mongodb-1.8.1/src/MongoDB/Session.c
@@ -1,836 +1,745 @@
/*
* Copyright 2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
#include "php_array_api.h"
#include "Session.h"
zend_class_entry* php_phongo_session_ce;
#define PHONGO_TRANSACTION_NONE "none"
#define PHONGO_TRANSACTION_STARTING "starting"
#define PHONGO_TRANSACTION_IN_PROGRESS "in_progress"
#define PHONGO_TRANSACTION_COMMITTED "committed"
#define PHONGO_TRANSACTION_ABORTED "aborted"
#define SESSION_CHECK_LIVELINESS(i, m) \
if (!(i)->client_session) { \
phongo_throw_exception( \
- PHONGO_ERROR_LOGIC TSRMLS_CC, \
+ PHONGO_ERROR_LOGIC, \
"Cannot call '%s', as the session has already been ended.", \
(m)); \
return; \
}
-static bool php_phongo_session_get_timestamp_parts(zval* obj, uint32_t* timestamp, uint32_t* increment TSRMLS_DC)
+static bool php_phongo_session_get_timestamp_parts(zval* obj, uint32_t* timestamp, uint32_t* increment)
{
- bool retval = false;
-#if PHP_VERSION_ID >= 70000
+ bool retval = false;
zval ztimestamp = ZVAL_STATIC_INIT;
zval zincrement = ZVAL_STATIC_INIT;
zend_call_method_with_0_params(obj, NULL, NULL, "getTimestamp", &ztimestamp);
if (Z_ISUNDEF(ztimestamp) || EG(exception)) {
goto cleanup;
}
zend_call_method_with_0_params(obj, NULL, NULL, "getIncrement", &zincrement);
if (Z_ISUNDEF(zincrement) || EG(exception)) {
goto cleanup;
}
*timestamp = Z_LVAL(ztimestamp);
*increment = Z_LVAL(zincrement);
-#else
- zval* ztimestamp = NULL;
- zval* zincrement = NULL;
-
- zend_call_method_with_0_params(&obj, NULL, NULL, "getTimestamp", &ztimestamp);
-
- if (Z_ISUNDEF(ztimestamp) || EG(exception)) {
- goto cleanup;
- }
-
- zend_call_method_with_0_params(&obj, NULL, NULL, "getIncrement", &zincrement);
-
- if (Z_ISUNDEF(zincrement) || EG(exception)) {
- goto cleanup;
- }
-
- *timestamp = Z_LVAL_P(ztimestamp);
- *increment = Z_LVAL_P(zincrement);
-#endif
retval = true;
cleanup:
if (!Z_ISUNDEF(ztimestamp)) {
zval_ptr_dtor(&ztimestamp);
}
if (!Z_ISUNDEF(zincrement)) {
zval_ptr_dtor(&zincrement);
}
return retval;
}
-static const char* php_phongo_get_transaction_state_string(mongoc_transaction_state_t state TSRMLS_DC)
+static const char* php_phongo_get_transaction_state_string(mongoc_transaction_state_t state)
{
switch (state) {
case MONGOC_TRANSACTION_NONE:
return PHONGO_TRANSACTION_NONE;
case MONGOC_TRANSACTION_STARTING:
return PHONGO_TRANSACTION_STARTING;
case MONGOC_TRANSACTION_IN_PROGRESS:
return PHONGO_TRANSACTION_IN_PROGRESS;
case MONGOC_TRANSACTION_COMMITTED:
return PHONGO_TRANSACTION_COMMITTED;
case MONGOC_TRANSACTION_ABORTED:
return PHONGO_TRANSACTION_ABORTED;
default:
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid transaction state %d given", (int) state);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Invalid transaction state %d given", (int) state);
return NULL;
}
}
/* {{{ proto void MongoDB\Driver\Session::advanceClusterTime(array|object $clusterTime)
Advances the cluster time for this Session */
static PHP_METHOD(Session, advanceClusterTime)
{
php_phongo_session_t* intern;
zval* zcluster_time;
bson_t cluster_time = BSON_INITIALIZER;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "advanceClusterTime")
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A", &zcluster_time) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "A", &zcluster_time) == FAILURE) {
return;
}
- php_phongo_zval_to_bson(zcluster_time, PHONGO_BSON_NONE, &cluster_time, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(zcluster_time, PHONGO_BSON_NONE, &cluster_time, NULL);
/* An exception may be thrown during BSON conversion */
if (EG(exception)) {
goto cleanup;
}
mongoc_client_session_advance_cluster_time(intern->client_session, &cluster_time);
cleanup:
bson_destroy(&cluster_time);
} /* }}} */
/* {{{ proto void MongoDB\Driver\Session::advanceOperationTime(MongoDB\BSON\TimestampInterface $timestamp)
Advances the operation time for this Session */
static PHP_METHOD(Session, advanceOperationTime)
{
php_phongo_session_t* intern;
zval* ztimestamp;
uint32_t timestamp = 0;
uint32_t increment = 0;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "advanceOperationTime")
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &ztimestamp, php_phongo_timestamp_interface_ce) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &ztimestamp, php_phongo_timestamp_interface_ce) == FAILURE) {
return;
}
- if (!php_phongo_session_get_timestamp_parts(ztimestamp, &timestamp, &increment TSRMLS_CC)) {
+ if (!php_phongo_session_get_timestamp_parts(ztimestamp, &timestamp, &increment)) {
return;
}
mongoc_client_session_advance_operation_time(intern->client_session, timestamp, increment);
} /* }}} */
/* {{{ proto object|null MongoDB\Driver\Session::getClusterTime()
Returns the cluster time for this Session */
static PHP_METHOD(Session, getClusterTime)
{
php_phongo_session_t* intern;
const bson_t* cluster_time;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "getClusterTime")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
cluster_time = mongoc_client_session_get_cluster_time(intern->client_session);
if (!cluster_time) {
RETURN_NULL();
}
if (!php_phongo_bson_to_zval_ex(bson_get_data(cluster_time), cluster_time->len, &state)) {
/* Exception should already have been thrown */
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
} /* }}} */
/* {{{ proto object MongoDB\Driver\Session::getLogicalSessionId()
Returns the logical session ID for this Session */
static PHP_METHOD(Session, getLogicalSessionId)
{
php_phongo_session_t* intern;
const bson_t* lsid;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "getLogicalSessionId")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
lsid = mongoc_client_session_get_lsid(intern->client_session);
if (!php_phongo_bson_to_zval_ex(bson_get_data(lsid), lsid->len, &state)) {
/* Exception should already have been thrown */
zval_ptr_dtor(&state.zchild);
return;
}
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&state.zchild, 0, 1);
-#else
- RETURN_ZVAL(state.zchild, 0, 1);
-#endif
} /* }}} */
/* {{{ proto MongoDB\BSON\Timestamp|null MongoDB\Driver\Session::getOperationTime()
Returns the operation time for this Session */
static PHP_METHOD(Session, getOperationTime)
{
php_phongo_session_t* intern;
uint32_t timestamp, increment;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "getOperationTime")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
mongoc_client_session_get_operation_time(intern->client_session, &timestamp, &increment);
/* mongoc_client_session_get_operation_time() returns 0 for both parts if
* the session has not been used. According to the causal consistency spec,
* the operation time for an unused session is null. */
if (timestamp == 0 && increment == 0) {
RETURN_NULL();
}
- php_phongo_bson_new_timestamp_from_increment_and_timestamp(return_value, increment, timestamp TSRMLS_CC);
+ php_phongo_bson_new_timestamp_from_increment_and_timestamp(return_value, increment, timestamp);
} /* }}} */
/* {{{ proto MongoDB\Driver\Server|null MongoDB\Driver\Session::getServer()
Returns the server this session is pinned to */
static PHP_METHOD(Session, getServer)
{
php_phongo_session_t* intern;
uint32_t server_id = 0;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "getServer")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
server_id = mongoc_client_session_get_server_id(intern->client_session);
/* For sessions without a pinned server, 0 is returned. */
if (!server_id) {
RETURN_NULL();
}
- phongo_server_init(return_value, intern->client, server_id TSRMLS_CC);
+ phongo_server_init(return_value, intern->client, server_id);
} /* }}} */
/* {{{ proto array|null MongoDB\Driver\Session::getTransactionOptions()
Returns options for the currently running transaction */
static PHP_METHOD(Session, getTransactionOptions)
{
php_phongo_session_t* intern;
mongoc_transaction_opt_t* opts;
int64_t max_commit_time_ms;
const mongoc_read_concern_t* read_concern;
const mongoc_read_prefs_t* read_preference;
const mongoc_write_concern_t* write_concern;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "getTransactionOptions")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
opts = mongoc_session_opts_get_transaction_opts(intern->client_session);
if (!opts) {
return;
}
max_commit_time_ms = mongoc_transaction_opts_get_max_commit_time_ms(opts);
read_concern = mongoc_transaction_opts_get_read_concern(opts);
read_preference = mongoc_transaction_opts_get_read_prefs(opts);
write_concern = mongoc_transaction_opts_get_write_concern(opts);
array_init_size(return_value, 4);
if (max_commit_time_ms) {
ADD_ASSOC_LONG_EX(return_value, "maxCommitTimeMS", max_commit_time_ms);
}
if (!mongoc_read_concern_is_default(read_concern)) {
-#if PHP_VERSION_ID >= 70000
zval zread_concern;
- phongo_readconcern_init(&zread_concern, read_concern TSRMLS_CC);
+ phongo_readconcern_init(&zread_concern, read_concern);
ADD_ASSOC_ZVAL_EX(return_value, "readConcern", &zread_concern);
-#else
- zval* zread_concern = NULL;
- MAKE_STD_ZVAL(zread_concern);
-
- phongo_readconcern_init(zread_concern, read_concern TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(return_value, "readConcern", zread_concern);
-#endif
}
if (read_preference) {
-#if PHP_VERSION_ID >= 70000
zval zread_preference;
- phongo_readpreference_init(&zread_preference, read_preference TSRMLS_CC);
+ phongo_readpreference_init(&zread_preference, read_preference);
ADD_ASSOC_ZVAL_EX(return_value, "readPreference", &zread_preference);
-#else
- zval* zread_preference = NULL;
- MAKE_STD_ZVAL(zread_preference);
-
- phongo_readpreference_init(zread_preference, read_preference TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(return_value, "readPreference", zread_preference);
-#endif
}
if (!mongoc_write_concern_is_default(write_concern)) {
-#if PHP_VERSION_ID >= 70000
zval zwrite_concern;
- phongo_writeconcern_init(&zwrite_concern, write_concern TSRMLS_CC);
+ phongo_writeconcern_init(&zwrite_concern, write_concern);
ADD_ASSOC_ZVAL_EX(return_value, "writeConcern", &zwrite_concern);
-#else
- zval* zwrite_concern = NULL;
- MAKE_STD_ZVAL(zwrite_concern);
-
- phongo_writeconcern_init(zwrite_concern, write_concern TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(return_value, "writeConcern", zwrite_concern);
-#endif
}
} /* }}} */
/* {{{ proto string MongoDB\Driver\Session::getTransactionState()
Returns the current transaction state for this session */
static PHP_METHOD(Session, getTransactionState)
{
php_phongo_session_t* intern;
const char* state;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "getTransactionState")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- state = php_phongo_get_transaction_state_string(mongoc_client_session_get_transaction_state(intern->client_session) TSRMLS_CC);
+ state = php_phongo_get_transaction_state_string(mongoc_client_session_get_transaction_state(intern->client_session));
if (!state) {
/* Exception already thrown */
return;
}
- PHONGO_RETURN_STRING(state);
+ RETURN_STRING(state);
} /* }}} */
/* Creates a opts structure from an array optionally containing an RP, RC,
* WC object, and/or maxCommitTimeMS int. Returns NULL if no options were found,
* or there was an invalid option. If there was an invalid option or structure,
* an exception will be thrown too. */
-mongoc_transaction_opt_t* php_mongodb_session_parse_transaction_options(zval* options TSRMLS_DC)
+mongoc_transaction_opt_t* php_mongodb_session_parse_transaction_options(zval* options)
{
mongoc_transaction_opt_t* opts = NULL;
if (php_array_existsc(options, "maxCommitTimeMS")) {
int64_t max_commit_time_ms = php_array_fetchc_long(options, "maxCommitTimeMS");
if (max_commit_time_ms < 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"maxCommitTimeMS\" option to be >= 0, %" PRId64 " given", max_commit_time_ms);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"maxCommitTimeMS\" option to be >= 0, %" PRId64 " given", max_commit_time_ms);
/* Freeing opts is not needed here, as it can't be set yet. The
* code is here to keep it consistent with the others in case more
* options are added before this one. */
if (opts) {
mongoc_transaction_opts_destroy(opts);
}
return NULL;
}
if (max_commit_time_ms > UINT32_MAX) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"maxCommitTimeMS\" option to be <= %" PRIu32 ", %" PRId64 " given", UINT32_MAX, max_commit_time_ms);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"maxCommitTimeMS\" option to be <= %" PRIu32 ", %" PRId64 " given", UINT32_MAX, max_commit_time_ms);
/* Freeing opts is not needed here, as it can't be set yet. The
* code is here to keep it consistent with the others in case more
* options are added before this one. */
if (opts) {
mongoc_transaction_opts_destroy(opts);
}
return NULL;
}
if (!opts) {
opts = mongoc_transaction_opts_new();
}
mongoc_transaction_opts_set_max_commit_time_ms(opts, max_commit_time_ms);
}
if (php_array_existsc(options, "readConcern")) {
zval* read_concern = php_array_fetchc(options, "readConcern");
- if (Z_TYPE_P(read_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(read_concern), php_phongo_readconcern_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(read_concern));
+ if (Z_TYPE_P(read_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(read_concern), php_phongo_readconcern_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(read_concern));
if (opts) {
mongoc_transaction_opts_destroy(opts);
}
return NULL;
}
if (!opts) {
opts = mongoc_transaction_opts_new();
}
- mongoc_transaction_opts_set_read_concern(opts, phongo_read_concern_from_zval(read_concern TSRMLS_CC));
+ mongoc_transaction_opts_set_read_concern(opts, phongo_read_concern_from_zval(read_concern));
}
if (php_array_existsc(options, "readPreference")) {
zval* read_preference = php_array_fetchc(options, "readPreference");
- if (Z_TYPE_P(read_preference) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(read_preference), php_phongo_readpreference_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"readPreference\" option to be %s, %s given", ZSTR_VAL(php_phongo_readpreference_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(read_preference));
+ if (Z_TYPE_P(read_preference) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(read_preference), php_phongo_readpreference_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"readPreference\" option to be %s, %s given", ZSTR_VAL(php_phongo_readpreference_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(read_preference));
if (opts) {
mongoc_transaction_opts_destroy(opts);
}
return NULL;
}
if (!opts) {
opts = mongoc_transaction_opts_new();
}
- mongoc_transaction_opts_set_read_prefs(opts, phongo_read_preference_from_zval(read_preference TSRMLS_CC));
+ mongoc_transaction_opts_set_read_prefs(opts, phongo_read_preference_from_zval(read_preference));
}
if (php_array_existsc(options, "writeConcern")) {
zval* write_concern = php_array_fetchc(options, "writeConcern");
- if (Z_TYPE_P(write_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(write_concern), php_phongo_writeconcern_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"writeConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_writeconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(write_concern));
+ if (Z_TYPE_P(write_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(write_concern), php_phongo_writeconcern_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"writeConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_writeconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(write_concern));
if (opts) {
mongoc_transaction_opts_destroy(opts);
}
return NULL;
}
if (!opts) {
opts = mongoc_transaction_opts_new();
}
- mongoc_transaction_opts_set_write_concern(opts, phongo_write_concern_from_zval(write_concern TSRMLS_CC));
+ mongoc_transaction_opts_set_write_concern(opts, phongo_write_concern_from_zval(write_concern));
}
return opts;
}
/* {{{ proto void MongoDB\Driver\Session::startTransaction([array $options = null])
Starts a new transaction */
static PHP_METHOD(Session, startTransaction)
{
php_phongo_session_t* intern;
zval* options = NULL;
mongoc_transaction_opt_t* txn_options = NULL;
bson_error_t error;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "startTransaction")
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &options) == FAILURE) {
return;
}
if (options) {
- txn_options = php_mongodb_session_parse_transaction_options(options TSRMLS_CC);
+ txn_options = php_mongodb_session_parse_transaction_options(options);
}
if (EG(exception)) {
return;
}
if (!mongoc_client_session_start_transaction(intern->client_session, txn_options, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
}
if (txn_options) {
mongoc_transaction_opts_destroy(txn_options);
}
} /* }}} */
/* {{{ proto void MongoDB\Driver\Session::commitTransaction(void)
Commits an existing transaction */
static PHP_METHOD(Session, commitTransaction)
{
php_phongo_session_t* intern;
bson_error_t error;
bson_t reply;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "commitTransaction")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!mongoc_client_session_commit_transaction(intern->client_session, &reply, &error)) {
- phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply TSRMLS_CC);
- bson_destroy(&reply);
+ phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply);
}
+
+ bson_destroy(&reply);
} /* }}} */
/* {{{ proto void MongoDB\Driver\Session::abortTransaction(void)
Aborts (rolls back) an existing transaction */
static PHP_METHOD(Session, abortTransaction)
{
php_phongo_session_t* intern;
bson_error_t error;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "abortTransaction")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!mongoc_client_session_abort_transaction(intern->client_session, &error)) {
- phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
+ phongo_throw_exception_from_bson_error_t(&error);
}
} /* }}} */
/* {{{ proto void MongoDB\Driver\Session::endSession(void)
Ends the session, and a running transaction if active */
static PHP_METHOD(Session, endSession)
{
php_phongo_session_t* intern;
intern = Z_SESSION_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
mongoc_client_session_destroy(intern->client_session);
intern->client_session = NULL;
} /* }}} */
/* {{{ proto void MongoDB\Driver\Session::isInTransaction(void)
Returns whether a multi-document transaction is in progress */
static PHP_METHOD(Session, isInTransaction)
{
php_phongo_session_t* intern;
intern = Z_SESSION_OBJ_P(getThis());
SESSION_CHECK_LIVELINESS(intern, "isInTransaction")
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_BOOL(mongoc_client_session_in_transaction(intern->client_session));
} /* }}} */
/* {{{ MongoDB\Driver\Session function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Session_advanceClusterTime, 0, 0, 1)
ZEND_ARG_INFO(0, clusterTime)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Session_advanceOperationTime, 0, 0, 1)
ZEND_ARG_INFO(0, timestamp)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Session_startTransaction, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Session_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_session_me[] = {
/* clang-format off */
PHP_ME(Session, abortTransaction, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, advanceClusterTime, ai_Session_advanceClusterTime, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, advanceOperationTime, ai_Session_advanceOperationTime, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, commitTransaction, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, endSession, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, getClusterTime, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, getLogicalSessionId, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, getOperationTime, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, getServer, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, getTransactionOptions, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, getTransactionState, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, isInTransaction, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Session, startTransaction, ai_Session_startTransaction, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Session_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Session object handlers */
static zend_object_handlers php_phongo_handler_session;
-static void php_phongo_session_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_session_free_object(zend_object* object) /* {{{ */
{
php_phongo_session_t* intern = Z_OBJ_SESSION(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
/* If this Session was created in a different process, reset the client so
* that its session pool is cleared and mongoc_client_session_destroy will
* destroy the corresponding server session rather than return it to the
* now-empty pool. This will ensure that we do not re-use a server session
* (i.e. LSID) created by a parent process. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern);
if (intern->client_session) {
mongoc_client_session_destroy(intern->client_session);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_session_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_session_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_session_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_session_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
PHONGO_SET_CREATED_BY_PID(intern);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_session;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_session_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_session;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_session_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_session_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_session_t* intern = NULL;
const mongoc_session_opt_t* cs_opts;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_SESSION_OBJ_P(object);
array_init(&retval);
if (intern->client_session) {
const bson_t* lsid;
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
lsid = mongoc_client_session_get_lsid(intern->client_session);
if (!php_phongo_bson_to_zval_ex(bson_get_data(lsid), lsid->len, &state)) {
zval_ptr_dtor(&state.zchild);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "logicalSessionId", &state.zchild);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "logicalSessionId", state.zchild);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "logicalSessionId");
}
if (intern->client_session) {
const bson_t* cluster_time;
cluster_time = mongoc_client_session_get_cluster_time(intern->client_session);
if (cluster_time) {
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
if (!php_phongo_bson_to_zval_ex(bson_get_data(cluster_time), cluster_time->len, &state)) {
zval_ptr_dtor(&state.zchild);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "clusterTime", &state.zchild);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "clusterTime", state.zchild);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "clusterTime");
}
} else {
ADD_ASSOC_NULL_EX(&retval, "clusterTime");
}
if (intern->client_session) {
cs_opts = mongoc_client_session_get_opts(intern->client_session);
ADD_ASSOC_BOOL_EX(&retval, "causalConsistency", mongoc_session_opts_get_causal_consistency(cs_opts));
} else {
ADD_ASSOC_NULL_EX(&retval, "causalConsistency");
}
if (intern->client_session) {
uint32_t timestamp, increment;
mongoc_client_session_get_operation_time(intern->client_session, &timestamp, &increment);
if (timestamp && increment) {
-#if PHP_VERSION_ID >= 70000
zval ztimestamp;
- php_phongo_bson_new_timestamp_from_increment_and_timestamp(&ztimestamp, increment, timestamp TSRMLS_CC);
+ php_phongo_bson_new_timestamp_from_increment_and_timestamp(&ztimestamp, increment, timestamp);
ADD_ASSOC_ZVAL_EX(&retval, "operationTime", &ztimestamp);
-#else
- zval* ztimestamp;
-
- MAKE_STD_ZVAL(ztimestamp);
- php_phongo_bson_new_timestamp_from_increment_and_timestamp(ztimestamp, increment, timestamp TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "operationTime", ztimestamp);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "operationTime");
}
} else {
ADD_ASSOC_NULL_EX(&retval, "operationTime");
}
if (intern->client_session) {
uint32_t server_id = mongoc_client_session_get_server_id(intern->client_session);
if (server_id) {
-#if PHP_VERSION_ID >= 70000
zval server;
- phongo_server_init(&server, intern->client, server_id TSRMLS_CC);
+ phongo_server_init(&server, intern->client, server_id);
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
-#else
- zval* server = NULL;
-
- MAKE_STD_ZVAL(server);
- phongo_server_init(server, intern->client, server_id TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "server", server);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "server");
}
} else {
ADD_ASSOC_NULL_EX(&retval, "server");
}
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_session_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Session", php_phongo_session_me);
- php_phongo_session_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_session_ce = zend_register_internal_class(&ce);
php_phongo_session_ce->create_object = php_phongo_session_create_object;
PHONGO_CE_FINAL(php_phongo_session_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_session_ce);
memcpy(&php_phongo_handler_session, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_session.get_debug_info = php_phongo_session_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_session.free_obj = php_phongo_session_free_object;
- php_phongo_handler_session.offset = XtOffsetOf(php_phongo_session_t, std);
-#endif
-
- zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_NONE"), PHONGO_TRANSACTION_NONE TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_STARTING"), PHONGO_TRANSACTION_STARTING TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_IN_PROGRESS"), PHONGO_TRANSACTION_IN_PROGRESS TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_COMMITTED"), PHONGO_TRANSACTION_COMMITTED TSRMLS_CC);
- zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_ABORTED"), PHONGO_TRANSACTION_ABORTED TSRMLS_CC);
+ php_phongo_handler_session.free_obj = php_phongo_session_free_object;
+ php_phongo_handler_session.offset = XtOffsetOf(php_phongo_session_t, std);
+
+ zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_NONE"), PHONGO_TRANSACTION_NONE);
+ zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_STARTING"), PHONGO_TRANSACTION_STARTING);
+ zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_IN_PROGRESS"), PHONGO_TRANSACTION_IN_PROGRESS);
+ zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_COMMITTED"), PHONGO_TRANSACTION_COMMITTED);
+ zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_ABORTED"), PHONGO_TRANSACTION_ABORTED);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/Session.h b/mongodb-1.8.1/src/MongoDB/Session.h
similarity index 95%
rename from mongodb-1.7.4/src/MongoDB/Session.h
rename to mongodb-1.8.1/src/MongoDB/Session.h
index 60105195..abdf6875 100644
--- a/mongodb-1.7.4/src/MongoDB/Session.h
+++ b/mongodb-1.8.1/src/MongoDB/Session.h
@@ -1,22 +1,22 @@
/*
* Copyright 2017 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.
*/
#ifndef PHP_MONGODB_DRIVER_SESSION_H
#define PHP_MONGODB_DRIVER_SESSION_H
-mongoc_transaction_opt_t* php_mongodb_session_parse_transaction_options(zval* txnOptions TSRMLS_DC);
+mongoc_transaction_opt_t* php_mongodb_session_parse_transaction_options(zval* txnOptions);
#endif /* PHP_MONGODB_DRIVER_SESSION_H */
diff --git a/mongodb-1.7.4/src/MongoDB/WriteConcern.c b/mongodb-1.8.1/src/MongoDB/WriteConcern.c
similarity index 60%
rename from mongodb-1.7.4/src/MongoDB/WriteConcern.c
rename to mongodb-1.8.1/src/MongoDB/WriteConcern.c
index 80257434..58df454f 100644
--- a/mongodb-1.7.4/src/MongoDB/WriteConcern.c
+++ b/mongodb-1.8.1/src/MongoDB/WriteConcern.c
@@ -1,708 +1,561 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#include <ext/standard/php_var.h>
-#if PHP_VERSION_ID >= 70000
#include <zend_smart_str.h>
-#else
-#include <ext/standard/php_smart_str.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_writeconcern_ce;
/* Initialize the object from a HashTable and return whether it was successful.
* An exception will be thrown on error. */
-static bool php_phongo_writeconcern_init_from_hash(php_phongo_writeconcern_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
+static bool php_phongo_writeconcern_init_from_hash(php_phongo_writeconcern_t* intern, HashTable* props) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zval *w, *wtimeout, *j;
intern->write_concern = mongoc_write_concern_new();
if ((w = zend_hash_str_find(props, "w", sizeof("w") - 1))) {
if (Z_TYPE_P(w) == IS_LONG) {
if (Z_LVAL_P(w) < -3) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"w\" integer field to be >= -3", ZSTR_VAL(php_phongo_writeconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"w\" integer field to be >= -3", ZSTR_VAL(php_phongo_writeconcern_ce->name));
goto failure;
}
mongoc_write_concern_set_w(intern->write_concern, Z_LVAL_P(w));
} else if (Z_TYPE_P(w) == IS_STRING) {
if (strcmp(Z_STRVAL_P(w), PHONGO_WRITE_CONCERN_W_MAJORITY) == 0) {
mongoc_write_concern_set_w(intern->write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY);
} else {
mongoc_write_concern_set_wtag(intern->write_concern, Z_STRVAL_P(w));
}
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"w\" field to be integer or string", ZSTR_VAL(php_phongo_writeconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"w\" field to be integer or string", ZSTR_VAL(php_phongo_writeconcern_ce->name));
goto failure;
}
}
if ((wtimeout = zend_hash_str_find(props, "wtimeout", sizeof("wtimeout") - 1))) {
if (Z_TYPE_P(wtimeout) == IS_LONG) {
if (Z_LVAL_P(wtimeout) < 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"wtimeout\" integer field to be >= 0", ZSTR_VAL(php_phongo_writeconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"wtimeout\" integer field to be >= 0", ZSTR_VAL(php_phongo_writeconcern_ce->name));
goto failure;
}
mongoc_write_concern_set_wtimeout_int64(intern->write_concern, (int64_t) Z_LVAL_P(wtimeout));
} else if (Z_TYPE_P(wtimeout) == IS_STRING) {
int64_t timeout;
if (!php_phongo_parse_int64(&timeout, Z_STRVAL_P(wtimeout), Z_STRLEN_P(wtimeout))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit value for %s initialization", Z_STRVAL_P(wtimeout), ZSTR_VAL(php_phongo_writeconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error parsing \"%s\" as 64-bit value for %s initialization", Z_STRVAL_P(wtimeout), ZSTR_VAL(php_phongo_writeconcern_ce->name));
return false;
}
mongoc_write_concern_set_wtimeout_int64(intern->write_concern, timeout);
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"wtimeout\" field to be integer or string", ZSTR_VAL(php_phongo_writeconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"wtimeout\" field to be integer or string", ZSTR_VAL(php_phongo_writeconcern_ce->name));
goto failure;
}
}
if ((j = zend_hash_str_find(props, "j", sizeof("j") - 1))) {
if (Z_TYPE_P(j) == IS_TRUE || Z_TYPE_P(j) == IS_FALSE) {
- mongoc_write_concern_set_journal(intern->write_concern, zend_is_true(j));
- } else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"j\" field to be boolean", ZSTR_VAL(php_phongo_writeconcern_ce->name));
- goto failure;
- }
- }
-#else
- zval **w, **wtimeout, **j;
-
- intern->write_concern = mongoc_write_concern_new();
-
- if (zend_hash_find(props, "w", sizeof("w"), (void**) &w) == SUCCESS) {
- if (Z_TYPE_PP(w) == IS_LONG) {
- if (Z_LVAL_PP(w) < -3) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"w\" integer field to be >= -3", ZSTR_VAL(php_phongo_writeconcern_ce->name));
- goto failure;
- }
- mongoc_write_concern_set_w(intern->write_concern, Z_LVAL_PP(w));
- } else if (Z_TYPE_PP(w) == IS_STRING) {
- if (strcmp(Z_STRVAL_PP(w), PHONGO_WRITE_CONCERN_W_MAJORITY) == 0) {
- mongoc_write_concern_set_w(intern->write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY);
- } else {
- mongoc_write_concern_set_wtag(intern->write_concern, Z_STRVAL_PP(w));
- }
- } else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"w\" field to be integer or string", ZSTR_VAL(php_phongo_writeconcern_ce->name));
- goto failure;
- }
- }
-
- if (zend_hash_find(props, "wtimeout", sizeof("wtimeout"), (void**) &wtimeout) == SUCCESS) {
- if (Z_TYPE_PP(wtimeout) == IS_LONG) {
- if (Z_LVAL_PP(wtimeout) < 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"wtimeout\" integer field to be >= 0", ZSTR_VAL(php_phongo_writeconcern_ce->name));
+ if (zend_is_true(j) && (mongoc_write_concern_get_w(intern->write_concern) == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || mongoc_write_concern_get_w(intern->write_concern) == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot enable journaling when using w = 0");
goto failure;
}
- mongoc_write_concern_set_wtimeout_int64(intern->write_concern, (int64_t) Z_LVAL_PP(wtimeout));
- } else if (Z_TYPE_PP(wtimeout) == IS_STRING) {
- int64_t timeout;
-
- if (!php_phongo_parse_int64(&timeout, Z_STRVAL_PP(wtimeout), Z_STRLEN_PP(wtimeout))) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit value for %s initialization", Z_STRVAL_PP(wtimeout), ZSTR_VAL(php_phongo_writeconcern_ce->name));
- return false;
- }
-
- mongoc_write_concern_set_wtimeout_int64(intern->write_concern, timeout);
+ mongoc_write_concern_set_journal(intern->write_concern, zend_is_true(j));
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"wtimeout\" field to be integer or string", ZSTR_VAL(php_phongo_writeconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"j\" field to be boolean", ZSTR_VAL(php_phongo_writeconcern_ce->name));
goto failure;
}
}
- if (zend_hash_find(props, "j", sizeof("j"), (void**) &j) == SUCCESS) {
- if (Z_TYPE_PP(j) == IS_BOOL) {
- mongoc_write_concern_set_journal(intern->write_concern, Z_BVAL_PP(j));
- } else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"j\" field to be boolean", ZSTR_VAL(php_phongo_writeconcern_ce->name));
- goto failure;
- }
+ if (!mongoc_write_concern_is_valid(intern->write_concern)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Write concern is not valid");
+ goto failure;
}
-#endif
-
return true;
failure:
mongoc_write_concern_destroy(intern->write_concern);
intern->write_concern = NULL;
return false;
} /* }}} */
/* {{{ proto void MongoDB\Driver\WriteConcern::__construct(integer|string $w[, integer $wtimeout[, boolean $journal]])
Constructs a new WriteConcern */
static PHP_METHOD(WriteConcern, __construct)
{
php_phongo_writeconcern_t* intern;
zend_error_handling error_handling;
zval * w, *journal;
- phongo_long wtimeout = 0;
+ zend_long wtimeout = 0;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
intern = Z_WRITECONCERN_OBJ_P(getThis());
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|lz", &w, &wtimeout, &journal) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|lz", &w, &wtimeout, &journal) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
intern->write_concern = mongoc_write_concern_new();
if (Z_TYPE_P(w) == IS_LONG) {
if (Z_LVAL_P(w) < -3) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected w to be >= -3, %ld given", Z_LVAL_P(w));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected w to be >= -3, %ld given", Z_LVAL_P(w));
return;
}
mongoc_write_concern_set_w(intern->write_concern, Z_LVAL_P(w));
} else if (Z_TYPE_P(w) == IS_STRING) {
if (strcmp(Z_STRVAL_P(w), PHONGO_WRITE_CONCERN_W_MAJORITY) == 0) {
mongoc_write_concern_set_w(intern->write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY);
} else {
mongoc_write_concern_set_wtag(intern->write_concern, Z_STRVAL_P(w));
}
} else {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected w to be integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(w));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected w to be integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(w));
return;
}
switch (ZEND_NUM_ARGS()) {
case 3:
if (Z_TYPE_P(journal) != IS_NULL) {
-#ifdef ZEND_ENGINE_3
+ if (zend_is_true(journal) && (mongoc_write_concern_get_w(intern->write_concern) == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || mongoc_write_concern_get_w(intern->write_concern) == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot enable journaling when using w = 0");
+ return;
+ }
+
mongoc_write_concern_set_journal(intern->write_concern, zend_is_true(journal));
-#else
- mongoc_write_concern_set_journal(intern->write_concern, Z_BVAL_P(journal));
-#endif
}
/* fallthrough */
case 2:
if (wtimeout < 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected wtimeout to be >= 0, %" PHONGO_LONG_FORMAT " given", wtimeout);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected wtimeout to be >= 0, %" PHONGO_LONG_FORMAT " given", wtimeout);
return;
}
mongoc_write_concern_set_wtimeout_int64(intern->write_concern, (int64_t) wtimeout);
}
+
+ if (!mongoc_write_concern_is_valid(intern->write_concern)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Write concern is not valid");
+ return;
+ }
} /* }}} */
/* {{{ proto void MongoDB\BSON\WriteConcern::__set_state(array $properties)
*/
static PHP_METHOD(WriteConcern, __set_state)
{
php_phongo_writeconcern_t* intern;
HashTable* props;
zval* array;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
RETURN_FALSE;
}
object_init_ex(return_value, php_phongo_writeconcern_ce);
intern = Z_WRITECONCERN_OBJ_P(return_value);
props = Z_ARRVAL_P(array);
- php_phongo_writeconcern_init_from_hash(intern, props TSRMLS_CC);
+ php_phongo_writeconcern_init_from_hash(intern, props);
} /* }}} */
/* {{{ proto string|integer|null MongoDB\Driver\WriteConcern::getW()
Returns the WriteConcern "w" option */
static PHP_METHOD(WriteConcern, getW)
{
php_phongo_writeconcern_t* intern;
const char* wtag;
intern = Z_WRITECONCERN_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
wtag = mongoc_write_concern_get_wtag(intern->write_concern);
if (wtag) {
- PHONGO_RETURN_STRING(wtag);
+ RETURN_STRING(wtag);
}
if (mongoc_write_concern_get_wmajority(intern->write_concern)) {
- PHONGO_RETURN_STRING(PHONGO_WRITE_CONCERN_W_MAJORITY);
+ RETURN_STRING(PHONGO_WRITE_CONCERN_W_MAJORITY);
}
if (mongoc_write_concern_get_w(intern->write_concern) != MONGOC_WRITE_CONCERN_W_DEFAULT) {
RETURN_LONG(mongoc_write_concern_get_w(intern->write_concern));
}
RETURN_NULL();
} /* }}} */
/* {{{ proto integer MongoDB\Driver\WriteConcern::getWtimeout()
Returns the WriteConcern "wtimeout" option */
static PHP_METHOD(WriteConcern, getWtimeout)
{
php_phongo_writeconcern_t* intern;
int64_t wtimeout;
intern = Z_WRITECONCERN_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
wtimeout = mongoc_write_concern_get_wtimeout_int64(intern->write_concern);
-#if SIZEOF_LONG == 4
+#if SIZEOF_ZEND_LONG == 4
if (wtimeout > INT32_MAX || wtimeout < INT32_MIN) {
zend_error(E_WARNING, "Truncating 64-bit value for wTimeoutMS");
}
#endif
RETURN_LONG(wtimeout);
} /* }}} */
/* {{{ proto null|boolean MongoDB\Driver\WriteConcern::getJournal()
Returns the WriteConcern "journal" option */
static PHP_METHOD(WriteConcern, getJournal)
{
php_phongo_writeconcern_t* intern;
intern = Z_WRITECONCERN_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (mongoc_write_concern_journal_is_set(intern->write_concern)) {
RETURN_BOOL(mongoc_write_concern_get_journal(intern->write_concern));
}
RETURN_NULL();
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\WriteConcern::isDefault()
Returns whether the write concern has not been modified (i.e. from a Manager
with no write concern URI options). */
static PHP_METHOD(WriteConcern, isDefault)
{
php_phongo_writeconcern_t* intern;
intern = Z_WRITECONCERN_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_BOOL(mongoc_write_concern_is_default(intern->write_concern));
} /* }}} */
-static HashTable* php_phongo_write_concern_get_properties_hash(zval* object, bool is_debug, bool is_bson TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_write_concern_get_properties_hash(zval* object, bool is_debug, bool is_bson) /* {{{ */
{
php_phongo_writeconcern_t* intern;
HashTable* props;
const char* wtag;
int32_t w;
int64_t wtimeout;
intern = Z_WRITECONCERN_OBJ_P(object);
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 4);
if (!intern->write_concern) {
return props;
}
wtag = mongoc_write_concern_get_wtag(intern->write_concern);
w = mongoc_write_concern_get_w(intern->write_concern);
wtimeout = mongoc_write_concern_get_wtimeout_int64(intern->write_concern);
-#if PHP_VERSION_ID >= 70000
{
zval z_w;
if (wtag) {
ZVAL_STRING(&z_w, wtag);
zend_hash_str_update(props, "w", sizeof("w") - 1, &z_w);
} else if (mongoc_write_concern_get_wmajority(intern->write_concern)) {
ZVAL_STRING(&z_w, PHONGO_WRITE_CONCERN_W_MAJORITY);
zend_hash_str_update(props, "w", sizeof("w") - 1, &z_w);
} else if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) {
ZVAL_LONG(&z_w, w);
zend_hash_str_update(props, "w", sizeof("w") - 1, &z_w);
}
if (mongoc_write_concern_journal_is_set(intern->write_concern)) {
zval z_j;
ZVAL_BOOL(&z_j, mongoc_write_concern_get_journal(intern->write_concern));
zend_hash_str_update(props, "j", sizeof("j") - 1, &z_j);
}
if (wtimeout != 0) {
zval z_wtimeout;
if (is_bson) {
ZVAL_INT64(&z_wtimeout, wtimeout);
} else {
-#if SIZEOF_LONG == 4
+#if SIZEOF_ZEND_LONG == 4
if (wtimeout > INT32_MAX || wtimeout < INT32_MIN) {
ZVAL_INT64_STRING(&z_wtimeout, wtimeout);
} else {
ZVAL_LONG(&z_wtimeout, wtimeout);
}
#else
ZVAL_LONG(&z_wtimeout, wtimeout);
#endif
}
zend_hash_str_update(props, "wtimeout", sizeof("wtimeout") - 1, &z_wtimeout);
}
-#else
- {
- zval* z_w;
-
- if (wtag) {
- MAKE_STD_ZVAL(z_w);
- ZVAL_STRING(z_w, wtag, 1);
- zend_hash_update(props, "w", sizeof("w"), &z_w, sizeof(z_w), NULL);
- } else if (mongoc_write_concern_get_wmajority(intern->write_concern)) {
- MAKE_STD_ZVAL(z_w);
- ZVAL_STRING(z_w, PHONGO_WRITE_CONCERN_W_MAJORITY, 1);
- zend_hash_update(props, "w", sizeof("w"), &z_w, sizeof(z_w), NULL);
- } else if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) {
- MAKE_STD_ZVAL(z_w);
- ZVAL_LONG(z_w, w);
- zend_hash_update(props, "w", sizeof("w"), &z_w, sizeof(z_w), NULL);
- }
-
- if (mongoc_write_concern_journal_is_set(intern->write_concern)) {
- zval* z_j;
-
- MAKE_STD_ZVAL(z_j);
- ZVAL_BOOL(z_j, mongoc_write_concern_get_journal(intern->write_concern));
- zend_hash_update(props, "j", sizeof("j"), &z_j, sizeof(z_j), NULL);
- }
-
- if (wtimeout != 0) {
- zval* z_wtimeout;
-
- MAKE_STD_ZVAL(z_wtimeout);
-
- if (is_bson) {
- ZVAL_INT64(z_wtimeout, wtimeout);
- } else {
-#if SIZEOF_LONG == 4
- if (wtimeout > INT32_MAX || wtimeout < INT32_MIN) {
- ZVAL_INT64_STRING(z_wtimeout, wtimeout);
- } else {
- ZVAL_LONG(z_wtimeout, wtimeout);
- }
-#else
- ZVAL_LONG(z_wtimeout, wtimeout);
-#endif
- }
-
- zend_hash_update(props, "wtimeout", sizeof("wtimeout"), &z_wtimeout, sizeof(z_wtimeout), NULL);
- }
-#endif
}
return props;
} /* }}} */
/* {{{ proto array MongoDB\Driver\WriteConcern::bsonSerialize()
*/
static PHP_METHOD(WriteConcern, bsonSerialize)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- ZVAL_ARR(return_value, php_phongo_write_concern_get_properties_hash(getThis(), true, true TSRMLS_CC));
+ ZVAL_ARR(return_value, php_phongo_write_concern_get_properties_hash(getThis(), true, true));
convert_to_object(return_value);
} /* }}} */
/* {{{ proto string MongoDB\Driver\WriteConcern::serialize()
*/
static PHP_METHOD(WriteConcern, serialize)
{
php_phongo_writeconcern_t* intern;
- ZVAL_RETVAL_TYPE retval;
+ zval retval;
php_serialize_data_t var_hash;
smart_str buf = { 0 };
const char* wtag;
int32_t w;
int64_t wtimeout;
intern = Z_WRITECONCERN_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!intern->write_concern) {
return;
}
wtag = mongoc_write_concern_get_wtag(intern->write_concern);
w = mongoc_write_concern_get_w(intern->write_concern);
wtimeout = mongoc_write_concern_get_wtimeout_int64(intern->write_concern);
-#if PHP_VERSION_ID >= 70000
array_init_size(&retval, 3);
if (wtag) {
ADD_ASSOC_STRING(&retval, "w", wtag);
} else if (mongoc_write_concern_get_wmajority(intern->write_concern)) {
ADD_ASSOC_STRING(&retval, "w", PHONGO_WRITE_CONCERN_W_MAJORITY);
} else if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) {
ADD_ASSOC_LONG_EX(&retval, "w", w);
}
if (mongoc_write_concern_journal_is_set(intern->write_concern)) {
ADD_ASSOC_BOOL_EX(&retval, "j", mongoc_write_concern_get_journal(intern->write_concern));
}
if (wtimeout != 0) {
if (wtimeout > INT32_MAX || wtimeout < INT32_MIN) {
ADD_ASSOC_INT64_AS_STRING(&retval, "wtimeout", wtimeout);
} else {
ADD_ASSOC_LONG_EX(&retval, "wtimeout", wtimeout);
}
}
-#else
- ALLOC_INIT_ZVAL(retval);
- array_init_size(retval, 3);
-
- if (wtag) {
- ADD_ASSOC_STRING(retval, "w", wtag);
- } else if (mongoc_write_concern_get_wmajority(intern->write_concern)) {
- ADD_ASSOC_STRING(retval, "w", PHONGO_WRITE_CONCERN_W_MAJORITY);
- } else if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) {
- ADD_ASSOC_LONG_EX(retval, "w", w);
- }
-
- if (mongoc_write_concern_journal_is_set(intern->write_concern)) {
- ADD_ASSOC_BOOL_EX(retval, "j", mongoc_write_concern_get_journal(intern->write_concern));
- }
-
- if (wtimeout != 0) {
- if (wtimeout > INT32_MAX || wtimeout < INT32_MIN) {
- ADD_ASSOC_INT64_AS_STRING(retval, "wtimeout", wtimeout);
- } else {
- ADD_ASSOC_LONG_EX(retval, "wtimeout", wtimeout);
- }
- }
-#endif
PHP_VAR_SERIALIZE_INIT(var_hash);
- php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC);
+ php_var_serialize(&buf, &retval, &var_hash);
smart_str_0(&buf);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
PHONGO_RETVAL_SMART_STR(buf);
smart_str_free(&buf);
zval_ptr_dtor(&retval);
} /* }}} */
/* {{{ proto void MongoDB\Driver\WriteConcern::unserialize(string $serialized)
*/
static PHP_METHOD(WriteConcern, unserialize)
{
php_phongo_writeconcern_t* intern;
zend_error_handling error_handling;
char* serialized;
- phongo_zpp_char_len serialized_len;
-#if PHP_VERSION_ID >= 70000
- zval props;
-#else
- zval* props;
-#endif
- php_unserialize_data_t var_hash;
+ size_t serialized_len;
+ zval props;
+ php_unserialize_data_t var_hash;
intern = Z_WRITECONCERN_OBJ_P(getThis());
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
+ zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) {
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &serialized, &serialized_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling);
return;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
+ zend_restore_error_handling(&error_handling);
if (!serialized_len) {
return;
}
-#if PHP_VERSION_ID < 70000
- ALLOC_INIT_ZVAL(props);
-#endif
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char*) serialized + serialized_len, &var_hash)) {
zval_ptr_dtor(&props);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_writeconcern_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s unserialization failed", ZSTR_VAL(php_phongo_writeconcern_ce->name));
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-#if PHP_VERSION_ID >= 70000
- php_phongo_writeconcern_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC);
-#else
- php_phongo_writeconcern_init_from_hash(intern, HASH_OF(props) TSRMLS_CC);
-#endif
+ php_phongo_writeconcern_init_from_hash(intern, HASH_OF(&props));
zval_ptr_dtor(&props);
} /* }}} */
/* {{{ MongoDB\Driver\WriteConcern function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcern___construct, 0, 0, 1)
ZEND_ARG_INFO(0, w)
ZEND_ARG_INFO(0, wtimeout)
ZEND_ARG_INFO(0, journal)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcern___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcern_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcern_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_writeconcern_me[] = {
/* clang-format off */
PHP_ME(WriteConcern, __construct, ai_WriteConcern___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcern, __set_state, ai_WriteConcern___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(WriteConcern, getW, ai_WriteConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcern, getWtimeout, ai_WriteConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcern, getJournal, ai_WriteConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcern, isDefault, ai_WriteConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcern, bsonSerialize, ai_WriteConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcern, serialize, ai_WriteConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcern, unserialize, ai_WriteConcern_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\WriteConcern object handlers */
static zend_object_handlers php_phongo_handler_writeconcern;
-static void php_phongo_writeconcern_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_writeconcern_free_object(zend_object* object) /* {{{ */
{
php_phongo_writeconcern_t* intern = Z_OBJ_WRITECONCERN(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
if (intern->write_concern) {
mongoc_write_concern_destroy(intern->write_concern);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_writeconcern_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_writeconcern_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_writeconcern_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_writeconcern_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_writeconcern;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_writeconcern_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_writeconcern;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_writeconcern_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_writeconcern_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
*is_temp = 1;
- return php_phongo_write_concern_get_properties_hash(object, true, false TSRMLS_CC);
+ return php_phongo_write_concern_get_properties_hash(object, true, false);
} /* }}} */
-static HashTable* php_phongo_writeconcern_get_properties(zval* object TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_writeconcern_get_properties(zval* object) /* {{{ */
{
- return php_phongo_write_concern_get_properties_hash(object, false, false TSRMLS_CC);
+ return php_phongo_write_concern_get_properties_hash(object, false, false);
} /* }}} */
void php_phongo_writeconcern_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "WriteConcern", php_phongo_writeconcern_me);
- php_phongo_writeconcern_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_writeconcern_ce = zend_register_internal_class(&ce);
php_phongo_writeconcern_ce->create_object = php_phongo_writeconcern_create_object;
PHONGO_CE_FINAL(php_phongo_writeconcern_ce);
- zend_class_implements(php_phongo_writeconcern_ce TSRMLS_CC, 1, php_phongo_serializable_ce);
- zend_class_implements(php_phongo_writeconcern_ce TSRMLS_CC, 1, zend_ce_serializable);
+ zend_class_implements(php_phongo_writeconcern_ce, 1, php_phongo_serializable_ce);
+ zend_class_implements(php_phongo_writeconcern_ce, 1, zend_ce_serializable);
memcpy(&php_phongo_handler_writeconcern, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_writeconcern.get_debug_info = php_phongo_writeconcern_get_debug_info;
php_phongo_handler_writeconcern.get_properties = php_phongo_writeconcern_get_properties;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_writeconcern.free_obj = php_phongo_writeconcern_free_object;
- php_phongo_handler_writeconcern.offset = XtOffsetOf(php_phongo_writeconcern_t, std);
-#endif
+ php_phongo_handler_writeconcern.free_obj = php_phongo_writeconcern_free_object;
+ php_phongo_handler_writeconcern.offset = XtOffsetOf(php_phongo_writeconcern_t, std);
- zend_declare_class_constant_stringl(php_phongo_writeconcern_ce, ZEND_STRL("MAJORITY"), ZEND_STRL(PHONGO_WRITE_CONCERN_W_MAJORITY) TSRMLS_CC);
+ zend_declare_class_constant_stringl(php_phongo_writeconcern_ce, ZEND_STRL("MAJORITY"), ZEND_STRL(PHONGO_WRITE_CONCERN_W_MAJORITY));
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/WriteConcernError.c b/mongodb-1.8.1/src/MongoDB/WriteConcernError.c
similarity index 78%
rename from mongodb-1.7.4/src/MongoDB/WriteConcernError.c
rename to mongodb-1.8.1/src/MongoDB/WriteConcernError.c
index ed99539a..078a48d9 100644
--- a/mongodb-1.7.4/src/MongoDB/WriteConcernError.c
+++ b/mongodb-1.8.1/src/MongoDB/WriteConcernError.c
@@ -1,194 +1,169 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_writeconcernerror_ce;
/* {{{ proto integer MongoDB\Driver\WriteConcernError::getCode()
Returns the MongoDB error code */
static PHP_METHOD(WriteConcernError, getCode)
{
php_phongo_writeconcernerror_t* intern;
intern = Z_WRITECONCERNERROR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(intern->code);
} /* }}} */
-/* {{{ proto mixed MongoDB\Driver\WriteConcernError::getInfo()
+/* {{{ proto object|null MongoDB\Driver\WriteConcernError::getInfo()
Returns additional metadata for the error */
static PHP_METHOD(WriteConcernError, getInfo)
{
php_phongo_writeconcernerror_t* intern;
intern = Z_WRITECONCERNERROR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!Z_ISUNDEF(intern->info)) {
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&intern->info, 1, 0);
-#else
- RETURN_ZVAL(intern->info, 1, 0);
-#endif
}
} /* }}} */
/* {{{ proto string MongoDB\Driver\WriteConcernError::getMessage()
Returns the actual error message from the server */
static PHP_METHOD(WriteConcernError, getMessage)
{
php_phongo_writeconcernerror_t* intern;
intern = Z_WRITECONCERNERROR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETURN_STRING(intern->message);
+ RETURN_STRING(intern->message);
} /* }}} */
/* {{{ MongoDB\Driver\WriteConcernError function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcernError_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_writeconcernerror_me[] = {
/* clang-format off */
PHP_ME(WriteConcernError, getCode, ai_WriteConcernError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcernError, getInfo, ai_WriteConcernError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteConcernError, getMessage, ai_WriteConcernError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_WriteConcernError_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_WriteConcernError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\WriteConcernError object handlers */
static zend_object_handlers php_phongo_handler_writeconcernerror;
-static void php_phongo_writeconcernerror_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_writeconcernerror_free_object(zend_object* object) /* {{{ */
{
php_phongo_writeconcernerror_t* intern = Z_OBJ_WRITECONCERNERROR(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->message) {
efree(intern->message);
}
if (!Z_ISUNDEF(intern->info)) {
zval_ptr_dtor(&intern->info);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_writeconcernerror_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_writeconcernerror_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_writeconcernerror_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_writeconcernerror_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_writeconcernerror;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_writeconcernerror_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_writeconcernerror;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_writeconcernerror_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_writeconcernerror_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_writeconcernerror_t* intern;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_WRITECONCERNERROR_OBJ_P(object);
array_init_size(&retval, 3);
ADD_ASSOC_STRING(&retval, "message", intern->message);
ADD_ASSOC_LONG_EX(&retval, "code", intern->code);
if (!Z_ISUNDEF(intern->info)) {
-#if PHP_VERSION_ID >= 70000
Z_ADDREF(intern->info);
ADD_ASSOC_ZVAL_EX(&retval, "info", &intern->info);
-#else
- Z_ADDREF_P(intern->info);
- ADD_ASSOC_ZVAL_EX(&retval, "info", intern->info);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "info");
}
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "WriteConcernError", php_phongo_writeconcernerror_me);
- php_phongo_writeconcernerror_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_writeconcernerror_ce = zend_register_internal_class(&ce);
php_phongo_writeconcernerror_ce->create_object = php_phongo_writeconcernerror_create_object;
PHONGO_CE_FINAL(php_phongo_writeconcernerror_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_writeconcernerror_ce);
memcpy(&php_phongo_handler_writeconcernerror, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_writeconcernerror.get_debug_info = php_phongo_writeconcernerror_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_writeconcernerror.free_obj = php_phongo_writeconcernerror_free_object;
- php_phongo_handler_writeconcernerror.offset = XtOffsetOf(php_phongo_writeconcernerror_t, std);
-#endif
+ php_phongo_handler_writeconcernerror.free_obj = php_phongo_writeconcernerror_free_object;
+ php_phongo_handler_writeconcernerror.offset = XtOffsetOf(php_phongo_writeconcernerror_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/WriteError.c b/mongodb-1.8.1/src/MongoDB/WriteError.c
similarity index 79%
rename from mongodb-1.7.4/src/MongoDB/WriteError.c
rename to mongodb-1.8.1/src/MongoDB/WriteError.c
index 142bbb71..0304565a 100644
--- a/mongodb-1.7.4/src/MongoDB/WriteError.c
+++ b/mongodb-1.8.1/src/MongoDB/WriteError.c
@@ -1,212 +1,187 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "phongo_compat.h"
#include "php_phongo.h"
zend_class_entry* php_phongo_writeerror_ce;
/* {{{ proto integer MongoDB\Driver\WriteError::getCode()
Returns the MongoDB error code */
static PHP_METHOD(WriteError, getCode)
{
php_phongo_writeerror_t* intern;
intern = Z_WRITEERROR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(intern->code);
} /* }}} */
/* {{{ proto integer MongoDB\Driver\WriteError::getIndex()
Returns the index of the operation in the BulkWrite to which this WriteError
corresponds. */
static PHP_METHOD(WriteError, getIndex)
{
php_phongo_writeerror_t* intern;
intern = Z_WRITEERROR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_LONG(intern->index);
} /* }}} */
/* {{{ proto string MongoDB\Driver\WriteError::getMessage()
Returns the actual error message from the server */
static PHP_METHOD(WriteError, getMessage)
{
php_phongo_writeerror_t* intern;
intern = Z_WRITEERROR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- PHONGO_RETURN_STRING(intern->message);
+ RETURN_STRING(intern->message);
} /* }}} */
-/* {{{ proto mixed MongoDB\Driver\WriteError::getInfo()
+/* {{{ proto object|null MongoDB\Driver\WriteError::getInfo()
Returns additional metadata for the error */
static PHP_METHOD(WriteError, getInfo)
{
php_phongo_writeerror_t* intern;
intern = Z_WRITEERROR_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!Z_ISUNDEF(intern->info)) {
-#if PHP_VERSION_ID >= 70000
RETURN_ZVAL(&intern->info, 1, 0);
-#else
- RETURN_ZVAL(intern->info, 1, 0);
-#endif
}
} /* }}} */
/* {{{ MongoDB\Driver\WriteError function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_WriteError_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_writeerror_me[] = {
/* clang-format off */
PHP_ME(WriteError, getCode, ai_WriteError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteError, getIndex, ai_WriteError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteError, getMessage, ai_WriteError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteError, getInfo, ai_WriteError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_WriteError_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_WriteError_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\WriteError object handlers */
static zend_object_handlers php_phongo_handler_writeerror;
-static void php_phongo_writeerror_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_writeerror_free_object(zend_object* object) /* {{{ */
{
php_phongo_writeerror_t* intern = Z_OBJ_WRITEERROR(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->message) {
efree(intern->message);
}
if (!Z_ISUNDEF(intern->info)) {
zval_ptr_dtor(&intern->info);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_writeerror_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_writeerror_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_writeerror_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_writeerror_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_writeerror;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_writeerror_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_writeerror;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_writeerror_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_writeerror_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_writeerror_t* intern;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_WRITEERROR_OBJ_P(object);
array_init_size(&retval, 3);
ADD_ASSOC_STRING(&retval, "message", intern->message);
ADD_ASSOC_LONG_EX(&retval, "code", intern->code);
ADD_ASSOC_LONG_EX(&retval, "index", intern->index);
if (!Z_ISUNDEF(intern->info)) {
-#if PHP_VERSION_ID >= 70000
Z_ADDREF(intern->info);
ADD_ASSOC_ZVAL_EX(&retval, "info", &intern->info);
-#else
- Z_ADDREF_P(intern->info);
- ADD_ASSOC_ZVAL_EX(&retval, "info", intern->info);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "info");
}
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_writeerror_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "WriteError", php_phongo_writeerror_me);
- php_phongo_writeerror_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_writeerror_ce = zend_register_internal_class(&ce);
php_phongo_writeerror_ce->create_object = php_phongo_writeerror_create_object;
PHONGO_CE_FINAL(php_phongo_writeerror_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_writeerror_ce);
memcpy(&php_phongo_handler_writeerror, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_writeerror.get_debug_info = php_phongo_writeerror_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_writeerror.free_obj = php_phongo_writeerror_free_object;
- php_phongo_handler_writeerror.offset = XtOffsetOf(php_phongo_writeerror_t, std);
-#endif
+ php_phongo_handler_writeerror.free_obj = php_phongo_writeerror_free_object;
+ php_phongo_handler_writeerror.offset = XtOffsetOf(php_phongo_writeerror_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/MongoDB/WriteResult.c b/mongodb-1.8.1/src/MongoDB/WriteResult.c
similarity index 79%
rename from mongodb-1.7.4/src/MongoDB/WriteResult.c
rename to mongodb-1.8.1/src/MongoDB/WriteResult.c
index 82e6c6f4..c96853ad 100644
--- a/mongodb-1.7.4/src/MongoDB/WriteResult.c
+++ b/mongodb-1.8.1/src/MongoDB/WriteResult.c
@@ -1,528 +1,441 @@
/*
* Copyright 2014-2017 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.
*/
#include <php.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_array_api.h"
#include "phongo_compat.h"
#include "php_phongo.h"
#include "php_bson.h"
#define PHONGO_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(iter, bson, key) \
if (bson_iter_init_find((iter), (bson), (key)) && BSON_ITER_HOLDS_INT32((iter))) { \
RETURN_LONG(bson_iter_int32((iter))); \
}
zend_class_entry* php_phongo_writeresult_ce;
-static bool php_phongo_writeresult_get_writeconcernerror(php_phongo_writeresult_t* intern, zval* return_value TSRMLS_DC) /* {{{ */
+static bool php_phongo_writeresult_get_writeconcernerror(php_phongo_writeresult_t* intern, zval* return_value) /* {{{ */
{
bson_iter_t iter, child;
-#if PHP_VERSION_ID >= 70000
- zval writeconcernerror;
-#else
- zval* writeconcernerror = NULL;
-#endif
+ zval writeconcernerror;
ZVAL_NULL(return_value);
if (bson_iter_init_find(&iter, intern->reply, "writeConcernErrors") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) {
while (bson_iter_next(&child)) {
bson_t cbson;
uint32_t len;
const uint8_t* data;
if (!BSON_ITER_HOLDS_DOCUMENT(&child)) {
continue;
}
bson_iter_document(&child, &len, &data);
if (!bson_init_static(&cbson, data, len)) {
continue;
}
-#if PHP_VERSION_ID >= 70000
- if (!phongo_writeconcernerror_init(&writeconcernerror, &cbson TSRMLS_CC)) {
+ if (!phongo_writeconcernerror_init(&writeconcernerror, &cbson)) {
zval_ptr_dtor(&writeconcernerror);
return false;
}
ZVAL_ZVAL(return_value, &writeconcernerror, 1, 1);
-#else
- MAKE_STD_ZVAL(writeconcernerror);
-
- if (!phongo_writeconcernerror_init(writeconcernerror, &cbson TSRMLS_CC)) {
- zval_ptr_dtor(&writeconcernerror);
- return false;
- }
-
- ZVAL_ZVAL(return_value, writeconcernerror, 1, 1);
-#endif
return true;
}
}
return true;
} /* }}} */
-static bool php_phongo_writeresult_get_writeerrors(php_phongo_writeresult_t* intern, zval* return_value TSRMLS_DC) /* {{{ */
+static bool php_phongo_writeresult_get_writeerrors(php_phongo_writeresult_t* intern, zval* return_value) /* {{{ */
{
bson_iter_t iter, child;
array_init(return_value);
if (bson_iter_init_find(&iter, intern->reply, "writeErrors") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) {
while (bson_iter_next(&child)) {
bson_t cbson;
uint32_t len;
const uint8_t* data;
-#if PHP_VERSION_ID >= 70000
- zval writeerror;
-#else
- zval* writeerror = NULL;
-#endif
+ zval writeerror;
if (!BSON_ITER_HOLDS_DOCUMENT(&child)) {
continue;
}
bson_iter_document(&child, &len, &data);
if (!bson_init_static(&cbson, data, len)) {
continue;
}
-#if PHP_VERSION_ID >= 70000
- if (!phongo_writeerror_init(&writeerror, &cbson TSRMLS_CC)) {
+ if (!phongo_writeerror_init(&writeerror, &cbson)) {
zval_ptr_dtor(&writeerror);
continue;
}
add_next_index_zval(return_value, &writeerror);
-#else
- MAKE_STD_ZVAL(writeerror);
-
- if (!phongo_writeerror_init(writeerror, &cbson TSRMLS_CC)) {
- zval_ptr_dtor(&writeerror);
- continue;
- }
-
- add_next_index_zval(return_value, writeerror);
-#endif
}
}
return true;
} /* }}} */
/* {{{ proto integer|null MongoDB\Driver\WriteResult::getInsertedCount()
Returns the number of documents that were inserted */
static PHP_METHOD(WriteResult, getInsertedCount)
{
bson_iter_t iter;
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
PHONGO_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nInserted");
} /* }}} */
/* {{{ proto integer|null MongoDB\Driver\WriteResult::getMatchedCount()
Returns the number of documents that matched the update criteria */
static PHP_METHOD(WriteResult, getMatchedCount)
{
bson_iter_t iter;
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
PHONGO_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nMatched");
} /* }}} */
/* {{{ proto integer|null MongoDB\Driver\WriteResult::getModifiedCount()
Returns the number of documents that were actually modified by an update */
static PHP_METHOD(WriteResult, getModifiedCount)
{
bson_iter_t iter;
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
PHONGO_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nModified");
} /* }}} */
/* {{{ proto integer|null MongoDB\Driver\WriteResult::getDeletedCount()
Returns the number of documents that were deleted */
static PHP_METHOD(WriteResult, getDeletedCount)
{
bson_iter_t iter;
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
PHONGO_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nRemoved");
} /* }}} */
/* {{{ proto integer|null MongoDB\Driver\WriteResult::getUpsertedCount()
Returns the number of documents that were upserted */
static PHP_METHOD(WriteResult, getUpsertedCount)
{
bson_iter_t iter;
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
PHONGO_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nUpserted");
} /* }}} */
/* {{{ proto MongoDB\Driver\Server MongoDB\Driver\WriteResult::getServer()
Returns the Server from which the result originated */
static PHP_METHOD(WriteResult, getServer)
{
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC);
+ phongo_server_init(return_value, intern->client, intern->server_id);
} /* }}} */
/* {{{ proto array MongoDB\Driver\WriteResult::getUpsertedIds()
Returns the identifiers generated by the server for upsert operations. */
static PHP_METHOD(WriteResult, getUpsertedIds)
{
bson_iter_t iter, child;
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
array_init(return_value);
if (bson_iter_init_find(&iter, intern->reply, "upserted") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) {
while (bson_iter_next(&child)) {
uint32_t data_len;
const uint8_t* data = NULL;
php_phongo_bson_state state;
/* Use PHONGO_TYPEMAP_NATIVE_ARRAY for the root type so we can
* easily access the "index" and "_id" fields. */
PHONGO_BSON_INIT_STATE(state);
state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
if (!BSON_ITER_HOLDS_DOCUMENT(&child)) {
continue;
}
bson_iter_document(&child, &data_len, &data);
if (php_phongo_bson_to_zval_ex(data, data_len, &state)) {
-#if PHP_VERSION_ID >= 70000
zval* zid = php_array_fetchc(&state.zchild, "_id");
add_index_zval(return_value, php_array_fetchc_long(&state.zchild, "index"), zid);
zval_add_ref(zid);
-#else
- zval* zid = php_array_fetchc(state.zchild, "_id");
- add_index_zval(return_value, php_array_fetchc_long(state.zchild, "index"), zid);
- zval_add_ref(&zid);
-#endif
}
zval_ptr_dtor(&state.zchild);
}
}
} /* }}} */
/* {{{ proto WriteConcernError MongoDB\Driver\WriteResult::getWriteConcernError()
Return any write concern error that occurred */
static PHP_METHOD(WriteResult, getWriteConcernError)
{
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- php_phongo_writeresult_get_writeconcernerror(intern, return_value TSRMLS_CC);
+ php_phongo_writeresult_get_writeconcernerror(intern, return_value);
} /* }}} */
/* {{{ proto WriteError[] MongoDB\Driver\WriteResult::getWriteErrors()
Returns any write errors that occurred */
static PHP_METHOD(WriteResult, getWriteErrors)
{
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- php_phongo_writeresult_get_writeerrors(intern, return_value TSRMLS_CC);
+ php_phongo_writeresult_get_writeerrors(intern, return_value);
} /* }}} */
/* {{{ proto boolean MongoDB\Driver\WriteResult::isAcknowledged()
Returns whether the write operation was acknowledged (based on the write
concern). */
static PHP_METHOD(WriteResult, isAcknowledged)
{
php_phongo_writeresult_t* intern;
intern = Z_WRITERESULT_OBJ_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
RETURN_BOOL(mongoc_write_concern_is_acknowledged(intern->write_concern));
} /* }}} */
/* {{{ MongoDB\Driver\WriteResult function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_writeresult_me[] = {
/* clang-format off */
PHP_ME(WriteResult, getInsertedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, getMatchedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, getModifiedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, getDeletedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, getUpsertedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, getServer, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, getUpsertedIds, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, getWriteConcernError, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, getWriteErrors, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(WriteResult, isAcknowledged, ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_WriteResult_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_WriteResult_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\WriteResult object handlers */
static zend_object_handlers php_phongo_handler_writeresult;
-static void php_phongo_writeresult_free_object(phongo_free_object_arg* object TSRMLS_DC) /* {{{ */
+static void php_phongo_writeresult_free_object(zend_object* object) /* {{{ */
{
php_phongo_writeresult_t* intern = Z_OBJ_WRITERESULT(object);
- zend_object_std_dtor(&intern->std TSRMLS_CC);
+ zend_object_std_dtor(&intern->std);
if (intern->reply) {
bson_destroy(intern->reply);
}
if (intern->write_concern) {
mongoc_write_concern_destroy(intern->write_concern);
}
-
-#if PHP_VERSION_ID < 70000
- efree(intern);
-#endif
} /* }}} */
-static phongo_create_object_retval php_phongo_writeresult_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
+static zend_object* php_phongo_writeresult_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_writeresult_t* intern = NULL;
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_writeresult_t, class_type);
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
-#if PHP_VERSION_ID >= 70000
intern->std.handlers = &php_phongo_handler_writeresult;
return &intern->std;
-#else
- {
- zend_object_value retval;
- retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_writeresult_free_object, NULL TSRMLS_CC);
- retval.handlers = &php_phongo_handler_writeresult;
-
- return retval;
- }
-#endif
} /* }}} */
-static HashTable* php_phongo_writeresult_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
+static HashTable* php_phongo_writeresult_get_debug_info(zval* object, int* is_temp) /* {{{ */
{
php_phongo_writeresult_t* intern;
zval retval = ZVAL_STATIC_INIT;
bson_iter_t iter;
intern = Z_WRITERESULT_OBJ_P(object);
*is_temp = 1;
array_init_size(&retval, 9);
#define PHONGO_WRITERESULT_SCP(field) \
if (bson_iter_init_find(&iter, intern->reply, (field)) && BSON_ITER_HOLDS_INT32(&iter)) { \
ADD_ASSOC_LONG_EX(&retval, (field), bson_iter_int32(&iter)); \
} else { \
ADD_ASSOC_NULL_EX(&retval, (field)); \
}
PHONGO_WRITERESULT_SCP("nInserted");
PHONGO_WRITERESULT_SCP("nMatched");
PHONGO_WRITERESULT_SCP("nModified");
PHONGO_WRITERESULT_SCP("nRemoved");
PHONGO_WRITERESULT_SCP("nUpserted");
#undef PHONGO_WRITERESULT_SCP
if (bson_iter_init_find(&iter, intern->reply, "upserted") && BSON_ITER_HOLDS_ARRAY(&iter)) {
uint32_t len;
const uint8_t* data;
php_phongo_bson_state state;
PHONGO_BSON_INIT_DEBUG_STATE(state);
bson_iter_array(&iter, &len, &data);
if (!php_phongo_bson_to_zval_ex(data, len, &state)) {
zval_ptr_dtor(&state.zchild);
goto done;
}
-#if PHP_VERSION_ID >= 70000
ADD_ASSOC_ZVAL_EX(&retval, "upsertedIds", &state.zchild);
-#else
- ADD_ASSOC_ZVAL_EX(&retval, "upsertedIds", state.zchild);
-#endif
} else {
-#if PHP_VERSION_ID >= 70000
zval upsertedIds;
array_init(&upsertedIds);
ADD_ASSOC_ZVAL_EX(&retval, "upsertedIds", &upsertedIds);
-#else
- zval* upsertedIds = NULL;
- MAKE_STD_ZVAL(upsertedIds);
- array_init(upsertedIds);
- ADD_ASSOC_ZVAL_EX(&retval, "upsertedIds", upsertedIds);
-#endif
}
{
-#if PHP_VERSION_ID >= 70000
zval writeerrors;
- php_phongo_writeresult_get_writeerrors(intern, &writeerrors TSRMLS_CC);
+ php_phongo_writeresult_get_writeerrors(intern, &writeerrors);
ADD_ASSOC_ZVAL_EX(&retval, "writeErrors", &writeerrors);
-#else
- zval* writeerrors = NULL;
-
- MAKE_STD_ZVAL(writeerrors);
- php_phongo_writeresult_get_writeerrors(intern, writeerrors TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "writeErrors", writeerrors);
-#endif
}
{
-#if PHP_VERSION_ID >= 70000
zval writeconcernerror;
- php_phongo_writeresult_get_writeconcernerror(intern, &writeconcernerror TSRMLS_CC);
+ php_phongo_writeresult_get_writeconcernerror(intern, &writeconcernerror);
ADD_ASSOC_ZVAL_EX(&retval, "writeConcernError", &writeconcernerror);
-#else
- zval* writeconcernerror = NULL;
-
- MAKE_STD_ZVAL(writeconcernerror);
- php_phongo_writeresult_get_writeconcernerror(intern, writeconcernerror TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "writeConcernError", writeconcernerror);
-#endif
}
if (intern->write_concern) {
-#if PHP_VERSION_ID >= 70000
zval write_concern;
phongo_writeconcern_init(&write_concern, intern->write_concern);
ADD_ASSOC_ZVAL_EX(&retval, "writeConcern", &write_concern);
-#else
- zval* write_concern = NULL;
-
- MAKE_STD_ZVAL(write_concern);
- phongo_writeconcern_init(write_concern, intern->write_concern TSRMLS_CC);
- ADD_ASSOC_ZVAL_EX(&retval, "writeConcern", write_concern);
-#endif
} else {
ADD_ASSOC_NULL_EX(&retval, "writeConcern");
}
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_writeresult_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "WriteResult", php_phongo_writeresult_me);
- php_phongo_writeresult_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_phongo_writeresult_ce = zend_register_internal_class(&ce);
php_phongo_writeresult_ce->create_object = php_phongo_writeresult_create_object;
PHONGO_CE_FINAL(php_phongo_writeresult_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_writeresult_ce);
memcpy(&php_phongo_handler_writeresult, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_writeresult.get_debug_info = php_phongo_writeresult_get_debug_info;
-#if PHP_VERSION_ID >= 70000
- php_phongo_handler_writeresult.free_obj = php_phongo_writeresult_free_object;
- php_phongo_handler_writeresult.offset = XtOffsetOf(php_phongo_writeresult_t, std);
-#endif
+ php_phongo_handler_writeresult.free_obj = php_phongo_writeresult_free_object;
+ php_phongo_handler_writeresult.offset = XtOffsetOf(php_phongo_writeresult_t, std);
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/bson-encode.c b/mongodb-1.8.1/src/bson-encode.c
similarity index 68%
rename from mongodb-1.7.4/src/bson-encode.c
rename to mongodb-1.8.1/src/bson-encode.c
index 0275aaf9..83c48d44 100644
--- a/mongodb-1.7.4/src/bson-encode.c
+++ b/mongodb-1.8.1/src/bson-encode.c
@@ -1,696 +1,530 @@
/*
* Copyright 2014-2017 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.
*/
#include <bson/bson.h>
#include <php.h>
#include <Zend/zend_hash.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_phongo.h"
#include "php_bson.h"
#include "phongo_compat.h"
-#if SIZEOF_PHONGO_LONG == 8
+#if SIZEOF_ZEND_LONG == 8
#define BSON_APPEND_INT(b, key, keylen, val) \
if (val > INT32_MAX || val < INT32_MIN) { \
bson_append_int64(b, key, keylen, val); \
} else { \
bson_append_int32(b, key, keylen, val); \
}
-#elif SIZEOF_PHONGO_LONG == 4
+#elif SIZEOF_ZEND_LONG == 4
#define BSON_APPEND_INT(b, key, keylen, val) \
bson_append_int32(b, key, keylen, val)
#else
#error Unsupported architecture (integers are neither 32-bit nor 64-bit)
#endif
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "PHONGO-BSON"
/* Forwards declarations */
-static void php_phongo_zval_to_bson_internal(zval* data, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out TSRMLS_DC);
+static void php_phongo_zval_to_bson_internal(zval* data, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out);
/* Determines whether the argument should be serialized as a BSON array or
* document. IS_ARRAY is returned if the argument's keys are a sequence of
* integers starting at zero; otherwise, IS_OBJECT is returned. */
-static int php_phongo_is_array_or_document(zval* val TSRMLS_DC) /* {{{ */
+static int php_phongo_is_array_or_document(zval* val) /* {{{ */
{
HashTable* ht_data = HASH_OF(val);
int count;
if (Z_TYPE_P(val) != IS_ARRAY) {
return IS_OBJECT;
}
count = ht_data ? zend_hash_num_elements(ht_data) : 0;
if (count > 0) {
-#if PHP_VERSION_ID >= 70000
zend_string* key;
zend_ulong index, idx;
idx = 0;
ZEND_HASH_FOREACH_KEY(ht_data, index, key)
{
if (key) {
return IS_OBJECT;
} else {
if (index != idx) {
return IS_OBJECT;
}
}
idx++;
}
ZEND_HASH_FOREACH_END();
-#else
- char* key;
- unsigned int key_len;
- unsigned long index = 0;
- unsigned long idx = 0;
- int hash_type = 0;
- HashPosition pos;
-
- zend_hash_internal_pointer_reset_ex(ht_data, &pos);
- for (;; zend_hash_move_forward_ex(ht_data, &pos)) {
- hash_type = zend_hash_get_current_key_ex(ht_data, &key, &key_len, &index, 0, &pos);
- if (hash_type == HASH_KEY_NON_EXISTENT) {
- break;
- }
-
- if (hash_type == HASH_KEY_IS_STRING) {
- return IS_OBJECT;
- } else {
- if (index != idx) {
- return IS_OBJECT;
- }
- }
- idx++;
- }
-#endif
} else {
return Z_TYPE_P(val);
}
return IS_ARRAY;
} /* }}} */
/* Appends the array or object argument to the BSON document. If the object is
* an instance of MongoDB\BSON\Serializable, the return value of bsonSerialize()
* will be appended as an embedded document. Other MongoDB\BSON\Type instances
* will be appended as the appropriate BSON type. Other array or object values
* will be appended as an embedded document. */
-static void php_phongo_bson_append_object(bson_t* bson, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, const char* key, long key_len, zval* object TSRMLS_DC) /* {{{ */
+static void php_phongo_bson_append_object(bson_t* bson, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, const char* key, long key_len, zval* object) /* {{{ */
{
- if (Z_TYPE_P(object) == IS_OBJECT && instanceof_function(Z_OBJCE_P(object), php_phongo_cursorid_ce TSRMLS_CC)) {
+ if (Z_TYPE_P(object) == IS_OBJECT && instanceof_function(Z_OBJCE_P(object), php_phongo_cursorid_ce)) {
bson_append_int64(bson, key, key_len, Z_CURSORID_OBJ_P(object)->id);
return;
}
- if (Z_TYPE_P(object) == IS_OBJECT && instanceof_function(Z_OBJCE_P(object), php_phongo_type_ce TSRMLS_CC)) {
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_serializable_ce TSRMLS_CC)) {
-#if PHP_VERSION_ID >= 70000
- zval obj_data;
-#else
- zval* obj_data = NULL;
-#endif
+ if (Z_TYPE_P(object) == IS_OBJECT && instanceof_function(Z_OBJCE_P(object), php_phongo_type_ce)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_serializable_ce)) {
+ zval obj_data;
bson_t child;
-#if PHP_VERSION_ID >= 70000
zend_call_method_with_0_params(object, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data);
-#else
- zend_call_method_with_0_params(&object, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data);
-#endif
if (Z_ISUNDEF(obj_data)) {
/* zend_call_method() failed or bsonSerialize() threw an
* exception. Either way, there is nothing else to do. */
return;
}
-#if PHP_VERSION_ID >= 70000
- if (Z_TYPE(obj_data) != IS_ARRAY && !(Z_TYPE(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE(obj_data), zend_standard_class_def TSRMLS_CC))) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC,
+ if (Z_TYPE(obj_data) != IS_ARRAY && !(Z_TYPE(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE(obj_data), zend_standard_class_def))) {
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE,
"Expected %s::%s() to return an array or stdClass, %s given",
ZSTR_VAL(Z_OBJCE_P(object)->name),
BSON_SERIALIZE_FUNC_NAME,
PHONGO_ZVAL_CLASS_OR_TYPE_NAME(obj_data));
zval_ptr_dtor(&obj_data);
-#else
- if (Z_TYPE_P(obj_data) != IS_ARRAY && !(Z_TYPE_P(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(obj_data), zend_standard_class_def TSRMLS_CC))) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC,
- "Expected %s::%s() to return an array or stdClass, %s given",
- ZSTR_VAL(Z_OBJCE_P(object)->name),
- BSON_SERIALIZE_FUNC_NAME,
- PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(obj_data));
- zval_ptr_dtor(&obj_data);
-#endif
return;
}
/* Persistable objects must always be serialized as BSON documents;
* otherwise, infer based on bsonSerialize()'s return value. */
-#if PHP_VERSION_ID >= 70000
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC) || php_phongo_is_array_or_document(&obj_data TSRMLS_CC) == IS_OBJECT) {
-#else
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC) || php_phongo_is_array_or_document(obj_data TSRMLS_CC) == IS_OBJECT) {
-#endif
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce) || php_phongo_is_array_or_document(&obj_data) == IS_OBJECT) {
bson_append_document_begin(bson, key, key_len, &child);
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC)) {
-#if PHP_VERSION_ID >= 70000
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce)) {
bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t*) Z_OBJCE_P(object)->name->val, Z_OBJCE_P(object)->name->len);
-#else
- bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t*) Z_OBJCE_P(object)->name, strlen(Z_OBJCE_P(object)->name));
-#endif
}
-#if PHP_VERSION_ID >= 70000
- php_phongo_zval_to_bson_internal(&obj_data, field_path, flags, &child, NULL TSRMLS_CC);
-#else
- php_phongo_zval_to_bson_internal(obj_data, field_path, flags, &child, NULL TSRMLS_CC);
-#endif
+ php_phongo_zval_to_bson_internal(&obj_data, field_path, flags, &child, NULL);
bson_append_document_end(bson, &child);
} else {
bson_append_array_begin(bson, key, key_len, &child);
-#if PHP_VERSION_ID >= 70000
- php_phongo_zval_to_bson_internal(&obj_data, field_path, flags, &child, NULL TSRMLS_CC);
-#else
- php_phongo_zval_to_bson_internal(obj_data, field_path, flags, &child, NULL TSRMLS_CC);
-#endif
+ php_phongo_zval_to_bson_internal(&obj_data, field_path, flags, &child, NULL);
bson_append_array_end(bson, &child);
}
zval_ptr_dtor(&obj_data);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_objectid_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_objectid_ce)) {
bson_oid_t oid;
php_phongo_objectid_t* intern = Z_OBJECTID_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding ObjectId");
bson_oid_init_from_string(&oid, intern->oid);
bson_append_oid(bson, key, key_len, &oid);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_utcdatetime_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_utcdatetime_ce)) {
php_phongo_utcdatetime_t* intern = Z_UTCDATETIME_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding UTCDateTime");
bson_append_date_time(bson, key, key_len, intern->milliseconds);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_binary_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_binary_ce)) {
php_phongo_binary_t* intern = Z_BINARY_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Binary");
bson_append_binary(bson, key, key_len, intern->type, (const uint8_t*) intern->data, (uint32_t) intern->data_len);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_decimal128_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_decimal128_ce)) {
php_phongo_decimal128_t* intern = Z_DECIMAL128_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Decimal128");
bson_append_decimal128(bson, key, key_len, &intern->decimal);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_int64_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_int64_ce)) {
php_phongo_int64_t* intern = Z_INT64_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Int64");
bson_append_int64(bson, key, key_len, intern->integer);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_regex_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_regex_ce)) {
php_phongo_regex_t* intern = Z_REGEX_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Regex");
bson_append_regex(bson, key, key_len, intern->pattern, intern->flags);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_javascript_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_javascript_ce)) {
php_phongo_javascript_t* intern = Z_JAVASCRIPT_OBJ_P(object);
if (intern->scope) {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Javascript with scope");
bson_append_code_with_scope(bson, key, key_len, intern->code, intern->scope);
} else {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Javascript without scope");
bson_append_code(bson, key, key_len, intern->code);
}
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_timestamp_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_timestamp_ce)) {
php_phongo_timestamp_t* intern = Z_TIMESTAMP_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Timestamp");
bson_append_timestamp(bson, key, key_len, intern->timestamp, intern->increment);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_maxkey_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_maxkey_ce)) {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding MaxKey");
bson_append_maxkey(bson, key, key_len);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_minkey_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_minkey_ce)) {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding MinKey");
bson_append_minkey(bson, key, key_len);
return;
}
/* Deprecated types */
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_dbpointer_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_dbpointer_ce)) {
bson_oid_t oid;
php_phongo_dbpointer_t* intern = Z_DBPOINTER_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding DBPointer");
bson_oid_init_from_string(&oid, intern->id);
bson_append_dbpointer(bson, key, key_len, intern->ref, &oid);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_symbol_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_symbol_ce)) {
php_phongo_symbol_t* intern = Z_SYMBOL_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Symbol");
bson_append_symbol(bson, key, key_len, intern->symbol, intern->symbol_len);
return;
}
- if (instanceof_function(Z_OBJCE_P(object), php_phongo_undefined_ce TSRMLS_CC)) {
+ if (instanceof_function(Z_OBJCE_P(object), php_phongo_undefined_ce)) {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Undefined");
bson_append_undefined(bson, key, key_len);
return;
}
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Unexpected %s instance: %s", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(object)->name));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Unexpected %s instance: %s", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(object)->name));
return;
} else {
bson_t child;
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding document");
bson_append_document_begin(bson, key, key_len, &child);
- php_phongo_zval_to_bson_internal(object, field_path, flags, &child, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson_internal(object, field_path, flags, &child, NULL);
bson_append_document_end(bson, &child);
}
} /* }}} */
/* Appends the zval argument to the BSON document. If the argument is an object,
* or an array that should be serialized as an embedded document, this function
* will defer to php_phongo_bson_append_object(). */
-static void php_phongo_bson_append(bson_t* bson, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, const char* key, long key_len, zval* entry TSRMLS_DC) /* {{{ */
+static void php_phongo_bson_append(bson_t* bson, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, const char* key, long key_len, zval* entry) /* {{{ */
{
php_phongo_field_path_write_item_at_current_level(field_path, key);
-#if PHP_VERSION_ID >= 70000
try_again:
-#endif
switch (Z_TYPE_P(entry)) {
case IS_NULL:
bson_append_null(bson, key, key_len);
break;
-#if PHP_VERSION_ID >= 70000
case IS_TRUE:
bson_append_bool(bson, key, key_len, true);
break;
case IS_FALSE:
bson_append_bool(bson, key, key_len, false);
break;
-#else
- case IS_BOOL:
- bson_append_bool(bson, key, key_len, Z_BVAL_P(entry));
- break;
-#endif
case IS_LONG:
BSON_APPEND_INT(bson, key, key_len, Z_LVAL_P(entry));
break;
case IS_DOUBLE:
bson_append_double(bson, key, key_len, Z_DVAL_P(entry));
break;
case IS_STRING:
if (bson_utf8_validate(Z_STRVAL_P(entry), Z_STRLEN_P(entry), true)) {
bson_append_utf8(bson, key, key_len, Z_STRVAL_P(entry), Z_STRLEN_P(entry));
} else {
char* path_string = php_phongo_field_path_as_string(field_path);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected invalid UTF-8 for field path \"%s\": %s", path_string, Z_STRVAL_P(entry));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected invalid UTF-8 for field path \"%s\": %s", path_string, Z_STRVAL_P(entry));
efree(path_string);
}
break;
case IS_ARRAY:
- if (php_phongo_is_array_or_document(entry TSRMLS_CC) == IS_ARRAY) {
+ if (php_phongo_is_array_or_document(entry) == IS_ARRAY) {
bson_t child;
HashTable* tmp_ht = HASH_OF(entry);
if (!php_phongo_zend_hash_apply_protection_begin(tmp_ht)) {
char* path_string = php_phongo_field_path_as_string(field_path);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected recursion for field path \"%s\"", path_string);
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected recursion for field path \"%s\"", path_string);
efree(path_string);
break;
}
bson_append_array_begin(bson, key, key_len, &child);
php_phongo_field_path_write_type_at_current_level(field_path, PHONGO_FIELD_PATH_ITEM_ARRAY);
field_path->size++;
- php_phongo_zval_to_bson_internal(entry, field_path, flags, &child, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson_internal(entry, field_path, flags, &child, NULL);
field_path->size--;
bson_append_array_end(bson, &child);
php_phongo_zend_hash_apply_protection_end(tmp_ht);
break;
}
PHONGO_BREAK_INTENTIONALLY_MISSING
case IS_OBJECT: {
HashTable* tmp_ht = HASH_OF(entry);
if (!php_phongo_zend_hash_apply_protection_begin(tmp_ht)) {
char* path_string = php_phongo_field_path_as_string(field_path);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected recursion for field path \"%s\"", path_string);
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected recursion for field path \"%s\"", path_string);
efree(path_string);
break;
}
php_phongo_field_path_write_type_at_current_level(field_path, PHONGO_FIELD_PATH_ITEM_DOCUMENT);
field_path->size++;
- php_phongo_bson_append_object(bson, field_path, flags, key, key_len, entry TSRMLS_CC);
+ php_phongo_bson_append_object(bson, field_path, flags, key, key_len, entry);
field_path->size--;
php_phongo_zend_hash_apply_protection_end(tmp_ht);
break;
}
-#if PHP_VERSION_ID >= 70000
case IS_REFERENCE:
ZVAL_DEREF(entry);
goto try_again;
-#endif
default: {
char* path_string = php_phongo_field_path_as_string(field_path);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected unsupported PHP type for field path \"%s\": %d (%s)", path_string, Z_TYPE_P(entry), zend_get_type_by_const(Z_TYPE_P(entry)));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected unsupported PHP type for field path \"%s\": %d (%s)", path_string, Z_TYPE_P(entry), zend_get_type_by_const(Z_TYPE_P(entry)));
efree(path_string);
}
}
} /* }}} */
-static void php_phongo_zval_to_bson_internal(zval* data, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out TSRMLS_DC) /* {{{ */
+static void php_phongo_zval_to_bson_internal(zval* data, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out) /* {{{ */
{
HashTable* ht_data = NULL;
-#if PHP_VERSION_ID >= 70000
- zval obj_data;
-#else
- HashPosition pos;
- zval* obj_data = NULL;
-#endif
+ zval obj_data;
/* If we will be encoding a class that may contain protected and private
* properties, we'll need to filter them out later. */
bool ht_data_from_properties = false;
/* If the object is an instance of MongoDB\BSON\Persistable, we will need to
* inject the PHP class name as a BSON key and ignore any existing key in
* the return value of bsonSerialize(). */
bool skip_odm_field = false;
ZVAL_UNDEF(&obj_data);
switch (Z_TYPE_P(data)) {
case IS_OBJECT:
- if (instanceof_function(Z_OBJCE_P(data), php_phongo_serializable_ce TSRMLS_CC)) {
-#if PHP_VERSION_ID >= 70000
+ if (instanceof_function(Z_OBJCE_P(data), php_phongo_serializable_ce)) {
zend_call_method_with_0_params(data, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data);
-#else
- zend_call_method_with_0_params(&data, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data);
-#endif
if (Z_ISUNDEF(obj_data)) {
/* zend_call_method() failed or bsonSerialize() threw an
* exception. Either way, there is nothing else to do. */
return;
}
-#if PHP_VERSION_ID >= 70000
- if (Z_TYPE(obj_data) != IS_ARRAY && !(Z_TYPE(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE(obj_data), zend_standard_class_def TSRMLS_CC))) {
-#else
- if (Z_TYPE_P(obj_data) != IS_ARRAY && !(Z_TYPE_P(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(obj_data), zend_standard_class_def TSRMLS_CC))) {
-#endif
+ if (Z_TYPE(obj_data) != IS_ARRAY && !(Z_TYPE(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE(obj_data), zend_standard_class_def))) {
phongo_throw_exception(
- PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC,
+ PHONGO_ERROR_UNEXPECTED_VALUE,
"Expected %s::%s() to return an array or stdClass, %s given",
ZSTR_VAL(Z_OBJCE_P(data)->name),
BSON_SERIALIZE_FUNC_NAME,
-#if PHP_VERSION_ID >= 70000
- PHONGO_ZVAL_CLASS_OR_TYPE_NAME(obj_data)
-#else
- PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(obj_data)
-#endif
- );
+ PHONGO_ZVAL_CLASS_OR_TYPE_NAME(obj_data));
goto cleanup;
}
-#if PHP_VERSION_ID >= 70000
ht_data = HASH_OF(&obj_data);
-#else
- ht_data = HASH_OF(obj_data);
-#endif
- if (instanceof_function(Z_OBJCE_P(data), php_phongo_persistable_ce TSRMLS_CC)) {
-#if PHP_VERSION_ID >= 70000
+ if (instanceof_function(Z_OBJCE_P(data), php_phongo_persistable_ce)) {
bson_append_binary(bson, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t*) Z_OBJCE_P(data)->name->val, Z_OBJCE_P(data)->name->len);
-#else
- bson_append_binary(bson, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t*) Z_OBJCE_P(data)->name, strlen(Z_OBJCE_P(data)->name));
-#endif
/* Ensure that we ignore an existing key with the same name
* if one exists in the bsonSerialize() return value. */
skip_odm_field = true;
}
break;
}
- if (instanceof_function(Z_OBJCE_P(data), php_phongo_type_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s instance %s cannot be serialized as a root element", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(data)->name));
+ if (instanceof_function(Z_OBJCE_P(data), php_phongo_type_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s instance %s cannot be serialized as a root element", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(data)->name));
return;
}
- ht_data = Z_OBJ_HT_P(data)->get_properties(data TSRMLS_CC);
+ ht_data = Z_OBJ_HT_P(data)->get_properties(data);
ht_data_from_properties = true;
break;
case IS_ARRAY:
ht_data = HASH_OF(data);
break;
default:
return;
}
-#if PHP_VERSION_ID >= 70000
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* value;
ZEND_HASH_FOREACH_KEY_VAL_IND(ht_data, num_key, string_key, value)
{
if (string_key) {
if (ht_data_from_properties) {
/* Skip protected and private properties */
if (ZSTR_VAL(string_key)[0] == '\0' && ZSTR_LEN(string_key) > 0) {
continue;
}
}
if (strlen(ZSTR_VAL(string_key)) != ZSTR_LEN(string_key)) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "BSON keys cannot contain null bytes. Unexpected null byte after \"%s\".", ZSTR_VAL(string_key));
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "BSON keys cannot contain null bytes. Unexpected null byte after \"%s\".", ZSTR_VAL(string_key));
goto cleanup;
}
if (skip_odm_field && !strcmp(ZSTR_VAL(string_key), PHONGO_ODM_FIELD_NAME)) {
continue;
}
if (flags & PHONGO_BSON_ADD_ID) {
if (!strcmp(ZSTR_VAL(string_key), "_id")) {
flags &= ~PHONGO_BSON_ADD_ID;
}
}
}
/* Ensure we're working with a string key */
if (!string_key) {
string_key = zend_long_to_str(num_key);
} else {
zend_string_addref(string_key);
}
- php_phongo_bson_append(bson, field_path, flags & ~PHONGO_BSON_ADD_ID, ZSTR_VAL(string_key), strlen(ZSTR_VAL(string_key)), value TSRMLS_CC);
+ php_phongo_bson_append(bson, field_path, flags & ~PHONGO_BSON_ADD_ID, ZSTR_VAL(string_key), strlen(ZSTR_VAL(string_key)), value);
zend_string_release(string_key);
}
ZEND_HASH_FOREACH_END();
}
-#else
- zend_hash_internal_pointer_reset_ex(ht_data, &pos);
- for (;; zend_hash_move_forward_ex(ht_data, &pos)) {
- char* string_key = NULL;
- uint string_key_len = 0;
- ulong num_key = 0;
- zval** value;
- int hash_type;
-
- hash_type = zend_hash_get_current_key_ex(ht_data, &string_key, &string_key_len, &num_key, 0, &pos);
-
- if (hash_type == HASH_KEY_NON_EXISTENT) {
- break;
- }
-
- if (zend_hash_get_current_data_ex(ht_data, (void**) &value, &pos) == FAILURE) {
- break;
- }
-
- if (hash_type == HASH_KEY_IS_STRING) {
- if (ht_data_from_properties) {
- /* Skip protected and private properties */
- if (string_key[0] == '\0' && string_key_len > 1) {
- continue;
- }
- }
-
- if (strlen(string_key) != string_key_len - 1) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "BSON keys cannot contain null bytes. Unexpected null byte after \"%s\".", ZSTR_VAL(string_key));
-
- goto cleanup;
- }
-
- if (skip_odm_field && !strcmp(string_key, PHONGO_ODM_FIELD_NAME)) {
- continue;
- }
-
- if (flags & PHONGO_BSON_ADD_ID) {
- if (!strcmp(string_key, "_id")) {
- flags &= ~PHONGO_BSON_ADD_ID;
- }
- }
- }
-
- /* Ensure we're working with a string key */
- if (hash_type == HASH_KEY_IS_LONG) {
- spprintf(&string_key, 0, "%ld", num_key);
- }
-
- php_phongo_bson_append(bson, field_path, flags & ~PHONGO_BSON_ADD_ID, string_key, strlen(string_key), *value TSRMLS_CC);
-
- if (hash_type == HASH_KEY_IS_LONG) {
- efree(string_key);
- }
- }
-#endif
if (flags & PHONGO_BSON_ADD_ID) {
bson_oid_t oid;
bson_oid_init(&oid, NULL);
bson_append_oid(bson, "_id", strlen("_id"), &oid);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "Added new _id");
}
if (flags & PHONGO_BSON_RETURN_ID && bson_out) {
bson_iter_t iter;
*bson_out = bson_new();
if (bson_iter_init_find(&iter, bson, "_id") && !bson_append_iter(*bson_out, NULL, 0, &iter)) {
/* This should not be able to happen since we are copying from
* within a valid bson_t. */
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Error copying \"_id\" field from encoded document");
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Error copying \"_id\" field from encoded document");
goto cleanup;
}
}
cleanup:
if (!Z_ISUNDEF(obj_data)) {
zval_ptr_dtor(&obj_data);
}
} /* }}} */
/* Converts the array or object argument to a BSON document. If the object is an
* instance of MongoDB\BSON\Serializable, the return value of bsonSerialize()
* will be used. */
-void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out TSRMLS_DC) /* {{{ */
+void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out) /* {{{ */
{
php_phongo_field_path* field_path = php_phongo_field_path_alloc(false);
- php_phongo_zval_to_bson_internal(data, field_path, flags, bson, bson_out TSRMLS_CC);
+ php_phongo_zval_to_bson_internal(data, field_path, flags, bson, bson_out);
php_phongo_field_path_free(field_path);
} /* }}} */
/* Converts the argument to a bson_value_t. If the object is an instance of
* MongoDB\BSON\Serializable, the return value of bsonSerialize() will be
* used. */
-void php_phongo_zval_to_bson_value(zval* data, php_phongo_bson_flags_t flags, bson_value_t* value TSRMLS_DC) /* {{{ */
+void php_phongo_zval_to_bson_value(zval* data, php_phongo_bson_flags_t flags, bson_value_t* value) /* {{{ */
{
bson_iter_t iter;
bson_t bson = BSON_INITIALIZER;
-#if PHP_VERSION_ID >= 70000
zval* data_object = ecalloc(sizeof(zval), 1);
-#else
- zval* data_object = NULL;
- ALLOC_INIT_ZVAL(data_object);
-#endif
array_init_size(data_object, 1);
add_assoc_zval(data_object, "data", data);
-#if PHP_VERSION_ID >= 70000
Z_TRY_ADDREF_P(data);
-#else
- Z_ADDREF_P(data);
-#endif
- php_phongo_zval_to_bson(data_object, flags, &bson, NULL TSRMLS_CC);
+ php_phongo_zval_to_bson(data_object, flags, &bson, NULL);
if (bson_iter_init_find(&iter, &bson, "data")) {
bson_value_copy(bson_iter_value(&iter), value);
}
-#if PHP_VERSION_ID >= 70000
zval_ptr_dtor(data_object);
efree(data_object);
-#else
- zval_ptr_dtor(&data_object);
-#endif
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/bson.c b/mongodb-1.8.1/src/bson.c
similarity index 73%
rename from mongodb-1.7.4/src/bson.c
rename to mongodb-1.8.1/src/bson.c
index ba118448..9312de93 100644
--- a/mongodb-1.7.4/src/bson.c
+++ b/mongodb-1.8.1/src/bson.c
@@ -1,1732 +1,1378 @@
/*
* Copyright 2014-2017 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.
*/
#include <bson/bson.h>
#include <php.h>
#include <Zend/zend_hash.h>
#include <Zend/zend_interfaces.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php_phongo.h"
#include "php_bson.h"
#include "phongo_compat.h"
#include "php_array_api.h"
#define DEBUG 0
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "PHONGO-BSON"
#define PHONGO_IS_CLASS_INSTANTIATABLE(ce) \
(!(ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)))
-#if PHP_VERSION_ID >= 70000
#define PHONGO_BSON_STATE_ZCHILD(state) (&((php_phongo_bson_state*) (state))->zchild)
-#else
-#define PHONGO_BSON_STATE_ZCHILD(state) (((php_phongo_bson_state*) (state))->zchild)
-#endif
#define PHONGO_FIELD_PATH_EXPANSION 8
/* Forward declarations */
static bool php_phongo_bson_visit_document(const bson_iter_t* iter ARG_UNUSED, const char* key, const bson_t* v_document, void* data);
static bool php_phongo_bson_visit_array(const bson_iter_t* iter ARG_UNUSED, const char* key, const bson_t* v_document, void* data);
/* Path builder */
char* php_phongo_field_path_as_string(php_phongo_field_path* field_path)
{
size_t length = 1; /* NULL character */
size_t i;
char* path;
char* ptr;
if (!field_path) {
return estrdup("");
}
if (!field_path->elements) {
return estrdup("");
}
for (i = 0; i <= field_path->size; i++) {
if (!field_path->elements[i]) {
continue;
}
length += (1 + strlen(field_path->elements[i]));
}
path = emalloc(length);
ptr = path;
for (i = 0; i <= field_path->size; i++) {
if (!field_path->elements[i]) {
continue;
}
strcpy(ptr, field_path->elements[i]);
ptr += strlen(field_path->elements[i]);
ptr[0] = '.';
ptr++;
}
ptr[-1] = '\0';
return path;
}
php_phongo_field_path* php_phongo_field_path_alloc(bool owns_elements)
{
php_phongo_field_path* tmp = ecalloc(1, sizeof(php_phongo_field_path));
tmp->ref_count = 1;
tmp->owns_elements = owns_elements;
return tmp;
}
void php_phongo_field_path_free(php_phongo_field_path* field_path)
{
if (field_path->owns_elements) {
size_t i;
for (i = 0; i < field_path->size; i++) {
efree(field_path->elements[i]);
}
}
if (field_path->elements) {
efree(field_path->elements);
}
if (field_path->element_types) {
efree(field_path->element_types);
}
efree(field_path);
}
static void php_phongo_field_path_ensure_allocation(php_phongo_field_path* field_path, size_t level)
{
if (level >= field_path->allocated_size) {
size_t i;
field_path->allocated_size = field_path->size + PHONGO_FIELD_PATH_EXPANSION;
field_path->elements = erealloc(field_path->elements, sizeof(char*) * field_path->allocated_size);
field_path->element_types = erealloc(field_path->element_types, sizeof(php_phongo_bson_field_path_item_types) * field_path->allocated_size);
for (i = level; i < field_path->allocated_size; i++) {
field_path->elements[i] = NULL;
field_path->element_types[i] = PHONGO_FIELD_PATH_ITEM_NONE;
}
}
}
void php_phongo_field_path_write_item_at_current_level(php_phongo_field_path* field_path, const char* element)
{
php_phongo_field_path_ensure_allocation(field_path, field_path->size);
if (field_path->owns_elements) {
field_path->elements[field_path->size] = estrdup(element);
} else {
field_path->elements[field_path->size] = (char*) element;
}
}
void php_phongo_field_path_write_type_at_current_level(php_phongo_field_path* field_path, php_phongo_bson_field_path_item_types element_type)
{
php_phongo_field_path_ensure_allocation(field_path, field_path->size);
field_path->element_types[field_path->size] = element_type;
}
bool php_phongo_field_path_push(php_phongo_field_path* field_path, const char* element, php_phongo_bson_field_path_item_types element_type)
{
php_phongo_field_path_write_item_at_current_level(field_path, element);
php_phongo_field_path_write_type_at_current_level(field_path, element_type);
field_path->size++;
return true;
}
bool php_phongo_field_path_pop(php_phongo_field_path* field_path)
{
php_phongo_field_path_ensure_allocation(field_path, field_path->size);
field_path->elements[field_path->size] = NULL;
field_path->element_types[field_path->size] = PHONGO_FIELD_PATH_ITEM_NONE;
field_path->size--;
field_path->elements[field_path->size] = NULL;
field_path->element_types[field_path->size] = PHONGO_FIELD_PATH_ITEM_NONE;
return true;
}
inline static bool php_phongo_bson_state_is_initialized(php_phongo_bson_state* state)
{
return state->field_path != NULL;
}
void php_phongo_bson_state_ctor(php_phongo_bson_state* state)
{
state->field_path = php_phongo_field_path_alloc(false);
}
void php_phongo_bson_state_copy_ctor(php_phongo_bson_state* dst, php_phongo_bson_state* src)
{
dst->map = src->map;
if (src->field_path) {
src->field_path->ref_count++;
}
dst->field_path = src->field_path;
}
void php_phongo_bson_state_dtor(php_phongo_bson_state* state)
{
if (state->field_path) {
state->field_path->ref_count--;
if (state->field_path->ref_count < 1) {
php_phongo_field_path_free(state->field_path);
}
state->field_path = NULL;
}
} /* }}} */
static void php_phongo_bson_visit_corrupt(const bson_iter_t* iter ARG_UNUSED, void* data ARG_UNUSED) /* {{{ */
{
mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Corrupt BSON data detected!");
} /* }}} */
static void php_phongo_bson_visit_unsupported_type(const bson_iter_t* iter ARG_UNUSED, const char* key, uint32_t v_type_code, void* data ARG_UNUSED) /* {{{ */
{
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
char* path_string;
- TSRMLS_FETCH();
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
path_string = php_phongo_field_path_as_string(state->field_path);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected unknown BSON type 0x%02hhx for field path \"%s\". Are you using the latest driver?", (unsigned char) v_type_code, path_string);
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected unknown BSON type 0x%02hhx for field path \"%s\". Are you using the latest driver?", (unsigned char) v_type_code, path_string);
efree(path_string);
} /* }}} */
static bool php_phongo_bson_visit_double(const bson_iter_t* iter ARG_UNUSED, const char* key, double v_double, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
if (state->is_visiting_array) {
add_next_index_double(retval, v_double);
} else {
add_assoc_double(retval, key, v_double);
}
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_utf8(const bson_iter_t* iter ARG_UNUSED, const char* key, size_t v_utf8_len, const char* v_utf8, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
if (state->is_visiting_array) {
ADD_NEXT_INDEX_STRINGL(retval, v_utf8, v_utf8_len);
} else {
ADD_ASSOC_STRING_EX(retval, key, strlen(key), v_utf8, v_utf8_len);
}
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
-static void php_phongo_bson_new_binary_from_binary_and_type(zval* object, const char* data, size_t data_len, bson_subtype_t type TSRMLS_DC) /* {{{ */
+static void php_phongo_bson_new_binary_from_binary_and_type(zval* object, const char* data, size_t data_len, bson_subtype_t type) /* {{{ */
{
php_phongo_binary_t* intern;
object_init_ex(object, php_phongo_binary_ce);
intern = Z_BINARY_OBJ_P(object);
intern->data = estrndup(data, data_len);
intern->data_len = data_len;
intern->type = (uint8_t) type;
} /* }}} */
static bool php_phongo_bson_visit_binary(const bson_iter_t* iter ARG_UNUSED, const char* key, bson_subtype_t v_subtype, size_t v_binary_len, const uint8_t* v_binary, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
- TSRMLS_FETCH();
if (v_subtype == 0x80 && strcmp(key, PHONGO_ODM_FIELD_NAME) == 0) {
-#if PHP_VERSION_ID >= 70000
zend_string* zs_classname = zend_string_init((const char*) v_binary, v_binary_len, 0);
- zend_class_entry* found_ce = zend_fetch_class(zs_classname, ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_SILENT TSRMLS_CC);
+ zend_class_entry* found_ce = zend_fetch_class(zs_classname, ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_SILENT);
zend_string_release(zs_classname);
-#else
- zend_class_entry* found_ce = zend_fetch_class((const char*) v_binary, v_binary_len, ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_SILENT TSRMLS_CC);
-#endif
- if (found_ce && PHONGO_IS_CLASS_INSTANTIATABLE(found_ce) && instanceof_function(found_ce, php_phongo_persistable_ce TSRMLS_CC)) {
+ if (found_ce && PHONGO_IS_CLASS_INSTANTIATABLE(found_ce) && instanceof_function(found_ce, php_phongo_persistable_ce)) {
((php_phongo_bson_state*) data)->odm = found_ce;
}
}
{
-#if PHP_VERSION_ID >= 70000
zval zchild;
- php_phongo_bson_new_binary_from_binary_and_type(&zchild, (const char*) v_binary, v_binary_len, v_subtype TSRMLS_CC);
+ php_phongo_bson_new_binary_from_binary_and_type(&zchild, (const char*) v_binary, v_binary_len, v_subtype);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
-
- MAKE_STD_ZVAL(zchild);
- php_phongo_bson_new_binary_from_binary_and_type(zchild, (const char*) v_binary, v_binary_len, v_subtype TSRMLS_CC);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
}
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_undefined(const bson_iter_t* iter, const char* key, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000 /* PHP_VERSION_ID >= 70000 */
- zval zchild;
+ zval zchild;
object_init_ex(&zchild, php_phongo_undefined_ce);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- object_init_ex(zchild, php_phongo_undefined_ce);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
-static void php_phongo_objectid_new_from_oid(zval* object, const bson_oid_t* oid TSRMLS_DC) /* {{{ */
+static void php_phongo_objectid_new_from_oid(zval* object, const bson_oid_t* oid) /* {{{ */
{
php_phongo_objectid_t* intern;
object_init_ex(object, php_phongo_objectid_ce);
intern = Z_OBJECTID_OBJ_P(object);
bson_oid_to_string(oid, intern->oid);
intern->initialized = true;
} /* }}} */
static bool php_phongo_bson_visit_oid(const bson_iter_t* iter ARG_UNUSED, const char* key, const bson_oid_t* v_oid, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- php_phongo_objectid_new_from_oid(&zchild, v_oid TSRMLS_CC);
+ php_phongo_objectid_new_from_oid(&zchild, v_oid);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- php_phongo_objectid_new_from_oid(zchild, v_oid TSRMLS_CC);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_bool(const bson_iter_t* iter ARG_UNUSED, const char* key, bool v_bool, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
if (state->is_visiting_array) {
add_next_index_bool(retval, v_bool);
} else {
add_assoc_bool(retval, key, v_bool);
}
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
-static void php_phongo_bson_new_utcdatetime_from_epoch(zval* object, int64_t msec_since_epoch TSRMLS_DC) /* {{{ */
+static void php_phongo_bson_new_utcdatetime_from_epoch(zval* object, int64_t msec_since_epoch) /* {{{ */
{
php_phongo_utcdatetime_t* intern;
object_init_ex(object, php_phongo_utcdatetime_ce);
intern = Z_UTCDATETIME_OBJ_P(object);
intern->milliseconds = msec_since_epoch;
intern->initialized = true;
} /* }}} */
static bool php_phongo_bson_visit_date_time(const bson_iter_t* iter ARG_UNUSED, const char* key, int64_t msec_since_epoch, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- php_phongo_bson_new_utcdatetime_from_epoch(&zchild, msec_since_epoch TSRMLS_CC);
+ php_phongo_bson_new_utcdatetime_from_epoch(&zchild, msec_since_epoch);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- php_phongo_bson_new_utcdatetime_from_epoch(zchild, msec_since_epoch TSRMLS_CC);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
-static void php_phongo_bson_new_decimal128(zval* object, const bson_decimal128_t* decimal TSRMLS_DC) /* {{{ */
+static void php_phongo_bson_new_decimal128(zval* object, const bson_decimal128_t* decimal) /* {{{ */
{
php_phongo_decimal128_t* intern;
object_init_ex(object, php_phongo_decimal128_ce);
intern = Z_DECIMAL128_OBJ_P(object);
memcpy(&intern->decimal, decimal, sizeof(bson_decimal128_t));
intern->initialized = true;
} /* }}} */
static bool php_phongo_bson_visit_decimal128(const bson_iter_t* iter ARG_UNUSED, const char* key, const bson_decimal128_t* decimal, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- php_phongo_bson_new_decimal128(&zchild, decimal TSRMLS_CC);
+ php_phongo_bson_new_decimal128(&zchild, decimal);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- php_phongo_bson_new_decimal128(zchild, decimal TSRMLS_CC);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_null(const bson_iter_t* iter ARG_UNUSED, const char* key, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
if (state->is_visiting_array) {
add_next_index_null(retval);
} else {
add_assoc_null(retval, key);
}
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
-static void php_phongo_bson_new_regex_from_regex_and_options(zval* object, const char* pattern, const char* flags TSRMLS_DC) /* {{{ */
+static void php_phongo_bson_new_regex_from_regex_and_options(zval* object, const char* pattern, const char* flags) /* {{{ */
{
php_phongo_regex_t* intern;
object_init_ex(object, php_phongo_regex_ce);
intern = Z_REGEX_OBJ_P(object);
intern->pattern_len = strlen(pattern);
intern->pattern = estrndup(pattern, intern->pattern_len);
intern->flags_len = strlen(flags);
intern->flags = estrndup(flags, intern->flags_len);
} /* }}} */
static bool php_phongo_bson_visit_regex(const bson_iter_t* iter ARG_UNUSED, const char* key, const char* v_regex, const char* v_options, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- php_phongo_bson_new_regex_from_regex_and_options(&zchild, v_regex, v_options TSRMLS_CC);
+ php_phongo_bson_new_regex_from_regex_and_options(&zchild, v_regex, v_options);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- php_phongo_bson_new_regex_from_regex_and_options(zchild, v_regex, v_options TSRMLS_CC);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
-static void php_phongo_bson_new_symbol(zval* object, const char* symbol, size_t symbol_len TSRMLS_DC) /* {{{ */
+static void php_phongo_bson_new_symbol(zval* object, const char* symbol, size_t symbol_len) /* {{{ */
{
php_phongo_symbol_t* intern;
object_init_ex(object, php_phongo_symbol_ce);
intern = Z_SYMBOL_OBJ_P(object);
intern->symbol = estrndup(symbol, symbol_len);
intern->symbol_len = symbol_len;
} /* }}} */
static bool php_phongo_bson_visit_symbol(const bson_iter_t* iter, const char* key, size_t v_symbol_len, const char* v_symbol, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- php_phongo_bson_new_symbol(&zchild, v_symbol, v_symbol_len TSRMLS_CC);
+ php_phongo_bson_new_symbol(&zchild, v_symbol, v_symbol_len);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- php_phongo_bson_new_symbol(zchild, v_symbol, v_symbol_len TSRMLS_CC);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
-static bool php_phongo_bson_new_javascript_from_javascript_and_scope(zval* object, const char* code, size_t code_len, const bson_t* scope TSRMLS_DC) /* {{{ */
+static bool php_phongo_bson_new_javascript_from_javascript_and_scope(zval* object, const char* code, size_t code_len, const bson_t* scope) /* {{{ */
{
php_phongo_javascript_t* intern;
if (scope) {
php_phongo_bson_state state;
bool valid_scope;
PHONGO_BSON_INIT_STATE(state);
valid_scope = php_phongo_bson_to_zval_ex(bson_get_data(scope), scope->len, &state);
zval_ptr_dtor(&state.zchild);
if (!valid_scope) {
return false;
}
}
object_init_ex(object, php_phongo_javascript_ce);
intern = Z_JAVASCRIPT_OBJ_P(object);
intern->code = estrndup(code, code_len);
intern->code_len = code_len;
intern->scope = scope ? bson_copy(scope) : NULL;
return true;
} /* }}} */
-static bool php_phongo_bson_new_javascript_from_javascript(zval* object, const char* code, size_t code_len TSRMLS_DC) /* {{{ */
+static bool php_phongo_bson_new_javascript_from_javascript(zval* object, const char* code, size_t code_len) /* {{{ */
{
- return php_phongo_bson_new_javascript_from_javascript_and_scope(object, code, code_len, NULL TSRMLS_CC);
+ return php_phongo_bson_new_javascript_from_javascript_and_scope(object, code, code_len, NULL);
} /* }}} */
static bool php_phongo_bson_visit_code(const bson_iter_t* iter ARG_UNUSED, const char* key, size_t v_code_len, const char* v_code, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- if (!php_phongo_bson_new_javascript_from_javascript(&zchild, v_code, v_code_len TSRMLS_CC)) {
+ if (!php_phongo_bson_new_javascript_from_javascript(&zchild, v_code, v_code_len)) {
return true;
}
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- if (!php_phongo_bson_new_javascript_from_javascript(zchild, v_code, v_code_len TSRMLS_CC)) {
- zval_ptr_dtor(&zchild);
- return true;
- }
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
-static void php_phongo_bson_new_dbpointer(zval* object, const char* ref, size_t ref_len, const bson_oid_t* oid TSRMLS_DC) /* {{{ */
+static void php_phongo_bson_new_dbpointer(zval* object, const char* ref, size_t ref_len, const bson_oid_t* oid) /* {{{ */
{
php_phongo_dbpointer_t* intern;
object_init_ex(object, php_phongo_dbpointer_ce);
intern = Z_DBPOINTER_OBJ_P(object);
intern->ref = estrndup(ref, ref_len);
intern->ref_len = ref_len;
bson_oid_to_string(oid, intern->id);
} /* }}} */
static bool php_phongo_bson_visit_dbpointer(const bson_iter_t* iter, const char* key, size_t namespace_len, const char* namespace, const bson_oid_t* oid, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- php_phongo_bson_new_dbpointer(&zchild, namespace, namespace_len, oid TSRMLS_CC);
+ php_phongo_bson_new_dbpointer(&zchild, namespace, namespace_len, oid);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- php_phongo_bson_new_dbpointer(zchild, namespace, namespace_len, oid TSRMLS_CC);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_codewscope(const bson_iter_t* iter ARG_UNUSED, const char* key, size_t v_code_len, const char* v_code, const bson_t* v_scope, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- if (!php_phongo_bson_new_javascript_from_javascript_and_scope(&zchild, v_code, v_code_len, v_scope TSRMLS_CC)) {
+ if (!php_phongo_bson_new_javascript_from_javascript_and_scope(&zchild, v_code, v_code_len, v_scope)) {
return true;
}
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- if (!php_phongo_bson_new_javascript_from_javascript_and_scope(zchild, v_code, v_code_len, v_scope TSRMLS_CC)) {
- zval_ptr_dtor(&zchild);
- return true;
- }
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_int32(const bson_iter_t* iter ARG_UNUSED, const char* key, int32_t v_int32, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
if (state->is_visiting_array) {
add_next_index_long(retval, v_int32);
} else {
add_assoc_long(retval, key, v_int32);
}
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_timestamp(const bson_iter_t* iter ARG_UNUSED, const char* key, uint32_t v_timestamp, uint32_t v_increment, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
- php_phongo_bson_new_timestamp_from_increment_and_timestamp(&zchild, v_increment, v_timestamp TSRMLS_CC);
+ php_phongo_bson_new_timestamp_from_increment_and_timestamp(&zchild, v_increment, v_timestamp);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- php_phongo_bson_new_timestamp_from_increment_and_timestamp(zchild, v_increment, v_timestamp TSRMLS_CC);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_int64(const bson_iter_t* iter ARG_UNUSED, const char* key, int64_t v_int64, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if SIZEOF_PHONGO_LONG == 4
- TSRMLS_FETCH();
-#endif
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
if (state->is_visiting_array) {
ADD_NEXT_INDEX_INT64(retval, v_int64);
} else {
ADD_ASSOC_INT64(retval, key, v_int64);
}
return false;
} /* }}} */
static bool php_phongo_bson_visit_maxkey(const bson_iter_t* iter ARG_UNUSED, const char* key, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
object_init_ex(&zchild, php_phongo_maxkey_ce);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- object_init_ex(zchild, php_phongo_maxkey_ce);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static bool php_phongo_bson_visit_minkey(const bson_iter_t* iter ARG_UNUSED, const char* key, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
php_phongo_bson_state* state = (php_phongo_bson_state*) data;
-#if PHP_VERSION_ID >= 70000
- zval zchild;
+ zval zchild;
object_init_ex(&zchild, php_phongo_minkey_ce);
if (state->is_visiting_array) {
add_next_index_zval(retval, &zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- zval* zchild = NULL;
- TSRMLS_FETCH();
-
- MAKE_STD_ZVAL(zchild);
- object_init_ex(zchild, php_phongo_minkey_ce);
-
- if (state->is_visiting_array) {
- add_next_index_zval(retval, zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
php_phongo_field_path_write_item_at_current_level(state->field_path, key);
return false;
} /* }}} */
static const bson_visitor_t php_bson_visitors = {
NULL /* php_phongo_bson_visit_before*/,
NULL /*php_phongo_bson_visit_after*/,
php_phongo_bson_visit_corrupt,
php_phongo_bson_visit_double,
php_phongo_bson_visit_utf8,
php_phongo_bson_visit_document,
php_phongo_bson_visit_array,
php_phongo_bson_visit_binary,
php_phongo_bson_visit_undefined,
php_phongo_bson_visit_oid,
php_phongo_bson_visit_bool,
php_phongo_bson_visit_date_time,
php_phongo_bson_visit_null,
php_phongo_bson_visit_regex,
php_phongo_bson_visit_dbpointer,
php_phongo_bson_visit_code,
php_phongo_bson_visit_symbol,
php_phongo_bson_visit_codewscope,
php_phongo_bson_visit_int32,
php_phongo_bson_visit_timestamp,
php_phongo_bson_visit_int64,
php_phongo_bson_visit_maxkey,
php_phongo_bson_visit_minkey,
php_phongo_bson_visit_unsupported_type,
php_phongo_bson_visit_decimal128,
{ NULL }
};
static inline bool map_element_matches_field_path(php_phongo_field_path_map_element* map_element, php_phongo_field_path* current)
{
size_t i;
if (map_element->entry->size != current->size) {
return false;
}
for (i = 0; i < current->size; i++) {
if (strcmp(map_element->entry->elements[i], "$") == 0) {
continue;
}
if (strcmp(map_element->entry->elements[i], current->elements[i]) != 0) {
return false;
}
}
return true;
}
static php_phongo_field_path_map_element* map_find_field_path_entry(php_phongo_bson_state* state)
{
size_t i;
/* Loop over all field path mappings, and for each, try to see whether it matches the current path */
for (i = 0; i < state->map.field_paths.size; i++) {
if (map_element_matches_field_path(state->map.field_paths.map[i], state->field_path)) {
return state->map.field_paths.map[i];
}
}
return NULL;
}
static void php_phongo_handle_field_path_entry_for_compound_type(php_phongo_bson_state* state, php_phongo_bson_typemap_types* type, zend_class_entry** ce)
{
php_phongo_field_path_map_element* entry = map_find_field_path_entry(state);
if (entry) {
switch (entry->node_type) {
case PHONGO_TYPEMAP_NATIVE_ARRAY:
case PHONGO_TYPEMAP_NATIVE_OBJECT:
*type = entry->node_type;
break;
case PHONGO_TYPEMAP_CLASS:
*type = entry->node_type;
*ce = entry->node_ce;
break;
default:
/* Do nothing - pacify compiler */
break;
}
}
}
static bool php_phongo_bson_visit_document(const bson_iter_t* iter ARG_UNUSED, const char* key, const bson_t* v_document, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
bson_iter_t child;
php_phongo_bson_state* parent_state = (php_phongo_bson_state*) data;
- TSRMLS_FETCH();
php_phongo_field_path_push(parent_state->field_path, key, PHONGO_FIELD_PATH_ITEM_DOCUMENT);
if (bson_iter_init(&child, v_document)) {
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
php_phongo_bson_state_copy_ctor(&state, parent_state);
-#if PHP_VERSION_ID >= 70000
array_init(&state.zchild);
-#else
- MAKE_STD_ZVAL(state.zchild);
- array_init(state.zchild);
-#endif
if (!bson_iter_visit_all(&child, &php_bson_visitors, &state) && !child.err_off) {
/* Check for entries in the fieldPath type map key, and use them to
* override the default ones for this type */
php_phongo_handle_field_path_entry_for_compound_type(&state, &state.map.document_type, &state.map.document);
/* If php_phongo_bson_visit_binary() finds an ODM class, it should
* supersede a default type map and named document class. */
if (state.odm && state.map.document_type == PHONGO_TYPEMAP_NONE) {
state.map.document_type = PHONGO_TYPEMAP_CLASS;
}
switch (state.map.document_type) {
case PHONGO_TYPEMAP_NATIVE_ARRAY:
-#if PHP_VERSION_ID >= 70000
if (((php_phongo_bson_state*) data)->is_visiting_array) {
add_next_index_zval(retval, &state.zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &state.zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- if (((php_phongo_bson_state*) data)->is_visiting_array) {
- add_next_index_zval(retval, state.zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, state.zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
break;
case PHONGO_TYPEMAP_CLASS: {
-#if PHP_VERSION_ID >= 70000
zval obj;
object_init_ex(&obj, state.odm ? state.odm : state.map.document);
zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, &state.zchild);
if (((php_phongo_bson_state*) data)->is_visiting_array) {
add_next_index_zval(retval, &obj);
} else {
ADD_ASSOC_ZVAL(retval, key, &obj);
}
zval_ptr_dtor(&state.zchild);
-#else /* PHP_VERSION_ID >= 70000 */
- zval* obj = NULL;
-
- MAKE_STD_ZVAL(obj);
- object_init_ex(obj, state.odm ? state.odm : state.map.document);
- zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, state.zchild);
- if (((php_phongo_bson_state*) data)->is_visiting_array) {
- add_next_index_zval(retval, obj);
- } else {
- ADD_ASSOC_ZVAL(retval, key, obj);
- }
- zval_ptr_dtor(&state.zchild);
-#endif /* PHP_VERSION_ID >= 70000 */
break;
}
case PHONGO_TYPEMAP_NATIVE_OBJECT:
default:
-#if PHP_VERSION_ID >= 70000
convert_to_object(&state.zchild);
if (((php_phongo_bson_state*) data)->is_visiting_array) {
add_next_index_zval(retval, &state.zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &state.zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- convert_to_object(state.zchild);
- if (((php_phongo_bson_state*) data)->is_visiting_array) {
- add_next_index_zval(retval, state.zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, state.zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
}
} else {
/* Iteration stopped prematurely due to corruption or a failed
* visitor. Free state.zchild, which we just initialized, and return
* true to stop iteration for our parent context. */
zval_ptr_dtor(&state.zchild);
php_phongo_bson_state_dtor(&state);
return true;
}
php_phongo_bson_state_dtor(&state);
php_phongo_field_path_pop(parent_state->field_path);
}
return false;
} /* }}} */
static bool php_phongo_bson_visit_array(const bson_iter_t* iter ARG_UNUSED, const char* key, const bson_t* v_array, void* data) /* {{{ */
{
zval* retval = PHONGO_BSON_STATE_ZCHILD(data);
bson_iter_t child;
php_phongo_bson_state* parent_state = (php_phongo_bson_state*) data;
- TSRMLS_FETCH();
php_phongo_field_path_push(parent_state->field_path, key, PHONGO_FIELD_PATH_ITEM_ARRAY);
if (bson_iter_init(&child, v_array)) {
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
php_phongo_bson_state_copy_ctor(&state, parent_state);
/* Note that we are visiting an array, so element visitors know to use
* add_next_index() (i.e. disregard BSON keys) instead of add_assoc()
* when building the PHP array.
*/
state.is_visiting_array = true;
-#if PHP_VERSION_ID >= 70000
array_init(&state.zchild);
-#else
- MAKE_STD_ZVAL(state.zchild);
- array_init(state.zchild);
-#endif
if (!bson_iter_visit_all(&child, &php_bson_visitors, &state) && !child.err_off) {
/* Check for entries in the fieldPath type map key, and use them to
* override the default ones for this type */
php_phongo_handle_field_path_entry_for_compound_type(&state, &state.map.array_type, &state.map.array);
switch (state.map.array_type) {
case PHONGO_TYPEMAP_CLASS: {
-#if PHP_VERSION_ID >= 70000
zval obj;
object_init_ex(&obj, state.map.array);
zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, &state.zchild);
if (((php_phongo_bson_state*) data)->is_visiting_array) {
add_next_index_zval(retval, &obj);
} else {
ADD_ASSOC_ZVAL(retval, key, &obj);
}
zval_ptr_dtor(&state.zchild);
-#else /* PHP_VERSION_ID >= 70000 */
- zval* obj = NULL;
-
- MAKE_STD_ZVAL(obj);
- object_init_ex(obj, state.map.array);
- zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, state.zchild);
- if (((php_phongo_bson_state*) data)->is_visiting_array) {
- add_next_index_zval(retval, obj);
- } else {
- ADD_ASSOC_ZVAL(retval, key, obj);
- }
- zval_ptr_dtor(&state.zchild);
-#endif /* PHP_VERSION_ID >= 70000 */
break;
}
case PHONGO_TYPEMAP_NATIVE_OBJECT:
-#if PHP_VERSION_ID >= 70000
convert_to_object(&state.zchild);
if (((php_phongo_bson_state*) data)->is_visiting_array) {
add_next_index_zval(retval, &state.zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &state.zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- convert_to_object(state.zchild);
- if (((php_phongo_bson_state*) data)->is_visiting_array) {
- add_next_index_zval(retval, state.zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, state.zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
break;
case PHONGO_TYPEMAP_NATIVE_ARRAY:
default:
-#if PHP_VERSION_ID >= 70000
if (((php_phongo_bson_state*) data)->is_visiting_array) {
add_next_index_zval(retval, &state.zchild);
} else {
ADD_ASSOC_ZVAL(retval, key, &state.zchild);
}
-#else /* PHP_VERSION_ID >= 70000 */
- if (((php_phongo_bson_state*) data)->is_visiting_array) {
- add_next_index_zval(retval, state.zchild);
- } else {
- ADD_ASSOC_ZVAL(retval, key, state.zchild);
- }
-#endif /* PHP_VERSION_ID >= 70000 */
break;
}
} else {
/* Iteration stopped prematurely due to corruption or a failed
* visitor. Free state.zchild, which we just initialized, and return
* true to stop iteration for our parent context. */
zval_ptr_dtor(&state.zchild);
php_phongo_bson_state_dtor(&state);
return true;
}
php_phongo_bson_state_dtor(&state);
php_phongo_field_path_pop(parent_state->field_path);
}
return false;
} /* }}} */
/* Converts a BSON document to a PHP value using the default typemap. */
-#if PHP_VERSION_ID >= 70000
bool php_phongo_bson_to_zval(const unsigned char* data, int data_len, zval* zv) /* {{{ */
-#else
-bool php_phongo_bson_to_zval(const unsigned char* data, int data_len, zval** zv)
-#endif
{
bool retval;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
retval = php_phongo_bson_to_zval_ex(data, data_len, &state);
-#if PHP_VERSION_ID >= 70000
ZVAL_ZVAL(zv, &state.zchild, 1, 1);
-#else
- *zv = state.zchild;
-#endif
return retval;
} /* }}} */
/* Converts a BSON value to a ZVAL. */
bool php_phongo_bson_value_to_zval(const bson_value_t* value, zval* zv) /* {{{ */
{
bson_t bson = BSON_INITIALIZER;
php_phongo_bson_state state;
zval* return_value;
bool retval = false;
PHONGO_BSON_INIT_STATE(state);
state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
bson_append_value(&bson, "data", 4, value);
if (!php_phongo_bson_to_zval_ex(bson_get_data(&bson), bson.len, &state)) {
/* Exception already thrown */
goto cleanup;
}
retval = true;
-#if PHP_VERSION_ID >= 70000
return_value = php_array_fetchc(&state.zchild, "data");
-#else
- return_value = php_array_fetchc(state.zchild, "data");
-#endif
if (return_value) {
ZVAL_ZVAL(zv, return_value, 1, 0);
}
cleanup:
zval_ptr_dtor(&state.zchild);
return retval;
} /* }}} */
/* Converts a BSON document to a PHP value according to the typemap specified in
* the state argument.
*
* On success, the result will be set on the state argument and true will be
* returned. On error, an exception will have been thrown and false will be
* returned.
*
* Note: the result zval in the state argument will always be initialized for
* PHP 5.x so that the caller may always zval_ptr_dtor() it. The zval is left
* as-is on PHP 7; however, it should have the type undefined if the state
* was initialized to zero.
*/
bool php_phongo_bson_to_zval_ex(const unsigned char* data, int data_len, php_phongo_bson_state* state) /* {{{ */
{
bson_reader_t* reader = NULL;
bson_iter_t iter;
const bson_t* b;
bool eof = false;
bool retval = false;
bool must_dtor_state = false;
- TSRMLS_FETCH();
-
-#if PHP_VERSION_ID < 70000
- MAKE_STD_ZVAL(state->zchild);
-
- /* Ensure that state->zchild has a type, since the calling code may want to
- * zval_ptr_dtor() it if we throw an exception. */
- ZVAL_NULL(state->zchild);
-
-#endif
if (!php_phongo_bson_state_is_initialized(state)) {
php_phongo_bson_state_ctor(state);
must_dtor_state = true;
}
reader = bson_reader_new_from_data(data, data_len);
if (!(b = bson_reader_read(reader, NULL))) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not read document from BSON reader");
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Could not read document from BSON reader");
goto cleanup;
}
if (!bson_iter_init(&iter, b)) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not initialize BSON iterator");
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Could not initialize BSON iterator");
goto cleanup;
}
/* We initialize an array because it will either be returned as-is (native
* array in type map), passed to bsonUnserialize() (ODM class), or used to
* initialize a stdClass object (native object in type map). */
-#if PHP_VERSION_ID >= 70000
array_init(&state->zchild);
-#else
- array_init(state->zchild);
-#endif
if (bson_iter_visit_all(&iter, &php_bson_visitors, state) || iter.err_off) {
/* Iteration stopped prematurely due to corruption or a failed visitor.
* While we free the reader, state->zchild should be left as-is, since
* the calling code may want to zval_ptr_dtor() it. If an exception has
* been thrown already (due to an unsupported BSON type for example,
* don't overwrite with a generic exception message. */
if (!EG(exception)) {
char* path = php_phongo_field_path_as_string(state->field_path);
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected corrupt BSON data for field path '%s' at offset %d", path, iter.err_off);
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected corrupt BSON data for field path '%s' at offset %d", path, iter.err_off);
efree(path);
}
goto cleanup;
}
/* If php_phongo_bson_visit_binary() finds an ODM class, it should supersede
* a default type map and named root class. */
if (state->odm && state->map.root_type == PHONGO_TYPEMAP_NONE) {
state->map.root_type = PHONGO_TYPEMAP_CLASS;
}
switch (state->map.root_type) {
case PHONGO_TYPEMAP_NATIVE_ARRAY:
/* Nothing to do here */
break;
case PHONGO_TYPEMAP_CLASS: {
-#if PHP_VERSION_ID >= 70000
zval obj;
object_init_ex(&obj, state->odm ? state->odm : state->map.root);
zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, &state->zchild);
zval_ptr_dtor(&state->zchild);
ZVAL_COPY_VALUE(&state->zchild, &obj);
-#else /* PHP_VERSION_ID >= 70000 */
- zval* obj = NULL;
-
- MAKE_STD_ZVAL(obj);
- object_init_ex(obj, state->odm ? state->odm : state->map.root);
- zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, state->zchild);
- zval_ptr_dtor(&state->zchild);
- state->zchild = obj;
-#endif /* PHP_VERSION_ID >= 70000 */
break;
}
case PHONGO_TYPEMAP_NATIVE_OBJECT:
default:
-#if PHP_VERSION_ID >= 70000
convert_to_object(&state->zchild);
-#else
- convert_to_object(state->zchild);
-#endif
}
if (bson_reader_read(reader, &eof) || !eof) {
- phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Reading document did not exhaust input buffer");
+ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Reading document did not exhaust input buffer");
goto cleanup;
}
retval = true;
cleanup:
if (reader) {
bson_reader_destroy(reader);
}
if (must_dtor_state) {
php_phongo_bson_state_dtor(state);
}
return retval;
} /* }}} */
/* Fetches a zend_class_entry for the given class name and checks that it is
* also instantiatable and implements a specified interface. Returns the class
* on success; otherwise, NULL is returned and an exception is thrown. */
-static zend_class_entry* php_phongo_bson_state_fetch_class(const char* classname, int classname_len, zend_class_entry* interface_ce TSRMLS_DC) /* {{{ */
+static zend_class_entry* php_phongo_bson_state_fetch_class(const char* classname, int classname_len, zend_class_entry* interface_ce) /* {{{ */
{
-#if PHP_VERSION_ID >= 70000
zend_string* zs_classname = zend_string_init(classname, classname_len, 0);
- zend_class_entry* found_ce = zend_fetch_class(zs_classname, ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_SILENT TSRMLS_CC);
+ zend_class_entry* found_ce = zend_fetch_class(zs_classname, ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_SILENT);
zend_string_release(zs_classname);
-#else
- zend_class_entry* found_ce = zend_fetch_class(classname, classname_len, ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_SILENT TSRMLS_CC);
-#endif
if (!found_ce) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Class %s does not exist", classname);
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Class %s does not exist", classname);
} else if (!PHONGO_IS_CLASS_INSTANTIATABLE(found_ce)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Class %s is not instantiatable", classname);
- } else if (!instanceof_function(found_ce, interface_ce TSRMLS_CC)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Class %s does not implement %s", classname, ZSTR_VAL(interface_ce->name));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Class %s is not instantiatable", classname);
+ } else if (!instanceof_function(found_ce, interface_ce)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Class %s does not implement %s", classname, ZSTR_VAL(interface_ce->name));
} else {
return found_ce;
}
return NULL;
} /* }}} */
/* Parses a BSON type (i.e. array, document, or root). On success, the type and
* type_ce output arguments will be assigned and true will be returned;
* otherwise, false is returned and an exception is thrown. */
-static bool php_phongo_bson_state_parse_type(zval* options, const char* name, php_phongo_bson_typemap_types* type, zend_class_entry** type_ce TSRMLS_DC) /* {{{ */
+static bool php_phongo_bson_state_parse_type(zval* options, const char* name, php_phongo_bson_typemap_types* type, zend_class_entry** type_ce) /* {{{ */
{
char* classname;
int classname_len;
zend_bool classname_free = 0;
bool retval = true;
classname = php_array_fetch_string(options, name, &classname_len, &classname_free);
if (!classname_len) {
goto cleanup;
}
if (!strcasecmp(classname, "array")) {
*type = PHONGO_TYPEMAP_NATIVE_ARRAY;
*type_ce = NULL;
} else if (!strcasecmp(classname, "stdclass") || !strcasecmp(classname, "object")) {
*type = PHONGO_TYPEMAP_NATIVE_OBJECT;
*type_ce = NULL;
} else {
- if ((*type_ce = php_phongo_bson_state_fetch_class(classname, classname_len, php_phongo_unserializable_ce TSRMLS_CC))) {
+ if ((*type_ce = php_phongo_bson_state_fetch_class(classname, classname_len, php_phongo_unserializable_ce))) {
*type = PHONGO_TYPEMAP_CLASS;
} else {
retval = false;
}
}
cleanup:
if (classname_free) {
- str_efree(classname);
+ efree(classname);
}
return retval;
} /* }}} */
static void field_path_map_element_set_info(php_phongo_field_path_map_element* element, php_phongo_bson_typemap_types type, zend_class_entry* ce)
{
element->node_type = type;
element->node_ce = ce;
}
static void map_add_field_path_element(php_phongo_bson_typemap* map, php_phongo_field_path_map_element* element)
{
/* Make sure we have allocated enough */
if (map->field_paths.allocated_size < map->field_paths.size + 1) {
map->field_paths.allocated_size += PHONGO_FIELD_PATH_EXPANSION;
map->field_paths.map = erealloc(map->field_paths.map, sizeof(php_phongo_field_path_map_element) * map->field_paths.allocated_size);
}
map->field_paths.map[map->field_paths.size] = element;
map->field_paths.size++;
}
static php_phongo_field_path_map_element* field_path_map_element_alloc(void)
{
php_phongo_field_path_map_element* tmp = ecalloc(1, sizeof(php_phongo_field_path_map_element));
tmp->entry = php_phongo_field_path_alloc(true);
return tmp;
}
static void field_path_map_element_dtor(php_phongo_field_path_map_element* element)
{
php_phongo_field_path_free(element->entry);
efree(element);
}
-bool php_phongo_bson_state_add_field_path(php_phongo_bson_typemap* map, char* field_path_original, php_phongo_bson_typemap_types type, zend_class_entry* ce TSRMLS_DC)
+bool php_phongo_bson_state_add_field_path(php_phongo_bson_typemap* map, char* field_path_original, php_phongo_bson_typemap_types type, zend_class_entry* ce)
{
char* ptr = NULL;
char* segment_end = NULL;
php_phongo_field_path_map_element* field_path_map_element;
if (field_path_original[0] == '.') {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "A 'fieldPaths' key may not start with a '.'");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "A 'fieldPaths' key may not start with a '.'");
return false;
}
if (field_path_original[strlen(field_path_original) - 1] == '.') {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "A 'fieldPaths' key may not end with a '.'");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "A 'fieldPaths' key may not end with a '.'");
return false;
}
field_path_map_element = field_path_map_element_alloc();
ptr = field_path_original;
/* Loop over all the segments. A segment is delimited by a "." */
while ((segment_end = strchr(ptr, '.')) != NULL) {
char* tmp = NULL;
/* Bail out if we have an empty segment */
if (ptr == segment_end) {
field_path_map_element_dtor(field_path_map_element);
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "A 'fieldPaths' key may not have an empty segment");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "A 'fieldPaths' key may not have an empty segment");
return false;
}
tmp = calloc(1, segment_end - ptr + 1);
memcpy(tmp, ptr, segment_end - ptr);
php_phongo_field_path_push(field_path_map_element->entry, tmp, PHONGO_FIELD_PATH_ITEM_NONE);
free(tmp);
ptr = segment_end + 1;
}
/* Add the last (or single) element */
php_phongo_field_path_push(field_path_map_element->entry, ptr, PHONGO_FIELD_PATH_ITEM_NONE);
field_path_map_element_set_info(field_path_map_element, type, ce);
map_add_field_path_element(map, field_path_map_element);
return true;
}
void php_phongo_bson_typemap_dtor(php_phongo_bson_typemap* map)
{
size_t i;
if (map->field_paths.map) {
for (i = 0; i < map->field_paths.size; i++) {
field_path_map_element_dtor(map->field_paths.map[i]);
}
efree(map->field_paths.map);
}
map->field_paths.map = NULL;
}
/* Loops over each element in the fieldPaths array (if exists, and is an
* array), and then checks whether each element is a valid type mapping */
-bool php_phongo_bson_state_parse_fieldpaths(zval* typemap, php_phongo_bson_typemap* map TSRMLS_DC) /* {{{ */
+bool php_phongo_bson_state_parse_fieldpaths(zval* typemap, php_phongo_bson_typemap* map) /* {{{ */
{
zval* fieldpaths = NULL;
HashTable* ht_data;
if (!php_array_existsc(typemap, "fieldPaths")) {
return true;
}
fieldpaths = php_array_fetchc_array(typemap, "fieldPaths");
if (!fieldpaths) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "The 'fieldPaths' element is not an array");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "The 'fieldPaths' element is not an array");
return false;
}
ht_data = HASH_OF(fieldpaths);
-#if PHP_VERSION_ID >= 70000
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* property;
ZEND_HASH_FOREACH_KEY_VAL(ht_data, num_key, string_key, property)
{
zend_class_entry* map_ce = NULL;
php_phongo_bson_typemap_types map_type;
if (!string_key) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "The 'fieldPaths' element is not an associative array");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "The 'fieldPaths' element is not an associative array");
return false;
}
if (strcmp(ZSTR_VAL(string_key), "") == 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "The 'fieldPaths' element may not be an empty string");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "The 'fieldPaths' element may not be an empty string");
return false;
}
- if (!php_phongo_bson_state_parse_type(fieldpaths, ZSTR_VAL(string_key), &map_type, &map_ce TSRMLS_CC)) {
+ if (!php_phongo_bson_state_parse_type(fieldpaths, ZSTR_VAL(string_key), &map_type, &map_ce)) {
return false;
}
- if (!php_phongo_bson_state_add_field_path(map, ZSTR_VAL(string_key), map_type, map_ce TSRMLS_CC)) {
+ if (!php_phongo_bson_state_add_field_path(map, ZSTR_VAL(string_key), map_type, map_ce)) {
return false;
}
}
ZEND_HASH_FOREACH_END();
}
-#else
- {
- HashPosition pos;
- zval** property;
-
- for (
- zend_hash_internal_pointer_reset_ex(ht_data, &pos);
- zend_hash_get_current_data_ex(ht_data, (void**) &property, &pos) == SUCCESS;
- zend_hash_move_forward_ex(ht_data, &pos)) {
-
- char* string_key = NULL;
- uint string_key_len = 0;
- ulong num_key = 0;
- zend_class_entry* map_ce = NULL;
- php_phongo_bson_typemap_types map_type;
-
- if (HASH_KEY_IS_STRING != zend_hash_get_current_key_ex(ht_data, &string_key, &string_key_len, &num_key, 0, &pos)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "The 'fieldPaths' element is not an associative array");
- return false;
- }
-
- if (strcmp(string_key, "") == 0) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "The 'fieldPaths' element may not be an empty string");
- return false;
- }
- if (!php_phongo_bson_state_parse_type(fieldpaths, string_key, &map_type, &map_ce TSRMLS_CC)) {
- return false;
- }
-
- if (!php_phongo_bson_state_add_field_path(map, string_key, map_type, map_ce TSRMLS_CC)) {
- return false;
- }
- }
- }
-#endif /* PHP_VERSION_ID >= 70000 */
return true;
} /* }}} */
#if DEBUG
static void print_node_info(php_phongo_field_path_node* ptr, int level)
{
printf("%*sNAME: %s\n", level * 4, "", ptr->name);
printf("%*s- type:", level * 4, "");
switch (ptr->node_type) {
case PHONGO_TYPEMAP_NONE:
printf(" none (unset)\n");
break;
case PHONGO_TYPEMAP_CLASS:
printf(" class (%s)\n", ZSTR_VAL(ptr->node_ce->name));
break;
case PHONGO_TYPEMAP_NATIVE_ARRAY:
printf(" array\n");
break;
case PHONGO_TYPEMAP_NATIVE_OBJECT:
printf(" stdClass\n");
break;
}
}
static void print_map_list(php_phongo_field_path_node* node, int level)
{
php_phongo_field_path_node* ptr = node->children;
if (!ptr) {
return;
}
do {
print_node_info(ptr, level);
if (ptr->children) {
printf("%*s- children:\n", level * 4, "");
print_map_list(ptr, level + 1);
}
ptr = ptr->next;
} while (ptr);
}
#endif
/* Applies the array argument to a typemap struct. Returns true on success;
* otherwise, false is returned an an exception is thrown. */
-bool php_phongo_bson_typemap_to_state(zval* typemap, php_phongo_bson_typemap* map TSRMLS_DC) /* {{{ */
+bool php_phongo_bson_typemap_to_state(zval* typemap, php_phongo_bson_typemap* map) /* {{{ */
{
if (!typemap) {
return true;
}
- if (!php_phongo_bson_state_parse_type(typemap, "array", &map->array_type, &map->array TSRMLS_CC) ||
- !php_phongo_bson_state_parse_type(typemap, "document", &map->document_type, &map->document TSRMLS_CC) ||
- !php_phongo_bson_state_parse_type(typemap, "root", &map->root_type, &map->root TSRMLS_CC) ||
- !php_phongo_bson_state_parse_fieldpaths(typemap, map TSRMLS_CC)) {
+ if (!php_phongo_bson_state_parse_type(typemap, "array", &map->array_type, &map->array) ||
+ !php_phongo_bson_state_parse_type(typemap, "document", &map->document_type, &map->document) ||
+ !php_phongo_bson_state_parse_type(typemap, "root", &map->root_type, &map->root) ||
+ !php_phongo_bson_state_parse_fieldpaths(typemap, map)) {
/* Exception should already have been thrown */
return false;
}
#if DEBUG
print_map_list(&map->field_path_map, 0);
#endif
return true;
} /* }}} */
-void php_phongo_bson_new_timestamp_from_increment_and_timestamp(zval* object, uint32_t increment, uint32_t timestamp TSRMLS_DC) /* {{{ */
+void php_phongo_bson_new_timestamp_from_increment_and_timestamp(zval* object, uint32_t increment, uint32_t timestamp) /* {{{ */
{
php_phongo_timestamp_t* intern;
object_init_ex(object, php_phongo_timestamp_ce);
intern = Z_TIMESTAMP_OBJ_P(object);
intern->increment = increment;
intern->timestamp = timestamp;
intern->initialized = true;
} /* }}} */
-void php_phongo_bson_new_int64(zval* object, int64_t integer TSRMLS_DC) /* {{{ */
+void php_phongo_bson_new_int64(zval* object, int64_t integer) /* {{{ */
{
php_phongo_int64_t* intern;
object_init_ex(object, php_phongo_int64_ce);
intern = Z_INT64_OBJ_P(object);
intern->integer = integer;
intern->initialized = true;
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
diff --git a/mongodb-1.7.4/src/contrib/php_array_api.h b/mongodb-1.8.1/src/contrib/php_array_api.h
similarity index 96%
rename from mongodb-1.7.4/src/contrib/php_array_api.h
rename to mongodb-1.8.1/src/contrib/php_array_api.h
index bea5e59c..9a332524 100644
--- a/mongodb-1.7.4/src/contrib/php_array_api.h
+++ b/mongodb-1.8.1/src/contrib/php_array_api.h
@@ -1,552 +1,552 @@
/* +----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2018 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Sara Golemon (pollita@php.net) |
+----------------------------------------------------------------------+
*/
#ifndef PHP_ARRAY_API_H
#define PHP_ARRAY_API_H
#include "zend.h"
#include "zend_execute.h"
#include "zend_API.h"
#include "zend_operators.h"
#include "zend_hash.h"
#include "zend_list.h"
#ifdef ZEND_ENGINE_3
# define PAA_LENGTH_ADJ(l) (l)
# define PAA_SYM_EXISTS zend_symtable_str_exists
# define PAA_SYM_DEL zend_symtable_str_del
# define PAA_LONG zend_long
# define PAA_ULONG zend_ulong
#else
# define PAA_LENGTH_ADJ(l) (l+1)
# define PAA_SYM_EXISTS zend_symtable_exists
# define PAA_SYM_DEL zend_symtable_del
# define PAA_LONG long
# define PAA_ULONG ulong
#endif
/**
* All APIs in this file follow a general format:
*
* php_array_{$verb}{$modifier}_{$type}(zval *zarr, ...)
*
* $verb is one of:
* exists - Boolean check whether the array offset exists
* fetch - Retrieve the value at $zarr[$key]
* unset - Delete the named offset from the array
*
* $modifier specifies what type of offset (key) is being used:
* <no modifer> - NULL terminated string variable, unknown length
* l - NULL terminated string variable, known length
* l_safe - String variable of known length, not necessarily NULL terminated
* n - Long (integer) offset
* c - NULL terminated string literal (e.g. "foo" rather than foo)
* z - zval* offset, type should be NULL, BOOL, LONG, DOUBLE, or STRING
*
* $type is specific to the "fetch" verb:
* <no type> - Fetch a zval* of any type
* bool - Fetch a zend_bool (converting as needed)
* long - Fetch a long (converting as needed)
* double - Fetch a double (converting as needed)
* string - Fetch a string (converting as needed, caller may need to free)
* array - Fetch an array (no conversion from other types)
* object - Fetch an object (no conversion, type spec optional)
* resource - Fetch a resource (no conversion, type spec mandatory)
*
* See the specific subsection for additional details
*/
/* isset($zarr[$key]) - Check for the existence of a key within an array
*
* zend_bool php_array_exists(zval *zarr, const char *key)
* zend_bool php_array_existsc(zval *zarr, const char *litstr)
* zend_bool php_array_existsl(zval *zarr, const char *key, int key_len)
* zend_bool php_array_existsl_safe(zval *zarr, const char *key, int key_len)
* zend_bool php_array_existsn(zval *zarr, unsigned long idx)
* zend_bool php_array_existsz(zval *zarr, zval *key)
*/
static inline
zend_bool php_array_exists(zval *zarr, const char *key) {
return PAA_SYM_EXISTS(Z_ARRVAL_P(zarr), key, PAA_LENGTH_ADJ(strlen(key)));
}
#define php_array_existsc(zarr, litstr) \
PAA_SYM_EXISTS(Z_ARRVAL_P(zarr), litstr, PAA_LENGTH_ADJ(sizeof(litstr) - 1))
#define php_array_existsl(zarr, key, len) \
PAA_SYM_EXISTS(Z_ARRVAL_P(zarr), key, PAA_LENGTH_ADJ(len))
static inline
zend_bool php_array_existsl_safe(zval *zarr, const char *key, int key_len) {
#ifdef ZEND_ENGINE_3
zend_string *keystr = zend_string_init(key, key_len, 0);
zend_bool ret = zend_symtable_exists(Z_ARRVAL_P(zarr), keystr);
zend_string_release(keystr);
#else
char *k = estrndup(key, key_len);
zend_bool ret = zend_symtable_exists(Z_ARRVAL_P(zarr), k, key_len + 1);
efree(k);
#endif
return ret;
}
#define php_array_existsn(zarr, idx) \
zend_hash_index_exists(Z_ARRVAL_P(zarr), idx)
static inline
zend_bool php_array_existsz(zval *zarr, zval *key) {
switch (Z_TYPE_P(key)) {
case IS_NULL:
return php_array_existsc(zarr, "");
#ifdef ZEND_ENGINE_3
case IS_FALSE:
return zend_hash_index_exists(Z_ARRVAL_P(zarr), 0);
case IS_TRUE:
return zend_hash_index_exists(Z_ARRVAL_P(zarr), 1);
#else
case IS_BOOL: /* fallthrough */
#endif
case IS_LONG:
return zend_hash_index_exists(Z_ARRVAL_P(zarr), Z_LVAL_P(key));
case IS_DOUBLE:
return zend_hash_index_exists(Z_ARRVAL_P(zarr),
zend_dval_to_lval(Z_DVAL_P(key)));
case IS_STRING:
return php_array_existsl(zarr, Z_STRVAL_P(key), Z_STRLEN_P(key));
default:
return 0;
}
}
/* =$zarr[$key] - Fetch a zval (or appropriate type) from an array
*
* Methods returning pointers yield NULL on key not existing,
* others yield 0, false, etc... as appropriate.
* Callers needing to distinguish empty scalars from non-existent
* scalars should use php_array_exists*() or fetch the zval then convert.
*
* If the type of the value does not match what is requested
* it will be implicitly converted (if possible).
*
* See each type section for specific prototypes
*
* php_array_fetch* - Fetch a zval
* php_array_fetch*_bool - Fetch a boolean
* php_array_fetch*_long - Fetch a long
* php_array_fetch*_double - Fetch a double
* php_array_fetch*_string - Fetch a string (must be efree()'d by caller)
* php_array_fetch*_array - Fetch an array
* php_array_fetch*_resource - Fetch a resource or a specific type
* php_array_fetch*_object - Fetch an object
*
* For each result type, there are six key forms:
* php_array_fetch_T(zval *zarr, const char *key, ...)
* NULL terminated string key
* php_array_fetchc_T(zval *zarr, const char *litkey, ...)
* String literal key
* php_array_fetchl_T(zval *zarr, const char *key, int key_len, ...)
* NULL terminated string key of known length
* php_array_fetchl_safe_T(zval *zarr, const char *key, int key_len, ...)
* String key of known length, may not be NULL terminated
* php_array_fetchn_T(zval *zarr, unsigned long idx, ...)
* Numeric key
* php_array_fetchz_T(zval *zarr, zval *key, ...)
* zval* key
*/
/* Fetch zval*
*
* zval *php_array_fetch(zval *zarr, const char *key)
* zval *php_array_fetchl(zval *zarr, const char *key, int key_len)
* zval *php_array_fetchl_safe(zval *zarr, const char *key, int key_len)
* zval *php_array_fetchn(zval *zarr, unsigned long idx)
* zval *php_array_fetchc(zval *zarr, const char *litstr)
* zval *php_array_fetchz(zval *zarr, zval *key)
*/
static inline
zval *php_array_fetchl(zval *zarr, const char *key, int key_len) {
#ifdef ZEND_ENGINE_3
return zend_symtable_str_find(Z_ARRVAL_P(zarr), key, key_len);
#else
zval **ppzval;
if (FAILURE == zend_symtable_find(Z_ARRVAL_P(zarr),
key, key_len + 1,
(void**)&ppzval)) {
return NULL;
}
return *ppzval;
#endif
}
static inline
zval *php_array_fetch(zval *zarr, const char *key) {
return php_array_fetchl(zarr, key, strlen(key));
}
#define php_array_fetchc(zarr, litstr) php_array_fetchl(zarr, litstr, sizeof(litstr)-1)
static inline
zval *php_array_fetchl_safe(zval *zarr, const char *key, int key_len) {
#ifdef ZEND_ENGINE_3
zend_string *keystr = zend_string_init(key, key_len, 0);
zval *ret = zend_symtable_find(Z_ARRVAL_P(zarr), keystr);
zend_string_release(keystr);
#else
char *k = estrndup(key, key_len);
zval *ret = php_array_fetchl(zarr, k, key_len);
efree(k);
#endif
return ret;
}
static inline
zval *php_array_fetchn(zval *zarr, PAA_ULONG idx) {
#ifdef ZEND_ENGINE_3
return zend_hash_index_find(Z_ARRVAL_P(zarr), idx);
#else
zval **ppzval;
if (FAILURE == zend_hash_index_find(Z_ARRVAL_P(zarr),
idx, (void**)&ppzval)) {
return NULL;
}
return *ppzval;
#endif
}
static inline
zval *php_array_fetchz(zval *zarr, zval *key) {
switch (Z_TYPE_P(key)) {
case IS_NULL:
return php_array_fetchn(zarr, 0);
#ifdef ZEND_ENGINE_3
case IS_FALSE:
return php_array_fetchn(zarr, 0);
case IS_TRUE:
return php_array_fetchn(zarr, 1);
#else
case IS_BOOL: /* fallthrough */
#endif
case IS_LONG:
return php_array_fetchn(zarr, Z_LVAL_P(key));
case IS_DOUBLE:
return php_array_fetchn(zarr, (long)Z_DVAL_P(key));
case IS_STRING:
return php_array_fetchl(zarr, Z_STRVAL_P(key), Z_STRLEN_P(key));
default:
return NULL;
}
}
#define PHP_ARRAY_FETCH_TYPE_MAP(ctype, ztype) \
static inline ctype php_array_fetch_##ztype(zval *zarr, const char *key) \
{ return php_array_zval_to_##ztype(php_array_fetch(zarr, key)); } \
static inline ctype php_array_fetchl_##ztype(zval *zarr, const char *key, int key_len) \
{ return php_array_zval_to_##ztype(php_array_fetchl(zarr, key, key_len)); } \
static inline ctype php_array_fetchl_safe_##ztype(zval *zarr, const char *key, int key_len) \
{ return php_array_zval_to_##ztype(php_array_fetchl_safe(zarr, key, key_len)); } \
static inline ctype php_array_fetchn_##ztype(zval *zarr, PAA_ULONG idx) \
{ return php_array_zval_to_##ztype(php_array_fetchn(zarr, idx)); } \
static inline ctype php_array_fetchz_##ztype(zval *zarr, zval *key) \
{ return php_array_zval_to_##ztype(php_array_fetchz(zarr, key)); }
/* Fetch zend_bool
*
* zend_bool php_array_fetch_bool(zval *zarr, const char *key)
* zend_bool php_array_fetchl_bool(zval *zarr, const char *key, int key_len)
* zend_bool php_array_fetchl_safe_bool(zval *zarr, const char *key, int key_len)
* zend_bool php_array_fetchn_bool(zval *zarr, unsigned long idx)
* zend_bool php_array_fetchc_bool(zval *zarr, const char *litstr)
* zend_bool php_array_fetchz_bool(zval *zarr, zval *key)
*/
static inline
zend_bool php_array_zval_to_bool(zval *z) {
return z && zend_is_true(z);
}
PHP_ARRAY_FETCH_TYPE_MAP(zend_bool, bool)
#define php_array_fetchc_bool(zarr, litstr) \
php_array_zval_to_bool(php_array_fetchc(zarr, litstr))
/* Fetch long
*
* long php_array_fetch_long(zval *zarr, const char *key)
* long php_array_fetchl_long(zval *zarr, const char *key, int key_len)
* long php_array_fetchl_safe_long(zval *zarr, const char *key, int key_len)
* long php_array_fetchn_long(zval *zarr, unsigned long idx)
* long php_array_fetchc_long(zval *zarr, const char *litstr)
* long php_array_fetchz_long(zval *zarr, zval *key)
*/
static inline
PAA_LONG php_array_zval_to_long(zval *z) {
if (!z) { return 0; }
switch(Z_TYPE_P(z)) {
case IS_NULL: return 0;
#ifdef ZEND_ENGINE_3
case IS_FALSE: return 0;
case IS_TRUE: return 1;
#else
case IS_BOOL: return Z_BVAL_P(z);
#endif
case IS_LONG: return Z_LVAL_P(z);
default:
{
zval c = *z;
zval_copy_ctor(&c);
convert_to_long(&c);
return Z_LVAL(c);
}
}
}
PHP_ARRAY_FETCH_TYPE_MAP(PAA_LONG, long)
#define php_array_fetchc_long(zarr, litstr) \
php_array_zval_to_long(php_array_fetchc(zarr, litstr))
/* Fetch double
*
* double php_array_fetch_double(zval *zarr, const char *key)
* double php_array_fetchl_double(zval *zarr, const char *key, int key_len)
* double php_array_fetchl_safe_double(zval *zarr, const char *key, int key_len)
* double php_array_fetchn_double(zval *zarr, unsigned long idx)
* double php_array_fetchc_double(zval *zarr, const char *litstr)
* double php_array_fetchz_double(zval *zarr, zval *key)
*/
static inline
double php_array_zval_to_double(zval *z) {
if (!z) { return 0.0; }
switch (Z_TYPE_P(z)) {
case IS_NULL: return 0.0;
#ifdef ZEND_ENGINE_3
case IS_FALSE: return 0.0;
case IS_TRUE: return 1.0;
#else
case IS_BOOL: return (double)Z_BVAL_P(z);
#endif
case IS_LONG: return (double)Z_LVAL_P(z);
case IS_DOUBLE: return Z_DVAL_P(z);
default:
{
zval c = *z;
zval_copy_ctor(&c);
convert_to_double(&c);
return Z_DVAL(c);
}
}
}
PHP_ARRAY_FETCH_TYPE_MAP(double, double)
#define php_array_fetchc_double(zarr, litstr) \
php_array_zval_to_double(php_array_fetchc(zarr, litstr))
/* Fetch string
*
* If the pfree is set to 1 on exit, then the return value is owned by the caller
* and must be efree()'d once it is no longer in use.
*
* plen is populated with the binary safe length of the string returned.
*
* char *php_array_fetch_string(zval *zarr, const char *key, int *plen, zend_bool *pfree)
* char *php_array_fetchl_string(zval *zarr, const char *key, int key_len, int *plen, zend_bool *pfree)
* char *php_array_fetchl_safe_string(zval *zarr, const char *key, int key_len, int *plen, zend_bool *pfree)
* char *php_array_fetchn_string(zval *zarr, unsigned long idx, int *plen, zend_bool *pfree)
* char *php_array_fetchc_string(zval *zarr, const char *litstr, int *plen, zend_bool *pfree)
* char *php_array_fetchz_string(zval *zarr, zval *key, int *plen, zend_bool *pfree)
*/
static inline
char *php_array_zval_to_string(zval *z, int *plen, zend_bool *pfree) {
*plen = 0;
*pfree = 0;
if (!z) { return NULL; }
switch (Z_TYPE_P(z)) {
case IS_NULL:
return (char *)"";
case IS_STRING:
*plen = Z_STRLEN_P(z);
return Z_STRVAL_P(z);
default:
{
zval c = *z;
zval_copy_ctor(&c);
convert_to_string(&c);
#ifdef ZEND_ENGINE_3
*pfree = ! IS_INTERNED(Z_STR(c));
#else
*pfree = ! IS_INTERNED(Z_STRVAL(c));
#endif
*plen = Z_STRLEN(c);
return Z_STRVAL(c);
}
}
}
#define php_array_fetch_string(zarr, key, plen, pfree) \
php_array_zval_to_string(php_array_fetch(zarr, key), plen, pfree)
#define php_array_fetchl_string(zarr, key, key_len, plen, pfree) \
php_array_zval_to_string(php_array_fetchl(zarr, key, key_len), plen, pfree)
#define php_array_fetchl_safe_string(zarr, key, key_len, plen, pfree) \
php_array_zval_to_string(php_array_fetchl_safe(zarr, key, key_len), plen, pfree)
#define php_array_fetchn_string(zarr, idx, plen, pfree) \
php_array_zval_to_string(php_array_fetchn(zarr, idx), plen, pfree)
#define php_array_fetchc_string(zarr, litstr, plen, pfree) \
php_array_zval_to_string(php_array_fetchc(zarr, litstr), plen, pfree)
#define php_array_fetchz_string(zarr, key, plen, pfree) \
php_array_zval_to_string(php_array_fetchz(zarr, key), plen, pfree)
/* Fetch array
*
* No implicit conversion is performed.
*
* If the value is an array, then that zval is returned,
* otherwise NULL is returned.
*
* zval *php_array_fetch_array(zval *zarr, const char *key)
* zval *php_array_fetchl_array(zval *zarr, const char *key, int key_len)
* zval *php_array_fetchl_safe_array(zval *zarr, const char *key, int key_len)
* zval *php_array_fetchn_array(zval *zarr, unsigned long idx)
* zval *php_array_fetchc_array(zval *zarr, const char *litstr)
* zval *php_array_fetchz_array(zval *zarr, zval *key)
*/
static inline zval *php_array_zval_to_array(zval *zarr) {
return (zarr && (Z_TYPE_P(zarr) == IS_ARRAY)) ? zarr : NULL;
}
PHP_ARRAY_FETCH_TYPE_MAP(zval*, array)
#define php_array_fetchc_array(zarr, litstr) \
php_array_zval_to_array(php_array_fetchc(zarr, litstr))
/* count($arr) - Count number of elements in the array
*
* int php_array_count(zval *arr)
*/
#define php_array_count(zarr) zend_hash_num_elements(Z_ARRVAL_P(zarr))
/* Fetch resource
*
* No implicit conversion is performed.
*
* If the value is a resource of the named type,
* then the pointer for it is returned,
* otherwise NULL is returned.
*
* To test for multiple resource types (e.g. 'stream' and 'persistent stream')
* Fetch a generic zval* and use Zend's ZEND_FETCH_RESOURCE() macro.
*
* zval *php_array_fetch_resource(zval *zarr, const char *key, int le)
* zval *php_array_fetchl_resource(zval *zarr, const char *key, int key_len, int le)
* zval *php_array_fetchl_safe_resource(zval *zarr, const char *key, int key_len, int le)
* zval *php_array_fetchn_resource(zval *zarr, unsigned long idx, int le)
* zval *php_array_fetchc_resource(zval *zarr, const char *litstr, int le)
* zval *php_array_fetchz_resource(zval *zarr, zval *key, int le)
*/
static inline
-void *php_array_zval_to_resource(zval *z, int le TSRMLS_DC) {
+void *php_array_zval_to_resource(zval *z, int le) {
#ifdef ZEND_ENGINE_3
return zend_fetch_resource_ex(z, NULL, le);
#else
void *ret;
int rtype;
if (!z || Z_TYPE_P(z) != IS_RESOURCE) { return NULL; }
ret = zend_list_find(Z_RESVAL_P(z), &rtype);
if (!ret || (rtype != le)) {
return NULL;
}
return ret;
#endif
}
#define php_array_fetch_resource(zarr, key, le) \
- php_array_zval_to_resource(php_array_fetch(zarr, key), le TSRMLS_CC)
+ php_array_zval_to_resource(php_array_fetch(zarr, key), le)
#define php_array_fetchl_resource(zarr, key, key_len, le) \
- php_array_zval_to_resource(php_array_fetchl(zarr, key, key_len), le TSRMLS_CC)
+ php_array_zval_to_resource(php_array_fetchl(zarr, key, key_len), le)
#define php_array_fetchl_safe_resource(zarr, key, key_len, le) \
- php_array_zval_to_resource(php_array_fetchl_safe(zarr, key, key_len), le TSRMLS_CC)
+ php_array_zval_to_resource(php_array_fetchl_safe(zarr, key, key_len), le)
#define php_array_fetchn_resource(zarr, idx, le) \
- php_array_zval_to_resource(php_array_fetchn(zarr, idx), le TSRMLS_CC)
+ php_array_zval_to_resource(php_array_fetchn(zarr, idx), le)
#define php_array_fetchc_resource(zarr, litstr, le) \
- php_array_zval_to_resource(php_array_fetchc(zarr, litstr), le TSRMLS_CC)
+ php_array_zval_to_resource(php_array_fetchc(zarr, litstr), le)
#define php_array_fetchz_resource(zarr, key, le) \
- php_array_zval_to_resource(php_array_fetchz(zarr, key), le TSRMLS_CC)
+ php_array_zval_to_resource(php_array_fetchz(zarr, key), le)
/* Fetch Object
*
* Fetch an object of a specific or non-specific type (pass ce == NULL)
*
* No implicit conversion is performed
*
* zval *php_array_fetch_object(zval *zarr, const char *key, zend_class_entry *ce)
* zval *php_array_fetchl_object(zval *zarr, const char *key, int key_len, zend_class_entry *ce)
* zval *php_array_fetchl_safe_object(zval *zarr, const char *key, int key_len, zend_class_entry *ce)
* zval *php_array_fetchn_object(zval *zarr, unsigned long idx, zend_class_entry *ce)
* zval *php_array_fetchc_object(zval *zarr, const char *litstr, zend_class_entry *ce)
* zval *php_array_fetchz_object(zval *zarr, zval *key, zend_class_entry *ce)
*/
static inline
-zval *php_array_zval_to_object(zval *z, zend_class_entry *ce TSRMLS_DC) {
+zval *php_array_zval_to_object(zval *z, zend_class_entry *ce) {
return (z && (Z_TYPE_P(z) == IS_OBJECT) &&
- ((!ce) || instanceof_function(Z_OBJCE_P(z), ce TSRMLS_CC))) ? z : NULL;
+ ((!ce) || instanceof_function(Z_OBJCE_P(z), ce))) ? z : NULL;
}
#define php_array_fetch_object(zarr, key, ce) \
- php_array_zval_to_object(php_array_fetch(zarr, key), ce TSRMLS_CC)
+ php_array_zval_to_object(php_array_fetch(zarr, key), ce)
#define php_array_fetchl_object(zarr, key, len, ce) \
- php_array_zval_to_object(php_array_fetchl(zarr, key, len), ce TSRMLS_CC)
+ php_array_zval_to_object(php_array_fetchl(zarr, key, len), ce)
#define php_array_fetchl_safe_object(zarr, key, len, ce) \
- php_array_zval_to_object(php_array_fetchl_safe(zarr, key, len), ce TSRMLS_CC)
+ php_array_zval_to_object(php_array_fetchl_safe(zarr, key, len), ce)
#define php_array_fetchn_object(zarr, idx, ce) \
- php_array_zval_to_object(php_array_fetchn(zarr, idx), ce TSRMLS_CC)
+ php_array_zval_to_object(php_array_fetchn(zarr, idx), ce)
#define php_array_fetchc_object(zarr, litstr, ce) \
- php_array_zval_to_object(php_array_fetchc(zarr, litstr), ce TSRMLS_CC)
+ php_array_zval_to_object(php_array_fetchc(zarr, litstr), ce)
#define php_array_fetchz_object(zarr, key, ce) \
- php_array_zval_to_object(php_array_fetchz(zarr, key), ce TSRMLS_CC)
+ php_array_zval_to_object(php_array_fetchz(zarr, key), ce)
/* unset($zarr[$key]) - Erase a key from an array
*
* void php_array_unset(zval *zarr, const char *key)
* void php_array_unsetl(zval *zarr, const char *key, int key_len)
* void php_array_unsetl_safe(zval *zarr, const char *key, int key_len)
* void php_array_unsetn(zval *zarr, long idx)
* void php_array_unsetc(zval *zarr, const char *litstr)
* void php_array_unsetz(zval *zarr, zval *key)
*/
static inline
void php_array_unset(zval *zarr, const char *key) {
PAA_SYM_DEL(Z_ARRVAL_P(zarr), key, PAA_LENGTH_ADJ(strlen(key)));
}
#define php_array_unsetl(zarr, key, len) \
PAA_SYM_DEL(Z_ARRVAL_P(zarr), key, PAA_LENGTH_ADJ(len))
static inline
void php_array_unsetl_safe(zval *zarr, const char *key, int key_len) {
char *k = estrndup(key, key_len);
PAA_SYM_DEL(Z_ARRVAL_P(zarr), k, PAA_LENGTH_ADJ(key_len));
efree(k);
}
#define php_array_unsetn(zarr, idx) \
zend_symtable_index_del(Z_ARRVAL_P(zarr), idx)
#define php_array_unsetc(zarr, litstr) \
PAA_SYM_DEL(Z_ARRVAL_P(zarr), litstr, PAA_LENGTH_ADJ(sizeof(litstr) - 1))
static inline void php_array_unsetz(zval *zarr, zval *key) {
switch (Z_TYPE_P(key)) {
case IS_NULL:
zend_hash_index_del(Z_ARRVAL_P(zarr), 0);
return;
#ifdef ZEND_ENGINE_3
case IS_FALSE:
zend_hash_index_del(Z_ARRVAL_P(zarr), 0);
return;
case IS_TRUE:
zend_hash_index_del(Z_ARRVAL_P(zarr), 1);
return;
#else
case IS_BOOL: /* fallthrough */
#endif
case IS_LONG:
zend_hash_index_del(Z_ARRVAL_P(zarr), Z_LVAL_P(key));
return;
case IS_DOUBLE:
zend_hash_index_del(Z_ARRVAL_P(zarr), (long)Z_DVAL_P(key));
break;
case IS_STRING:
php_array_unsetl(zarr, Z_STRVAL_P(key), Z_STRLEN_P(key));
break;
}
}
#endif /* PHP_ARRAY_API_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/common/common-b64-private.h b/mongodb-1.8.1/src/libmongoc/src/common/common-b64-private.h
new file mode 100644
index 00000000..e3959d3c
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/common/common-b64-private.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018-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
+ *
+ * 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.
+ */
+
+#include "common-prelude.h"
+
+#ifndef COMMON_B64_PRIVATE_H
+#define COMMON_B64_PRIVATE_H
+
+#include <bson/bson.h>
+
+/* When encoding from "network" (raw data) to "presentation" (base64 encoded).
+ * Includes the trailing null byte. */
+size_t COMMON_PREFIX (bson_b64_ntop_calculate_target_size) (size_t raw_size);
+
+/* When encoding from "presentation" (base64 encoded) to "network" (raw data).
+ * This may be an overestimate if the base64 data includes spaces. For a more
+ * accurate size, call bson_b64_pton (src, NULL, 0), which will read the src
+ * data and return an exact size. */
+size_t COMMON_PREFIX (bson_b64_pton_calculate_target_size) (
+ size_t base64_encoded_size);
+
+/* Returns the number of bytes written (excluding NULL byte) to target on
+ * success or -1 on error. Adds a trailing NULL byte.
+ * Encodes from "network" (raw data) to "presentation" (base64 encoded),
+ * hence the obscure name "ntop".
+ */
+int COMMON_PREFIX (bson_b64_ntop) (uint8_t const *src,
+ size_t srclength,
+ char *target,
+ size_t targsize);
+
+/* If target is not NULL, the number of bytes written to target on success or -1
+ * on error.
+ * If target is NULL, returns the exact number of bytes that would be
+ * written to target on decoding.
+ * Encodes from "presentation" (base64 encoded) to "network" (raw data),
+ * hence the obscure name "pton".
+ */
+int COMMON_PREFIX (bson_b64_pton) (char const *src,
+ uint8_t *target,
+ size_t targsize);
+
+#endif /* COMMON_B64_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/common/common-b64.c b/mongodb-1.8.1/src/libmongoc/src/common/common-b64.c
similarity index 92%
rename from mongodb-1.7.4/src/libmongoc/src/common/common-b64.c
rename to mongodb-1.8.1/src/libmongoc/src/common/common-b64.c
index 2921b1bc..552d0e5a 100644
--- a/mongodb-1.7.4/src/libmongoc/src/common/common-b64.c
+++ b/mongodb-1.8.1/src/libmongoc/src/common/common-b64.c
@@ -1,528 +1,559 @@
/*
* Copyright (c) 1996, 1998 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include "bson/bson.h"
#include "common-b64-private.h"
#define Assert(Cond) \
if (!(Cond)) \
abort ()
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
* The following encoding technique is taken from RFC 1521 by Borenstein
* and Freed. It is reproduced here in a slightly edited form for
* convenience.
*
* A 65-character subset of US-ASCII is used, enabling 6 bits to be
* represented per printable character. (The extra 65th character, "=",
* is used to signify a special processing function.)
*
* The encoding process represents 24-bit groups of input bits as output
* strings of 4 encoded characters. Proceeding from left to right, a
* 24-bit input group is formed by concatenating 3 8-bit input groups.
* These 24 bits are then treated as 4 concatenated 6-bit groups, each
* of which is translated into a single digit in the base64 alphabet.
*
* Each 6-bit group is used as an index into an array of 64 printable
* characters. The character referenced by the index is placed in the
* output string.
*
* Table 1: The Base64 Alphabet
*
* Value Encoding Value Encoding Value Encoding Value Encoding
* 0 A 17 R 34 i 51 z
* 1 B 18 S 35 j 52 0
* 2 C 19 T 36 k 53 1
* 3 D 20 U 37 l 54 2
* 4 E 21 V 38 m 55 3
* 5 F 22 W 39 n 56 4
* 6 G 23 X 40 o 57 5
* 7 H 24 Y 41 p 58 6
* 8 I 25 Z 42 q 59 7
* 9 J 26 a 43 r 60 8
* 10 K 27 b 44 s 61 9
* 11 L 28 c 45 t 62 +
* 12 M 29 d 46 u 63 /
* 13 N 30 e 47 v
* 14 O 31 f 48 w (pad) =
* 15 P 32 g 49 x
* 16 Q 33 h 50 y
*
* Special processing is performed if fewer than 24 bits are available
* at the end of the data being encoded. A full encoding quantum is
* always completed at the end of a quantity. When fewer than 24 input
* bits are available in an input group, zero bits are added (on the
* right) to form an integral number of 6-bit groups. Padding at the
* end of the data is performed using the '=' character.
*
* Since all base64 input is an integral number of octets, only the
* following cases can arise:
*
* (1) the final quantum of encoding input is an integral
* multiple of 24 bits; here, the final unit of encoded
* output will be an integral multiple of 4 characters
* with no "=" padding,
* (2) the final quantum of encoding input is exactly 8 bits;
* here, the final unit of encoded output will be two
* characters followed by two "=" padding characters, or
* (3) the final quantum of encoding input is exactly 16 bits;
* here, the final unit of encoded output will be three
* characters followed by one "=" padding character.
*/
-int
-bson_b64_ntop (uint8_t const *src,
- size_t srclength,
- char *target,
- size_t targsize)
+int COMMON_PREFIX (bson_b64_ntop) (uint8_t const *src,
+ size_t srclength,
+ char *target,
+ size_t targsize)
{
size_t datalength = 0;
uint8_t input[3];
uint8_t output[4];
size_t i;
+ if (!target) {
+ return -1;
+ }
+
while (2 < srclength) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
srclength -= 3;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;
Assert (output[0] < 64);
Assert (output[1] < 64);
Assert (output[2] < 64);
Assert (output[3] < 64);
if (datalength + 4 > targsize) {
return -1;
}
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclength; i++) {
input[i] = *src++;
}
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
Assert (output[0] < 64);
Assert (output[1] < 64);
Assert (output[2] < 64);
if (datalength + 4 > targsize) {
return -1;
}
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
if (srclength == 1) {
target[datalength++] = Pad64;
} else {
target[datalength++] = Base64[output[2]];
}
target[datalength++] = Pad64;
}
if (datalength >= targsize) {
return -1;
}
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (int) datalength;
}
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
The following encoding technique is taken from RFC 1521 by Borenstein
and Freed. It is reproduced here in a slightly edited form for
convenience.
A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string.
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a quantity. When fewer than 24 input
bits are available in an input group, zero bits are added (on the
right) to form an integral number of 6-bit groups. Padding at the
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
following cases can arise:
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
with no "=" padding,
(2) the final quantum of encoding input is exactly 8 bits;
here, the final unit of encoded output will be two
characters followed by two "=" padding characters, or
(3) the final quantum of encoding input is exactly 16 bits;
here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/
static uint8_t mongoc_b64rmap[256];
static const uint8_t mongoc_b64rmap_special = 0xf0;
static const uint8_t mongoc_b64rmap_end = 0xfd;
static const uint8_t mongoc_b64rmap_space = 0xfe;
static const uint8_t mongoc_b64rmap_invalid = 0xff;
/* initializing the reverse map isn't thread safe, do it in pthread_once */
#if defined(BSON_OS_UNIX)
#include <pthread.h>
#define mongoc_common_once_t pthread_once_t
#define mongoc_common_once pthread_once
#define MONGOC_COMMON_ONCE_FUN(n) void n (void)
#define MONGOC_COMMON_ONCE_RETURN return
#define MONGOC_COMMON_ONCE_INIT PTHREAD_ONCE_INIT
#else
#define mongoc_common_once_t INIT_ONCE
#define MONGOC_COMMON_ONCE_INIT INIT_ONCE_STATIC_INIT
#define mongoc_common_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL)
#define MONGOC_COMMON_ONCE_FUN(n) \
BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c)
#define MONGOC_COMMON_ONCE_RETURN return true
#endif
static MONGOC_COMMON_ONCE_FUN (bson_b64_initialize_rmap)
{
int i;
unsigned char ch;
/* Null: end of string, stop parsing */
mongoc_b64rmap[0] = mongoc_b64rmap_end;
for (i = 1; i < 256; ++i) {
ch = (unsigned char) i;
/* Whitespaces */
if (bson_isspace (ch))
mongoc_b64rmap[i] = mongoc_b64rmap_space;
/* Padding: stop parsing */
else if (ch == Pad64)
mongoc_b64rmap[i] = mongoc_b64rmap_end;
/* Non-base64 char */
else
mongoc_b64rmap[i] = mongoc_b64rmap_invalid;
}
/* Fill reverse mapping for base64 chars */
for (i = 0; Base64[i] != '\0'; ++i)
mongoc_b64rmap[(uint8_t) Base64[i]] = i;
MONGOC_COMMON_ONCE_RETURN;
}
static int
mongoc_b64_pton_do (char const *src, uint8_t *target, size_t targsize)
{
int tarindex, state;
uint8_t ch, ofs;
state = 0;
tarindex = 0;
while (1) {
ch = *src++;
ofs = mongoc_b64rmap[ch];
if (ofs >= mongoc_b64rmap_special) {
/* Ignore whitespaces */
if (ofs == mongoc_b64rmap_space)
continue;
/* End of base64 characters */
if (ofs == mongoc_b64rmap_end)
break;
/* A non-base64 character. */
return (-1);
}
switch (state) {
case 0:
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] = ofs << 2;
state = 1;
break;
case 1:
if ((size_t) tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= ofs >> 4;
target[tarindex + 1] = (ofs & 0x0f) << 4;
tarindex++;
state = 2;
break;
case 2:
if ((size_t) tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= ofs >> 2;
target[tarindex + 1] = (ofs & 0x03) << 6;
tarindex++;
state = 3;
break;
case 3:
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] |= ofs;
tarindex++;
state = 0;
break;
default:
abort ();
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for ((void) NULL; ch != '\0'; ch = *src++)
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
- /* Fall through to "single trailing =" case. */
- /* FALLTHROUGH */
+ /* Fall through to "single trailing =" case. */
+ /* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for ((void) NULL; ch != '\0'; ch = *src++)
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target[tarindex] != 0)
return (-1);
default:
break;
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}
static int
mongoc_b64_pton_len (char const *src)
{
int tarindex, state;
uint8_t ch, ofs;
state = 0;
tarindex = 0;
while (1) {
ch = *src++;
ofs = mongoc_b64rmap[ch];
if (ofs >= mongoc_b64rmap_special) {
/* Ignore whitespaces */
if (ofs == mongoc_b64rmap_space)
continue;
/* End of base64 characters */
if (ofs == mongoc_b64rmap_end)
break;
/* A non-base64 character. */
return (-1);
}
switch (state) {
case 0:
state = 1;
break;
case 1:
tarindex++;
state = 2;
break;
case 2:
tarindex++;
state = 3;
break;
case 3:
tarindex++;
state = 0;
break;
default:
abort ();
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for ((void) NULL; ch != '\0'; ch = *src++)
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
- /* Fall through to "single trailing =" case. */
- /* FALLTHROUGH */
+ /* Fall through to "single trailing =" case. */
+ /* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for ((void) NULL; ch != '\0'; ch = *src++)
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
return (-1);
default:
break;
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}
-int
-bson_b64_pton (char const *src, uint8_t *target, size_t targsize)
+int COMMON_PREFIX (bson_b64_pton) (char const *src,
+ uint8_t *target,
+ size_t targsize)
{
static mongoc_common_once_t once = MONGOC_COMMON_ONCE_INIT;
mongoc_common_once (&once, bson_b64_initialize_rmap);
+ if (!src) {
+ return -1;
+ }
+
if (target)
return mongoc_b64_pton_do (src, target, targsize);
else
return mongoc_b64_pton_len (src);
}
+
+size_t COMMON_PREFIX (bson_b64_ntop_calculate_target_size) (size_t raw_size)
+{
+ size_t num_bits = raw_size * 8;
+ /* Calculate how many groups of six bits this contains, adding 5 to round up
+ * to the nearest group of 6. */
+ size_t num_b64_chars = (num_bits + 5) / 6;
+ /* Round to nearest set of four. */
+ size_t num_b64_chars_with_padding = 4 * ((num_b64_chars + 3) / 4);
+ /* Add one for NULL byte. */
+ return num_b64_chars_with_padding + 1;
+}
+
+size_t COMMON_PREFIX (bson_b64_pton_calculate_target_size) (
+ size_t base64_encoded_size)
+{
+ /* Without inspecting the data, we don't know how many padding characters
+ * there are. Assuming none, that means each character represents 6 bits of
+ * data. */
+ size_t num_bits = base64_encoded_size * 6;
+ /* Round down to the nearest group of eight. */
+ return num_bits / 8;
+}
diff --git a/mongodb-1.8.1/src/libmongoc/src/common/common-config.h b/mongodb-1.8.1/src/libmongoc/src/common/common-config.h
new file mode 100644
index 00000000..1636581f
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/common/common-config.h
@@ -0,0 +1,10 @@
+#ifndef COMMON_CONFIG_H
+#define COMMON_CONFIG_H
+
+#define MONGOC_ENABLE_DEBUG_ASSERTIONS 1
+
+#if MONGOC_ENABLE_DEBUG_ASSERTIONS != 1
+# undef MONGOC_ENABLE_DEBUG_ASSERTIONS
+#endif
+
+#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/common/common-md5-private.h b/mongodb-1.8.1/src/libmongoc/src/common/common-md5-private.h
similarity index 72%
rename from mongodb-1.7.4/src/libmongoc/src/common/common-md5-private.h
rename to mongodb-1.8.1/src/libmongoc/src/common/common-md5-private.h
index e786992e..b2d164ae 100644
--- a/mongodb-1.7.4/src/libmongoc/src/common/common-md5-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/common/common-md5-private.h
@@ -1,35 +1,34 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "common-prelude.h"
#ifndef COMMON_MD5_PRIVATE_H
#define COMMON_MD5_PRIVATE_H
#include "bson/bson.h"
BSON_BEGIN_DECLS
-void
-_bson_md5_init (bson_md5_t *pms);
-void
-_bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes);
-void
-_bson_md5_finish (bson_md5_t *pms, uint8_t digest[16]);
+void COMMON_PREFIX (_bson_md5_init) (bson_md5_t *pms);
+void COMMON_PREFIX (_bson_md5_append) (bson_md5_t *pms,
+ const uint8_t *data,
+ uint32_t nbytes);
+void COMMON_PREFIX (_bson_md5_finish) (bson_md5_t *pms, uint8_t digest[16]);
BSON_END_DECLS
#endif /* COMMON_MD5_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/common/common-md5.c b/mongodb-1.8.1/src/libmongoc/src/common/common-md5.c
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/common/common-md5.c
rename to mongodb-1.8.1/src/libmongoc/src/common/common-md5.c
index 86f6f671..13254535 100644
--- a/mongodb-1.7.4/src/libmongoc/src/common/common-md5.c
+++ b/mongodb-1.8.1/src/libmongoc/src/common/common-md5.c
@@ -1,395 +1,395 @@
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgement in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
/*
* The following MD5 implementation has been modified to use types as
* specified in libbson.
*/
#include <string.h>
#include "common-md5-private.h"
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
#define BYTE_ORDER 1
#else
#define BYTE_ORDER -1
#endif
#define T_MASK ((uint32_t) ~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
bson_md5_process (bson_md5_t *md5, const uint8_t *data)
{
uint32_t a = md5->abcd[0];
uint32_t b = md5->abcd[1];
uint32_t c = md5->abcd[2];
uint32_t d = md5->abcd[3];
uint32_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
uint32_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
uint32_t xbuf[16];
const uint32_t *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const uint8_t *) &w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const uint8_t *) 0) & 3)) {
/* data are properly aligned */
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-align"
#endif
X = (const uint32_t *) data;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
} else {
/* not aligned */
memcpy (xbuf, data, sizeof (xbuf));
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const uint8_t *xp = data;
int i;
#if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
#else
#define xbuf X /* (static only) */
#endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti) \
t = a + F (b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT (t, s) + b
/* Do the following 16 operations. */
SET (a, b, c, d, 0, 7, T1);
SET (d, a, b, c, 1, 12, T2);
SET (c, d, a, b, 2, 17, T3);
SET (b, c, d, a, 3, 22, T4);
SET (a, b, c, d, 4, 7, T5);
SET (d, a, b, c, 5, 12, T6);
SET (c, d, a, b, 6, 17, T7);
SET (b, c, d, a, 7, 22, T8);
SET (a, b, c, d, 8, 7, T9);
SET (d, a, b, c, 9, 12, T10);
SET (c, d, a, b, 10, 17, T11);
SET (b, c, d, a, 11, 22, T12);
SET (a, b, c, d, 12, 7, T13);
SET (d, a, b, c, 13, 12, T14);
SET (c, d, a, b, 14, 17, T15);
SET (b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti) \
t = a + G (b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT (t, s) + b
/* Do the following 16 operations. */
SET (a, b, c, d, 1, 5, T17);
SET (d, a, b, c, 6, 9, T18);
SET (c, d, a, b, 11, 14, T19);
SET (b, c, d, a, 0, 20, T20);
SET (a, b, c, d, 5, 5, T21);
SET (d, a, b, c, 10, 9, T22);
SET (c, d, a, b, 15, 14, T23);
SET (b, c, d, a, 4, 20, T24);
SET (a, b, c, d, 9, 5, T25);
SET (d, a, b, c, 14, 9, T26);
SET (c, d, a, b, 3, 14, T27);
SET (b, c, d, a, 8, 20, T28);
SET (a, b, c, d, 13, 5, T29);
SET (d, a, b, c, 2, 9, T30);
SET (c, d, a, b, 7, 14, T31);
SET (b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti) \
t = a + H (b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT (t, s) + b
/* Do the following 16 operations. */
SET (a, b, c, d, 5, 4, T33);
SET (d, a, b, c, 8, 11, T34);
SET (c, d, a, b, 11, 16, T35);
SET (b, c, d, a, 14, 23, T36);
SET (a, b, c, d, 1, 4, T37);
SET (d, a, b, c, 4, 11, T38);
SET (c, d, a, b, 7, 16, T39);
SET (b, c, d, a, 10, 23, T40);
SET (a, b, c, d, 13, 4, T41);
SET (d, a, b, c, 0, 11, T42);
SET (c, d, a, b, 3, 16, T43);
SET (b, c, d, a, 6, 23, T44);
SET (a, b, c, d, 9, 4, T45);
SET (d, a, b, c, 12, 11, T46);
SET (c, d, a, b, 15, 16, T47);
SET (b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti) \
t = a + I (b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT (t, s) + b
/* Do the following 16 operations. */
SET (a, b, c, d, 0, 6, T49);
SET (d, a, b, c, 7, 10, T50);
SET (c, d, a, b, 14, 15, T51);
SET (b, c, d, a, 5, 21, T52);
SET (a, b, c, d, 12, 6, T53);
SET (d, a, b, c, 3, 10, T54);
SET (c, d, a, b, 10, 15, T55);
SET (b, c, d, a, 1, 21, T56);
SET (a, b, c, d, 8, 6, T57);
SET (d, a, b, c, 15, 10, T58);
SET (c, d, a, b, 6, 15, T59);
SET (b, c, d, a, 13, 21, T60);
SET (a, b, c, d, 4, 6, T61);
SET (d, a, b, c, 11, 10, T62);
SET (c, d, a, b, 2, 15, T63);
SET (b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
md5->abcd[0] += a;
md5->abcd[1] += b;
md5->abcd[2] += c;
md5->abcd[3] += d;
}
-void
-_bson_md5_init (bson_md5_t *pms)
+void COMMON_PREFIX (_bson_md5_init) (bson_md5_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
-void
-_bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes)
+void COMMON_PREFIX (_bson_md5_append) (bson_md5_t *pms,
+ const uint8_t *data,
+ uint32_t nbytes)
{
const uint8_t *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
uint32_t nbits = (uint32_t) (nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy (pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
bson_md5_process (pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
bson_md5_process (pms, p);
/* Process a final partial block. */
if (left)
memcpy (pms->buf, p, left);
}
-void
-_bson_md5_finish (bson_md5_t *pms, uint8_t digest[16])
+void COMMON_PREFIX (_bson_md5_finish) (bson_md5_t *pms, uint8_t digest[16])
{
static const uint8_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (uint8_t) (pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
- _bson_md5_append (pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ COMMON_PREFIX (_bson_md5_append)
+ (pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
- _bson_md5_append (pms, data, sizeof (data));
+ COMMON_PREFIX (_bson_md5_append) (pms, data, sizeof (data));
for (i = 0; i < 16; ++i)
digest[i] = (uint8_t) (pms->abcd[i >> 2] >> ((i & 3) << 3));
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/common/common-prelude.h b/mongodb-1.8.1/src/libmongoc/src/common/common-prelude.h
similarity index 80%
rename from mongodb-1.7.4/src/libmongoc/src/common/common-prelude.h
rename to mongodb-1.8.1/src/libmongoc/src/common/common-prelude.h
index 17eae966..42f0afad 100644
--- a/mongodb-1.7.4/src/libmongoc/src/common/common-prelude.h
+++ b/mongodb-1.8.1/src/libmongoc/src/common/common-prelude.h
@@ -1,20 +1,27 @@
/*
* Copyright 2018-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
*
* 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.
*/
#if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) && \
!defined(BSON_COMPILATION) && !defined(BSON_INSIDE)
#error "Only <mongoc/mongoc.h> or <bson/bson.h> can be included directly."
-#endif
\ No newline at end of file
+#endif
+
+#ifndef COMMON_PREFIX_
+#define COMMON_PREFIX_
+#endif
+#define JOINER(x, y) x##_##y
+#define NAME_EVALUATOR(x, y) JOINER (x, y)
+#define COMMON_PREFIX(name) NAME_EVALUATOR (COMMON_PREFIX_, name)
diff --git a/mongodb-1.7.4/src/libmongoc/src/common/common-thread-private.h b/mongodb-1.8.1/src/libmongoc/src/common/common-thread-private.h
similarity index 68%
rename from mongodb-1.7.4/src/libmongoc/src/common/common-thread-private.h
rename to mongodb-1.8.1/src/libmongoc/src/common/common-thread-private.h
index 5f700dfe..a43180f0 100644
--- a/mongodb-1.7.4/src/libmongoc/src/common/common-thread-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/common/common-thread-private.h
@@ -1,65 +1,78 @@
/*
* Copyright 2013-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
*
* 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.
*/
#include "common-prelude.h"
#ifndef COMMON_THREAD_PRIVATE_H
#define COMMON_THREAD_PRIVATE_H
#define BSON_INSIDE
#include "bson/bson-compat.h"
#include "bson/bson-config.h"
#include "bson/bson-macros.h"
#undef BSON_INSIDE
BSON_BEGIN_DECLS
#if defined(BSON_OS_UNIX)
#include <pthread.h>
#define BSON_ONCE_FUN(n) void n (void)
#define BSON_ONCE_RETURN return
#define BSON_ONCE_INIT PTHREAD_ONCE_INIT
#define bson_mutex_destroy pthread_mutex_destroy
#define bson_mutex_init(_n) pthread_mutex_init ((_n), NULL)
#define bson_mutex_lock pthread_mutex_lock
#define bson_mutex_t pthread_mutex_t
#define bson_mutex_unlock pthread_mutex_unlock
#define bson_once pthread_once
#define bson_once_t pthread_once_t
-#define bson_thread_create(_t, _f, _d) pthread_create ((_t), NULL, (_f), (_d))
-#define bson_thread_join(_n) pthread_join ((_n), NULL)
#define bson_thread_t pthread_t
+#define BSON_THREAD_FUN(_function_name, _arg_name) \
+ void *(_function_name) (void *(_arg_name))
+#define BSON_THREAD_FUN_TYPE(_function_name) void *(*(_function_name)) (void *)
+#define BSON_THREAD_RETURN return NULL
#else
+#include <process.h>
#define BSON_ONCE_FUN(n) \
BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c)
#define BSON_ONCE_INIT INIT_ONCE_STATIC_INIT
#define BSON_ONCE_RETURN return true
#define bson_mutex_destroy DeleteCriticalSection
#define bson_mutex_init InitializeCriticalSection
#define bson_mutex_lock EnterCriticalSection
#define bson_mutex_t CRITICAL_SECTION
#define bson_mutex_unlock LeaveCriticalSection
#define bson_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL)
#define bson_once_t INIT_ONCE
-#define bson_thread_create(_t, _f, _d) \
- (!(*(_t) = CreateThread (NULL, 0, (void *) _f, _d, 0, NULL)))
-#define bson_thread_join(_n) WaitForSingleObject ((_n), INFINITE)
#define bson_thread_t HANDLE
+#define BSON_THREAD_FUN(_function_name, _arg_name) \
+ unsigned(__stdcall _function_name) (void *(_arg_name))
+#define BSON_THREAD_FUN_TYPE(_function_name) \
+ unsigned(__stdcall * _function_name) (void *)
+#define BSON_THREAD_RETURN return
#endif
+/* Functions that require definitions get the common prefix (_mongoc for
+ * libmongoc or _bson for libbson) to avoid duplicate symbols when linking both
+ * libbson and libmongoc statically. */
+int COMMON_PREFIX (thread_join) (bson_thread_t thread);
+int COMMON_PREFIX (thread_create) (bson_thread_t *thread,
+ BSON_THREAD_FUN_TYPE (func),
+ void *arg);
+
BSON_END_DECLS
#endif /* COMMON_THREAD_PRIVATE_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/common/common-thread.c b/mongodb-1.8.1/src/libmongoc/src/common/common-thread.c
new file mode 100644
index 00000000..c3c0957a
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/common/common-thread.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "common-thread-private.h"
+
+#if defined(BSON_OS_UNIX)
+int COMMON_PREFIX (thread_create) (bson_thread_t *thread,
+ BSON_THREAD_FUN_TYPE (func),
+ void *arg)
+{
+ return pthread_create (thread, NULL, func, arg);
+}
+int COMMON_PREFIX (thread_join) (bson_thread_t thread)
+{
+ return pthread_join (thread, NULL);
+}
+#else
+int COMMON_PREFIX (thread_create) (bson_thread_t *thread,
+ BSON_THREAD_FUN_TYPE (func),
+ void *arg)
+{
+ *thread = (HANDLE) _beginthreadex (NULL, 0, func, arg, 0, NULL);
+ if (0 == *thread) {
+ return 1;
+ }
+ return 0;
+}
+int COMMON_PREFIX (thread_join) (bson_thread_t thread)
+{
+ int ret;
+
+ /* zero indicates success for WaitForSingleObject. */
+ ret = WaitForSingleObject (thread, INFINITE);
+ if (WAIT_OBJECT_0 != ret) {
+ return ret;
+ }
+ /* zero indicates failure for CloseHandle. */
+ ret = CloseHandle (thread);
+ if (0 == ret) {
+ return 1;
+ }
+ return 0;
+}
+#endif
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/hexlify.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/hexlify.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/hexlify.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/hexlify.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/hexlify.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/hexlify.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/hexlify.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/hexlify.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_b64.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_b64.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_b64.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_b64.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_caller_identity_request.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_caller_identity_request.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_apple.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto_apple.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_apple.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto_apple.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto_libcrypto.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto_libcrypto.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_none.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto_none.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_none.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto_none.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_windows.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto_windows.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_windows.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_crypto_windows.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_decrypt_request.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_decrypt_request.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_decrypt_request.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_decrypt_request.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_encrypt_request.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_encrypt_request.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_encrypt_request.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_encrypt_request.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_kv_list.c
similarity index 98%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_kv_list.c
index 3678900a..0cff3dc2 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.c
+++ b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_kv_list.c
@@ -1,149 +1,149 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "kms_kv_list.h"
#include "kms_message/kms_message.h"
#include "kms_message_private.h"
#include "kms_request_str.h"
#include "kms_port.h"
#include "sort.h"
static void
kv_init (kms_kv_t *kv, kms_request_str_t *key, kms_request_str_t *value)
{
kv->key = kms_request_str_dup (key);
kv->value = kms_request_str_dup (value);
}
static void
kv_cleanup (kms_kv_t *kv)
{
kms_request_str_destroy (kv->key);
kms_request_str_destroy (kv->value);
}
kms_kv_list_t *
kms_kv_list_new (void)
{
kms_kv_list_t *lst = malloc (sizeof (kms_kv_list_t));
KMS_ASSERT (lst);
lst->size = 16;
lst->kvs = malloc (lst->size * sizeof (kms_kv_t));
KMS_ASSERT (lst->kvs);
lst->len = 0;
return lst;
}
void
kms_kv_list_destroy (kms_kv_list_t *lst)
{
size_t i;
if (!lst) {
return;
}
for (i = 0; i < lst->len; i++) {
kv_cleanup (&lst->kvs[i]);
}
free (lst->kvs);
free (lst);
}
void
kms_kv_list_add (kms_kv_list_t *lst,
kms_request_str_t *key,
kms_request_str_t *value)
{
if (lst->len == lst->size) {
lst->size *= 2;
lst->kvs = realloc (lst->kvs, lst->size * sizeof (kms_kv_t));
KMS_ASSERT (lst->kvs);
}
kv_init (&lst->kvs[lst->len], key, value);
++lst->len;
}
const kms_kv_t *
kms_kv_list_find (const kms_kv_list_t *lst, const char *key)
{
size_t i;
for (i = 0; i < lst->len; i++) {
- if (0 == strcasecmp (lst->kvs[i].key->str, key)) {
+ if (0 == kms_strcasecmp (lst->kvs[i].key->str, key)) {
return &lst->kvs[i];
}
}
return NULL;
}
void
kms_kv_list_del (kms_kv_list_t *lst, const char *key)
{
size_t i;
for (i = 0; i < lst->len; i++) {
if (0 == strcmp (lst->kvs[i].key->str, key)) {
kv_cleanup (&lst->kvs[i]);
memmove (&lst->kvs[i],
&lst->kvs[i + 1],
sizeof (kms_kv_t) * (lst->len - i - 1));
lst->len--;
}
}
}
kms_kv_list_t *
kms_kv_list_dup (const kms_kv_list_t *lst)
{
kms_kv_list_t *dup;
size_t i;
if (lst->len == 0) {
return kms_kv_list_new ();
}
dup = malloc (sizeof (kms_kv_list_t));
KMS_ASSERT (dup);
dup->size = dup->len = lst->len;
dup->kvs = malloc (lst->len * sizeof (kms_kv_t));
KMS_ASSERT (dup->kvs);
for (i = 0; i < lst->len; i++) {
kv_init (&dup->kvs[i], lst->kvs[i].key, lst->kvs[i].value);
}
return dup;
}
void
kms_kv_list_sort (kms_kv_list_t *lst, int (*cmp) (const void *, const void *))
{
/* A stable sort is required to sort headers when creating canonical
* requests. qsort is not stable. */
insertionsort (
(unsigned char *) (lst->kvs), lst->len, sizeof (kms_kv_t), cmp);
}
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_kv_list.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_kv_list.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_b64.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_b64.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_caller_identity_request.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_caller_identity_request.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_decrypt_request.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_decrypt_request.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_encrypt_request.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_encrypt_request.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_message.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_message.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_message.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_message.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_message_defines.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_message_defines.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_request.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_request.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_request.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_request.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_request_opt.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_request_opt.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_response.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_response.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_response.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_response.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_response_parser.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message/kms_response_parser.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message_private.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message_private.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message_private.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_message_private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_port.c
similarity index 84%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_port.c
index c3cbbac3..58f7e39e 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h
+++ b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_port.c
@@ -1,35 +1,31 @@
/*
- * Copyright 2018-present MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"){}
+ * Copyright 2020-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
*
* 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.
*/
+#include "kms_port.h"
#if defined(_WIN32)
-#define strcasecmp _stricmp
-
-inline char *
-strndup (const char *src, size_t len)
+char * kms_strndup (const char *src, size_t len)
{
char *dst = (char *) malloc (len + 1);
if (!dst) {
return 0;
}
memcpy (dst, src, len);
dst[len] = '\0';
return dst;
}
-
-#endif
+#endif
\ No newline at end of file
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_port.h
similarity index 73%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_port.h
index c3cbbac3..2123a99d 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h
+++ b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_port.h
@@ -1,35 +1,32 @@
/*
* Copyright 2018-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
*
* 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.
*/
-#if defined(_WIN32)
-#define strcasecmp _stricmp
-
-inline char *
-strndup (const char *src, size_t len)
-{
- char *dst = (char *) malloc (len + 1);
- if (!dst) {
- return 0;
- }
-
- memcpy (dst, src, len);
- dst[len] = '\0';
+#ifndef KMS_PORT_H
+#define KMS_PORT_H
- return dst;
-}
+#include <stddef.h>
+#if defined(_WIN32)
+#define kms_strcasecmp _stricmp
+char *
+kms_strndup (const char *src, size_t len);
+#else
+#define kms_strndup strndup
+#define kms_strcasecmp strcasecmp
#endif
+
+#endif /* KMS_PORT_H */
\ No newline at end of file
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request.c
similarity index 98%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request.c
index 7f273b7e..ac2b07ea 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request.c
+++ b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request.c
@@ -1,760 +1,763 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "kms_crypto.h"
#include "kms_message/kms_message.h"
#include "kms_message_private.h"
#include "kms_request_opt_private.h"
#include "kms_port.h"
static kms_kv_list_t *
parse_query_params (kms_request_str_t *q)
{
kms_kv_list_t *lst = kms_kv_list_new ();
char *p = q->str;
char *end = q->str + q->len;
char *amp, *equals;
kms_request_str_t *k, *v;
do {
equals = strchr ((const char *) p, '=');
if (!equals) {
kms_kv_list_destroy (lst);
return NULL;
}
amp = strchr ((const char *) equals, '&');
if (!amp) {
amp = end;
}
k = kms_request_str_new_from_chars (p, equals - p);
v = kms_request_str_new_from_chars (equals + 1, amp - equals - 1);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
p = amp + 1;
} while (p < end);
return lst;
}
kms_request_t *
kms_request_new (const char *method,
const char *path_and_query,
const kms_request_opt_t *opt)
{
kms_request_t *request = calloc (1, sizeof (kms_request_t));
const char *question_mark;
KMS_ASSERT (request);
/* parsing may set failed to true */
request->failed = false;
request->finalized = false;
request->region = kms_request_str_new ();
request->service = kms_request_str_new ();
request->access_key_id = kms_request_str_new ();
request->secret_key = kms_request_str_new ();
question_mark = strchr (path_and_query, '?');
if (question_mark) {
request->path = kms_request_str_new_from_chars (
path_and_query, question_mark - path_and_query);
request->query = kms_request_str_new_from_chars (question_mark + 1, -1);
request->query_params = parse_query_params (request->query);
if (!request->query_params) {
KMS_ERROR (request, "Cannot parse query: %s", request->query->str);
}
} else {
request->path = kms_request_str_new_from_chars (path_and_query, -1);
request->query = kms_request_str_new ();
request->query_params = kms_kv_list_new ();
}
request->payload = kms_request_str_new ();
request->date = kms_request_str_new ();
request->datetime = kms_request_str_new ();
request->method = kms_request_str_new_from_chars (method, -1);
request->header_fields = kms_kv_list_new ();
request->auto_content_length = true;
if (!kms_request_set_date (request, NULL)) {
return request;
}
if (opt && opt->connection_close) {
if (!kms_request_add_header_field (request, "Connection", "close")) {
return request;
}
}
if (opt && opt->crypto.sha256) {
memcpy (&request->crypto, &opt->crypto, sizeof (opt->crypto));
} else {
request->crypto.sha256 = kms_sha256;
request->crypto.sha256_hmac = kms_sha256_hmac;
}
return request;
}
void
kms_request_destroy (kms_request_t *request)
{
kms_request_str_destroy (request->region);
kms_request_str_destroy (request->service);
kms_request_str_destroy (request->access_key_id);
kms_request_str_destroy (request->secret_key);
kms_request_str_destroy (request->method);
kms_request_str_destroy (request->path);
kms_request_str_destroy (request->query);
kms_request_str_destroy (request->payload);
kms_request_str_destroy (request->datetime);
kms_request_str_destroy (request->date);
kms_kv_list_destroy (request->query_params);
kms_kv_list_destroy (request->header_fields);
free (request);
}
const char *
kms_request_get_error (kms_request_t *request)
{
return request->failed ? request->error : NULL;
}
#define AMZ_DT_FORMAT "YYYYmmDDTHHMMSSZ"
bool
kms_request_set_date (kms_request_t *request, const struct tm *tm)
{
char buf[sizeof AMZ_DT_FORMAT];
struct tm tmp_tm;
if (request->failed) {
return false;
}
if (!tm) {
/* use current time */
time_t t;
time (&t);
#ifdef _WIN32
gmtime_s (&tmp_tm, &t);
#else
gmtime_r (&t, &tmp_tm);
#endif
tm = &tmp_tm;
}
if (0 == strftime (buf, sizeof AMZ_DT_FORMAT, "%Y%m%dT%H%M%SZ", tm)) {
KMS_ERROR (request, "Invalid tm struct");
return false;
}
kms_request_str_set_chars (request->date, buf, sizeof "YYYYmmDD" - 1);
kms_request_str_set_chars (request->datetime, buf, sizeof AMZ_DT_FORMAT - 1);
kms_kv_list_del (request->header_fields, "X-Amz-Date");
if (!kms_request_add_header_field (request, "X-Amz-Date", buf)) {
return false;
}
return true;
}
#undef AMZ_DT_FORMAT
bool
kms_request_set_region (kms_request_t *request, const char *region)
{
kms_request_str_set_chars (request->region, region, -1);
return true;
}
bool
kms_request_set_service (kms_request_t *request, const char *service)
{
kms_request_str_set_chars (request->service, service, -1);
return true;
}
bool
kms_request_set_access_key_id (kms_request_t *request, const char *akid)
{
kms_request_str_set_chars (request->access_key_id, akid, -1);
return true;
}
bool
kms_request_set_secret_key (kms_request_t *request, const char *key)
{
kms_request_str_set_chars (request->secret_key, key, -1);
return true;
}
bool
kms_request_add_header_field (kms_request_t *request,
const char *field_name,
const char *value)
{
kms_request_str_t *k, *v;
CHECK_FAILED;
k = kms_request_str_new_from_chars (field_name, -1);
v = kms_request_str_new_from_chars (value, -1);
kms_kv_list_add (request->header_fields, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
return true;
}
bool
kms_request_append_header_field_value (kms_request_t *request,
const char *value,
size_t len)
{
kms_request_str_t *v;
CHECK_FAILED;
if (request->header_fields->len == 0) {
KMS_ERROR (
request,
"Ensure the request has at least one header field before calling %s",
__FUNCTION__);
}
v = request->header_fields->kvs[request->header_fields->len - 1].value;
kms_request_str_append_chars (v, value, len);
return true;
}
bool
kms_request_append_payload (kms_request_t *request,
const char *payload,
size_t len)
{
CHECK_FAILED;
kms_request_str_append_chars (request->payload, payload, len);
return true;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
*
* "Sort the parameter names by character code point in ascending order. For
* example, a parameter name that begins with the uppercase letter F precedes a
* parameter name that begins with a lowercase letter b."
*/
static int
cmp_query_params (const void *a, const void *b)
{
int r = strcmp (((kms_kv_t *) a)->key->str, ((kms_kv_t *) b)->key->str);
if (r != 0) {
return r;
}
/* not in docs, but tested in get-vanilla-query-order-key: sort by value */
return strcmp (((kms_kv_t *) a)->value->str, ((kms_kv_t *) b)->value->str);
}
static void
append_canonical_query (kms_request_t *request, kms_request_str_t *str)
{
size_t i;
kms_kv_list_t *lst;
if (!request->query_params->len) {
return;
}
lst = kms_kv_list_dup (request->query_params);
kms_kv_list_sort (lst, cmp_query_params);
for (i = 0; i < lst->len; i++) {
kms_request_str_append_escaped (str, lst->kvs[i].key, true);
kms_request_str_append_char (str, '=');
kms_request_str_append_escaped (str, lst->kvs[i].value, true);
if (i < lst->len - 1) {
kms_request_str_append_char (str, '&');
}
}
kms_kv_list_destroy (lst);
}
/* "lst" is a sorted list of headers */
static void
append_canonical_headers (kms_kv_list_t *lst, kms_request_str_t *str)
{
size_t i;
kms_kv_t *kv;
const kms_request_str_t *previous_key = NULL;
/* aws docs: "To create the canonical headers list, convert all header names
* to lowercase and remove leading spaces and trailing spaces. Convert
* sequential spaces in the header value to a single space." "Do not sort the
* values in headers that have multiple values." */
for (i = 0; i < lst->len; i++) {
kv = &lst->kvs[i];
- if (previous_key && 0 == strcasecmp (previous_key->str, kv->key->str)) {
+ if (previous_key &&
+ 0 == kms_strcasecmp (previous_key->str, kv->key->str)) {
/* duplicate header */
kms_request_str_append_char (str, ',');
kms_request_str_append_stripped (str, kv->value);
continue;
}
if (i > 0) {
kms_request_str_append_newline (str);
}
kms_request_str_append_lowercase (str, kv->key);
kms_request_str_append_char (str, ':');
kms_request_str_append_stripped (str, kv->value);
previous_key = kv->key;
}
kms_request_str_append_newline (str);
}
static void
append_signed_headers (kms_kv_list_t *lst, kms_request_str_t *str)
{
size_t i;
kms_kv_t *kv;
const kms_request_str_t *previous_key = NULL;
for (i = 0; i < lst->len; i++) {
kv = &lst->kvs[i];
- if (previous_key && 0 == strcasecmp (previous_key->str, kv->key->str)) {
+ if (previous_key &&
+ 0 == kms_strcasecmp (previous_key->str, kv->key->str)) {
/* duplicate header */
continue;
}
- if (0 == strcasecmp (kv->key->str, "connection")) {
+ if (0 == kms_strcasecmp (kv->key->str, "connection")) {
continue;
}
kms_request_str_append_lowercase (str, kv->key);
if (i < lst->len - 1) {
kms_request_str_append_char (str, ';');
}
previous_key = kv->key;
}
}
static bool
finalize (kms_request_t *request)
{
kms_kv_list_t *lst;
kms_request_str_t *k;
kms_request_str_t *v;
if (request->failed) {
return false;
}
if (request->finalized) {
return true;
}
request->finalized = true;
lst = request->header_fields;
/* By default, if no explicit Host was set, it is derived from region +
* service */
if (!kms_kv_list_find (lst, "Host")) {
/* like "kms.us-east-1.amazonaws.com" */
k = kms_request_str_new_from_chars ("Host", -1);
v = kms_request_str_dup (request->service);
kms_request_str_append_char (v, '.');
kms_request_str_append (v, request->region);
kms_request_str_append_chars (v, ".amazonaws.com", -1);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
}
if (!kms_kv_list_find (lst, "Content-Length") && request->payload->len &&
request->auto_content_length) {
k = kms_request_str_new_from_chars ("Content-Length", -1);
v = kms_request_str_new ();
kms_request_str_appendf (v, "%zu", request->payload->len);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
}
return true;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
*
* "Build the canonical headers list by sorting the (lowercase) headers by
* character code... Do not sort the values in headers that have multiple
* values."
*/
static int
cmp_header_field_names (const void *a, const void *b)
{
- return strcasecmp (((kms_kv_t *) a)->key->str, ((kms_kv_t *) b)->key->str);
+ return kms_strcasecmp (((kms_kv_t *) a)->key->str,
+ ((kms_kv_t *) b)->key->str);
}
static kms_kv_list_t *
canonical_headers (const kms_request_t *request)
{
kms_kv_list_t *lst;
KMS_ASSERT (request->finalized);
lst = kms_kv_list_dup (request->header_fields);
kms_kv_list_sort (lst, cmp_header_field_names);
kms_kv_list_del (lst, "Connection");
return lst;
}
char *
kms_request_get_canonical (kms_request_t *request)
{
kms_request_str_t *canonical;
kms_request_str_t *normalized;
kms_kv_list_t *lst;
if (request->failed) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
canonical = kms_request_str_new ();
kms_request_str_append (canonical, request->method);
kms_request_str_append_newline (canonical);
normalized = kms_request_str_path_normalized (request->path);
kms_request_str_append_escaped (canonical, normalized, false);
kms_request_str_destroy (normalized);
kms_request_str_append_newline (canonical);
append_canonical_query (request, canonical);
kms_request_str_append_newline (canonical);
lst = canonical_headers (request);
append_canonical_headers (lst, canonical);
kms_request_str_append_newline (canonical);
append_signed_headers (lst, canonical);
kms_kv_list_destroy (lst);
kms_request_str_append_newline (canonical);
if (!kms_request_str_append_hashed (
&request->crypto, canonical, request->payload)) {
KMS_ERROR (request, "could not generate hash");
kms_request_str_destroy (canonical);
return NULL;
}
return kms_request_str_detach (canonical);
}
const char *
kms_request_get_canonical_header (kms_request_t *request, const char *header)
{
const kms_kv_t *value;
if (request->failed) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
value = kms_kv_list_find (request->header_fields, header);
if (!value) {
return NULL;
}
return value->value->str;
}
char *
kms_request_get_string_to_sign (kms_request_t *request)
{
bool success = false;
kms_request_str_t *sts;
kms_request_str_t *creq = NULL; /* canonical request */
if (request->failed) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
sts = kms_request_str_new ();
kms_request_str_append_chars (sts, "AWS4-HMAC-SHA256\n", -1);
kms_request_str_append (sts, request->datetime);
kms_request_str_append_newline (sts);
/* credential scope, like "20150830/us-east-1/service/aws4_request" */
kms_request_str_append (sts, request->date);
kms_request_str_append_char (sts, '/');
kms_request_str_append (sts, request->region);
kms_request_str_append_char (sts, '/');
kms_request_str_append (sts, request->service);
kms_request_str_append_chars (sts, "/aws4_request\n", -1);
creq = kms_request_str_wrap (kms_request_get_canonical (request), -1);
if (!creq) {
goto done;
}
if (!kms_request_str_append_hashed (&request->crypto, sts, creq)) {
goto done;
}
success = true;
done:
kms_request_str_destroy (creq);
if (!success) {
kms_request_str_destroy (sts);
sts = NULL;
}
return kms_request_str_detach (sts);
}
static bool
kms_request_hmac (_kms_crypto_t *crypto,
unsigned char *out,
kms_request_str_t *key,
kms_request_str_t *data)
{
return crypto->sha256_hmac (
crypto->ctx, key->str, (int) key->len, data->str, data->len, out);
}
static bool
kms_request_hmac_again (_kms_crypto_t *crypto,
unsigned char *out,
unsigned char *in,
kms_request_str_t *data)
{
return crypto->sha256_hmac (
crypto->ctx, (const char *) in, 32, data->str, data->len, out);
}
bool
kms_request_get_signing_key (kms_request_t *request, unsigned char *key)
{
bool success = false;
kms_request_str_t *aws4_plus_secret = NULL;
kms_request_str_t *aws4_request = NULL;
unsigned char k_date[32];
unsigned char k_region[32];
unsigned char k_service[32];
if (request->failed) {
return false;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
* Pseudocode for deriving a signing key
*
* kSecret = your secret access key
* kDate = HMAC("AWS4" + kSecret, Date)
* kRegion = HMAC(kDate, Region)
* kService = HMAC(kRegion, Service)
* kSigning = HMAC(kService, "aws4_request")
*/
aws4_plus_secret = kms_request_str_new_from_chars ("AWS4", -1);
kms_request_str_append (aws4_plus_secret, request->secret_key);
aws4_request = kms_request_str_new_from_chars ("aws4_request", -1);
if (!(kms_request_hmac (
&request->crypto, k_date, aws4_plus_secret, request->date) &&
kms_request_hmac_again (
&request->crypto, k_region, k_date, request->region) &&
kms_request_hmac_again (
&request->crypto, k_service, k_region, request->service) &&
kms_request_hmac_again (
&request->crypto, key, k_service, aws4_request))) {
goto done;
}
success = true;
done:
kms_request_str_destroy (aws4_plus_secret);
kms_request_str_destroy (aws4_request);
return success;
}
char *
kms_request_get_signature (kms_request_t *request)
{
bool success = false;
kms_kv_list_t *lst = NULL;
kms_request_str_t *sig = NULL;
kms_request_str_t *sts = NULL;
unsigned char signing_key[32];
unsigned char signature[32];
if (request->failed) {
return NULL;
}
sts = kms_request_str_wrap (kms_request_get_string_to_sign (request), -1);
if (!sts) {
goto done;
}
sig = kms_request_str_new ();
kms_request_str_append_chars (sig, "AWS4-HMAC-SHA256 Credential=", -1);
kms_request_str_append (sig, request->access_key_id);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->date);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->region);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->service);
kms_request_str_append_chars (sig, "/aws4_request, SignedHeaders=", -1);
lst = canonical_headers (request);
append_signed_headers (lst, sig);
kms_request_str_append_chars (sig, ", Signature=", -1);
if (!(kms_request_get_signing_key (request, signing_key) &&
kms_request_hmac_again (
&request->crypto, signature, signing_key, sts))) {
goto done;
}
kms_request_str_append_hex (sig, signature, sizeof (signature));
success = true;
done:
kms_kv_list_destroy (lst);
kms_request_str_destroy (sts);
if (!success) {
kms_request_str_destroy (sig);
sig = NULL;
}
return kms_request_str_detach (sig);
}
void
kms_request_validate (kms_request_t *request)
{
if (0 == request->region->len) {
KMS_ERROR (request, "Region not set");
} else if (0 == request->service->len) {
KMS_ERROR (request, "Service not set");
} else if (0 == request->access_key_id->len) {
KMS_ERROR (request, "Access key ID not set");
} else if (0 == request->method->len) {
KMS_ERROR (request, "Method not set");
} else if (0 == request->path->len) {
KMS_ERROR (request, "Path not set");
} else if (0 == request->date->len) {
KMS_ERROR (request, "Date not set");
} else if (0 == request->secret_key->len) {
KMS_ERROR (request, "Secret key not set");
}
}
char *
kms_request_get_signed (kms_request_t *request)
{
bool success = false;
kms_kv_list_t *lst = NULL;
char *signature = NULL;
kms_request_str_t *sreq = NULL;
size_t i;
kms_request_validate (request);
if (request->failed) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
sreq = kms_request_str_new ();
/* like "POST / HTTP/1.1" */
kms_request_str_append (sreq, request->method);
kms_request_str_append_char (sreq, ' ');
kms_request_str_append (sreq, request->path);
if (request->query->len) {
kms_request_str_append_char (sreq, '?');
kms_request_str_append (sreq, request->query);
}
kms_request_str_append_chars (sreq, " HTTP/1.1", -1);
kms_request_str_append_newline (sreq);
/* headers */
lst = kms_kv_list_dup (request->header_fields);
kms_kv_list_sort (lst, cmp_header_field_names);
for (i = 0; i < lst->len; i++) {
kms_request_str_append (sreq, lst->kvs[i].key);
kms_request_str_append_char (sreq, ':');
kms_request_str_append (sreq, lst->kvs[i].value);
kms_request_str_append_newline (sreq);
}
/* authorization header */
signature = kms_request_get_signature (request);
if (!signature) {
goto done;
}
/* note space after ':', to match test .sreq files */
kms_request_str_append_chars (sreq, "Authorization: ", -1);
kms_request_str_append_chars (sreq, signature, -1);
/* body */
if (request->payload->len) {
kms_request_str_append_newline (sreq);
kms_request_str_append_newline (sreq);
kms_request_str_append (sreq, request->payload);
}
success = true;
done:
free (signature);
kms_kv_list_destroy (lst);
if (!success) {
kms_request_str_destroy (sreq);
sreq = NULL;
}
return kms_request_str_detach (sreq);
}
void
kms_request_free_string (char *ptr)
{
free (ptr);
}
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_opt.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_opt.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_opt.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_opt.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_opt_private.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_opt_private.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_opt_private.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_opt_private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_str.c
similarity index 99%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_str.c
index c94b3f58..65207d2f 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.c
+++ b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_str.c
@@ -1,514 +1,514 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "hexlify.h"
#include "kms_crypto.h"
#include "kms_message/kms_message.h"
#include "kms_message_private.h"
#include "kms_request_str.h"
#include "kms_port.h"
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
bool rfc_3986_tab[256] = {0};
bool kms_initialized = false;
static void
tables_init ()
{
int i;
if (kms_initialized) {
return;
}
for (i = 0; i < 256; ++i) {
rfc_3986_tab[i] =
isalnum (i) || i == '~' || i == '-' || i == '.' || i == '_';
}
kms_initialized = true;
}
kms_request_str_t *
kms_request_str_new (void)
{
kms_request_str_t *s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
s->len = 0;
s->size = 16;
s->str = malloc (s->size);
KMS_ASSERT (s->str);
s->str[0] = '\0';
return s;
}
kms_request_str_t *
kms_request_str_new_from_chars (const char *chars, ssize_t len)
{
kms_request_str_t *s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
size_t actual_len;
actual_len = len < 0 ? strlen (chars) : (size_t) len;
s->size = actual_len + 1;
s->str = malloc (s->size);
KMS_ASSERT (s->str);
memcpy (s->str, chars, actual_len);
s->str[actual_len] = '\0';
s->len = actual_len;
return s;
}
kms_request_str_t *
kms_request_str_wrap (char *chars, ssize_t len)
{
kms_request_str_t *s;
if (!chars) {
return NULL;
}
s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
s->str = chars;
s->len = len < 0 ? strlen (chars) : (size_t) len;
s->size = s->len;
return s;
}
void
kms_request_str_destroy (kms_request_str_t *str)
{
if (!str) {
return;
}
free (str->str);
free (str);
}
char *
kms_request_str_detach (kms_request_str_t *str)
{
if (!str) {
return NULL;
}
char *r = str->str;
free (str);
return r;
}
const char *
kms_request_str_get (kms_request_str_t *str)
{
return str->str;
}
bool
kms_request_str_reserve (kms_request_str_t *str, size_t size)
{
size_t next_size = str->len + size + 1;
if (str->size < next_size) {
/* next power of 2 */
--next_size;
next_size |= next_size >> 1U;
next_size |= next_size >> 2U;
next_size |= next_size >> 4U;
next_size |= next_size >> 8U;
next_size |= next_size >> 16U;
++next_size;
str->size = next_size;
str->str = realloc (str->str, next_size);
}
return str->str != NULL;
}
kms_request_str_t *
kms_request_str_dup (kms_request_str_t *str)
{
kms_request_str_t *dup = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (dup);
- dup->str = strndup (str->str, str->len);
+ dup->str = kms_strndup (str->str, str->len);
dup->len = str->len;
dup->size = str->len + 1;
return dup;
}
void
kms_request_str_set_chars (kms_request_str_t *str,
const char *chars,
ssize_t len)
{
size_t actual_len = len < 0 ? strlen (chars) : (size_t) len;
kms_request_str_reserve (str, actual_len); /* adds 1 for nil */
memcpy (str->str, chars, actual_len + 1);
str->len = actual_len;
}
bool
kms_request_str_ends_with (kms_request_str_t *str, kms_request_str_t *suffix)
{
if (str->len >= suffix->len &&
0 == strncmp (
&str->str[str->len - suffix->len], suffix->str, suffix->len)) {
return true;
}
return false;
}
void
kms_request_str_append (kms_request_str_t *str, kms_request_str_t *appended)
{
size_t next_len = str->len + appended->len;
kms_request_str_reserve (str, next_len);
memcpy (str->str + str->len, appended->str, appended->len);
str->len += appended->len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_char (kms_request_str_t *str, char c)
{
kms_request_str_reserve (str, 1);
*(str->str + str->len) = c;
++str->len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_chars (kms_request_str_t *str,
const char *appended,
ssize_t len)
{
if (len < 0) {
len = strlen (appended);
}
kms_request_str_reserve (str, (size_t) len);
memcpy (str->str + str->len, appended, (size_t) len);
str->len += len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_newline (kms_request_str_t *str)
{
kms_request_str_append_char (str, '\n');
}
void
kms_request_str_append_lowercase (kms_request_str_t *str,
kms_request_str_t *appended)
{
size_t i;
char *p;
i = str->len;
kms_request_str_append (str, appended);
/* downcase the chars from the old end to the new end of str */
for (; i < str->len; ++i) {
p = &str->str[i];
/* ignore UTF-8 non-ASCII chars, which have 1 in the top bit */
if ((*p & (0x1U << 7U)) == 0) {
*p = (char) tolower (*p);
}
}
}
void
kms_request_str_appendf (kms_request_str_t *str, const char *format, ...)
{
va_list args;
size_t remaining;
int n;
KMS_ASSERT (format);
while (true) {
remaining = str->size - str->len;
va_start (args, format);
n = vsnprintf (&str->str[str->len], remaining, format, args);
va_end (args);
if (n > -1 && (size_t) n < remaining) {
/* success */
str->len += (size_t) n;
return;
}
if (n > -1) {
kms_request_str_reserve (str, (size_t) n);
} else {
/* TODO: error! */
abort ();
}
}
}
void
kms_request_str_append_escaped (kms_request_str_t *str,
kms_request_str_t *appended,
bool escape_slash)
{
uint8_t *in;
uint8_t *out;
size_t i;
tables_init ();
/* might replace each input char with 3 output chars: "%AB" */
kms_request_str_reserve (str, 3 * appended->len);
in = (uint8_t *) appended->str;
out = (uint8_t *) str->str + str->len;
for (i = 0; i < appended->len; ++i) {
if (rfc_3986_tab[*in] || (*in == '/' && !escape_slash)) {
*out = *in;
++out;
++str->len;
} else {
sprintf ((char *) out, "%%%02X", *in);
out += 3;
str->len += 3;
}
++in;
}
}
void
kms_request_str_append_stripped (kms_request_str_t *str,
kms_request_str_t *appended)
{
const char *src = appended->str;
const char *end = appended->str + appended->len;
bool space = false;
bool comma = false;
kms_request_str_reserve (str, appended->len);
// msvcrt is unhappy when it gets non-ANSI characters in isspace
while (*src >= 0 && isspace (*src)) {
++src;
}
while (src < end) {
/* replace newlines with commas. not documented but see
* get-header-value-multiline.creq */
if (*src == '\n') {
comma = true;
space = false;
} else if (*src >= 0 && isspace (*src)) {
space = true;
} else {
if (comma) {
kms_request_str_append_char (str, ',');
comma = false;
space = false;
}
/* is there a run of spaces waiting to be written as one space? */
if (space) {
kms_request_str_append_char (str, ' ');
space = false;
}
kms_request_str_append_char (str, *src);
}
++src;
}
}
bool
kms_request_str_append_hashed (_kms_crypto_t *crypto,
kms_request_str_t *str,
kms_request_str_t *appended)
{
uint8_t hash[32];
char *hex_chars;
if (!crypto->sha256 (crypto->ctx, appended->str, appended->len, hash)) {
return false;
}
hex_chars = hexlify (hash, sizeof (hash));
kms_request_str_append_chars (str, hex_chars, 2 * sizeof (hash));
free (hex_chars);
return true;
}
bool
kms_request_str_append_hex (kms_request_str_t *str,
unsigned char *data,
size_t len)
{
char *hex_chars;
hex_chars = hexlify (data, len);
kms_request_str_append_chars (str, hex_chars, len * 2);
free (hex_chars);
return true;
}
static bool
starts_with (char *s, const char *prefix)
{
if (strstr (s, prefix) == s) {
return true;
}
return false;
}
/* remove from last slash to the end, but don't remove slash from start */
static void
delete_last_segment (kms_request_str_t *str, bool is_absolute)
{
ssize_t i;
if (!str->len) {
return;
}
for (i = str->len - 1; i >= 0; --i) {
if (str->str[i] == '/') {
if (i == 0 && is_absolute) {
str->len = 1;
} else {
str->len = (size_t) i;
}
goto done;
}
}
/* no slashes */
str->len = 0;
done:
str->str[str->len] = '\0';
}
/* follow algorithm in https://tools.ietf.org/html/rfc3986#section-5.2.4,
* the block comments are copied from there */
kms_request_str_t *
kms_request_str_path_normalized (kms_request_str_t *str)
{
kms_request_str_t *slash = kms_request_str_new_from_chars ("/", 1);
kms_request_str_t *out = kms_request_str_new ();
char *in = strdup (str->str);
char *p = in;
char *end = in + str->len;
bool is_absolute = (*p == '/');
if (0 == strcmp (p, "/")) {
goto done;
}
while (p < end) {
/* If the input buffer begins with a prefix of "../" or "./",
* then remove that prefix from the input buffer */
if (starts_with (p, "../")) {
p += 3;
} else if (starts_with (p, "./")) {
p += 2;
}
/* otherwise, if the input buffer begins with a prefix of "/./" or "/.",
* where "." is a complete path segment, then replace that prefix with "/"
* in the input buffer */
else if (starts_with (p, "/./")) {
p += 2;
} else if (0 == strcmp (p, "/.")) {
break;
}
/* otherwise, if the input buffer begins with a prefix of "/../" or "/..",
* where ".." is a complete path segment, then replace that prefix with
* "/" in the input buffer and remove the last segment and its preceding
* "/" (if any) from the output buffer */
else if (starts_with (p, "/../")) {
p += 3;
delete_last_segment (out, is_absolute);
} else if (0 == strcmp (p, "/..")) {
delete_last_segment (out, is_absolute);
break;
}
/* otherwise, if the input buffer consists only of "." or "..", then
remove that from the input buffer */
else if (0 == strcmp (p, ".") || 0 == strcmp (p, "..")) {
break;
}
/* otherwise, move the first path segment in the input buffer to the end
* of the output buffer, including the initial "/" character (if any) and
* any subsequent characters up to, but not including, the next "/"
* character or the end of the input buffer. */
else {
char *next_slash = strchr (p + 1, '/');
if (!next_slash) {
next_slash = end;
}
/* fold repeated slashes */
if (kms_request_str_ends_with (out, slash) && *p == '/') {
++p;
}
/* normalize "a/../b" as "b", not as "/b" */
if (out->len == 0 && !is_absolute && *p == '/') {
++p;
}
kms_request_str_append_chars (out, p, next_slash - p);
p = next_slash;
}
}
done:
free (in);
kms_request_str_destroy (slash);
if (!out->len) {
kms_request_str_append_char (out, '/');
}
return out;
}
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_str.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_request_str.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_response.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_response.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_response.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_response.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_response_parser.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_response_parser.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_response_parser.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/kms_response_parser.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/sort.c b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/sort.c
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/sort.c
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/sort.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/sort.h b/mongodb-1.8.1/src/libmongoc/src/kms-message/src/sort.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/sort.h
copy to mongodb-1.8.1/src/libmongoc/src/kms-message/src/sort.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bcon.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bcon.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bcon.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bcon.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bcon.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bcon.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bcon.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bcon.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-atomic.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-atomic.c
similarity index 79%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-atomic.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-atomic.c
index 2c8bfdaa..b06d5158 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-atomic.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-atomic.c
@@ -1,73 +1,95 @@
/*
* Copyright 2014 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.
*/
#include "bson-atomic.h"
/*
* We should only ever hit these on non-Windows systems, for which we require
* pthread support. Therefore, we will avoid making a threading portability
* for threads here and just use pthreads directly.
*/
#ifdef __BSON_NEED_BARRIER
#include <pthread.h>
static pthread_mutex_t gBarrier = PTHREAD_MUTEX_INITIALIZER;
void
bson_memory_barrier (void)
{
pthread_mutex_lock (&gBarrier);
pthread_mutex_unlock (&gBarrier);
}
#endif
#ifdef __BSON_NEED_ATOMIC_32
#include <pthread.h>
static pthread_mutex_t gSync32 = PTHREAD_MUTEX_INITIALIZER;
int32_t
bson_atomic_int_add (volatile int32_t *p, int32_t n)
{
int ret;
pthread_mutex_lock (&gSync32);
*p += n;
ret = *p;
pthread_mutex_unlock (&gSync32);
return ret;
}
#endif
#ifdef __BSON_NEED_ATOMIC_64
#include <pthread.h>
static pthread_mutex_t gSync64 = PTHREAD_MUTEX_INITIALIZER;
int64_t
bson_atomic_int64_add (volatile int64_t *p, int64_t n)
{
int64_t ret;
pthread_mutex_lock (&gSync64);
*p += n;
ret = *p;
pthread_mutex_unlock (&gSync64);
return ret;
}
#endif
+
+
+/*
+ * The logic in the header is such that __BSON_NEED_ATOMIC_WINDOWS should only
+ * be defined if neither __BSON_NEED_ATOMIC_32 nor __BSON_NEED_ATOMIC_64 are.
+ */
+
+
+#ifdef __BSON_NEED_ATOMIC_WINDOWS
+int32_t
+bson_atomic_int_add (volatile int32_t *p, int32_t n)
+{
+ return InterlockedExchangeAdd (p, n) + n;
+}
+
+
+int64_t
+bson_atomic_int64_add (volatile int64_t *p, int64_t n)
+{
+ return InterlockedExchangeAdd (p, n) + n;
+}
+#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-atomic.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-atomic.h
similarity index 86%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-atomic.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-atomic.h
index d12e8fc9..4e352d63 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-atomic.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-atomic.h
@@ -1,105 +1,111 @@
/*
* Copyright 2013-2014 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.
*/
#include "bson-prelude.h"
#ifndef BSON_ATOMIC_H
#define BSON_ATOMIC_H
#include "bson-config.h"
#include "bson-compat.h"
#include "bson-macros.h"
BSON_BEGIN_DECLS
#if defined(__sun) && defined(__SVR4)
/* Solaris */
#include <atomic.h>
#define bson_atomic_int_add(p, v) \
atomic_add_32_nv ((volatile uint32_t *) p, (v))
#define bson_atomic_int64_add(p, v) \
atomic_add_64_nv ((volatile uint64_t *) p, (v))
#elif defined(_WIN32)
/* MSVC/MinGW */
-#define bson_atomic_int_add(p, v) \
- (InterlockedExchangeAdd ((volatile LONG *) (p), (LONG) (v)) + (LONG) (v))
-#define bson_atomic_int64_add(p, v) \
- (InterlockedExchangeAdd64 ((volatile LONGLONG *) (p), (LONGLONG) (v)) + \
- (LONGLONG) (v))
+#define __BSON_NEED_ATOMIC_WINDOWS
#else
#ifdef BSON_HAVE_ATOMIC_32_ADD_AND_FETCH
#define bson_atomic_int_add(p, v) __sync_add_and_fetch ((p), (v))
#else
#define __BSON_NEED_ATOMIC_32
#endif
#ifdef BSON_HAVE_ATOMIC_64_ADD_AND_FETCH
#if BSON_GNUC_IS_VERSION(4, 1)
/*
* GCC 4.1 on i386 can generate buggy 64-bit atomic increment.
* So we will work around with a fallback.
*
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40693
*/
#define __BSON_NEED_ATOMIC_64
#else
#define bson_atomic_int64_add(p, v) \
__sync_add_and_fetch ((volatile int64_t *) (p), (int64_t) (v))
#endif
#else
#define __BSON_NEED_ATOMIC_64
#endif
#endif
#ifdef __BSON_NEED_ATOMIC_32
BSON_EXPORT (int32_t)
bson_atomic_int_add (volatile int32_t *p, int32_t n);
#endif
#ifdef __BSON_NEED_ATOMIC_64
BSON_EXPORT (int64_t)
bson_atomic_int64_add (volatile int64_t *p, int64_t n);
#endif
+/*
+ * The logic above is such that __BSON_NEED_ATOMIC_WINDOWS should only be
+ * defined if neither __BSON_NEED_ATOMIC_32 nor __BSON_NEED_ATOMIC_64 are.
+ */
+#ifdef __BSON_NEED_ATOMIC_WINDOWS
+BSON_EXPORT (int32_t)
+bson_atomic_int_add (volatile int32_t *p, int32_t n);
+BSON_EXPORT (int64_t)
+bson_atomic_int64_add (volatile int64_t *p, int64_t n);
+#endif
#if defined(_WIN32)
#define bson_memory_barrier() MemoryBarrier ()
#elif defined(__GNUC__)
#if BSON_GNUC_CHECK_VERSION(4, 1)
#define bson_memory_barrier() __sync_synchronize ()
#else
#warning "GCC Pre-4.1 discovered, using inline assembly for memory barrier."
#define bson_memory_barrier() __asm__ volatile("" ::: "memory")
#endif
#elif defined(__SUNPRO_C)
#include <mbarrier.h>
#define bson_memory_barrier() __machine_rw_barrier ()
#elif defined(__xlC__)
#define bson_memory_barrier() __sync ()
#else
#define __BSON_NEED_BARRIER 1
#warning "Unknown compiler, using lock for compiler barrier."
BSON_EXPORT (void)
bson_memory_barrier (void);
#endif
BSON_END_DECLS
#endif /* BSON_ATOMIC_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-clock.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-clock.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-clock.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-clock.c
index cf981acf..95287dca 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-clock.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-clock.c
@@ -1,155 +1,155 @@
/*
* Copyright 2013 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.
*/
#ifdef __APPLE__
#include <mach/clock.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <sys/time.h>
#endif
#include "bson-config.h"
#include "bson-compat.h"
#if defined(BSON_HAVE_CLOCK_GETTIME)
#include <time.h>
#include <sys/time.h>
#endif
#include "bson-clock.h"
/*
*--------------------------------------------------------------------------
*
* bson_gettimeofday --
*
* A wrapper around gettimeofday() with fallback support for Windows.
*
* Returns:
* 0 if successful.
*
* Side effects:
* @tv is set.
*
*--------------------------------------------------------------------------
*/
int
bson_gettimeofday (struct timeval *tv) /* OUT */
{
#if defined(_WIN32)
#if defined(_MSC_VER)
#define DELTA_EPOCH_IN_MICROSEC 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSEC 11644473600000000ULL
#endif
FILETIME ft;
uint64_t tmp = 0;
/*
* The const value is shamelessly stolen from
* http://www.boost.org/doc/libs/1_55_0/boost/chrono/detail/inlined/win/chrono.hpp
*
* File times are the number of 100 nanosecond intervals elapsed since
* 12:00 am Jan 1, 1601 UTC. I haven't check the math particularly hard
*
* ... good luck
*/
if (tv) {
GetSystemTimeAsFileTime (&ft);
/* pull out of the filetime into a 64 bit uint */
tmp |= ft.dwHighDateTime;
tmp <<= 32;
tmp |= ft.dwLowDateTime;
/* convert from 100's of nanosecs to microsecs */
tmp /= 10;
/* adjust to unix epoch */
tmp -= DELTA_EPOCH_IN_MICROSEC;
tv->tv_sec = (long) (tmp / 1000000UL);
tv->tv_usec = (long) (tmp % 1000000UL);
}
return 0;
#else
return gettimeofday (tv, NULL);
#endif
}
/*
*--------------------------------------------------------------------------
*
* bson_get_monotonic_time --
*
* Returns the monotonic system time, if available. A best effort is
* made to use the monotonic clock. However, some systems may not
* support such a feature.
*
* Returns:
* The monotonic clock in microseconds.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int64_t
bson_get_monotonic_time (void)
{
#if defined(BSON_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
struct timespec ts;
/* ts.tv_sec may be a four-byte integer on 32 bit machines, so cast to
* int64_t to avoid truncation. */
clock_gettime (CLOCK_MONOTONIC, &ts);
return (((int64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000));
#elif defined(__APPLE__)
static mach_timebase_info_data_t info = {0};
static double ratio = 0.0;
if (!info.denom) {
/* the value from mach_absolute_time () * info.numer / info.denom
* is in nano seconds. So we have to divid by 1000.0 to get micro
* seconds*/
mach_timebase_info (&info);
ratio = (double) info.numer / (double) info.denom / 1000.0;
}
return mach_absolute_time () * ratio;
#elif defined(_WIN32)
/* Despite it's name, this is in milliseconds! */
int64_t ticks = GetTickCount64 ();
return (ticks * 1000);
#elif defined(__hpux__)
int64_t nanosec = gethrtime ();
return (nanosec / 1000UL);
#else
-#warning "Monotonic clock is not yet supported on your platform."
+#pragma message "Monotonic clock is not yet supported on your platform."
struct timeval tv;
bson_gettimeofday (&tv);
return ((int64_t) tv.tv_sec * 1000000) + tv.tv_usec;
#endif
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-clock.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-clock.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-clock.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-clock.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-compat.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-compat.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-compat.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-compat.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-config.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-config.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-config.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-config.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-config.h.in b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-config.h.in
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-config.h.in
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-config.h.in
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-context-private.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-context-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-context-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-context-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-context.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-context.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-context.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-context.c
index 632fff7f..b6f85d9a 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-context.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-context.c
@@ -1,448 +1,444 @@
/*
* Copyright 2013 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.
*/
#include "bson-compat.h"
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "bson-atomic.h"
#include "bson-clock.h"
#include "bson-context.h"
#include "bson-context-private.h"
#include "bson-memory.h"
#include "common-thread-private.h"
#ifdef BSON_HAVE_SYSCALL_TID
#include <sys/syscall.h>
#endif
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 256
#endif
/*
* Globals.
*/
static bson_context_t gContextDefault;
static BSON_INLINE uint16_t
_bson_getpid (void)
{
uint16_t pid;
#ifdef BSON_OS_WIN32
DWORD real_pid;
real_pid = GetCurrentProcessId ();
pid = (real_pid & 0xFFFF) ^ ((real_pid >> 16) & 0xFFFF);
#else
pid = getpid ();
#endif
return pid;
}
/*
*--------------------------------------------------------------------------
*
* _bson_context_set_oid_seq32 --
*
* 32-bit sequence generator, non-thread-safe version.
*
* Returns:
* None.
*
* Side effects:
* @oid is modified.
*
*--------------------------------------------------------------------------
*/
static void
_bson_context_set_oid_seq32 (bson_context_t *context, /* IN */
bson_oid_t *oid) /* OUT */
{
uint32_t seq = context->seq32++;
seq = BSON_UINT32_TO_BE (seq);
memcpy (&oid->bytes[9], ((uint8_t *) &seq) + 1, 3);
}
/*
*--------------------------------------------------------------------------
*
* _bson_context_set_oid_seq32_threadsafe --
*
* Thread-safe version of 32-bit sequence generator.
*
* Returns:
* None.
*
* Side effects:
* @oid is modified.
*
*--------------------------------------------------------------------------
*/
static void
_bson_context_set_oid_seq32_threadsafe (bson_context_t *context, /* IN */
bson_oid_t *oid) /* OUT */
{
int32_t seq = bson_atomic_int_add (&context->seq32, 1);
seq = BSON_UINT32_TO_BE (seq);
memcpy (&oid->bytes[9], ((uint8_t *) &seq) + 1, 3);
}
/*
*--------------------------------------------------------------------------
*
* _bson_context_set_oid_seq64 --
*
* 64-bit oid sequence generator, non-thread-safe version.
*
* Returns:
* None.
*
* Side effects:
* @oid is modified.
*
*--------------------------------------------------------------------------
*/
static void
_bson_context_set_oid_seq64 (bson_context_t *context, /* IN */
bson_oid_t *oid) /* OUT */
{
uint64_t seq;
BSON_ASSERT (context);
BSON_ASSERT (oid);
seq = BSON_UINT64_TO_BE (context->seq64++);
memcpy (&oid->bytes[4], &seq, sizeof (seq));
}
/*
*--------------------------------------------------------------------------
*
* _bson_context_set_oid_seq64_threadsafe --
*
* Thread-safe 64-bit sequence generator.
*
* Returns:
* None.
*
* Side effects:
* @oid is modified.
*
*--------------------------------------------------------------------------
*/
static void
_bson_context_set_oid_seq64_threadsafe (bson_context_t *context, /* IN */
bson_oid_t *oid) /* OUT */
{
int64_t seq = bson_atomic_int64_add (&context->seq64, 1);
seq = BSON_UINT64_TO_BE (seq);
memcpy (&oid->bytes[4], &seq, sizeof (seq));
}
static void
_bson_context_init_random (bson_context_t *context, bool init_sequence);
/*
*--------------------------------------------------------------------------
*
* _bson_context_set_oid_rand --
*
* Sets the process specific five byte random sequence in an oid.
*
* Returns:
* None.
*
* Side effects:
* @oid is modified.
*
*--------------------------------------------------------------------------
*/
void
_bson_context_set_oid_rand (bson_context_t *context, bson_oid_t *oid)
{
BSON_ASSERT (context);
BSON_ASSERT (oid);
if (context->flags & BSON_CONTEXT_DISABLE_PID_CACHE) {
uint16_t pid = _bson_getpid ();
if (pid != context->pid) {
context->pid = pid;
/* randomize the random bytes, not the sequence. */
_bson_context_init_random (context, false);
}
}
memcpy (&oid->bytes[4], &context->rand, sizeof (context->rand));
}
/*
*--------------------------------------------------------------------------
*
* _get_rand --
*
* Gets a random four byte integer. Callers that will use the "rand"
* function must call "srand" prior.
*
* Returns:
* A random int32_t.
*
*--------------------------------------------------------------------------
*/
static int32_t
_get_rand (unsigned int *pseed)
{
int32_t result = 0;
#ifndef BSON_HAVE_RAND_R
/* ms's runtime is multithreaded by default, so no rand_r */
/* no rand_r on android either */
result = rand ();
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
defined(__OpenBSD__)
arc4random_buf (&result, sizeof (result));
#else
result = rand_r (pseed);
#endif
return result;
}
/*
* --------------------------------------------------------------------------
*
* _bson_context_get_hostname
*
* Gets the hostname of the machine, logs a warning on failure. "out"
* must be an array of HOST_NAME_MAX bytes.
*
* --------------------------------------------------------------------------
*/
static void
_bson_context_get_hostname (char *out)
{
if (gethostname (out, HOST_NAME_MAX) != 0) {
if (errno == ENAMETOOLONG) {
fprintf (stderr,
"hostname exceeds %d characters, truncating.",
HOST_NAME_MAX);
} else {
fprintf (stderr, "unable to get hostname: %d", errno);
}
}
out[HOST_NAME_MAX - 1] = '\0';
}
static void
_bson_context_init_random (bson_context_t *context, bool init_sequence)
{
int64_t rand_bytes;
struct timeval tv;
unsigned int seed = 0;
char hostname[HOST_NAME_MAX];
char *ptr;
int hostname_chars_left;
/*
* The seed consists of the following xor'd together:
* - current time in seconds
* - current time in milliseconds
* - current pid
* - current hostname
*/
bson_gettimeofday (&tv);
seed ^= (unsigned int) tv.tv_sec;
seed ^= (unsigned int) tv.tv_usec;
seed ^= (unsigned int) context->pid;
context->gethostname (hostname);
hostname_chars_left = strlen (hostname);
ptr = hostname;
while (hostname_chars_left) {
uint32_t hostname_chunk = 0;
uint32_t to_copy = hostname_chars_left > 4 ? 4 : hostname_chars_left;
memcpy (&hostname_chunk, ptr, to_copy);
seed ^= (unsigned int) hostname_chunk;
hostname_chars_left -= to_copy;
ptr += to_copy;
}
#ifndef BSON_HAVE_RAND_R
srand (seed);
#endif
/* Generate a seed for the random starting position of our increment
* bytes and the five byte random number. */
if (init_sequence) {
/* We mask off the last nibble so that the last digit of the OID will
* start at zero. Just to be nice. */
context->seq32 = _get_rand (&seed) & 0x007FFFF0;
}
rand_bytes = _get_rand (&seed);
rand_bytes <<= 32;
rand_bytes |= _get_rand (&seed);
/* Copy five random bytes, endianness does not matter. */
memcpy (&context->rand, (char *) &rand_bytes, sizeof (context->rand));
}
static void
_bson_context_init (bson_context_t *context, bson_context_flags_t flags)
{
context->flags = (int) flags;
context->oid_set_seq32 = _bson_context_set_oid_seq32;
context->oid_set_seq64 = _bson_context_set_oid_seq64;
context->gethostname = _bson_context_get_hostname;
if ((flags & BSON_CONTEXT_THREAD_SAFE)) {
context->oid_set_seq32 = _bson_context_set_oid_seq32_threadsafe;
context->oid_set_seq64 = _bson_context_set_oid_seq64_threadsafe;
}
context->pid = _bson_getpid ();
_bson_context_init_random (context, true);
}
/*
*--------------------------------------------------------------------------
*
* bson_context_new --
*
* Initializes a new context with the flags specified.
*
* In most cases, you want to call this with @flags set to
* BSON_CONTEXT_NONE.
*
* If you are running on Linux, %BSON_CONTEXT_USE_TASK_ID can result
* in a healthy speedup for multi-threaded scenarios.
*
* If you absolutely must have a single context for your application
* and use more than one thread, then %BSON_CONTEXT_THREAD_SAFE should
* be bitwise-or'd with your flags. This requires synchronization
* between threads.
*
- * If you expect your hostname to change often, you may consider
- * specifying %BSON_CONTEXT_DISABLE_HOST_CACHE so that gethostname()
- * is called for every OID generated. This is much slower.
- *
* If you expect your pid to change without notice, such as from an
* unexpected call to fork(), then specify
* %BSON_CONTEXT_DISABLE_PID_CACHE.
*
* Returns:
* A newly allocated bson_context_t that should be freed with
* bson_context_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bson_context_t *
bson_context_new (bson_context_flags_t flags)
{
bson_context_t *context;
context = bson_malloc0 (sizeof *context);
_bson_context_init (context, flags);
return context;
}
/*
*--------------------------------------------------------------------------
*
* bson_context_destroy --
*
* Cleans up a bson_context_t and releases any associated resources.
* This should be called when you are done using @context.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_context_destroy (bson_context_t *context) /* IN */
{
bson_free (context);
}
static BSON_ONCE_FUN (_bson_context_init_default)
{
_bson_context_init (
&gContextDefault,
(BSON_CONTEXT_THREAD_SAFE | BSON_CONTEXT_DISABLE_PID_CACHE));
BSON_ONCE_RETURN;
}
/*
*--------------------------------------------------------------------------
*
* bson_context_get_default --
*
* Fetches the default, thread-safe implementation of #bson_context_t.
* If you need faster generation, it is recommended you create your
* own #bson_context_t with bson_context_new().
*
* Returns:
* A shared instance to the default #bson_context_t. This should not
* be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bson_context_t *
bson_context_get_default (void)
{
static bson_once_t once = BSON_ONCE_INIT;
bson_once (&once, _bson_context_init_default);
return &gContextDefault;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-context.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-context.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-context.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-context.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-decimal128.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-decimal128.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-decimal128.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-decimal128.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-decimal128.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-decimal128.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-decimal128.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-decimal128.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-endian.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-endian.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-endian.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-endian.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-error.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-error.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-error.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-error.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-error.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-error.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-error.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-error.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-iso8601.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-iso8601.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-iso8601.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-iso8601.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-iter.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-iter.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-iter.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-iter.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-iter.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-iter.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-iter.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-iter.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-json.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-json.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-json.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-json.c
index 488d4438..d3fe18c6 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-json.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-json.c
@@ -1,2408 +1,2408 @@
/*
* Copyright 2014 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.
*/
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <math.h>
#include "bson.h"
#include "bson-config.h"
#include "bson-json.h"
#include "bson-iso8601-private.h"
#include "common-b64-private.h"
#include "jsonsl/jsonsl.h"
#ifdef _WIN32
#include <io.h>
#include <share.h>
#endif
#ifndef _MSC_VER
#include <strings.h>
#endif
#ifdef _MSC_VER
#define SSCANF sscanf_s
#else
#define SSCANF sscanf
#endif
#define STACK_MAX 100
#define BSON_JSON_DEFAULT_BUF_SIZE (1 << 14)
#define AT_LEAST_0(x) ((x) >= 0 ? (x) : 0)
#define READ_STATE_ENUM(ENUM) BSON_JSON_##ENUM,
#define GENERATE_STRING(STRING) #STRING,
#define FOREACH_READ_STATE(RS) \
RS (REGULAR) \
RS (DONE) \
RS (ERROR) \
RS (IN_START_MAP) \
RS (IN_BSON_TYPE) \
RS (IN_BSON_TYPE_DATE_NUMBERLONG) \
RS (IN_BSON_TYPE_DATE_ENDMAP) \
RS (IN_BSON_TYPE_TIMESTAMP_STARTMAP) \
RS (IN_BSON_TYPE_TIMESTAMP_VALUES) \
RS (IN_BSON_TYPE_TIMESTAMP_ENDMAP) \
RS (IN_BSON_TYPE_REGEX_STARTMAP) \
RS (IN_BSON_TYPE_REGEX_VALUES) \
RS (IN_BSON_TYPE_REGEX_ENDMAP) \
RS (IN_BSON_TYPE_BINARY_VALUES) \
RS (IN_BSON_TYPE_BINARY_ENDMAP) \
RS (IN_BSON_TYPE_SCOPE_STARTMAP) \
RS (IN_BSON_TYPE_DBPOINTER_STARTMAP) \
RS (IN_SCOPE) \
RS (IN_DBPOINTER)
typedef enum { FOREACH_READ_STATE (READ_STATE_ENUM) } bson_json_read_state_t;
static const char *read_state_names[] = {FOREACH_READ_STATE (GENERATE_STRING)};
#define BSON_STATE_ENUM(ENUM) BSON_JSON_LF_##ENUM,
#define FOREACH_BSON_STATE(BS) \
/* legacy {$regex: "...", $options: "..."} */ \
BS (REGEX) \
BS (OPTIONS) \
/* modern $regularExpression: {pattern: "...", options: "..."} */ \
BS (REGULAR_EXPRESSION_PATTERN) \
BS (REGULAR_EXPRESSION_OPTIONS) \
BS (CODE) \
BS (SCOPE) \
BS (OID) \
BS (BINARY) \
BS (TYPE) \
BS (DATE) \
BS (TIMESTAMP_T) \
BS (TIMESTAMP_I) \
BS (UNDEFINED) \
BS (MINKEY) \
BS (MAXKEY) \
BS (INT32) \
BS (INT64) \
BS (DOUBLE) \
BS (DECIMAL128) \
BS (DBPOINTER) \
BS (SYMBOL) \
BS (DBREF)
typedef enum {
FOREACH_BSON_STATE (BSON_STATE_ENUM)
} bson_json_read_bson_state_t;
static const char *bson_state_names[] = {FOREACH_BSON_STATE (GENERATE_STRING)};
typedef struct {
uint8_t *buf;
size_t n_bytes;
size_t len;
} bson_json_buf_t;
typedef enum {
BSON_JSON_FRAME_INITIAL = 0,
BSON_JSON_FRAME_ARRAY,
BSON_JSON_FRAME_DOC,
BSON_JSON_FRAME_SCOPE,
BSON_JSON_FRAME_DBPOINTER,
} bson_json_frame_type_t;
typedef struct {
int i;
bson_json_frame_type_t type;
bool has_ref;
bool has_id;
bson_t bson;
} bson_json_stack_frame_t;
typedef union {
struct {
bool has_pattern;
bool has_options;
bool is_legacy;
} regex;
struct {
bool has_oid;
bson_oid_t oid;
} oid;
struct {
bool has_binary;
bool has_subtype;
bson_subtype_t type;
bool is_legacy;
} binary;
struct {
bool has_date;
int64_t date;
} date;
struct {
bool has_t;
bool has_i;
uint32_t t;
uint32_t i;
} timestamp;
struct {
bool has_undefined;
} undefined;
struct {
bool has_minkey;
} minkey;
struct {
bool has_maxkey;
} maxkey;
struct {
int32_t value;
} v_int32;
struct {
int64_t value;
} v_int64;
struct {
double value;
} v_double;
struct {
bson_decimal128_t value;
} v_decimal128;
} bson_json_bson_data_t;
/* collect info while parsing a {$code: "...", $scope: {...}} object */
typedef struct {
bool has_code;
bool has_scope;
bool in_scope;
bson_json_buf_t key_buf;
bson_json_buf_t code_buf;
} bson_json_code_t;
static void
_bson_json_code_cleanup (bson_json_code_t *code_data)
{
bson_free (code_data->key_buf.buf);
bson_free (code_data->code_buf.buf);
}
typedef struct {
bson_t *bson;
bson_json_stack_frame_t stack[STACK_MAX];
int n;
const char *key;
bson_json_buf_t key_buf;
bson_json_buf_t unescaped;
bson_json_read_state_t read_state;
bson_json_read_bson_state_t bson_state;
bson_type_t bson_type;
bson_json_buf_t bson_type_buf[3];
bson_json_bson_data_t bson_type_data;
bson_json_code_t code_data;
bson_json_buf_t dbpointer_key;
} bson_json_reader_bson_t;
typedef struct {
void *data;
bson_json_reader_cb cb;
bson_json_destroy_cb dcb;
uint8_t *buf;
size_t buf_size;
size_t bytes_read;
size_t bytes_parsed;
bool all_whitespace;
} bson_json_reader_producer_t;
struct _bson_json_reader_t {
bson_json_reader_producer_t producer;
bson_json_reader_bson_t bson;
jsonsl_t json;
ssize_t json_text_pos;
bool should_reset;
ssize_t advance;
bson_json_buf_t tok_accumulator;
bson_error_t *error;
};
typedef struct {
int fd;
bool do_close;
} bson_json_reader_handle_fd_t;
/* forward decl */
static void
_bson_json_save_map_key (bson_json_reader_bson_t *bson,
const uint8_t *val,
size_t len);
static void
_noop (void)
{
}
#define STACK_ELE(_delta, _name) (bson->stack[(_delta) + bson->n]._name)
#define STACK_BSON(_delta) \
(((_delta) + bson->n) == 0 ? bson->bson : &STACK_ELE (_delta, bson))
#define STACK_BSON_PARENT STACK_BSON (-1)
#define STACK_BSON_CHILD STACK_BSON (0)
#define STACK_I STACK_ELE (0, i)
#define STACK_FRAME_TYPE STACK_ELE (0, type)
#define STACK_IS_INITIAL (STACK_FRAME_TYPE == BSON_JSON_FRAME_INITIAL)
#define STACK_IS_ARRAY (STACK_FRAME_TYPE == BSON_JSON_FRAME_ARRAY)
#define STACK_IS_DOC (STACK_FRAME_TYPE == BSON_JSON_FRAME_DOC)
#define STACK_IS_SCOPE (STACK_FRAME_TYPE == BSON_JSON_FRAME_SCOPE)
#define STACK_IS_DBPOINTER (STACK_FRAME_TYPE == BSON_JSON_FRAME_DBPOINTER)
#define FRAME_TYPE_HAS_BSON(_type) \
((_type) == BSON_JSON_FRAME_SCOPE || (_type) == BSON_JSON_FRAME_DBPOINTER)
#define STACK_HAS_BSON FRAME_TYPE_HAS_BSON (STACK_FRAME_TYPE)
#define STACK_HAS_REF STACK_ELE (0, has_ref)
#define STACK_HAS_ID STACK_ELE (0, has_id)
#define STACK_PUSH(frame_type) \
do { \
if (bson->n >= (STACK_MAX - 1)) { \
return; \
} \
bson->n++; \
if (STACK_HAS_BSON) { \
if (FRAME_TYPE_HAS_BSON (frame_type)) { \
bson_reinit (STACK_BSON_CHILD); \
} else { \
bson_destroy (STACK_BSON_CHILD); \
} \
} else if (FRAME_TYPE_HAS_BSON (frame_type)) { \
bson_init (STACK_BSON_CHILD); \
} \
STACK_FRAME_TYPE = frame_type; \
} while (0)
#define STACK_PUSH_ARRAY(statement) \
do { \
STACK_PUSH (BSON_JSON_FRAME_ARRAY); \
STACK_I = 0; \
if (bson->n != 0) { \
statement; \
} \
} while (0)
#define STACK_PUSH_DOC(statement) \
do { \
STACK_PUSH (BSON_JSON_FRAME_DOC); \
STACK_HAS_REF = false; \
STACK_HAS_ID = false; \
if (bson->n != 0) { \
statement; \
} \
} while (0)
#define STACK_PUSH_SCOPE \
do { \
STACK_PUSH (BSON_JSON_FRAME_SCOPE); \
bson->code_data.in_scope = true; \
} while (0)
#define STACK_PUSH_DBPOINTER \
do { \
STACK_PUSH (BSON_JSON_FRAME_DBPOINTER); \
} while (0)
#define STACK_POP_ARRAY(statement) \
do { \
if (!STACK_IS_ARRAY) { \
return; \
} \
if (bson->n < 0) { \
return; \
} \
if (bson->n > 0) { \
statement; \
} \
bson->n--; \
} while (0)
#define STACK_POP_DOC(statement) \
do { \
if (STACK_IS_ARRAY) { \
return; \
} \
if (bson->n < 0) { \
return; \
} \
if (bson->n > 0) { \
statement; \
} \
bson->n--; \
} while (0)
#define STACK_POP_SCOPE \
do { \
STACK_POP_DOC (_noop ()); \
bson->code_data.in_scope = false; \
} while (0);
#define STACK_POP_DBPOINTER STACK_POP_DOC (_noop ())
#define BASIC_CB_PREAMBLE \
const char *key; \
size_t len; \
bson_json_reader_bson_t *bson = &reader->bson; \
_bson_json_read_fixup_key (bson); \
key = bson->key; \
len = bson->key_buf.len;
#define BASIC_CB_BAIL_IF_NOT_NORMAL(_type) \
if (bson->read_state != BSON_JSON_REGULAR) { \
_bson_json_read_set_error (reader, \
"Invalid read of %s in state %s", \
(_type), \
read_state_names[bson->read_state]); \
return; \
} else if (!key) { \
_bson_json_read_set_error (reader, \
"Invalid read of %s without key in state %s", \
(_type), \
read_state_names[bson->read_state]); \
return; \
}
#define HANDLE_OPTION(_key, _type, _state) \
(len == strlen (_key) && strncmp ((const char *) val, (_key), len) == 0) \
{ \
if (bson->bson_type && bson->bson_type != (_type)) { \
_bson_json_read_set_error (reader, \
"Invalid key \"%s\". Looking for values " \
"for type \"%s\", got \"%s\"", \
(_key), \
_bson_json_type_name (bson->bson_type), \
_bson_json_type_name (_type)); \
return; \
} \
bson->bson_type = (_type); \
bson->bson_state = (_state); \
}
static void
_bson_json_read_set_error (bson_json_reader_t *reader, const char *fmt, ...)
BSON_GNUC_PRINTF (2, 3);
static void
_bson_json_read_set_error (bson_json_reader_t *reader, /* IN */
const char *fmt, /* IN */
...)
{
va_list ap;
if (reader->error) {
reader->error->domain = BSON_ERROR_JSON;
reader->error->code = BSON_JSON_ERROR_READ_INVALID_PARAM;
va_start (ap, fmt);
bson_vsnprintf (
reader->error->message, sizeof reader->error->message, fmt, ap);
va_end (ap);
reader->error->message[sizeof reader->error->message - 1] = '\0';
}
reader->bson.read_state = BSON_JSON_ERROR;
jsonsl_stop (reader->json);
}
static void
_bson_json_read_corrupt (bson_json_reader_t *reader, const char *fmt, ...)
BSON_GNUC_PRINTF (2, 3);
static void
_bson_json_read_corrupt (bson_json_reader_t *reader, /* IN */
const char *fmt, /* IN */
...)
{
va_list ap;
if (reader->error) {
reader->error->domain = BSON_ERROR_JSON;
reader->error->code = BSON_JSON_ERROR_READ_CORRUPT_JS;
va_start (ap, fmt);
bson_vsnprintf (
reader->error->message, sizeof reader->error->message, fmt, ap);
va_end (ap);
reader->error->message[sizeof reader->error->message - 1] = '\0';
}
reader->bson.read_state = BSON_JSON_ERROR;
jsonsl_stop (reader->json);
}
static void
_bson_json_buf_ensure (bson_json_buf_t *buf, /* IN */
size_t len) /* IN */
{
if (buf->n_bytes < len) {
bson_free (buf->buf);
buf->n_bytes = bson_next_power_of_two (len);
buf->buf = bson_malloc (buf->n_bytes);
}
}
static void
_bson_json_buf_set (bson_json_buf_t *buf, const void *from, size_t len)
{
_bson_json_buf_ensure (buf, len + 1);
memcpy (buf->buf, from, len);
buf->buf[len] = '\0';
buf->len = len;
}
static void
_bson_json_buf_append (bson_json_buf_t *buf, const void *from, size_t len)
{
size_t len_with_null = len + 1;
if (buf->len == 0) {
_bson_json_buf_ensure (buf, len_with_null);
} else if (buf->n_bytes < buf->len + len_with_null) {
buf->n_bytes = bson_next_power_of_two (buf->len + len_with_null);
buf->buf = bson_realloc (buf->buf, buf->n_bytes);
}
memcpy (buf->buf + buf->len, from, len);
buf->len += len;
buf->buf[buf->len] = '\0';
}
static const char *
_bson_json_type_name (bson_type_t type)
{
switch (type) {
case BSON_TYPE_EOD:
return "end of document";
case BSON_TYPE_DOUBLE:
return "double";
case BSON_TYPE_UTF8:
return "utf-8";
case BSON_TYPE_DOCUMENT:
return "document";
case BSON_TYPE_ARRAY:
return "array";
case BSON_TYPE_BINARY:
return "binary";
case BSON_TYPE_UNDEFINED:
return "undefined";
case BSON_TYPE_OID:
return "objectid";
case BSON_TYPE_BOOL:
return "bool";
case BSON_TYPE_DATE_TIME:
return "datetime";
case BSON_TYPE_NULL:
return "null";
case BSON_TYPE_REGEX:
return "regex";
case BSON_TYPE_DBPOINTER:
return "dbpointer";
case BSON_TYPE_CODE:
return "code";
case BSON_TYPE_SYMBOL:
return "symbol";
case BSON_TYPE_CODEWSCOPE:
return "code with scope";
case BSON_TYPE_INT32:
return "int32";
case BSON_TYPE_TIMESTAMP:
return "timestamp";
case BSON_TYPE_INT64:
return "int64";
case BSON_TYPE_DECIMAL128:
return "decimal128";
case BSON_TYPE_MAXKEY:
return "maxkey";
case BSON_TYPE_MINKEY:
return "minkey";
default:
return "";
}
}
static void
_bson_json_read_fixup_key (bson_json_reader_bson_t *bson) /* IN */
{
bson_json_read_state_t rs = bson->read_state;
if (bson->n >= 0 && STACK_IS_ARRAY && rs == BSON_JSON_REGULAR) {
_bson_json_buf_ensure (&bson->key_buf, 12);
bson->key_buf.len = bson_uint32_to_string (
STACK_I, &bson->key, (char *) bson->key_buf.buf, 12);
STACK_I++;
}
}
static void
_bson_json_read_null (bson_json_reader_t *reader)
{
BASIC_CB_PREAMBLE;
BASIC_CB_BAIL_IF_NOT_NORMAL ("null");
bson_append_null (STACK_BSON_CHILD, key, (int) len);
}
static void
_bson_json_read_boolean (bson_json_reader_t *reader, /* IN */
int val) /* IN */
{
BASIC_CB_PREAMBLE;
if (bson->read_state == BSON_JSON_IN_BSON_TYPE &&
bson->bson_state == BSON_JSON_LF_UNDEFINED) {
bson->bson_type_data.undefined.has_undefined = true;
return;
}
BASIC_CB_BAIL_IF_NOT_NORMAL ("boolean");
bson_append_bool (STACK_BSON_CHILD, key, (int) len, val);
}
/* sign is -1 or 1 */
static void
_bson_json_read_integer (bson_json_reader_t *reader, uint64_t val, int64_t sign)
{
bson_json_read_state_t rs;
bson_json_read_bson_state_t bs;
BASIC_CB_PREAMBLE;
if (sign == 1 && val > INT64_MAX) {
_bson_json_read_set_error (
reader, "Number \"%" PRIu64 "\" is out of range", val);
return;
} else if (sign == -1 && val > ((uint64_t) INT64_MAX + 1)) {
_bson_json_read_set_error (
reader, "Number \"-%" PRIu64 "\" is out of range", val);
return;
}
rs = bson->read_state;
bs = bson->bson_state;
if (rs == BSON_JSON_REGULAR) {
BASIC_CB_BAIL_IF_NOT_NORMAL ("integer");
if (val <= INT32_MAX || (sign == -1 && val <= (uint64_t) INT32_MAX + 1)) {
bson_append_int32 (
STACK_BSON_CHILD, key, (int) len, (int) (val * sign));
} else if (sign == -1) {
bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) -val);
} else {
bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) val);
}
} else if (rs == BSON_JSON_IN_BSON_TYPE ||
rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
switch (bs) {
case BSON_JSON_LF_DATE:
bson->bson_type_data.date.has_date = true;
bson->bson_type_data.date.date = sign * val;
break;
case BSON_JSON_LF_TIMESTAMP_T:
if (sign == -1) {
_bson_json_read_set_error (
reader, "Invalid timestamp value: \"-%" PRIu64 "\"", val);
return;
}
bson->bson_type_data.timestamp.has_t = true;
bson->bson_type_data.timestamp.t = (uint32_t) val;
break;
case BSON_JSON_LF_TIMESTAMP_I:
if (sign == -1) {
_bson_json_read_set_error (
reader, "Invalid timestamp value: \"-%" PRIu64 "\"", val);
return;
}
bson->bson_type_data.timestamp.has_i = true;
bson->bson_type_data.timestamp.i = (uint32_t) val;
break;
case BSON_JSON_LF_MINKEY:
if (sign == -1) {
_bson_json_read_set_error (
reader, "Invalid MinKey value: \"-%" PRIu64 "\"", val);
return;
} else if (val != 1) {
_bson_json_read_set_error (
reader, "Invalid MinKey value: \"%" PRIu64 "\"", val);
}
bson->bson_type_data.minkey.has_minkey = true;
break;
case BSON_JSON_LF_MAXKEY:
if (sign == -1) {
_bson_json_read_set_error (
reader, "Invalid MinKey value: \"-%" PRIu64 "\"", val);
return;
} else if (val != 1) {
_bson_json_read_set_error (
reader, "Invalid MinKey value: \"%" PRIu64 "\"", val);
}
bson->bson_type_data.maxkey.has_maxkey = true;
break;
case BSON_JSON_LF_INT32:
case BSON_JSON_LF_INT64:
_bson_json_read_set_error (
reader,
"Invalid state for integer read: %s, "
"expected number as quoted string like \"123\"",
bson_state_names[bs]);
break;
case BSON_JSON_LF_REGEX:
case BSON_JSON_LF_OPTIONS:
case BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN:
case BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS:
case BSON_JSON_LF_CODE:
case BSON_JSON_LF_SCOPE:
case BSON_JSON_LF_OID:
case BSON_JSON_LF_BINARY:
case BSON_JSON_LF_TYPE:
case BSON_JSON_LF_UNDEFINED:
case BSON_JSON_LF_DOUBLE:
case BSON_JSON_LF_DECIMAL128:
case BSON_JSON_LF_DBPOINTER:
case BSON_JSON_LF_SYMBOL:
case BSON_JSON_LF_DBREF:
default:
_bson_json_read_set_error (reader,
"Unexpected integer %s%" PRIu64
" in type \"%s\"",
sign == -1 ? "-" : "",
val,
_bson_json_type_name (bson->bson_type));
}
} else {
_bson_json_read_set_error (reader,
"Unexpected integer %s%" PRIu64
" in state \"%s\"",
sign == -1 ? "-" : "",
val,
read_state_names[rs]);
}
}
static bool
_bson_json_parse_double (bson_json_reader_t *reader,
const char *val,
size_t vlen,
double *d)
{
errno = 0;
*d = strtod (val, NULL);
#ifdef _MSC_VER
/* Microsoft's strtod parses "NaN", "Infinity", "-Infinity" as 0 */
if (*d == 0.0) {
if (!_strnicmp (val, "nan", vlen)) {
#ifdef NAN
*d = NAN;
#else
/* Visual Studio 2010 doesn't define NAN or INFINITY
* https://msdn.microsoft.com/en-us/library/w22adx1s(v=vs.100).aspx */
unsigned long nan[2] = {0xffffffff, 0x7fffffff};
*d = *(double *) nan;
#endif
return true;
} else if (!_strnicmp (val, "infinity", vlen)) {
#ifdef INFINITY
*d = INFINITY;
#else
unsigned long inf[2] = {0x00000000, 0x7ff00000};
*d = *(double *) inf;
#endif
return true;
} else if (!_strnicmp (val, "-infinity", vlen)) {
#ifdef INFINITY
*d = -INFINITY;
#else
unsigned long inf[2] = {0x00000000, 0xfff00000};
*d = *(double *) inf;
#endif
return true;
}
}
if ((*d == HUGE_VAL || *d == -HUGE_VAL) && errno == ERANGE) {
_bson_json_read_set_error (
reader, "Number \"%.*s\" is out of range", (int) vlen, val);
return false;
}
#else
/* not MSVC - set err on overflow, but avoid err for infinity */
if ((*d == HUGE_VAL || *d == -HUGE_VAL) && errno == ERANGE &&
strncasecmp (val, "infinity", vlen) &&
strncasecmp (val, "-infinity", vlen)) {
_bson_json_read_set_error (
reader, "Number \"%.*s\" is out of range", (int) vlen, val);
return false;
}
#endif /* _MSC_VER */
return true;
}
static void
_bson_json_read_double (bson_json_reader_t *reader, /* IN */
double val) /* IN */
{
BASIC_CB_PREAMBLE;
BASIC_CB_BAIL_IF_NOT_NORMAL ("double");
if (!bson_append_double (STACK_BSON_CHILD, key, (int) len, val)) {
_bson_json_read_set_error (reader, "Cannot append double value %g", val);
}
}
static bool
_bson_json_read_int64_or_set_error (bson_json_reader_t *reader, /* IN */
const unsigned char *val, /* IN */
size_t vlen, /* IN */
int64_t *v64) /* OUT */
{
bson_json_reader_bson_t *bson = &reader->bson;
char *endptr = NULL;
_bson_json_read_fixup_key (bson);
errno = 0;
*v64 = bson_ascii_strtoll ((const char *) val, &endptr, 10);
if (((*v64 == INT64_MIN) || (*v64 == INT64_MAX)) && (errno == ERANGE)) {
_bson_json_read_set_error (reader, "Number \"%s\" is out of range", val);
return false;
}
if (endptr != ((const char *) val + vlen)) {
_bson_json_read_set_error (reader, "Number \"%s\" is invalid", val);
return false;
}
return true;
}
/* parse a value for "base64", "subType" or legacy "$binary" or "$type" */
static void
_bson_json_parse_binary_elem (bson_json_reader_t *reader,
const char *val_w_null,
size_t vlen)
{
bson_json_read_bson_state_t bs;
bson_json_bson_data_t *data;
int binary_len;
BASIC_CB_PREAMBLE;
bs = bson->bson_state;
data = &bson->bson_type_data;
if (bs == BSON_JSON_LF_BINARY) {
data->binary.has_binary = true;
- binary_len = bson_b64_pton (val_w_null, NULL, 0);
+ binary_len = COMMON_PREFIX (bson_b64_pton (val_w_null, NULL, 0));
if (binary_len < 0) {
_bson_json_read_set_error (
reader,
"Invalid input string \"%s\", looking for base64-encoded binary",
val_w_null);
}
_bson_json_buf_ensure (&bson->bson_type_buf[0], (size_t) binary_len + 1);
- if (bson_b64_pton (val_w_null,
- bson->bson_type_buf[0].buf,
- (size_t) binary_len + 1) < 0) {
+ if (COMMON_PREFIX (bson_b64_pton (val_w_null,
+ bson->bson_type_buf[0].buf,
+ (size_t) binary_len + 1) < 0)) {
_bson_json_read_set_error (
reader,
"Invalid input string \"%s\", looking for base64-encoded binary",
val_w_null);
}
bson->bson_type_buf[0].len = (size_t) binary_len;
} else if (bs == BSON_JSON_LF_TYPE) {
data->binary.has_subtype = true;
if (SSCANF (val_w_null, "%02x", &data->binary.type) != 1) {
if (!data->binary.is_legacy || data->binary.has_binary) {
/* misformatted subtype, like {$binary: {base64: "", subType: "x"}},
* or legacy {$binary: "", $type: "x"} */
_bson_json_read_set_error (
reader,
"Invalid input string \"%s\", looking for binary subtype",
val_w_null);
} else {
/* actually a query operator: {x: {$type: "array"}}*/
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DOC (bson_append_document_begin (
STACK_BSON_PARENT, key, (int) len, STACK_BSON_CHILD));
bson_append_utf8 (STACK_BSON_CHILD,
"$type",
5,
(const char *) val_w_null,
(int) vlen);
}
}
}
}
static void
_bson_json_read_string (bson_json_reader_t *reader, /* IN */
const unsigned char *val, /* IN */
size_t vlen) /* IN */
{
bson_json_read_state_t rs;
bson_json_read_bson_state_t bs;
BASIC_CB_PREAMBLE;
rs = bson->read_state;
bs = bson->bson_state;
if (!bson_utf8_validate ((const char *) val, vlen, true /*allow null*/)) {
_bson_json_read_corrupt (reader, "invalid bytes in UTF8 string");
return;
}
if (rs == BSON_JSON_REGULAR) {
BASIC_CB_BAIL_IF_NOT_NORMAL ("string");
bson_append_utf8 (
STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen);
} else if (rs == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP ||
rs == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
_bson_json_read_set_error (reader,
"Invalid read of \"%s\" in state \"%s\"",
val,
read_state_names[rs]);
} else if (rs == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) {
const char *val_w_null;
_bson_json_buf_set (&bson->bson_type_buf[2], val, vlen);
val_w_null = (const char *) bson->bson_type_buf[2].buf;
_bson_json_parse_binary_elem (reader, val_w_null, vlen);
} else if (rs == BSON_JSON_IN_BSON_TYPE ||
rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES ||
rs == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES ||
rs == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
const char *val_w_null;
_bson_json_buf_set (&bson->bson_type_buf[2], val, vlen);
val_w_null = (const char *) bson->bson_type_buf[2].buf;
switch (bs) {
case BSON_JSON_LF_REGEX:
bson->bson_type_data.regex.is_legacy = true;
/* FALL THROUGH */
case BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN:
bson->bson_type_data.regex.has_pattern = true;
_bson_json_buf_set (&bson->bson_type_buf[0], val, vlen);
break;
case BSON_JSON_LF_OPTIONS:
bson->bson_type_data.regex.is_legacy = true;
/* FALL THROUGH */
case BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS:
bson->bson_type_data.regex.has_options = true;
_bson_json_buf_set (&bson->bson_type_buf[1], val, vlen);
break;
case BSON_JSON_LF_OID:
if (vlen != 24) {
goto BAD_PARSE;
}
bson->bson_type_data.oid.has_oid = true;
bson_oid_init_from_string (&bson->bson_type_data.oid.oid, val_w_null);
break;
case BSON_JSON_LF_BINARY:
case BSON_JSON_LF_TYPE:
bson->bson_type_data.binary.is_legacy = true;
_bson_json_parse_binary_elem (reader, val_w_null, vlen);
break;
case BSON_JSON_LF_INT32: {
int64_t v64;
if (!_bson_json_read_int64_or_set_error (reader, val, vlen, &v64)) {
/* the error is set, return and let the reader exit */
return;
}
if (v64 < INT32_MIN || v64 > INT32_MAX) {
goto BAD_PARSE;
}
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
bson->bson_type_data.v_int32.value = (int32_t) v64;
} else {
goto BAD_PARSE;
}
} break;
case BSON_JSON_LF_INT64: {
int64_t v64;
if (!_bson_json_read_int64_or_set_error (reader, val, vlen, &v64)) {
/* the error is set, return and let the reader exit */
return;
}
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
bson->bson_type_data.v_int64.value = v64;
} else if (bson->read_state ==
BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
bson->bson_type_data.date.has_date = true;
bson->bson_type_data.date.date = v64;
} else {
goto BAD_PARSE;
}
} break;
case BSON_JSON_LF_DOUBLE: {
if (!_bson_json_parse_double (reader,
(const char *) val,
vlen,
&bson->bson_type_data.v_double.value)) {
/* the error is set, return and let the reader exit */
return;
}
} break;
case BSON_JSON_LF_DATE: {
int64_t v64;
if (!_bson_iso8601_date_parse (
(char *) val, (int) vlen, &v64, reader->error)) {
jsonsl_stop (reader->json);
} else {
bson->bson_type_data.date.has_date = true;
bson->bson_type_data.date.date = v64;
}
} break;
case BSON_JSON_LF_DECIMAL128: {
bson_decimal128_t decimal128;
bson_decimal128_from_string (val_w_null, &decimal128);
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
bson->bson_type_data.v_decimal128.value = decimal128;
} else {
goto BAD_PARSE;
}
} break;
case BSON_JSON_LF_CODE:
_bson_json_buf_set (&bson->code_data.code_buf, val, vlen);
break;
case BSON_JSON_LF_SYMBOL:
bson_append_symbol (
STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen);
break;
case BSON_JSON_LF_DBREF:
/* the "$ref" of a {$ref: "...", $id: ... }, append normally */
bson_append_utf8 (
STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen);
bson->read_state = BSON_JSON_REGULAR;
break;
case BSON_JSON_LF_SCOPE:
case BSON_JSON_LF_TIMESTAMP_T:
case BSON_JSON_LF_TIMESTAMP_I:
case BSON_JSON_LF_UNDEFINED:
case BSON_JSON_LF_MINKEY:
case BSON_JSON_LF_MAXKEY:
case BSON_JSON_LF_DBPOINTER:
default:
goto BAD_PARSE;
}
return;
BAD_PARSE:
_bson_json_read_set_error (reader,
"Invalid input string \"%s\", looking for %s",
val_w_null,
bson_state_names[bs]);
} else {
_bson_json_read_set_error (
reader, "Invalid state to look for string: %s", read_state_names[rs]);
}
}
static void
_bson_json_read_start_map (bson_json_reader_t *reader) /* IN */
{
BASIC_CB_PREAMBLE;
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
if (bson->bson_state == BSON_JSON_LF_DATE) {
bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG;
} else if (bson->bson_state == BSON_JSON_LF_BINARY) {
bson->read_state = BSON_JSON_IN_BSON_TYPE_BINARY_VALUES;
} else if (bson->bson_state == BSON_JSON_LF_TYPE) {
/* special case, we started parsing {$type: {$numberInt: "2"}} and we
* expected a legacy Binary format. now we see the second "{", so
* backtrack and parse $type query operator. */
bson->read_state = BSON_JSON_IN_START_MAP;
STACK_PUSH_DOC (bson_append_document_begin (
STACK_BSON_PARENT, key, len, STACK_BSON_CHILD));
_bson_json_save_map_key (bson, (const uint8_t *) "$type", 5);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP) {
bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP) {
bson->read_state = BSON_JSON_IN_SCOPE;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
bson->read_state = BSON_JSON_IN_DBPOINTER;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_STARTMAP) {
bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_VALUES;
} else {
bson->read_state = BSON_JSON_IN_START_MAP;
}
/* silence some warnings */
(void) len;
(void) key;
}
static bool
_is_known_key (const char *key, size_t len)
{
bool ret;
#define IS_KEY(k) (len == strlen (k) && (0 == memcmp (k, key, len)))
ret = (IS_KEY ("$regularExpression") || IS_KEY ("$regex") ||
IS_KEY ("$options") || IS_KEY ("$code") || IS_KEY ("$scope") ||
IS_KEY ("$oid") || IS_KEY ("$binary") || IS_KEY ("$type") ||
IS_KEY ("$date") || IS_KEY ("$undefined") || IS_KEY ("$maxKey") ||
IS_KEY ("$minKey") || IS_KEY ("$timestamp") ||
IS_KEY ("$numberInt") || IS_KEY ("$numberLong") ||
IS_KEY ("$numberDouble") || IS_KEY ("$numberDecimal") ||
IS_KEY ("$numberInt") || IS_KEY ("$numberLong") ||
IS_KEY ("$numberDouble") || IS_KEY ("$numberDecimal") ||
IS_KEY ("$dbPointer") || IS_KEY ("$symbol"));
#undef IS_KEY
return ret;
}
static void
_bson_json_save_map_key (bson_json_reader_bson_t *bson,
const uint8_t *val,
size_t len)
{
_bson_json_buf_set (&bson->key_buf, val, len);
bson->key = (const char *) bson->key_buf.buf;
}
static void
_bson_json_read_code_or_scope_key (bson_json_reader_bson_t *bson,
bool is_scope,
const uint8_t *val,
size_t len)
{
bson_json_code_t *code = &bson->code_data;
if (code->in_scope) {
/* we're reading something weirdly nested, e.g. we just read "$code" in
* "$scope: {x: {$code: {}}}". just create the subdoc within the scope. */
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
bson->key,
(int) bson->key_buf.len,
STACK_BSON_CHILD));
_bson_json_save_map_key (bson, val, len);
} else {
if (!bson->code_data.key_buf.len) {
/* save the key, e.g. {"key": {"$code": "return x", "$scope":{"x":1}}},
* in case it is overwritten while parsing scope sub-object */
_bson_json_buf_set (
&bson->code_data.key_buf, bson->key_buf.buf, bson->key_buf.len);
}
if (is_scope) {
bson->bson_type = BSON_TYPE_CODEWSCOPE;
bson->read_state = BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP;
bson->bson_state = BSON_JSON_LF_SCOPE;
bson->code_data.has_scope = true;
} else {
bson->bson_type = BSON_TYPE_CODE;
bson->bson_state = BSON_JSON_LF_CODE;
bson->code_data.has_code = true;
}
}
}
static void
_bson_json_bad_key_in_type (bson_json_reader_t *reader, /* IN */
const uint8_t *val) /* IN */
{
bson_json_reader_bson_t *bson = &reader->bson;
_bson_json_read_set_error (
reader,
"Invalid key \"%s\". Looking for values for type \"%s\"",
val,
_bson_json_type_name (bson->bson_type));
}
static void
_bson_json_read_map_key (bson_json_reader_t *reader, /* IN */
const uint8_t *val, /* IN */
size_t len) /* IN */
{
bson_json_reader_bson_t *bson = &reader->bson;
if (!bson_utf8_validate ((const char *) val, len, true /* allow null */)) {
_bson_json_read_corrupt (reader, "invalid bytes in UTF8 string");
return;
}
if (bson->read_state == BSON_JSON_IN_START_MAP) {
if (len > 0 && val[0] == '$' && _is_known_key ((const char *) val, len) &&
bson->n >= 0 /* key is in subdocument */) {
bson->read_state = BSON_JSON_IN_BSON_TYPE;
bson->bson_type = (bson_type_t) 0;
memset (&bson->bson_type_data, 0, sizeof bson->bson_type_data);
} else {
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
bson->key,
(int) bson->key_buf.len,
STACK_BSON_CHILD));
}
} else if (bson->read_state == BSON_JSON_IN_SCOPE) {
/* we've read "key" in {$code: "", $scope: {key: ""}}*/
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_SCOPE;
_bson_json_save_map_key (bson, val, len);
} else if (bson->read_state == BSON_JSON_IN_DBPOINTER) {
/* we've read "$ref" or "$id" in {$dbPointer: {$ref: ..., $id: ...}} */
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DBPOINTER;
_bson_json_save_map_key (bson, val, len);
}
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
if
HANDLE_OPTION ("$regex", BSON_TYPE_REGEX, BSON_JSON_LF_REGEX)
else if
HANDLE_OPTION ("$options", BSON_TYPE_REGEX, BSON_JSON_LF_OPTIONS)
else if
HANDLE_OPTION ("$oid", BSON_TYPE_OID, BSON_JSON_LF_OID)
else if
HANDLE_OPTION ("$binary", BSON_TYPE_BINARY, BSON_JSON_LF_BINARY)
else if
HANDLE_OPTION ("$type", BSON_TYPE_BINARY, BSON_JSON_LF_TYPE)
else if
HANDLE_OPTION ("$date", BSON_TYPE_DATE_TIME, BSON_JSON_LF_DATE)
else if
HANDLE_OPTION (
"$undefined", BSON_TYPE_UNDEFINED, BSON_JSON_LF_UNDEFINED)
else if
HANDLE_OPTION ("$minKey", BSON_TYPE_MINKEY, BSON_JSON_LF_MINKEY)
else if
HANDLE_OPTION ("$maxKey", BSON_TYPE_MAXKEY, BSON_JSON_LF_MAXKEY)
else if
HANDLE_OPTION ("$numberInt", BSON_TYPE_INT32, BSON_JSON_LF_INT32)
else if
HANDLE_OPTION ("$numberLong", BSON_TYPE_INT64, BSON_JSON_LF_INT64)
else if
HANDLE_OPTION ("$numberDouble", BSON_TYPE_DOUBLE, BSON_JSON_LF_DOUBLE)
else if
HANDLE_OPTION ("$symbol", BSON_TYPE_SYMBOL, BSON_JSON_LF_SYMBOL)
else if
HANDLE_OPTION (
"$numberDecimal", BSON_TYPE_DECIMAL128, BSON_JSON_LF_DECIMAL128)
else if (!strcmp ("$timestamp", (const char *) val)) {
bson->bson_type = BSON_TYPE_TIMESTAMP;
bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP;
} else if (!strcmp ("$regularExpression", (const char *) val)) {
bson->bson_type = BSON_TYPE_REGEX;
bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_STARTMAP;
} else if (!strcmp ("$dbPointer", (const char *) val)) {
/* start parsing "key": {"$dbPointer": {...}}, save "key" for later */
_bson_json_buf_set (
&bson->dbpointer_key, bson->key_buf.buf, bson->key_buf.len);
bson->bson_type = BSON_TYPE_DBPOINTER;
bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP;
} else if (!strcmp ("$code", (const char *) val)) {
_bson_json_read_code_or_scope_key (
bson, false /* is_scope */, val, len);
} else if (!strcmp ("$scope", (const char *) val)) {
_bson_json_read_code_or_scope_key (
bson, true /* is_scope */, val, len);
} else {
_bson_json_bad_key_in_type (reader, val);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
if
HANDLE_OPTION ("$numberLong", BSON_TYPE_DATE_TIME, BSON_JSON_LF_INT64)
else {
_bson_json_bad_key_in_type (reader, val);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
if
HANDLE_OPTION ("t", BSON_TYPE_TIMESTAMP, BSON_JSON_LF_TIMESTAMP_T)
else if
HANDLE_OPTION ("i", BSON_TYPE_TIMESTAMP, BSON_JSON_LF_TIMESTAMP_I)
else {
_bson_json_bad_key_in_type (reader, val);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES) {
if
HANDLE_OPTION (
"pattern", BSON_TYPE_REGEX, BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN)
else if
HANDLE_OPTION (
"options", BSON_TYPE_REGEX, BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS)
else {
_bson_json_bad_key_in_type (reader, val);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) {
if
HANDLE_OPTION ("base64", BSON_TYPE_BINARY, BSON_JSON_LF_BINARY)
else if
HANDLE_OPTION ("subType", BSON_TYPE_BINARY, BSON_JSON_LF_TYPE)
else {
_bson_json_bad_key_in_type (reader, val);
}
} else {
_bson_json_save_map_key (bson, val, len);
/* in x: {$ref: "collection", $id: {$oid: "..."}, $db: "..." } */
if (bson->n > 0) {
if (!strcmp ("$ref", (const char *) val)) {
STACK_HAS_REF = true;
bson->read_state = BSON_JSON_IN_BSON_TYPE;
bson->bson_state = BSON_JSON_LF_DBREF;
} else if (!strcmp ("$id", (const char *) val)) {
STACK_HAS_ID = true;
} else if (!strcmp ("$db", (const char *) val)) {
bson->read_state = BSON_JSON_IN_BSON_TYPE;
bson->bson_state = BSON_JSON_LF_DBREF;
}
}
}
}
static void
_bson_json_read_append_binary (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
bson_json_bson_data_t *data = &bson->bson_type_data;
if (data->binary.is_legacy) {
if (!data->binary.has_binary) {
_bson_json_read_set_error (
reader,
"Missing \"$binary\" after \"$type\" reading type \"binary\"");
return;
} else if (!data->binary.has_subtype) {
_bson_json_read_set_error (
reader,
"Missing \"$type\" after \"$binary\" reading type \"binary\"");
return;
}
} else {
if (!data->binary.has_binary) {
_bson_json_read_set_error (
reader,
"Missing \"base64\" after \"subType\" reading type \"binary\"");
return;
} else if (!data->binary.has_subtype) {
_bson_json_read_set_error (
reader,
"Missing \"subType\" after \"base64\" reading type \"binary\"");
return;
}
}
if (!bson_append_binary (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
data->binary.type,
bson->bson_type_buf[0].buf,
(uint32_t) bson->bson_type_buf[0].len)) {
_bson_json_read_set_error (reader, "Error storing binary data");
}
}
static void
_bson_json_read_append_regex (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
bson_json_bson_data_t *data = &bson->bson_type_data;
if (data->regex.is_legacy) {
if (!data->regex.has_pattern) {
_bson_json_read_set_error (reader,
"Missing \"$regex\" after \"$options\"");
return;
}
if (!data->regex.has_options) {
_bson_json_read_set_error (reader,
"Missing \"$options\" after \"$regex\"");
return;
}
} else if (!data->regex.has_pattern) {
_bson_json_read_set_error (
reader, "Missing \"pattern\" after \"options\" in regular expression");
return;
} else if (!data->regex.has_options) {
_bson_json_read_set_error (
reader, "Missing \"options\" after \"pattern\" in regular expression");
return;
}
if (!bson_append_regex (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
(char *) bson->bson_type_buf[0].buf,
(char *) bson->bson_type_buf[1].buf)) {
_bson_json_read_set_error (reader, "Error storing regex");
}
}
static void
_bson_json_read_append_code (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
bson_json_code_t *code_data;
char *code = NULL;
bson_t *scope = NULL;
bool r;
code_data = &bson->code_data;
BSON_ASSERT (!code_data->in_scope);
if (!code_data->has_code) {
_bson_json_read_set_error (reader, "Missing $code after $scope");
return;
}
code = (char *) code_data->code_buf.buf;
if (code_data->has_scope) {
scope = STACK_BSON (1);
}
/* creates BSON "code" elem, or "code with scope" if scope is not NULL */
r = bson_append_code_with_scope (STACK_BSON_CHILD,
(const char *) code_data->key_buf.buf,
(int) code_data->key_buf.len,
code,
scope);
if (!r) {
_bson_json_read_set_error (reader, "Error storing Javascript code");
}
/* keep the buffer but truncate it */
code_data->key_buf.len = 0;
code_data->has_code = code_data->has_scope = false;
}
static void
_bson_json_read_append_dbpointer (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
bson_t *db_pointer;
bson_iter_t iter;
const char *ns = NULL;
const bson_oid_t *oid = NULL;
bool r;
BSON_ASSERT (reader->bson.dbpointer_key.buf);
db_pointer = STACK_BSON (1);
if (!bson_iter_init (&iter, db_pointer)) {
_bson_json_read_set_error (reader, "Error storing DBPointer");
return;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "$id")) {
if (!BSON_ITER_HOLDS_OID (&iter)) {
_bson_json_read_set_error (
reader, "$dbPointer.$id must be like {\"$oid\": ...\"}");
return;
}
oid = bson_iter_oid (&iter);
} else if (!strcmp (bson_iter_key (&iter), "$ref")) {
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
_bson_json_read_set_error (
reader,
"$dbPointer.$ref must be a string like \"db.collection\"");
return;
}
ns = bson_iter_utf8 (&iter, NULL);
} else {
_bson_json_read_set_error (reader,
"$dbPointer contains invalid key: \"%s\"",
bson_iter_key (&iter));
return;
}
}
if (!oid || !ns) {
_bson_json_read_set_error (reader,
"$dbPointer requires both $id and $ref");
return;
}
r = bson_append_dbpointer (STACK_BSON_CHILD,
(char *) reader->bson.dbpointer_key.buf,
(int) reader->bson.dbpointer_key.len,
ns,
oid);
if (!r) {
_bson_json_read_set_error (reader, "Error storing DBPointer");
}
}
static void
_bson_json_read_append_oid (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
if (!bson_append_oid (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
&bson->bson_type_data.oid.oid)) {
_bson_json_read_set_error (reader, "Error storing ObjectId");
}
}
static void
_bson_json_read_append_date_time (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
if (!bson_append_date_time (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.date.date)) {
_bson_json_read_set_error (reader, "Error storing datetime");
}
}
static void
_bson_json_read_append_timestamp (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
if (!bson->bson_type_data.timestamp.has_t) {
_bson_json_read_set_error (
reader, "Missing t after $timestamp in BSON_TYPE_TIMESTAMP");
return;
} else if (!bson->bson_type_data.timestamp.has_i) {
_bson_json_read_set_error (
reader, "Missing i after $timestamp in BSON_TYPE_TIMESTAMP");
return;
}
bson_append_timestamp (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.timestamp.t,
bson->bson_type_data.timestamp.i);
}
static void
_bad_extended_json (bson_json_reader_t *reader)
{
_bson_json_read_corrupt (reader, "Invalid MongoDB extended JSON");
}
static void
_bson_json_read_end_map (bson_json_reader_t *reader) /* IN */
{
bson_json_reader_bson_t *bson = &reader->bson;
bool r = true;
if (bson->read_state == BSON_JSON_IN_START_MAP) {
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
bson->key,
(int) bson->key_buf.len,
STACK_BSON_CHILD));
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP) {
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_SCOPE;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
/* we've read last "}" in "{$dbPointer: {$id: ..., $ref: ...}}" */
_bson_json_read_append_dbpointer (reader, bson);
bson->read_state = BSON_JSON_REGULAR;
return;
}
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
if (!bson->key) {
/* invalid, like {$numberLong: "1"} at the document top level */
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_REGULAR;
switch (bson->bson_type) {
case BSON_TYPE_REGEX:
_bson_json_read_append_regex (reader, bson);
break;
case BSON_TYPE_CODE:
case BSON_TYPE_CODEWSCOPE:
/* we've read the closing "}" in "{$code: ..., $scope: ...}" */
_bson_json_read_append_code (reader, bson);
break;
case BSON_TYPE_OID:
_bson_json_read_append_oid (reader, bson);
break;
case BSON_TYPE_BINARY:
_bson_json_read_append_binary (reader, bson);
break;
case BSON_TYPE_DATE_TIME:
_bson_json_read_append_date_time (reader, bson);
break;
case BSON_TYPE_UNDEFINED:
r = bson_append_undefined (
STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
break;
case BSON_TYPE_MINKEY:
r = bson_append_minkey (
STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
break;
case BSON_TYPE_MAXKEY:
r = bson_append_maxkey (
STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
break;
case BSON_TYPE_INT32:
r = bson_append_int32 (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.v_int32.value);
break;
case BSON_TYPE_INT64:
r = bson_append_int64 (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.v_int64.value);
break;
case BSON_TYPE_DOUBLE:
r = bson_append_double (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.v_double.value);
break;
case BSON_TYPE_DECIMAL128:
r = bson_append_decimal128 (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
&bson->bson_type_data.v_decimal128.value);
break;
case BSON_TYPE_DBPOINTER:
/* shouldn't set type to DBPointer unless inside $dbPointer: {...} */
_bson_json_read_set_error (
reader,
"Internal error: shouldn't be in state BSON_TYPE_DBPOINTER");
break;
case BSON_TYPE_SYMBOL:
break;
case BSON_TYPE_EOD:
case BSON_TYPE_UTF8:
case BSON_TYPE_DOCUMENT:
case BSON_TYPE_ARRAY:
case BSON_TYPE_BOOL:
case BSON_TYPE_NULL:
case BSON_TYPE_TIMESTAMP:
default:
_bson_json_read_set_error (
reader,
"Internal error: can't parse JSON wrapper for type \"%s\"",
_bson_json_type_name (bson->bson_type));
break;
}
if (!r) {
_bson_json_read_set_error (
reader,
"Cannot append value at end of JSON object for key %s",
bson->key);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
if (!bson->key) {
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP;
_bson_json_read_append_timestamp (reader, bson);
return;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES) {
if (!bson->key) {
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_ENDMAP;
_bson_json_read_append_regex (reader, bson);
return;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) {
if (!bson->key) {
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_IN_BSON_TYPE_BINARY_ENDMAP;
_bson_json_read_append_binary (reader, bson);
return;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP) {
bson->read_state = BSON_JSON_REGULAR;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_ENDMAP) {
bson->read_state = BSON_JSON_REGULAR;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_ENDMAP) {
bson->read_state = BSON_JSON_REGULAR;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
if (!bson->key) {
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP;
_bson_json_read_append_date_time (reader, bson);
return;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP) {
bson->read_state = BSON_JSON_REGULAR;
} else if (bson->read_state == BSON_JSON_REGULAR) {
if (STACK_IS_SCOPE) {
bson->read_state = BSON_JSON_IN_BSON_TYPE;
bson->bson_type = BSON_TYPE_CODE;
STACK_POP_SCOPE;
} else if (STACK_IS_DBPOINTER) {
bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP;
STACK_POP_DBPOINTER;
} else {
if (STACK_HAS_ID != STACK_HAS_REF) {
_bson_json_read_set_error (
reader, "%s", "DBRef object must have both $ref and $id keys");
}
STACK_POP_DOC (
bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
}
if (bson->n == -1) {
bson->read_state = BSON_JSON_DONE;
}
} else if (bson->read_state == BSON_JSON_IN_SCOPE) {
/* empty $scope */
BSON_ASSERT (bson->code_data.has_scope);
STACK_PUSH_SCOPE;
STACK_POP_SCOPE;
bson->read_state = BSON_JSON_IN_BSON_TYPE;
bson->bson_type = BSON_TYPE_CODE;
} else if (bson->read_state == BSON_JSON_IN_DBPOINTER) {
/* empty $dbPointer??? */
_bson_json_read_set_error (reader, "Empty $dbPointer");
} else {
_bson_json_read_set_error (
reader, "Invalid state \"%s\"", read_state_names[bson->read_state]);
}
}
static void
_bson_json_read_start_array (bson_json_reader_t *reader) /* IN */
{
const char *key;
size_t len;
bson_json_reader_bson_t *bson = &reader->bson;
if (bson->read_state != BSON_JSON_REGULAR) {
_bson_json_read_set_error (reader,
"Invalid read of \"[\" in state \"%s\"",
read_state_names[bson->read_state]);
return;
}
if (bson->n == -1) {
STACK_PUSH_ARRAY (_noop ());
} else {
_bson_json_read_fixup_key (bson);
key = bson->key;
len = bson->key_buf.len;
STACK_PUSH_ARRAY (bson_append_array_begin (
STACK_BSON_PARENT, key, (int) len, STACK_BSON_CHILD));
}
}
static void
_bson_json_read_end_array (bson_json_reader_t *reader) /* IN */
{
bson_json_reader_bson_t *bson = &reader->bson;
if (bson->read_state != BSON_JSON_REGULAR) {
_bson_json_read_set_error (reader,
"Invalid read of \"]\" in state \"%s\"",
read_state_names[bson->read_state]);
return;
}
STACK_POP_ARRAY (
bson_append_array_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
if (bson->n == -1) {
bson->read_state = BSON_JSON_DONE;
}
}
/* put unescaped text in reader->bson.unescaped, or set reader->error.
* json_text has length len and it is not null-terminated. */
static bool
_bson_json_unescape (bson_json_reader_t *reader,
struct jsonsl_state_st *state,
const char *json_text,
ssize_t len)
{
bson_json_reader_bson_t *reader_bson;
jsonsl_error_t err;
reader_bson = &reader->bson;
/* add 1 for NULL */
_bson_json_buf_ensure (&reader_bson->unescaped, (size_t) len + 1);
/* length of unescaped str is always <= len */
reader_bson->unescaped.len = jsonsl_util_unescape (
json_text, (char *) reader_bson->unescaped.buf, (size_t) len, NULL, &err);
if (err != JSONSL_ERROR_SUCCESS) {
bson_set_error (reader->error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_CORRUPT_JS,
"error near position %d: \"%s\"",
(int) state->pos_begin,
jsonsl_strerror (err));
return false;
}
reader_bson->unescaped.buf[reader_bson->unescaped.len] = '\0';
return true;
}
/* read the buffered JSON plus new data, and fill out @len with its length */
static const char *
_get_json_text (jsonsl_t json, /* IN */
struct jsonsl_state_st *state, /* IN */
const char *buf /* IN */,
ssize_t *len /* OUT */)
{
bson_json_reader_t *reader;
ssize_t bytes_available;
reader = (bson_json_reader_t *) json->data;
BSON_ASSERT (state->pos_cur > state->pos_begin);
*len = (ssize_t) (state->pos_cur - state->pos_begin);
bytes_available = buf - json->base;
if (*len <= bytes_available) {
/* read directly from stream, not from saved JSON */
return buf - (size_t) *len;
} else {
/* combine saved text with new data from the jsonsl_t */
ssize_t append = buf - json->base;
if (append > 0) {
_bson_json_buf_append (
&reader->tok_accumulator, buf - append, (size_t) append);
}
return (const char *) reader->tok_accumulator.buf;
}
}
static void
_push_callback (jsonsl_t json,
jsonsl_action_t action,
struct jsonsl_state_st *state,
const char *buf)
{
bson_json_reader_t *reader = (bson_json_reader_t *) json->data;
switch (state->type) {
case JSONSL_T_STRING:
case JSONSL_T_HKEY:
case JSONSL_T_SPECIAL:
case JSONSL_T_UESCAPE:
reader->json_text_pos = state->pos_begin;
break;
case JSONSL_T_OBJECT:
_bson_json_read_start_map (reader);
break;
case JSONSL_T_LIST:
_bson_json_read_start_array (reader);
break;
default:
break;
}
}
static void
_pop_callback (jsonsl_t json,
jsonsl_action_t action,
struct jsonsl_state_st *state,
const char *buf)
{
bson_json_reader_t *reader;
bson_json_reader_bson_t *reader_bson;
ssize_t len;
double d;
const char *obj_text;
reader = (bson_json_reader_t *) json->data;
reader_bson = &reader->bson;
switch (state->type) {
case JSONSL_T_HKEY:
case JSONSL_T_STRING:
obj_text = _get_json_text (json, state, buf, &len);
BSON_ASSERT (obj_text[0] == '"');
/* remove start/end quotes, replace backslash-escapes, null-terminate */
/* you'd think it would be faster to check if state->nescapes > 0 first,
* but tests show no improvement */
if (!_bson_json_unescape (reader, state, obj_text + 1, len - 1)) {
/* reader->error is set */
jsonsl_stop (json);
break;
}
if (state->type == JSONSL_T_HKEY) {
_bson_json_read_map_key (
reader, reader_bson->unescaped.buf, reader_bson->unescaped.len);
} else {
_bson_json_read_string (
reader, reader_bson->unescaped.buf, reader_bson->unescaped.len);
}
break;
case JSONSL_T_OBJECT:
_bson_json_read_end_map (reader);
break;
case JSONSL_T_LIST:
_bson_json_read_end_array (reader);
break;
case JSONSL_T_SPECIAL:
obj_text = _get_json_text (json, state, buf, &len);
if (state->special_flags & JSONSL_SPECIALf_NUMNOINT) {
if (_bson_json_parse_double (reader, obj_text, (size_t) len, &d)) {
_bson_json_read_double (reader, d);
}
} else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
/* jsonsl puts the unsigned value in state->nelem */
_bson_json_read_integer (
reader,
state->nelem,
state->special_flags & JSONSL_SPECIALf_SIGNED ? -1 : 1);
} else if (state->special_flags & JSONSL_SPECIALf_BOOLEAN) {
_bson_json_read_boolean (reader, obj_text[0] == 't' ? 1 : 0);
} else if (state->special_flags & JSONSL_SPECIALf_NULL) {
_bson_json_read_null (reader);
}
break;
default:
break;
}
reader->json_text_pos = -1;
reader->tok_accumulator.len = 0;
}
static int
_error_callback (jsonsl_t json,
jsonsl_error_t err,
struct jsonsl_state_st *state,
char *errat)
{
bson_json_reader_t *reader = (bson_json_reader_t *) json->data;
if (err == JSONSL_ERROR_CANT_INSERT && *errat == '{') {
/* start the next document */
reader->should_reset = true;
reader->advance = errat - json->base;
return 0;
}
bson_set_error (reader->error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_CORRUPT_JS,
"Got parse error at \"%c\", position %d: \"%s\"",
*errat,
(int) json->pos,
jsonsl_strerror (err));
return 0;
}
/*
*--------------------------------------------------------------------------
*
* bson_json_reader_read --
*
* Read the next json document from @reader and write its value
* into @bson. @bson will be allocated as part of this process.
*
* @bson MUST be initialized before calling this function as it
* will not be initialized automatically. The reasoning for this
* is so that you can chain together bson_json_reader_t with
* other components like bson_writer_t.
*
* Returns:
* 1 if successful and data was read.
* 0 if successful and no data was read.
* -1 if there was an error and @error is set.
*
* Side effects:
* @error may be set.
*
*--------------------------------------------------------------------------
*/
int
bson_json_reader_read (bson_json_reader_t *reader, /* IN */
bson_t *bson, /* IN */
bson_error_t *error) /* OUT */
{
bson_json_reader_producer_t *p;
ssize_t start_pos;
ssize_t r;
ssize_t buf_offset;
ssize_t accum;
bson_error_t error_tmp;
int ret = 0;
BSON_ASSERT (reader);
BSON_ASSERT (bson);
p = &reader->producer;
reader->bson.bson = bson;
reader->bson.n = -1;
reader->bson.read_state = BSON_JSON_REGULAR;
reader->error = error ? error : &error_tmp;
memset (reader->error, 0, sizeof (bson_error_t));
for (;;) {
start_pos = reader->json->pos;
if (p->bytes_read > 0) {
/* leftover data from previous JSON doc in the stream */
r = p->bytes_read;
} else {
/* read a chunk of bytes by executing the callback */
r = p->cb (p->data, p->buf, p->buf_size);
}
if (r < 0) {
if (error) {
bson_set_error (error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_CB_FAILURE,
"reader cb failed");
}
ret = -1;
goto cleanup;
} else if (r == 0) {
break;
} else {
ret = 1;
p->bytes_read = (size_t) r;
jsonsl_feed (reader->json, (const jsonsl_char_t *) p->buf, (size_t) r);
if (reader->should_reset) {
/* end of a document */
jsonsl_reset (reader->json);
reader->should_reset = false;
/* advance past already-parsed data */
memmove (p->buf, p->buf + reader->advance, r - reader->advance);
p->bytes_read -= reader->advance;
ret = 1;
goto cleanup;
}
if (reader->error->domain) {
ret = -1;
goto cleanup;
}
/* accumulate a key or string value */
if (reader->json_text_pos != -1) {
if (reader->json_text_pos < reader->json->pos) {
accum = BSON_MIN (reader->json->pos - reader->json_text_pos, r);
/* if this chunk stopped mid-token, buf_offset is how far into
* our current chunk the token begins. */
buf_offset = AT_LEAST_0 (reader->json_text_pos - start_pos);
_bson_json_buf_append (&reader->tok_accumulator,
p->buf + buf_offset,
(size_t) accum);
}
}
p->bytes_read = 0;
}
}
cleanup:
if (ret == 1 && reader->bson.read_state != BSON_JSON_DONE) {
/* data ended in the middle */
_bson_json_read_corrupt (reader, "%s", "Incomplete JSON");
return -1;
}
return ret;
}
bson_json_reader_t *
bson_json_reader_new (void *data, /* IN */
bson_json_reader_cb cb, /* IN */
bson_json_destroy_cb dcb, /* IN */
bool allow_multiple, /* unused */
size_t buf_size) /* IN */
{
bson_json_reader_t *r;
bson_json_reader_producer_t *p;
r = bson_malloc0 (sizeof *r);
r->json = jsonsl_new (STACK_MAX);
r->json->error_callback = _error_callback;
r->json->action_callback_PUSH = _push_callback;
r->json->action_callback_POP = _pop_callback;
r->json->data = r;
r->json_text_pos = -1;
jsonsl_enable_all_callbacks (r->json);
p = &r->producer;
p->data = data;
p->cb = cb;
p->dcb = dcb;
p->buf_size = buf_size ? buf_size : BSON_JSON_DEFAULT_BUF_SIZE;
p->buf = bson_malloc (p->buf_size);
return r;
}
void
bson_json_reader_destroy (bson_json_reader_t *reader) /* IN */
{
int i;
bson_json_reader_producer_t *p;
bson_json_reader_bson_t *b;
if (!reader) {
return;
}
p = &reader->producer;
b = &reader->bson;
if (reader->producer.dcb) {
reader->producer.dcb (reader->producer.data);
}
bson_free (p->buf);
bson_free (b->key_buf.buf);
bson_free (b->unescaped.buf);
bson_free (b->dbpointer_key.buf);
/* destroy each bson_t initialized in parser stack frames */
for (i = 1; i < STACK_MAX; i++) {
if (b->stack[i].type == BSON_JSON_FRAME_INITIAL) {
/* highest the stack grew */
break;
}
if (FRAME_TYPE_HAS_BSON (b->stack[i].type)) {
bson_destroy (&b->stack[i].bson);
}
}
for (i = 0; i < 3; i++) {
bson_free (b->bson_type_buf[i].buf);
}
_bson_json_code_cleanup (&b->code_data);
jsonsl_destroy (reader->json);
bson_free (reader->tok_accumulator.buf);
bson_free (reader);
}
typedef struct {
const uint8_t *data;
size_t len;
size_t bytes_parsed;
} bson_json_data_reader_t;
static ssize_t
_bson_json_data_reader_cb (void *_ctx, uint8_t *buf, size_t len)
{
size_t bytes;
bson_json_data_reader_t *ctx = (bson_json_data_reader_t *) _ctx;
if (!ctx->data) {
return -1;
}
bytes = BSON_MIN (len, ctx->len - ctx->bytes_parsed);
memcpy (buf, ctx->data + ctx->bytes_parsed, bytes);
ctx->bytes_parsed += bytes;
return bytes;
}
bson_json_reader_t *
bson_json_data_reader_new (bool allow_multiple, /* IN */
size_t size) /* IN */
{
bson_json_data_reader_t *dr = bson_malloc0 (sizeof *dr);
return bson_json_reader_new (
dr, &_bson_json_data_reader_cb, &bson_free, allow_multiple, size);
}
void
bson_json_data_reader_ingest (bson_json_reader_t *reader, /* IN */
const uint8_t *data, /* IN */
size_t len) /* IN */
{
bson_json_data_reader_t *ctx =
(bson_json_data_reader_t *) reader->producer.data;
ctx->data = data;
ctx->len = len;
ctx->bytes_parsed = 0;
}
bson_t *
bson_new_from_json (const uint8_t *data, /* IN */
ssize_t len, /* IN */
bson_error_t *error) /* OUT */
{
bson_json_reader_t *reader;
bson_t *bson;
int r;
BSON_ASSERT (data);
if (len < 0) {
len = (ssize_t) strlen ((const char *) data);
}
bson = bson_new ();
reader = bson_json_data_reader_new (false, BSON_JSON_DEFAULT_BUF_SIZE);
bson_json_data_reader_ingest (reader, data, len);
r = bson_json_reader_read (reader, bson, error);
bson_json_reader_destroy (reader);
if (r == 0) {
bson_set_error (error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_INVALID_PARAM,
"Empty JSON string");
}
if (r != 1) {
bson_destroy (bson);
return NULL;
}
return bson;
}
bool
bson_init_from_json (bson_t *bson, /* OUT */
const char *data, /* IN */
ssize_t len, /* IN */
bson_error_t *error) /* OUT */
{
bson_json_reader_t *reader;
int r;
BSON_ASSERT (bson);
BSON_ASSERT (data);
if (len < 0) {
len = strlen (data);
}
bson_init (bson);
reader = bson_json_data_reader_new (false, BSON_JSON_DEFAULT_BUF_SIZE);
bson_json_data_reader_ingest (reader, (const uint8_t *) data, len);
r = bson_json_reader_read (reader, bson, error);
bson_json_reader_destroy (reader);
if (r == 0) {
bson_set_error (error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_INVALID_PARAM,
"Empty JSON string");
}
if (r != 1) {
bson_destroy (bson);
return false;
}
return true;
}
static void
_bson_json_reader_handle_fd_destroy (void *handle) /* IN */
{
bson_json_reader_handle_fd_t *fd = handle;
if (fd) {
if ((fd->fd != -1) && fd->do_close) {
#ifdef _WIN32
_close (fd->fd);
#else
close (fd->fd);
#endif
}
bson_free (fd);
}
}
static ssize_t
_bson_json_reader_handle_fd_read (void *handle, /* IN */
uint8_t *buf, /* IN */
size_t len) /* IN */
{
bson_json_reader_handle_fd_t *fd = handle;
ssize_t ret = -1;
if (fd && (fd->fd != -1)) {
again:
#ifdef BSON_OS_WIN32
ret = _read (fd->fd, buf, (unsigned int) len);
#else
ret = read (fd->fd, buf, len);
#endif
if ((ret == -1) && (errno == EAGAIN)) {
goto again;
}
}
return ret;
}
bson_json_reader_t *
bson_json_reader_new_from_fd (int fd, /* IN */
bool close_on_destroy) /* IN */
{
bson_json_reader_handle_fd_t *handle;
BSON_ASSERT (fd != -1);
handle = bson_malloc0 (sizeof *handle);
handle->fd = fd;
handle->do_close = close_on_destroy;
return bson_json_reader_new (handle,
_bson_json_reader_handle_fd_read,
_bson_json_reader_handle_fd_destroy,
true,
BSON_JSON_DEFAULT_BUF_SIZE);
}
bson_json_reader_t *
bson_json_reader_new_from_file (const char *path, /* IN */
bson_error_t *error) /* OUT */
{
char errmsg_buf[BSON_ERROR_BUFFER_SIZE];
char *errmsg;
int fd = -1;
BSON_ASSERT (path);
#ifdef BSON_OS_WIN32
_sopen_s (&fd, path, (_O_RDONLY | _O_BINARY), _SH_DENYNO, _S_IREAD);
#else
fd = open (path, O_RDONLY);
#endif
if (fd == -1) {
errmsg = bson_strerror_r (errno, errmsg_buf, sizeof errmsg_buf);
bson_set_error (
error, BSON_ERROR_READER, BSON_ERROR_READER_BADFD, "%s", errmsg);
return NULL;
}
return bson_json_reader_new_from_fd (fd, true);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-json.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-json.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-json.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-json.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-keys.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-keys.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-keys.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-keys.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-keys.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-keys.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-keys.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-keys.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-macros.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-macros.h
similarity index 88%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-macros.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-macros.h
index acfd1a58..848fb344 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-macros.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-macros.h
@@ -1,293 +1,305 @@
/*
* Copyright 2013 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.
*/
#include "bson-prelude.h"
#ifndef BSON_MACROS_H
#define BSON_MACROS_H
#include <stdio.h>
#ifdef __cplusplus
#include <algorithm>
#endif
#include "bson-config.h"
#if BSON_OS == 1
#define BSON_OS_UNIX
#elif BSON_OS == 2
#define BSON_OS_WIN32
#else
#error "Unknown operating system."
#endif
#ifdef __cplusplus
#define BSON_BEGIN_DECLS extern "C" {
#define BSON_END_DECLS }
#else
#define BSON_BEGIN_DECLS
#define BSON_END_DECLS
#endif
#if defined(__GNUC__)
#define BSON_GNUC_CHECK_VERSION(major, minor) \
((__GNUC__ > (major)) || \
((__GNUC__ == (major)) && (__GNUC_MINOR__ >= (minor))))
#else
#define BSON_GNUC_CHECK_VERSION(major, minor) 0
#endif
#if defined(__GNUC__)
#define BSON_GNUC_IS_VERSION(major, minor) \
((__GNUC__ == (major)) && (__GNUC_MINOR__ == (minor)))
#else
#define BSON_GNUC_IS_VERSION(major, minor) 0
#endif
/* Decorate public functions:
* - if BSON_STATIC, we're compiling a program that uses libbson as a static
* library, don't decorate functions
* - else if BSON_COMPILATION, we're compiling a static or shared libbson, mark
* public functions for export from the shared lib (which has no effect on
* the static lib)
* - else, we're compiling a program that uses libbson as a shared library,
* mark public functions as DLL imports for Microsoft Visual C
*/
#ifdef _MSC_VER
/*
* Microsoft Visual C
*/
#ifdef BSON_STATIC
#define BSON_API
#elif defined(BSON_COMPILATION)
#define BSON_API __declspec(dllexport)
#else
#define BSON_API __declspec(dllimport)
#endif
#define BSON_CALL __cdecl
#elif defined(__GNUC__)
/*
* GCC
*/
#ifdef BSON_STATIC
#define BSON_API
#elif defined(BSON_COMPILATION)
#define BSON_API __attribute__ ((visibility ("default")))
#else
#define BSON_API
#endif
#define BSON_CALL
#else
/*
* Other compilers
*/
#define BSON_API
#define BSON_CALL
#endif
#define BSON_EXPORT(type) BSON_API type BSON_CALL
#ifdef MIN
#define BSON_MIN MIN
#elif defined(__cplusplus)
#define BSON_MIN(a, b) ((std::min) (a, b))
#elif defined(_MSC_VER)
#define BSON_MIN(a, b) ((a) < (b) ? (a) : (b))
#else
#define BSON_MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifdef MAX
#define BSON_MAX MAX
#elif defined(__cplusplus)
#define BSON_MAX(a, b) ((std::max) (a, b))
#elif defined(_MSC_VER)
#define BSON_MAX(a, b) ((a) > (b) ? (a) : (b))
#else
#define BSON_MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifdef ABS
#define BSON_ABS ABS
#else
#define BSON_ABS(a) (((a) < 0) ? ((a) * -1) : (a))
#endif
#ifdef _MSC_VER
#ifdef _WIN64
#define BSON_ALIGN_OF_PTR 8
#else
#define BSON_ALIGN_OF_PTR 4
#endif
#else
#define BSON_ALIGN_OF_PTR (sizeof (void *))
#endif
#ifdef BSON_EXTRA_ALIGN
#if defined(_MSC_VER)
#define BSON_ALIGNED_BEGIN(_N) __declspec(align (_N))
#define BSON_ALIGNED_END(_N)
#else
#define BSON_ALIGNED_BEGIN(_N)
#define BSON_ALIGNED_END(_N) __attribute__ ((aligned (_N)))
#endif
#else
#if defined(_MSC_VER)
#define BSON_ALIGNED_BEGIN(_N) __declspec(align (BSON_ALIGN_OF_PTR))
#define BSON_ALIGNED_END(_N)
#else
#define BSON_ALIGNED_BEGIN(_N)
#define BSON_ALIGNED_END(_N) \
__attribute__ ( \
(aligned ((_N) > BSON_ALIGN_OF_PTR ? BSON_ALIGN_OF_PTR : (_N))))
#endif
#endif
#define bson_str_empty(s) (!s[0])
#define bson_str_empty0(s) (!s || !s[0])
-#if defined(_WIN32)
+#if defined(_MSC_VER)
#define BSON_FUNC __FUNCTION__
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L
#define BSON_FUNC __FUNCTION__
#else
#define BSON_FUNC __func__
#endif
#define BSON_ASSERT(test) \
do { \
if (!(BSON_LIKELY (test))) { \
fprintf (stderr, \
"%s:%d %s(): precondition failed: %s\n", \
__FILE__, \
__LINE__, \
BSON_FUNC, \
#test); \
abort (); \
} \
} while (0)
+
+/* Used for asserting parameters to provide a more precise error message */
+#define BSON_ASSERT_PARAM(param) \
+ do { \
+ if ((BSON_UNLIKELY (param == NULL))) { \
+ fprintf (stderr, \
+ "The parameter: %s, in function %s, cannot be NULL\n", \
+ #param, \
+ BSON_FUNC); \
+ abort (); \
+ } \
+ } while (0)
/* obsolete macros, preserved for compatibility */
#define BSON_STATIC_ASSERT(s) BSON_STATIC_ASSERT_ (s, __LINE__)
#define BSON_STATIC_ASSERT_JOIN(a, b) BSON_STATIC_ASSERT_JOIN2 (a, b)
#define BSON_STATIC_ASSERT_JOIN2(a, b) a##b
#define BSON_STATIC_ASSERT_(s, l) \
typedef char BSON_STATIC_ASSERT_JOIN (static_assert_test_, \
__LINE__)[(s) ? 1 : -1]
/* modern macros */
#define BSON_STATIC_ASSERT2(_name, _s) \
BSON_STATIC_ASSERT2_ (_s, __LINE__, _name)
#define BSON_STATIC_ASSERT_JOIN3(_a, _b, _name) \
BSON_STATIC_ASSERT_JOIN4 (_a, _b, _name)
#define BSON_STATIC_ASSERT_JOIN4(_a, _b, _name) _a##_b##_name
#define BSON_STATIC_ASSERT2_(_s, _l, _name) \
typedef char BSON_STATIC_ASSERT_JOIN3 ( \
static_assert_test_, __LINE__, _name)[(_s) ? 1 : -1]
#if defined(__GNUC__)
#define BSON_GNUC_PURE __attribute__ ((pure))
#define BSON_GNUC_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
#else
#define BSON_GNUC_PURE
#define BSON_GNUC_WARN_UNUSED_RESULT
#endif
#if BSON_GNUC_CHECK_VERSION(4, 0) && !defined(_WIN32)
#define BSON_GNUC_NULL_TERMINATED __attribute__ ((sentinel))
#define BSON_GNUC_INTERNAL __attribute__ ((visibility ("hidden")))
#else
#define BSON_GNUC_NULL_TERMINATED
#define BSON_GNUC_INTERNAL
#endif
#if defined(__GNUC__)
#define BSON_LIKELY(x) __builtin_expect (!!(x), 1)
#define BSON_UNLIKELY(x) __builtin_expect (!!(x), 0)
#else
#define BSON_LIKELY(v) v
#define BSON_UNLIKELY(v) v
#endif
#if defined(__clang__)
#define BSON_GNUC_PRINTF(f, v) __attribute__ ((format (printf, f, v)))
#elif BSON_GNUC_CHECK_VERSION(4, 4)
#define BSON_GNUC_PRINTF(f, v) __attribute__ ((format (gnu_printf, f, v)))
#else
#define BSON_GNUC_PRINTF(f, v)
#endif
#if defined(__LP64__) || defined(_LP64)
#define BSON_WORD_SIZE 64
#else
#define BSON_WORD_SIZE 32
#endif
#if defined(_MSC_VER)
#define BSON_INLINE __inline
#else
#define BSON_INLINE __inline__
#endif
#ifdef _MSC_VER
#define BSON_ENSURE_ARRAY_PARAM_SIZE(_n)
#define BSON_TYPEOF decltype
#else
#define BSON_ENSURE_ARRAY_PARAM_SIZE(_n) static(_n)
#define BSON_TYPEOF typeof
#endif
#if BSON_GNUC_CHECK_VERSION(3, 1)
#define BSON_GNUC_DEPRECATED __attribute__ ((__deprecated__))
#else
#define BSON_GNUC_DEPRECATED
#endif
#if BSON_GNUC_CHECK_VERSION(4, 5)
#define BSON_GNUC_DEPRECATED_FOR(f) \
__attribute__ ((deprecated ("Use " #f " instead")))
#else
#define BSON_GNUC_DEPRECATED_FOR(f) BSON_GNUC_DEPRECATED
#endif
#endif /* BSON_MACROS_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-md5.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-md5.c
similarity index 64%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-md5.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-md5.c
index a541fabe..36377314 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-md5.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-md5.c
@@ -1,24 +1,24 @@
#include "bson-compat.h"
#include "bson-md5.h"
#include "common-md5-private.h"
void
bson_md5_init (bson_md5_t *pms)
{
- _bson_md5_init (pms);
+ COMMON_PREFIX (_bson_md5_init (pms));
}
void
bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes)
{
- _bson_md5_append (pms, data, nbytes);
+ COMMON_PREFIX (_bson_md5_append (pms, data, nbytes));
}
void
bson_md5_finish (bson_md5_t *pms, uint8_t digest[16])
{
- _bson_md5_finish (pms, digest);
+ COMMON_PREFIX (_bson_md5_finish (pms, digest));
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-md5.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-md5.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-md5.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-md5.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-memory.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-memory.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-memory.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-memory.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-memory.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-memory.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-memory.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-memory.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-oid.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-oid.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-oid.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-oid.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-oid.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-oid.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-oid.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-oid.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-prelude.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-prelude.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-prelude.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-prelude.h
index 7d917b52..2469125f 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-prelude.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-prelude.h
@@ -1,19 +1,19 @@
/*
* Copyright 2018-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
*
* 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.
*/
#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
#error "Only <bson/bson.h> can be included directly."
-#endif
\ No newline at end of file
+#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-private.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-reader.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-reader.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-reader.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-reader.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-reader.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-reader.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-reader.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-reader.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-string.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-string.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-string.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-string.c
index 1ca5b5a5..68c6ef20 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-string.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-string.c
@@ -1,820 +1,820 @@
/*
* Copyright 2013 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.
*/
#include <limits.h>
#include <stdarg.h>
#include "bson-compat.h"
#include "bson-config.h"
#include "bson-string.h"
#include "bson-memory.h"
#include "bson-utf8.h"
#ifdef BSON_HAVE_STRINGS_H
#include <strings.h>
#else
#include <string.h>
#endif
/*
*--------------------------------------------------------------------------
*
* bson_string_new --
*
* Create a new bson_string_t.
*
* bson_string_t is a power-of-2 allocation growing string. Every
* time data is appended the next power of two size is chosen for
* the allocation. Pretty standard stuff.
*
* It is UTF-8 aware through the use of bson_string_append_unichar().
* The proper UTF-8 character sequence will be used.
*
* Parameters:
* @str: a string to copy or NULL.
*
* Returns:
* A newly allocated bson_string_t that should be freed with
* bson_string_free().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bson_string_t *
bson_string_new (const char *str) /* IN */
{
bson_string_t *ret;
ret = bson_malloc0 (sizeof *ret);
ret->len = str ? (int) strlen (str) : 0;
ret->alloc = ret->len + 1;
if (!bson_is_power_of_two (ret->alloc)) {
ret->alloc = (uint32_t) bson_next_power_of_two ((size_t) ret->alloc);
}
BSON_ASSERT (ret->alloc >= 1);
ret->str = bson_malloc (ret->alloc);
if (str) {
memcpy (ret->str, str, ret->len);
}
ret->str[ret->len] = '\0';
ret->str[ret->len] = '\0';
return ret;
}
char *
bson_string_free (bson_string_t *string, /* IN */
bool free_segment) /* IN */
{
char *ret = NULL;
BSON_ASSERT (string);
if (!free_segment) {
ret = string->str;
} else {
bson_free (string->str);
}
bson_free (string);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* bson_string_append --
*
* Append the UTF-8 string @str to @string.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_string_append (bson_string_t *string, /* IN */
const char *str) /* IN */
{
uint32_t len;
BSON_ASSERT (string);
BSON_ASSERT (str);
len = (uint32_t) strlen (str);
if ((string->alloc - string->len - 1) < len) {
string->alloc += len;
if (!bson_is_power_of_two (string->alloc)) {
string->alloc =
(uint32_t) bson_next_power_of_two ((size_t) string->alloc);
}
string->str = bson_realloc (string->str, string->alloc);
}
memcpy (string->str + string->len, str, len);
string->len += len;
string->str[string->len] = '\0';
}
/*
*--------------------------------------------------------------------------
*
* bson_string_append_c --
*
* Append the ASCII character @c to @string.
*
* Do not use this if you are working with UTF-8 sequences,
* use bson_string_append_unichar().
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_string_append_c (bson_string_t *string, /* IN */
char c) /* IN */
{
char cc[2];
BSON_ASSERT (string);
if (BSON_UNLIKELY (string->alloc == (string->len + 1))) {
cc[0] = c;
cc[1] = '\0';
bson_string_append (string, cc);
return;
}
string->str[string->len++] = c;
string->str[string->len] = '\0';
}
/*
*--------------------------------------------------------------------------
*
* bson_string_append_unichar --
*
* Append the bson_unichar_t @unichar to the string @string.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_string_append_unichar (bson_string_t *string, /* IN */
bson_unichar_t unichar) /* IN */
{
uint32_t len;
char str[8];
BSON_ASSERT (string);
BSON_ASSERT (unichar);
bson_utf8_from_unichar (unichar, str, &len);
if (len <= 6) {
str[len] = '\0';
bson_string_append (string, str);
}
}
/*
*--------------------------------------------------------------------------
*
* bson_string_append_printf --
*
* Format a string according to @format and append it to @string.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_string_append_printf (bson_string_t *string, const char *format, ...)
{
va_list args;
char *ret;
BSON_ASSERT (string);
BSON_ASSERT (format);
va_start (args, format);
ret = bson_strdupv_printf (format, args);
va_end (args);
bson_string_append (string, ret);
bson_free (ret);
}
/*
*--------------------------------------------------------------------------
*
* bson_string_truncate --
*
* Truncate the string @string to @len bytes.
*
* The underlying memory will be released via realloc() down to
* the minimum required size specified by @len.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_string_truncate (bson_string_t *string, /* IN */
uint32_t len) /* IN */
{
uint32_t alloc;
BSON_ASSERT (string);
BSON_ASSERT (len < INT_MAX);
alloc = len + 1;
if (alloc < 16) {
alloc = 16;
}
if (!bson_is_power_of_two (alloc)) {
alloc = (uint32_t) bson_next_power_of_two ((size_t) alloc);
}
string->str = bson_realloc (string->str, alloc);
string->alloc = alloc;
string->len = len;
string->str[string->len] = '\0';
}
/*
*--------------------------------------------------------------------------
*
* bson_strdup --
*
* Portable strdup().
*
* Returns:
* A newly allocated string that should be freed with bson_free().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
char *
bson_strdup (const char *str) /* IN */
{
long len;
char *out;
if (!str) {
return NULL;
}
len = (long) strlen (str);
out = bson_malloc (len + 1);
if (!out) {
return NULL;
}
memcpy (out, str, len + 1);
return out;
}
/*
*--------------------------------------------------------------------------
*
* bson_strdupv_printf --
*
* Like bson_strdup_printf() but takes a va_list.
*
* Returns:
* A newly allocated string that should be freed with bson_free().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
char *
bson_strdupv_printf (const char *format, /* IN */
va_list args) /* IN */
{
va_list my_args;
char *buf;
int len = 32;
int n;
BSON_ASSERT (format);
buf = bson_malloc0 (len);
while (true) {
va_copy (my_args, args);
n = bson_vsnprintf (buf, len, format, my_args);
va_end (my_args);
if (n > -1 && n < len) {
return buf;
}
if (n > -1) {
len = n + 1;
} else {
len *= 2;
}
buf = bson_realloc (buf, len);
}
}
/*
*--------------------------------------------------------------------------
*
* bson_strdup_printf --
*
* Convenience function that formats a string according to @format
* and returns a copy of it.
*
* Returns:
* A newly created string that should be freed with bson_free().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
char *
bson_strdup_printf (const char *format, /* IN */
...) /* IN */
{
va_list args;
char *ret;
BSON_ASSERT (format);
va_start (args, format);
ret = bson_strdupv_printf (format, args);
va_end (args);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* bson_strndup --
*
* A portable strndup().
*
* Returns:
* A newly allocated string that should be freed with bson_free().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
char *
bson_strndup (const char *str, /* IN */
size_t n_bytes) /* IN */
{
char *ret;
BSON_ASSERT (str);
ret = bson_malloc (n_bytes + 1);
bson_strncpy (ret, str, n_bytes + 1);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* bson_strfreev --
*
* Frees each string in a NULL terminated array of strings.
* This also frees the underlying array.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_strfreev (char **str) /* IN */
{
int i;
if (str) {
for (i = 0; str[i]; i++)
bson_free (str[i]);
bson_free (str);
}
}
/*
*--------------------------------------------------------------------------
*
* bson_strnlen --
*
* A portable strnlen().
*
* Returns:
* The length of @s up to @maxlen.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
size_t
bson_strnlen (const char *s, /* IN */
size_t maxlen) /* IN */
{
#ifdef BSON_HAVE_STRNLEN
return strnlen (s, maxlen);
#else
size_t i;
for (i = 0; i < maxlen; i++) {
if (s[i] == '\0') {
return i;
}
}
return maxlen;
#endif
}
/*
*--------------------------------------------------------------------------
*
* bson_strncpy --
*
* A portable strncpy.
*
* Copies @src into @dst, which must be @size bytes or larger.
* The result is guaranteed to be \0 terminated.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_strncpy (char *dst, /* IN */
const char *src, /* IN */
size_t size) /* IN */
{
if (size == 0) {
return;
}
/* Prefer strncpy_s for MSVC, or strlcpy, which has additional checks and only
* adds one trailing \0 */
#ifdef _MSC_VER
strncpy_s (dst, size, src, _TRUNCATE);
#elif defined(BSON_HAVE_STRLCPY)
strlcpy (dst, src, size);
#else
strncpy (dst, src, size);
dst[size - 1] = '\0';
#endif
}
/*
*--------------------------------------------------------------------------
*
* bson_vsnprintf --
*
* A portable vsnprintf.
*
* If more than @size bytes are required (exluding the null byte),
* then @size bytes will be written to @string and the return value
* is the number of bytes required.
*
* This function will always return a NULL terminated string.
*
* Returns:
* The number of bytes required for @format excluding the null byte.
*
* Side effects:
* @str is initialized with the formatted string.
*
*--------------------------------------------------------------------------
*/
int
bson_vsnprintf (char *str, /* IN */
size_t size, /* IN */
const char *format, /* IN */
va_list ap) /* IN */
{
#ifdef _MSC_VER
int r = -1;
BSON_ASSERT (str);
if (size == 0) {
return 0;
}
r = _vsnprintf_s (str, size, _TRUNCATE, format, ap);
if (r == -1) {
r = _vscprintf (format, ap);
}
str[size - 1] = '\0';
return r;
#else
int r;
BSON_ASSERT (str);
if (size == 0) {
return 0;
}
r = vsnprintf (str, size, format, ap);
str[size - 1] = '\0';
return r;
#endif
}
/*
*--------------------------------------------------------------------------
*
* bson_snprintf --
*
* A portable snprintf.
*
* If @format requires more than @size bytes, then @size bytes are
* written and the result is the number of bytes required (excluding
* the null byte).
*
* This function will always return a NULL terminated string.
*
* Returns:
* The number of bytes required for @format.
*
* Side effects:
* @str is initialized.
*
*--------------------------------------------------------------------------
*/
int
bson_snprintf (char *str, /* IN */
size_t size, /* IN */
const char *format, /* IN */
...)
{
int r;
va_list ap;
BSON_ASSERT (str);
va_start (ap, format);
r = bson_vsnprintf (str, size, format, ap);
va_end (ap);
return r;
}
/*
*--------------------------------------------------------------------------
*
* bson_ascii_strtoll --
*
* A portable strtoll.
*
* Convert a string to a 64-bit signed integer according to the given
* @base, which must be 16, 10, or 8. Leading whitespace will be ignored.
*
* If base is 0 is passed in, the base is inferred from the string's
* leading characters. Base-16 numbers start with "0x" or "0X", base-8
* numbers start with "0", base-10 numbers start with a digit from 1 to 9.
*
* If @e is not NULL, it will be assigned the address of the first invalid
* character of @s, or its null terminating byte if the entire string was
* valid.
*
* If an invalid value is encountered, errno will be set to EINVAL and
* zero will be returned. If the number is out of range, errno is set to
* ERANGE and LLONG_MAX or LLONG_MIN is returned.
*
* Returns:
* The result of the conversion.
*
* Side effects:
* errno will be set on error.
*
*--------------------------------------------------------------------------
*/
int64_t
bson_ascii_strtoll (const char *s, char **e, int base)
{
char *tok = (char *) s;
char *digits_start;
char c;
int64_t number = 0;
int64_t sign = 1;
int64_t cutoff;
int64_t cutlim;
errno = 0;
if (!s) {
errno = EINVAL;
return 0;
}
c = *tok;
while (bson_isspace (c)) {
c = *++tok;
}
if (c == '-') {
sign = -1;
c = *++tok;
} else if (c == '+') {
c = *++tok;
} else if (!isdigit (c)) {
errno = EINVAL;
return 0;
}
/* from here down, inspired by NetBSD's strtoll */
if ((base == 0 || base == 16) && c == '0' &&
(tok[1] == 'x' || tok[1] == 'X')) {
tok += 2;
c = *tok;
base = 16;
}
if (base == 0) {
base = c == '0' ? 8 : 10;
}
/* Cutoff is the greatest magnitude we'll be able to multiply by base without
* range error. If the current number is past cutoff and we see valid digit,
* fail. If the number is *equal* to cutoff, then the next digit must be less
* than cutlim, otherwise fail.
*/
cutoff = sign == -1 ? INT64_MIN : INT64_MAX;
cutlim = (int) (cutoff % base);
cutoff /= base;
if (sign == -1) {
if (cutlim > 0) {
cutlim -= base;
cutoff += 1;
}
cutlim = -cutlim;
}
digits_start = tok;
while ((c = *tok)) {
if (isdigit (c)) {
c -= '0';
} else if (isalpha (c)) {
c -= isupper (c) ? 'A' - 10 : 'a' - 10;
} else {
/* end of number string */
break;
}
if (c >= base) {
break;
}
if (sign == -1) {
if (number < cutoff || (number == cutoff && c > cutlim)) {
number = INT64_MIN;
errno = ERANGE;
break;
} else {
number *= base;
number -= c;
}
} else {
if (number > cutoff || (number == cutoff && c > cutlim)) {
number = INT64_MAX;
errno = ERANGE;
break;
} else {
number *= base;
number += c;
}
}
tok++;
}
/* did we parse any digits at all? */
if (e != NULL && tok > digits_start) {
*e = tok;
}
return number;
}
int
bson_strcasecmp (const char *s1, const char *s2)
{
#ifdef BSON_OS_WIN32
return _stricmp (s1, s2);
#else
return strcasecmp (s1, s2);
#endif
}
bool
bson_isspace (int c)
{
return c >= -1 && c <= 255 && isspace (c);
-}
\ No newline at end of file
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-string.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-string.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-string.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-string.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-timegm-private.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-timegm-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-timegm-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-timegm-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-timegm.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-timegm.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-timegm.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-timegm.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-types.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-types.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-types.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-types.h
index bffdb79e..760ff240 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-types.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-types.h
@@ -1,565 +1,564 @@
/*
* Copyright 2013 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.
*/
#include "bson-prelude.h"
#ifndef BSON_TYPES_H
#define BSON_TYPES_H
#include <stdlib.h>
#include <sys/types.h>
#include "bson-macros.h"
#include "bson-config.h"
#include "bson-compat.h"
#include "bson-endian.h"
BSON_BEGIN_DECLS
/*
*--------------------------------------------------------------------------
*
* bson_unichar_t --
*
* bson_unichar_t provides an unsigned 32-bit type for containing
* unicode characters. When iterating UTF-8 sequences, this should
* be used to avoid losing the high-bits of non-ascii characters.
*
* See also:
* bson_string_append_unichar()
*
*--------------------------------------------------------------------------
*/
typedef uint32_t bson_unichar_t;
/**
* bson_context_flags_t:
*
* This enumeration is used to configure a bson_context_t.
*
* %BSON_CONTEXT_NONE: Use default options.
* %BSON_CONTEXT_THREAD_SAFE: Context will be called from multiple threads.
+ * %BSON_CONTEXT_DISABLE_HOST_CACHE: Does nothing, is ignored.
* %BSON_CONTEXT_DISABLE_PID_CACHE: Call getpid() instead of caching the
* result of getpid() when initializing the context.
- * %BSON_CONTEXT_DISABLE_HOST_CACHE: Call gethostname() instead of caching the
- * result of gethostname() when initializing the context.
*/
typedef enum {
BSON_CONTEXT_NONE = 0,
BSON_CONTEXT_THREAD_SAFE = (1 << 0),
BSON_CONTEXT_DISABLE_HOST_CACHE = (1 << 1),
BSON_CONTEXT_DISABLE_PID_CACHE = (1 << 2),
#ifdef BSON_HAVE_SYSCALL_TID
BSON_CONTEXT_USE_TASK_ID = (1 << 3),
#endif
} bson_context_flags_t;
/**
* bson_context_t:
*
* This structure manages context for the bson library. It handles
* configuration for thread-safety and other performance related requirements.
* Consumers will create a context and may use multiple under a variety of
* situations.
*
* If your program calls fork(), you should initialize a new bson_context_t
* using bson_context_init().
*
* If you are using threading, it is suggested that you use a bson_context_t
* per thread for best performance. Alternatively, you can initialize the
* bson_context_t with BSON_CONTEXT_THREAD_SAFE, although a performance penalty
* will be incurred.
*
* Many functions will require that you provide a bson_context_t such as OID
* generation.
*
* This structure is opaque in that you cannot see the contents of the
* structure. However, it is stack allocatable in that enough padding is
* provided in _bson_context_t to hold the structure.
*/
typedef struct _bson_context_t bson_context_t;
/**
* bson_t:
*
* This structure manages a buffer whose contents are a properly formatted
* BSON document. You may perform various transforms on the BSON documents.
* Additionally, it can be iterated over using bson_iter_t.
*
* See bson_iter_init() for iterating the contents of a bson_t.
*
* When building a bson_t structure using the various append functions,
* memory allocations may occur. That is performed using power of two
* allocations and realloc().
*
* See http://bsonspec.org for the BSON document spec.
*
* This structure is meant to fit in two sequential 64-byte cachelines.
*/
#ifdef BSON_MEMCHECK
BSON_ALIGNED_BEGIN (128)
typedef struct _bson_t {
uint32_t flags; /* Internal flags for the bson_t. */
uint32_t len; /* Length of BSON data. */
char *canary; /* For valgrind check */
uint8_t padding[120 - sizeof (char*)];
} bson_t BSON_ALIGNED_END (128);
#else
BSON_ALIGNED_BEGIN (128)
typedef struct _bson_t {
uint32_t flags; /* Internal flags for the bson_t. */
uint32_t len; /* Length of BSON data. */
uint8_t padding[120]; /* Padding for stack allocation. */
} bson_t BSON_ALIGNED_END (128);
#endif
/**
* BSON_INITIALIZER:
*
* This macro can be used to initialize a #bson_t structure on the stack
* without calling bson_init().
*
* |[
* bson_t b = BSON_INITIALIZER;
* ]|
*/
#ifdef BSON_MEMCHECK
#define BSON_INITIALIZER \
{ \
3, 5, \
bson_malloc (1), \
{ \
5 \
}, \
}
#else
#define BSON_INITIALIZER \
{ \
3, 5, \
{ \
5 \
} \
}
#endif
BSON_STATIC_ASSERT2 (bson_t, sizeof (bson_t) == 128);
/**
* bson_oid_t:
*
* This structure contains the binary form of a BSON Object Id as specified
* on http://bsonspec.org. If you would like the bson_oid_t in string form
* see bson_oid_to_string() or bson_oid_to_string_r().
*/
typedef struct {
uint8_t bytes[12];
} bson_oid_t;
BSON_STATIC_ASSERT2 (oid_t, sizeof (bson_oid_t) == 12);
/**
* bson_decimal128_t:
*
* @high The high-order bytes of the decimal128. This field contains sign,
* combination bits, exponent, and part of the coefficient continuation.
* @low The low-order bytes of the decimal128. This field contains the second
* part of the coefficient continuation.
*
* This structure is a boxed type containing the value for the BSON decimal128
* type. The structure stores the 128 bits such that they correspond to the
* native format for the IEEE decimal128 type, if it is implemented.
**/
typedef struct {
#if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN
uint64_t low;
uint64_t high;
#elif BSON_BYTE_ORDER == BSON_BIG_ENDIAN
uint64_t high;
uint64_t low;
#endif
} bson_decimal128_t;
/**
* bson_validate_flags_t:
*
* This enumeration is used for validation of BSON documents. It allows
* selective control on what you wish to validate.
*
* %BSON_VALIDATE_NONE: No additional validation occurs.
* %BSON_VALIDATE_UTF8: Check that strings are valid UTF-8.
* %BSON_VALIDATE_DOLLAR_KEYS: Check that keys do not start with $.
* %BSON_VALIDATE_DOT_KEYS: Check that keys do not contain a period.
* %BSON_VALIDATE_UTF8_ALLOW_NULL: Allow NUL bytes in UTF-8 text.
* %BSON_VALIDATE_EMPTY_KEYS: Prohibit zero-length field names
*/
typedef enum {
BSON_VALIDATE_NONE = 0,
BSON_VALIDATE_UTF8 = (1 << 0),
BSON_VALIDATE_DOLLAR_KEYS = (1 << 1),
BSON_VALIDATE_DOT_KEYS = (1 << 2),
BSON_VALIDATE_UTF8_ALLOW_NULL = (1 << 3),
BSON_VALIDATE_EMPTY_KEYS = (1 << 4),
} bson_validate_flags_t;
/**
* bson_type_t:
*
* This enumeration contains all of the possible types within a BSON document.
* Use bson_iter_type() to fetch the type of a field while iterating over it.
*/
typedef enum {
BSON_TYPE_EOD = 0x00,
BSON_TYPE_DOUBLE = 0x01,
BSON_TYPE_UTF8 = 0x02,
BSON_TYPE_DOCUMENT = 0x03,
BSON_TYPE_ARRAY = 0x04,
BSON_TYPE_BINARY = 0x05,
BSON_TYPE_UNDEFINED = 0x06,
BSON_TYPE_OID = 0x07,
BSON_TYPE_BOOL = 0x08,
BSON_TYPE_DATE_TIME = 0x09,
BSON_TYPE_NULL = 0x0A,
BSON_TYPE_REGEX = 0x0B,
BSON_TYPE_DBPOINTER = 0x0C,
BSON_TYPE_CODE = 0x0D,
BSON_TYPE_SYMBOL = 0x0E,
BSON_TYPE_CODEWSCOPE = 0x0F,
BSON_TYPE_INT32 = 0x10,
BSON_TYPE_TIMESTAMP = 0x11,
BSON_TYPE_INT64 = 0x12,
BSON_TYPE_DECIMAL128 = 0x13,
BSON_TYPE_MAXKEY = 0x7F,
BSON_TYPE_MINKEY = 0xFF,
} bson_type_t;
/**
* bson_subtype_t:
*
* This enumeration contains the various subtypes that may be used in a binary
* field. See http://bsonspec.org for more information.
*/
typedef enum {
BSON_SUBTYPE_BINARY = 0x00,
BSON_SUBTYPE_FUNCTION = 0x01,
BSON_SUBTYPE_BINARY_DEPRECATED = 0x02,
BSON_SUBTYPE_UUID_DEPRECATED = 0x03,
BSON_SUBTYPE_UUID = 0x04,
BSON_SUBTYPE_MD5 = 0x05,
BSON_SUBTYPE_ENCRYPTED = 0x06,
BSON_SUBTYPE_USER = 0x80,
} bson_subtype_t;
/*
*--------------------------------------------------------------------------
*
* bson_value_t --
*
* A boxed type to contain various bson_type_t types.
*
* See also:
* bson_value_copy()
* bson_value_destroy()
*
*--------------------------------------------------------------------------
*/
BSON_ALIGNED_BEGIN (8)
typedef struct _bson_value_t {
bson_type_t value_type;
int32_t padding;
union {
bson_oid_t v_oid;
int64_t v_int64;
int32_t v_int32;
int8_t v_int8;
double v_double;
bool v_bool;
int64_t v_datetime;
struct {
uint32_t timestamp;
uint32_t increment;
} v_timestamp;
struct {
char *str;
uint32_t len;
} v_utf8;
struct {
uint8_t *data;
uint32_t data_len;
} v_doc;
struct {
uint8_t *data;
uint32_t data_len;
bson_subtype_t subtype;
} v_binary;
struct {
char *regex;
char *options;
} v_regex;
struct {
char *collection;
uint32_t collection_len;
bson_oid_t oid;
} v_dbpointer;
struct {
char *code;
uint32_t code_len;
} v_code;
struct {
char *code;
uint8_t *scope_data;
uint32_t code_len;
uint32_t scope_len;
} v_codewscope;
struct {
char *symbol;
uint32_t len;
} v_symbol;
bson_decimal128_t v_decimal128;
} value;
} bson_value_t BSON_ALIGNED_END (8);
/**
* bson_iter_t:
*
* This structure manages iteration over a bson_t structure. It keeps track
* of the location of the current key and value within the buffer. Using the
* various functions to get the value of the iter will read from these
* locations.
*
* This structure is safe to discard on the stack. No cleanup is necessary
* after using it.
*/
BSON_ALIGNED_BEGIN (128)
typedef struct {
const uint8_t *raw; /* The raw buffer being iterated. */
uint32_t len; /* The length of raw. */
uint32_t off; /* The offset within the buffer. */
uint32_t type; /* The offset of the type byte. */
uint32_t key; /* The offset of the key byte. */
uint32_t d1; /* The offset of the first data byte. */
uint32_t d2; /* The offset of the second data byte. */
uint32_t d3; /* The offset of the third data byte. */
uint32_t d4; /* The offset of the fourth data byte. */
uint32_t next_off; /* The offset of the next field. */
uint32_t err_off; /* The offset of the error. */
bson_value_t value; /* Internal value for various state. */
} bson_iter_t BSON_ALIGNED_END (128);
/**
* bson_reader_t:
*
* This structure is used to iterate over a sequence of BSON documents. It
* allows for them to be iterated with the possibility of no additional
* memory allocations under certain circumstances such as reading from an
* incoming mongo packet.
*/
BSON_ALIGNED_BEGIN (BSON_ALIGN_OF_PTR)
typedef struct {
uint32_t type;
/*< private >*/
} bson_reader_t BSON_ALIGNED_END (BSON_ALIGN_OF_PTR);
/**
* bson_visitor_t:
*
* This structure contains a series of pointers that can be executed for
* each field of a BSON document based on the field type.
*
* For example, if an int32 field is found, visit_int32 will be called.
*
* When visiting each field using bson_iter_visit_all(), you may provide a
* data pointer that will be provided with each callback. This might be useful
* if you are marshaling to another language.
*
* You may pre-maturely stop the visitation of fields by returning true in your
* visitor. Returning false will continue visitation to further fields.
*/
BSON_ALIGNED_BEGIN (8)
typedef struct {
/* run before / after descending into a document */
bool (*visit_before) (const bson_iter_t *iter, const char *key, void *data);
bool (*visit_after) (const bson_iter_t *iter, const char *key, void *data);
/* corrupt BSON, or unsupported type and visit_unsupported_type not set */
void (*visit_corrupt) (const bson_iter_t *iter, void *data);
/* normal bson field callbacks */
bool (*visit_double) (const bson_iter_t *iter,
const char *key,
double v_double,
void *data);
bool (*visit_utf8) (const bson_iter_t *iter,
const char *key,
size_t v_utf8_len,
const char *v_utf8,
void *data);
bool (*visit_document) (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data);
bool (*visit_array) (const bson_iter_t *iter,
const char *key,
const bson_t *v_array,
void *data);
bool (*visit_binary) (const bson_iter_t *iter,
const char *key,
bson_subtype_t v_subtype,
size_t v_binary_len,
const uint8_t *v_binary,
void *data);
/* normal field with deprecated "Undefined" BSON type */
bool (*visit_undefined) (const bson_iter_t *iter,
const char *key,
void *data);
bool (*visit_oid) (const bson_iter_t *iter,
const char *key,
const bson_oid_t *v_oid,
void *data);
bool (*visit_bool) (const bson_iter_t *iter,
const char *key,
bool v_bool,
void *data);
bool (*visit_date_time) (const bson_iter_t *iter,
const char *key,
int64_t msec_since_epoch,
void *data);
bool (*visit_null) (const bson_iter_t *iter, const char *key, void *data);
bool (*visit_regex) (const bson_iter_t *iter,
const char *key,
const char *v_regex,
const char *v_options,
void *data);
bool (*visit_dbpointer) (const bson_iter_t *iter,
const char *key,
size_t v_collection_len,
const char *v_collection,
const bson_oid_t *v_oid,
void *data);
bool (*visit_code) (const bson_iter_t *iter,
const char *key,
size_t v_code_len,
const char *v_code,
void *data);
bool (*visit_symbol) (const bson_iter_t *iter,
const char *key,
size_t v_symbol_len,
const char *v_symbol,
void *data);
bool (*visit_codewscope) (const bson_iter_t *iter,
const char *key,
size_t v_code_len,
const char *v_code,
const bson_t *v_scope,
void *data);
bool (*visit_int32) (const bson_iter_t *iter,
const char *key,
int32_t v_int32,
void *data);
bool (*visit_timestamp) (const bson_iter_t *iter,
const char *key,
uint32_t v_timestamp,
uint32_t v_increment,
void *data);
bool (*visit_int64) (const bson_iter_t *iter,
const char *key,
int64_t v_int64,
void *data);
bool (*visit_maxkey) (const bson_iter_t *iter, const char *key, void *data);
bool (*visit_minkey) (const bson_iter_t *iter, const char *key, void *data);
/* if set, called instead of visit_corrupt when an apparently valid BSON
* includes an unrecognized field type (reading future version of BSON) */
void (*visit_unsupported_type) (const bson_iter_t *iter,
const char *key,
uint32_t type_code,
void *data);
bool (*visit_decimal128) (const bson_iter_t *iter,
const char *key,
const bson_decimal128_t *v_decimal128,
void *data);
void *padding[7];
} bson_visitor_t BSON_ALIGNED_END (8);
#define BSON_ERROR_BUFFER_SIZE 504
BSON_ALIGNED_BEGIN (8)
typedef struct _bson_error_t {
uint32_t domain;
uint32_t code;
char message[BSON_ERROR_BUFFER_SIZE];
} bson_error_t BSON_ALIGNED_END (8);
BSON_STATIC_ASSERT2 (error_t, sizeof (bson_error_t) == 512);
/**
* bson_next_power_of_two:
* @v: A 32-bit unsigned integer of required bytes.
*
* Determines the next larger power of two for the value of @v
* in a constant number of operations.
*
* It is up to the caller to guarantee this will not overflow.
*
* Returns: The next power of 2 from @v.
*/
static BSON_INLINE size_t
bson_next_power_of_two (size_t v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
#if BSON_WORD_SIZE == 64
v |= v >> 32;
#endif
v++;
return v;
}
static BSON_INLINE bool
bson_is_power_of_two (uint32_t v)
{
return ((v != 0) && ((v & (v - 1)) == 0));
}
BSON_END_DECLS
#endif /* BSON_TYPES_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-utf8.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-utf8.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-utf8.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-utf8.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-utf8.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-utf8.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-utf8.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-utf8.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-value.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-value.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-value.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-value.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-value.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-value.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-value.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-value.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version-functions.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version-functions.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version-functions.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version-functions.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version-functions.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version-functions.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version-functions.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version-functions.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version.h
similarity index 94%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version.h
index c8766fff..1a986ff7 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version.h
@@ -1,101 +1,101 @@
/*
* Copyright 2013 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.
*/
#if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION)
#error "Only <bson/bson.h> can be included directly."
#endif
#ifndef BSON_VERSION_H
#define BSON_VERSION_H
/**
* BSON_MAJOR_VERSION:
*
* BSON major version component (e.g. 1 if %BSON_VERSION is 1.2.3)
*/
#define BSON_MAJOR_VERSION (1)
/**
* BSON_MINOR_VERSION:
*
* BSON minor version component (e.g. 2 if %BSON_VERSION is 1.2.3)
*/
-#define BSON_MINOR_VERSION (16)
+#define BSON_MINOR_VERSION (17)
/**
* BSON_MICRO_VERSION:
*
* BSON micro version component (e.g. 3 if %BSON_VERSION is 1.2.3)
*/
-#define BSON_MICRO_VERSION (2)
+#define BSON_MICRO_VERSION (0)
/**
* BSON_PRERELEASE_VERSION:
*
* BSON prerelease version component (e.g. pre if %BSON_VERSION is 1.2.3-pre)
*/
#define BSON_PRERELEASE_VERSION ()
/**
* BSON_VERSION:
*
* BSON version.
*/
-#define BSON_VERSION (1.16.2)
+#define BSON_VERSION (1.17.0)
/**
* BSON_VERSION_S:
*
* BSON version, encoded as a string, useful for printing and
* concatenation.
*/
-#define BSON_VERSION_S "1.16.2"
+#define BSON_VERSION_S "1.17.0"
/**
* BSON_VERSION_HEX:
*
* BSON version, encoded as an hexadecimal number, useful for
* integer comparisons.
*/
#define BSON_VERSION_HEX (BSON_MAJOR_VERSION << 24 | \
BSON_MINOR_VERSION << 16 | \
BSON_MICRO_VERSION << 8)
/**
* BSON_CHECK_VERSION:
* @major: required major version
* @minor: required minor version
* @micro: required micro version
*
* Compile-time version checking. Evaluates to %TRUE if the version
* of BSON is greater than the required one.
*/
#define BSON_CHECK_VERSION(major,minor,micro) \
(BSON_MAJOR_VERSION > (major) || \
(BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION > (minor)) || \
(BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION == (minor) && \
BSON_MICRO_VERSION >= (micro)))
#endif /* BSON_VERSION_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version.h.in b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version.h.in
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-version.h.in
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-version.h.in
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-writer.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-writer.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-writer.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-writer.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-writer.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-writer.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson-writer.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson-writer.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson.c
index 54ef9a32..d36d80af 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson.c
@@ -1,3518 +1,3520 @@
/*
* Copyright 2013 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.
*/
#include "bson.h"
#include "bson-config.h"
#include "bson-private.h"
#include "bson-string.h"
#include "bson-iso8601-private.h"
#include "common-b64-private.h"
#include <string.h>
#include <math.h>
#ifndef BSON_MAX_RECURSION
#define BSON_MAX_RECURSION 200
#endif
typedef enum {
BSON_VALIDATE_PHASE_START,
BSON_VALIDATE_PHASE_TOP,
BSON_VALIDATE_PHASE_LF_REF_KEY,
BSON_VALIDATE_PHASE_LF_REF_UTF8,
BSON_VALIDATE_PHASE_LF_ID_KEY,
BSON_VALIDATE_PHASE_LF_DB_KEY,
BSON_VALIDATE_PHASE_LF_DB_UTF8,
BSON_VALIDATE_PHASE_NOT_DBREF,
} bson_validate_phase_t;
typedef enum {
BSON_JSON_MODE_LEGACY,
BSON_JSON_MODE_CANONICAL,
BSON_JSON_MODE_RELAXED,
} bson_json_mode_t;
/*
* Structures.
*/
typedef struct {
bson_validate_flags_t flags;
ssize_t err_offset;
bson_validate_phase_t phase;
bson_error_t error;
} bson_validate_state_t;
typedef struct {
uint32_t count;
bool keys;
ssize_t *err_offset;
uint32_t depth;
bson_string_t *str;
bson_json_mode_t mode;
} bson_json_state_t;
/*
* Forward declarations.
*/
static bool
_bson_as_json_visit_array (const bson_iter_t *iter,
const char *key,
const bson_t *v_array,
void *data);
static bool
_bson_as_json_visit_document (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data);
static char *
_bson_as_json_visit_all (const bson_t *bson,
size_t *length,
bson_json_mode_t mode);
/*
* Globals.
*/
static const uint8_t gZero;
/*
*--------------------------------------------------------------------------
*
* _bson_impl_inline_grow --
*
* Document growth implementation for documents that currently
* contain stack based buffers. The document may be switched to
* a malloc based buffer.
*
* Returns:
- * true if successful; otherwise false indicating INT_MAX overflow.
+ * true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_impl_inline_grow (bson_impl_inline_t *impl, /* IN */
size_t size) /* IN */
{
bson_impl_alloc_t *alloc = (bson_impl_alloc_t *) impl;
uint8_t *data;
size_t req;
if (((size_t) impl->len + size) <= sizeof impl->data) {
return true;
}
req = bson_next_power_of_two (impl->len + size);
- if (req <= INT32_MAX) {
+ if (req <= BSON_MAX_SIZE) {
data = bson_malloc (req);
memcpy (data, impl->data, impl->len);
#ifdef BSON_MEMCHECK
bson_free (impl->canary);
#endif
alloc->flags &= ~BSON_FLAG_INLINE;
alloc->parent = NULL;
alloc->depth = 0;
alloc->buf = &alloc->alloc;
alloc->buflen = &alloc->alloclen;
alloc->offset = 0;
alloc->alloc = data;
alloc->alloclen = req;
alloc->realloc = bson_realloc_ctx;
alloc->realloc_func_ctx = NULL;
return true;
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* _bson_impl_alloc_grow --
*
* Document growth implementation for documents containing malloc
* based buffers.
*
* Returns:
- * true if successful; otherwise false indicating INT_MAX overflow.
+ * true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_impl_alloc_grow (bson_impl_alloc_t *impl, /* IN */
size_t size) /* IN */
{
size_t req;
/*
* Determine how many bytes we need for this document in the buffer
* including necessary trailing bytes for parent documents.
*/
req = (impl->offset + impl->len + size + impl->depth);
if (req <= *impl->buflen) {
return true;
}
req = bson_next_power_of_two (req);
- if ((req <= INT32_MAX) && impl->realloc) {
+ if ((req <= BSON_MAX_SIZE) && impl->realloc) {
*impl->buf = impl->realloc (*impl->buf, req, impl->realloc_func_ctx);
*impl->buflen = req;
return true;
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* _bson_grow --
*
* Grows the bson_t structure to be large enough to contain @size
* bytes.
*
* Returns:
* true if successful, false if the size would overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_grow (bson_t *bson, /* IN */
uint32_t size) /* IN */
{
if ((bson->flags & BSON_FLAG_INLINE)) {
return _bson_impl_inline_grow ((bson_impl_inline_t *) bson, size);
}
return _bson_impl_alloc_grow ((bson_impl_alloc_t *) bson, size);
}
/*
*--------------------------------------------------------------------------
*
* _bson_data --
*
* A helper function to return the contents of the bson document
* taking into account the polymorphic nature of bson_t.
*
* Returns:
* A buffer which should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static BSON_INLINE uint8_t *
_bson_data (const bson_t *bson) /* IN */
{
if ((bson->flags & BSON_FLAG_INLINE)) {
return ((bson_impl_inline_t *) bson)->data;
} else {
bson_impl_alloc_t *impl = (bson_impl_alloc_t *) bson;
return (*impl->buf) + impl->offset;
}
}
/*
*--------------------------------------------------------------------------
*
* _bson_encode_length --
*
* Helper to encode the length of the bson_t in the first 4 bytes
* of the bson document. Little endian format is used as specified
* by bsonspec.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static BSON_INLINE void
_bson_encode_length (bson_t *bson) /* IN */
{
#if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN
memcpy (_bson_data (bson), &bson->len, sizeof (bson->len));
#else
uint32_t length_le = BSON_UINT32_TO_LE (bson->len);
memcpy (_bson_data (bson), &length_le, sizeof (length_le));
#endif
}
/*
*--------------------------------------------------------------------------
*
* _bson_append_va --
*
* Appends the length,buffer pairs to the bson_t. @n_bytes is an
* optimization to perform one array growth rather than many small
* growths.
*
* @bson: A bson_t
* @n_bytes: The number of bytes to append to the document.
* @n_pairs: The number of length,buffer pairs.
* @first_len: Length of first buffer.
* @first_data: First buffer.
* @args: va_list of additional tuples.
*
* Returns:
* true if the bytes were appended successfully.
- * false if it bson would overflow INT_MAX.
+ * false if it bson would overflow BSON_MAX_SIZE.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static BSON_INLINE bool
_bson_append_va (bson_t *bson, /* IN */
uint32_t n_bytes, /* IN */
uint32_t n_pairs, /* IN */
uint32_t first_len, /* IN */
const uint8_t *first_data, /* IN */
va_list args) /* IN */
{
const uint8_t *data;
uint32_t data_len;
uint8_t *buf;
BSON_ASSERT (!(bson->flags & BSON_FLAG_IN_CHILD));
BSON_ASSERT (!(bson->flags & BSON_FLAG_RDONLY));
if (BSON_UNLIKELY (!_bson_grow (bson, n_bytes))) {
return false;
}
data = first_data;
data_len = first_len;
buf = _bson_data (bson) + bson->len - 1;
do {
n_pairs--;
- /* data may be NULL if data_len is 0. memcpy is not safe to call with NULL. */
+ /* data may be NULL if data_len is 0. memcpy is not safe to call with
+ * NULL. */
if (BSON_LIKELY (data_len != 0 && data != NULL)) {
memcpy (buf, data, data_len);
bson->len += data_len;
buf += data_len;
} else if (BSON_UNLIKELY (data_len != 0 && data == NULL)) {
/* error, user appending NULL with non-zero length. */
return false;
}
if (n_pairs) {
data_len = va_arg (args, uint32_t);
data = va_arg (args, const uint8_t *);
}
} while (n_pairs);
_bson_encode_length (bson);
*buf = '\0';
return true;
}
/*
*--------------------------------------------------------------------------
*
* _bson_append --
*
* Variadic function to append length,buffer pairs to a bson_t. If the
* append would cause the bson_t to overflow a 32-bit length, it will
* return false and no append will have occurred.
*
* Parameters:
* @bson: A bson_t.
* @n_pairs: Number of length,buffer pairs.
* @n_bytes: the total number of bytes being appended.
* @first_len: Length of first buffer.
* @first_data: First buffer.
*
* Returns:
- * true if successful; otherwise false indicating INT_MAX overflow.
+ * true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_append (bson_t *bson, /* IN */
uint32_t n_pairs, /* IN */
uint32_t n_bytes, /* IN */
uint32_t first_len, /* IN */
const uint8_t *first_data, /* IN */
...)
{
va_list args;
bool ok;
BSON_ASSERT (n_pairs);
BSON_ASSERT (first_len);
BSON_ASSERT (first_data);
/*
* Check to see if this append would overflow 32-bit signed integer. I know
* what you're thinking. BSON uses a signed 32-bit length field? Yeah. It
* does.
*/
if (BSON_UNLIKELY (n_bytes > (BSON_MAX_SIZE - bson->len))) {
return false;
}
va_start (args, first_data);
ok = _bson_append_va (bson, n_bytes, n_pairs, first_len, first_data, args);
va_end (args);
return ok;
}
/*
*--------------------------------------------------------------------------
*
* _bson_append_bson_begin --
*
* Begin appending a subdocument or subarray to the document using
* the key provided by @key.
*
* If @key_length is < 0, then strlen() will be called on @key
* to determine the length.
*
* @key_type MUST be either BSON_TYPE_DOCUMENT or BSON_TYPE_ARRAY.
*
* Returns:
- * true if successful; otherwise false indicating INT_MAX overflow.
+ * true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* @child is initialized if true is returned.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_append_bson_begin (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bson_type_t child_type, /* IN */
bson_t *child) /* OUT */
{
const uint8_t type = child_type;
const uint8_t empty[5] = {5};
bson_impl_alloc_t *aparent = (bson_impl_alloc_t *) bson;
bson_impl_alloc_t *achild = (bson_impl_alloc_t *) child;
BSON_ASSERT (!(bson->flags & BSON_FLAG_RDONLY));
BSON_ASSERT (!(bson->flags & BSON_FLAG_IN_CHILD));
BSON_ASSERT (key);
BSON_ASSERT ((child_type == BSON_TYPE_DOCUMENT) ||
(child_type == BSON_TYPE_ARRAY));
BSON_ASSERT (child);
if (key_length < 0) {
key_length = (int) strlen (key);
}
/*
* If the parent is an inline bson_t, then we need to convert
* it to a heap allocated buffer. This makes extending buffers
* of child bson documents much simpler logic, as they can just
* realloc the *buf pointer.
*/
if ((bson->flags & BSON_FLAG_INLINE)) {
BSON_ASSERT (bson->len <= 120);
if (!_bson_grow (bson, 128 - bson->len)) {
return false;
}
BSON_ASSERT (!(bson->flags & BSON_FLAG_INLINE));
}
/*
* Append the type and key for the field.
*/
if (!_bson_append (bson,
4,
(1 + key_length + 1 + 5),
1,
&type,
key_length,
key,
1,
&gZero,
5,
empty)) {
return false;
}
/*
* Mark the document as working on a child document so that no
* further modifications can happen until the caller has called
* bson_append_{document,array}_end().
*/
bson->flags |= BSON_FLAG_IN_CHILD;
/*
* Initialize the child bson_t structure and point it at the parents
* buffers. This allows us to realloc directly from the child without
* walking up to the parent bson_t.
*/
achild->flags = (BSON_FLAG_CHILD | BSON_FLAG_NO_FREE | BSON_FLAG_STATIC);
if ((bson->flags & BSON_FLAG_CHILD)) {
achild->depth = ((bson_impl_alloc_t *) bson)->depth + 1;
} else {
achild->depth = 1;
}
achild->parent = bson;
achild->buf = aparent->buf;
achild->buflen = aparent->buflen;
achild->offset = aparent->offset + aparent->len - 1 - 5;
achild->len = 5;
achild->alloc = NULL;
achild->alloclen = 0;
achild->realloc = aparent->realloc;
achild->realloc_func_ctx = aparent->realloc_func_ctx;
return true;
}
/*
*--------------------------------------------------------------------------
*
* _bson_append_bson_end --
*
* Complete a call to _bson_append_bson_begin.
*
* Returns:
* true if successful.
*
* Side effects:
* @child is destroyed and no longer valid after calling this
* function.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_append_bson_end (bson_t *bson, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT ((bson->flags & BSON_FLAG_IN_CHILD));
BSON_ASSERT (!(child->flags & BSON_FLAG_IN_CHILD));
/*
* Unmark the IN_CHILD flag.
*/
bson->flags &= ~BSON_FLAG_IN_CHILD;
/*
* Now that we are done building the sub-document, add the size to the
* parent, not including the default 5 byte empty document already added.
*/
bson->len = (bson->len + child->len - 5);
/*
* Ensure we have a \0 byte at the end and proper length encoded at
* the beginning of the document.
*/
_bson_data (bson)[bson->len - 1] = '\0';
_bson_encode_length (bson);
return true;
}
/*
*--------------------------------------------------------------------------
*
* bson_append_array_begin --
*
* Start appending a new array.
*
* Use @child to append to the data area for the given field.
*
* It is a programming error to call any other bson function on
* @bson until bson_append_array_end() has been called. It is
* valid to call bson_append*() functions on @child.
*
* This function is useful to allow building nested documents using
* a single buffer owned by the top-level bson document.
*
* Returns:
* true if successful; otherwise false and @child is invalid.
*
* Side effects:
* @child is initialized if true is returned.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_array_begin (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (child);
return _bson_append_bson_begin (
bson, key, key_length, BSON_TYPE_ARRAY, child);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_array_end --
*
* Complete a call to bson_append_array_begin().
*
* It is safe to append other fields to @bson after calling this
* function.
*
* Returns:
* true if successful.
*
* Side effects:
* @child is invalid after calling this function.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_array_end (bson_t *bson, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT (child);
return _bson_append_bson_end (bson, child);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_document_begin --
*
* Start appending a new document.
*
* Use @child to append to the data area for the given field.
*
* It is a programming error to call any other bson function on
* @bson until bson_append_document_end() has been called. It is
* valid to call bson_append*() functions on @child.
*
* This function is useful to allow building nested documents using
* a single buffer owned by the top-level bson document.
*
* Returns:
* true if successful; otherwise false and @child is invalid.
*
* Side effects:
* @child is initialized if true is returned.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_document_begin (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (child);
return _bson_append_bson_begin (
bson, key, key_length, BSON_TYPE_DOCUMENT, child);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_document_end --
*
* Complete a call to bson_append_document_begin().
*
* It is safe to append new fields to @bson after calling this
* function, if true is returned.
*
* Returns:
- * true if successful; otherwise false indicating INT_MAX overflow.
+ * true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* @child is destroyed and invalid after calling this function.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_document_end (bson_t *bson, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT (child);
return _bson_append_bson_end (bson, child);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_array --
*
* Append an array to @bson.
*
* Generally, bson_append_array_begin() will result in faster code
* since few buffers need to be malloced.
*
* Returns:
- * true if successful; otherwise false indicating INT_MAX overflow.
+ * true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_array (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const bson_t *array) /* IN */
{
static const uint8_t type = BSON_TYPE_ARRAY;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (array);
if (key_length < 0) {
key_length = (int) strlen (key);
}
/*
* Let's be a bit pedantic and ensure the array has properly formatted key
* names. We will verify this simply by checking the first element for "0"
* if the array is non-empty.
*/
if (array && !bson_empty (array)) {
bson_iter_t iter;
if (bson_iter_init (&iter, array) && bson_iter_next (&iter)) {
if (0 != strcmp ("0", bson_iter_key (&iter))) {
fprintf (stderr,
"%s(): invalid array detected. first element of array "
"parameter is not \"0\".\n",
BSON_FUNC);
}
}
}
return _bson_append (bson,
4,
(1 + key_length + 1 + array->len),
1,
&type,
key_length,
key,
1,
&gZero,
array->len,
_bson_data (array));
}
/*
*--------------------------------------------------------------------------
*
* bson_append_binary --
*
* Append binary data to @bson. The field will have the
* BSON_TYPE_BINARY type.
*
* Parameters:
* @subtype: the BSON Binary Subtype. See bsonspec.org for more
* information.
* @binary: a pointer to the raw binary data.
* @length: the size of @binary in bytes.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_binary (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bson_subtype_t subtype, /* IN */
const uint8_t *binary, /* IN */
uint32_t length) /* IN */
{
static const uint8_t type = BSON_TYPE_BINARY;
uint32_t length_le;
uint32_t deprecated_length_le;
uint8_t subtype8 = 0;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
subtype8 = subtype;
if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
length_le = BSON_UINT32_TO_LE (length + 4);
deprecated_length_le = BSON_UINT32_TO_LE (length);
return _bson_append (bson,
7,
(1 + key_length + 1 + 4 + 1 + 4 + length),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
1,
&subtype8,
4,
&deprecated_length_le,
length,
binary);
} else {
length_le = BSON_UINT32_TO_LE (length);
return _bson_append (bson,
6,
(1 + key_length + 1 + 4 + 1 + length),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
1,
&subtype8,
length,
binary);
}
}
/*
*--------------------------------------------------------------------------
*
* bson_append_bool --
*
* Append a new field to @bson with the name @key. The value is
* a boolean indicated by @value.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_bool (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bool value) /* IN */
{
static const uint8_t type = BSON_TYPE_BOOL;
uint8_t abyte = !!value;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
return _bson_append (bson,
4,
(1 + key_length + 1 + 1),
1,
&type,
key_length,
key,
1,
&gZero,
1,
&abyte);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_code --
*
* Append a new field to @bson containing javascript code.
*
* @javascript MUST be a zero terminated UTF-8 string. It MUST NOT
* containing embedded \0 characters.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
* See also:
* bson_append_code_with_scope().
*
*--------------------------------------------------------------------------
*/
bool
bson_append_code (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const char *javascript) /* IN */
{
static const uint8_t type = BSON_TYPE_CODE;
uint32_t length;
uint32_t length_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (javascript);
if (key_length < 0) {
key_length = (int) strlen (key);
}
length = (int) strlen (javascript) + 1;
length_le = BSON_UINT32_TO_LE (length);
return _bson_append (bson,
5,
(1 + key_length + 1 + 4 + length),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
length,
javascript);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_code_with_scope --
*
* Append a new field to @bson containing javascript code with
* supplied scope.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_code_with_scope (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const char *javascript, /* IN */
const bson_t *scope) /* IN */
{
static const uint8_t type = BSON_TYPE_CODEWSCOPE;
uint32_t codews_length_le;
uint32_t codews_length;
uint32_t js_length_le;
uint32_t js_length;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (javascript);
if (scope == NULL) {
return bson_append_code (bson, key, key_length, javascript);
}
if (key_length < 0) {
key_length = (int) strlen (key);
}
js_length = (int) strlen (javascript) + 1;
js_length_le = BSON_UINT32_TO_LE (js_length);
codews_length = 4 + 4 + js_length + scope->len;
codews_length_le = BSON_UINT32_TO_LE (codews_length);
return _bson_append (bson,
7,
(1 + key_length + 1 + 4 + 4 + js_length + scope->len),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&codews_length_le,
4,
&js_length_le,
js_length,
javascript,
scope->len,
_bson_data (scope));
}
/*
*--------------------------------------------------------------------------
*
* bson_append_dbpointer --
*
* This BSON data type is DEPRECATED.
*
* Append a BSON dbpointer field to @bson.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_dbpointer (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const char *collection, /* IN */
const bson_oid_t *oid)
{
static const uint8_t type = BSON_TYPE_DBPOINTER;
uint32_t length;
uint32_t length_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (collection);
BSON_ASSERT (oid);
if (key_length < 0) {
key_length = (int) strlen (key);
}
length = (int) strlen (collection) + 1;
length_le = BSON_UINT32_TO_LE (length);
return _bson_append (bson,
6,
(1 + key_length + 1 + 4 + length + 12),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
length,
collection,
12,
oid);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_document --
*
* Append a new field to @bson containing a BSON document.
*
* In general, using bson_append_document_begin() results in faster
* code and less memory fragmentation.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
* See also:
* bson_append_document_begin().
*
*--------------------------------------------------------------------------
*/
bool
bson_append_document (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const bson_t *value) /* IN */
{
static const uint8_t type = BSON_TYPE_DOCUMENT;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
if (key_length < 0) {
key_length = (int) strlen (key);
}
return _bson_append (bson,
4,
(1 + key_length + 1 + value->len),
1,
&type,
key_length,
key,
1,
&gZero,
value->len,
_bson_data (value));
}
bool
bson_append_double (bson_t *bson, const char *key, int key_length, double value)
{
static const uint8_t type = BSON_TYPE_DOUBLE;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
value = BSON_DOUBLE_TO_LE (value);
#endif
return _bson_append (bson,
4,
(1 + key_length + 1 + 8),
1,
&type,
key_length,
key,
1,
&gZero,
8,
&value);
}
bool
bson_append_int32 (bson_t *bson, const char *key, int key_length, int32_t value)
{
static const uint8_t type = BSON_TYPE_INT32;
uint32_t value_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
value_le = BSON_UINT32_TO_LE (value);
return _bson_append (bson,
4,
(1 + key_length + 1 + 4),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&value_le);
}
bool
bson_append_int64 (bson_t *bson, const char *key, int key_length, int64_t value)
{
static const uint8_t type = BSON_TYPE_INT64;
uint64_t value_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
value_le = BSON_UINT64_TO_LE (value);
return _bson_append (bson,
4,
(1 + key_length + 1 + 8),
1,
&type,
key_length,
key,
1,
&gZero,
8,
&value_le);
}
bool
bson_append_decimal128 (bson_t *bson,
const char *key,
int key_length,
const bson_decimal128_t *value)
{
static const uint8_t type = BSON_TYPE_DECIMAL128;
uint64_t value_le[2];
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
if (key_length < 0) {
key_length = (int) strlen (key);
}
value_le[0] = BSON_UINT64_TO_LE (value->low);
value_le[1] = BSON_UINT64_TO_LE (value->high);
return _bson_append (bson,
4,
(1 + key_length + 1 + 16),
1,
&type,
key_length,
key,
1,
&gZero,
16,
value_le);
}
bool
bson_append_iter (bson_t *bson,
const char *key,
int key_length,
const bson_iter_t *iter)
{
bool ret = false;
BSON_ASSERT (bson);
BSON_ASSERT (iter);
if (!key) {
key = bson_iter_key (iter);
key_length = -1;
}
switch (bson_iter_type_unsafe (iter)) {
case BSON_TYPE_EOD:
return false;
case BSON_TYPE_DOUBLE:
ret = bson_append_double (bson, key, key_length, bson_iter_double (iter));
break;
case BSON_TYPE_UTF8: {
uint32_t len = 0;
const char *str;
str = bson_iter_utf8 (iter, &len);
ret = bson_append_utf8 (bson, key, key_length, str, len);
} break;
case BSON_TYPE_DOCUMENT: {
const uint8_t *buf = NULL;
uint32_t len = 0;
bson_t doc;
bson_iter_document (iter, &len, &buf);
if (bson_init_static (&doc, buf, len)) {
ret = bson_append_document (bson, key, key_length, &doc);
bson_destroy (&doc);
}
} break;
case BSON_TYPE_ARRAY: {
const uint8_t *buf = NULL;
uint32_t len = 0;
bson_t doc;
bson_iter_array (iter, &len, &buf);
if (bson_init_static (&doc, buf, len)) {
ret = bson_append_array (bson, key, key_length, &doc);
bson_destroy (&doc);
}
} break;
case BSON_TYPE_BINARY: {
const uint8_t *binary = NULL;
bson_subtype_t subtype = BSON_SUBTYPE_BINARY;
uint32_t len = 0;
bson_iter_binary (iter, &subtype, &len, &binary);
ret = bson_append_binary (bson, key, key_length, subtype, binary, len);
} break;
case BSON_TYPE_UNDEFINED:
ret = bson_append_undefined (bson, key, key_length);
break;
case BSON_TYPE_OID:
ret = bson_append_oid (bson, key, key_length, bson_iter_oid (iter));
break;
case BSON_TYPE_BOOL:
ret = bson_append_bool (bson, key, key_length, bson_iter_bool (iter));
break;
case BSON_TYPE_DATE_TIME:
ret = bson_append_date_time (
bson, key, key_length, bson_iter_date_time (iter));
break;
case BSON_TYPE_NULL:
ret = bson_append_null (bson, key, key_length);
break;
case BSON_TYPE_REGEX: {
const char *regex;
const char *options;
regex = bson_iter_regex (iter, &options);
ret = bson_append_regex (bson, key, key_length, regex, options);
} break;
case BSON_TYPE_DBPOINTER: {
const bson_oid_t *oid;
uint32_t len;
const char *collection;
bson_iter_dbpointer (iter, &len, &collection, &oid);
ret = bson_append_dbpointer (bson, key, key_length, collection, oid);
} break;
case BSON_TYPE_CODE: {
uint32_t len;
const char *code;
code = bson_iter_code (iter, &len);
ret = bson_append_code (bson, key, key_length, code);
} break;
case BSON_TYPE_SYMBOL: {
uint32_t len;
const char *symbol;
symbol = bson_iter_symbol (iter, &len);
ret = bson_append_symbol (bson, key, key_length, symbol, len);
} break;
case BSON_TYPE_CODEWSCOPE: {
const uint8_t *scope = NULL;
uint32_t scope_len = 0;
uint32_t len = 0;
const char *javascript = NULL;
bson_t doc;
javascript = bson_iter_codewscope (iter, &len, &scope_len, &scope);
if (bson_init_static (&doc, scope, scope_len)) {
ret = bson_append_code_with_scope (
bson, key, key_length, javascript, &doc);
bson_destroy (&doc);
}
} break;
case BSON_TYPE_INT32:
ret = bson_append_int32 (bson, key, key_length, bson_iter_int32 (iter));
break;
case BSON_TYPE_TIMESTAMP: {
uint32_t ts;
uint32_t inc;
bson_iter_timestamp (iter, &ts, &inc);
ret = bson_append_timestamp (bson, key, key_length, ts, inc);
} break;
case BSON_TYPE_INT64:
ret = bson_append_int64 (bson, key, key_length, bson_iter_int64 (iter));
break;
case BSON_TYPE_DECIMAL128: {
bson_decimal128_t dec;
if (!bson_iter_decimal128 (iter, &dec)) {
return false;
}
ret = bson_append_decimal128 (bson, key, key_length, &dec);
} break;
case BSON_TYPE_MAXKEY:
ret = bson_append_maxkey (bson, key, key_length);
break;
case BSON_TYPE_MINKEY:
ret = bson_append_minkey (bson, key, key_length);
break;
default:
break;
}
return ret;
}
bool
bson_append_maxkey (bson_t *bson, const char *key, int key_length)
{
static const uint8_t type = BSON_TYPE_MAXKEY;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
return _bson_append (
bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
}
bool
bson_append_minkey (bson_t *bson, const char *key, int key_length)
{
static const uint8_t type = BSON_TYPE_MINKEY;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
return _bson_append (
bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
}
bool
bson_append_null (bson_t *bson, const char *key, int key_length)
{
static const uint8_t type = BSON_TYPE_NULL;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
return _bson_append (
bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
}
bool
bson_append_oid (bson_t *bson,
const char *key,
int key_length,
const bson_oid_t *value)
{
static const uint8_t type = BSON_TYPE_OID;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
if (key_length < 0) {
key_length = (int) strlen (key);
}
return _bson_append (bson,
4,
(1 + key_length + 1 + 12),
1,
&type,
key_length,
key,
1,
&gZero,
12,
value);
}
/*
*--------------------------------------------------------------------------
*
* _bson_append_regex_options_sorted --
*
* Helper to append regex options to a buffer in a sorted order.
* Any duplicate or unsupported options will be ignored.
*
* Parameters:
* @buffer: Buffer to which sorted options will be appended
* @options: Regex options
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static BSON_INLINE void
_bson_append_regex_options_sorted (bson_string_t *buffer, /* IN */
const char *options) /* IN */
{
const char *c;
for (c = BSON_REGEX_OPTIONS_SORTED; *c; c++) {
if (strchr (options, *c)) {
bson_string_append_c (buffer, *c);
}
}
}
bool
bson_append_regex (bson_t *bson,
const char *key,
int key_length,
const char *regex,
const char *options)
{
return bson_append_regex_w_len (bson, key, key_length, regex, -1, options);
}
bool
bson_append_regex_w_len (bson_t *bson,
const char *key,
int key_length,
const char *regex,
int regex_length,
const char *options)
{
static const uint8_t type = BSON_TYPE_REGEX;
bson_string_t *options_sorted;
bool r;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
if (regex_length < 0) {
regex_length = (int) strlen (regex);
}
if (!regex) {
regex = "";
}
if (!options) {
options = "";
}
options_sorted = bson_string_new (NULL);
_bson_append_regex_options_sorted (options_sorted, options);
r = _bson_append (
bson,
6,
(1 + key_length + 1 + regex_length + 1 + options_sorted->len + 1),
1,
&type,
key_length,
key,
1,
&gZero,
regex_length,
regex,
1,
&gZero,
options_sorted->len + 1,
options_sorted->str);
bson_string_free (options_sorted, true);
return r;
}
bool
bson_append_utf8 (
bson_t *bson, const char *key, int key_length, const char *value, int length)
{
static const uint8_t type = BSON_TYPE_UTF8;
uint32_t length_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (BSON_UNLIKELY (!value)) {
return bson_append_null (bson, key, key_length);
}
if (BSON_UNLIKELY (key_length < 0)) {
key_length = (int) strlen (key);
}
if (BSON_UNLIKELY (length < 0)) {
length = (int) strlen (value);
}
length_le = BSON_UINT32_TO_LE (length + 1);
return _bson_append (bson,
6,
(1 + key_length + 1 + 4 + length + 1),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
length,
value,
1,
&gZero);
}
bool
bson_append_symbol (
bson_t *bson, const char *key, int key_length, const char *value, int length)
{
static const uint8_t type = BSON_TYPE_SYMBOL;
uint32_t length_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (!value) {
return bson_append_null (bson, key, key_length);
}
if (key_length < 0) {
key_length = (int) strlen (key);
}
if (length < 0) {
length = (int) strlen (value);
}
length_le = BSON_UINT32_TO_LE (length + 1);
return _bson_append (bson,
6,
(1 + key_length + 1 + 4 + length + 1),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
length,
value,
1,
&gZero);
}
bool
bson_append_time_t (bson_t *bson, const char *key, int key_length, time_t value)
{
#ifdef BSON_OS_WIN32
struct timeval tv = {(long) value, 0};
#else
struct timeval tv = {value, 0};
#endif
BSON_ASSERT (bson);
BSON_ASSERT (key);
return bson_append_timeval (bson, key, key_length, &tv);
}
bool
bson_append_timestamp (bson_t *bson,
const char *key,
int key_length,
uint32_t timestamp,
uint32_t increment)
{
static const uint8_t type = BSON_TYPE_TIMESTAMP;
uint64_t value;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
value = ((((uint64_t) timestamp) << 32) | ((uint64_t) increment));
value = BSON_UINT64_TO_LE (value);
return _bson_append (bson,
4,
(1 + key_length + 1 + 8),
1,
&type,
key_length,
key,
1,
&gZero,
8,
&value);
}
bool
bson_append_now_utc (bson_t *bson, const char *key, int key_length)
{
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (key_length >= -1);
return bson_append_time_t (bson, key, key_length, time (NULL));
}
bool
bson_append_date_time (bson_t *bson,
const char *key,
int key_length,
int64_t value)
{
static const uint8_t type = BSON_TYPE_DATE_TIME;
uint64_t value_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
value_le = BSON_UINT64_TO_LE (value);
return _bson_append (bson,
4,
(1 + key_length + 1 + 8),
1,
&type,
key_length,
key,
1,
&gZero,
8,
&value_le);
}
bool
bson_append_timeval (bson_t *bson,
const char *key,
int key_length,
struct timeval *value)
{
uint64_t unix_msec;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
unix_msec =
(((uint64_t) value->tv_sec) * 1000UL) + (value->tv_usec / 1000UL);
return bson_append_date_time (bson, key, key_length, unix_msec);
}
bool
bson_append_undefined (bson_t *bson, const char *key, int key_length)
{
static const uint8_t type = BSON_TYPE_UNDEFINED;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (key_length < 0) {
key_length = (int) strlen (key);
}
return _bson_append (
bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
}
bool
bson_append_value (bson_t *bson,
const char *key,
int key_length,
const bson_value_t *value)
{
bson_t local;
bool ret = false;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
switch (value->value_type) {
case BSON_TYPE_DOUBLE:
ret = bson_append_double (bson, key, key_length, value->value.v_double);
break;
case BSON_TYPE_UTF8:
ret = bson_append_utf8 (bson,
key,
key_length,
value->value.v_utf8.str,
value->value.v_utf8.len);
break;
case BSON_TYPE_DOCUMENT:
if (bson_init_static (
&local, value->value.v_doc.data, value->value.v_doc.data_len)) {
ret = bson_append_document (bson, key, key_length, &local);
bson_destroy (&local);
}
break;
case BSON_TYPE_ARRAY:
if (bson_init_static (
&local, value->value.v_doc.data, value->value.v_doc.data_len)) {
ret = bson_append_array (bson, key, key_length, &local);
bson_destroy (&local);
}
break;
case BSON_TYPE_BINARY:
ret = bson_append_binary (bson,
key,
key_length,
value->value.v_binary.subtype,
value->value.v_binary.data,
value->value.v_binary.data_len);
break;
case BSON_TYPE_UNDEFINED:
ret = bson_append_undefined (bson, key, key_length);
break;
case BSON_TYPE_OID:
ret = bson_append_oid (bson, key, key_length, &value->value.v_oid);
break;
case BSON_TYPE_BOOL:
ret = bson_append_bool (bson, key, key_length, value->value.v_bool);
break;
case BSON_TYPE_DATE_TIME:
ret =
bson_append_date_time (bson, key, key_length, value->value.v_datetime);
break;
case BSON_TYPE_NULL:
ret = bson_append_null (bson, key, key_length);
break;
case BSON_TYPE_REGEX:
ret = bson_append_regex (bson,
key,
key_length,
value->value.v_regex.regex,
value->value.v_regex.options);
break;
case BSON_TYPE_DBPOINTER:
ret = bson_append_dbpointer (bson,
key,
key_length,
value->value.v_dbpointer.collection,
&value->value.v_dbpointer.oid);
break;
case BSON_TYPE_CODE:
ret = bson_append_code (bson, key, key_length, value->value.v_code.code);
break;
case BSON_TYPE_SYMBOL:
ret = bson_append_symbol (bson,
key,
key_length,
value->value.v_symbol.symbol,
value->value.v_symbol.len);
break;
case BSON_TYPE_CODEWSCOPE:
if (bson_init_static (&local,
value->value.v_codewscope.scope_data,
value->value.v_codewscope.scope_len)) {
ret = bson_append_code_with_scope (
bson, key, key_length, value->value.v_codewscope.code, &local);
bson_destroy (&local);
}
break;
case BSON_TYPE_INT32:
ret = bson_append_int32 (bson, key, key_length, value->value.v_int32);
break;
case BSON_TYPE_TIMESTAMP:
ret = bson_append_timestamp (bson,
key,
key_length,
value->value.v_timestamp.timestamp,
value->value.v_timestamp.increment);
break;
case BSON_TYPE_INT64:
ret = bson_append_int64 (bson, key, key_length, value->value.v_int64);
break;
case BSON_TYPE_DECIMAL128:
ret = bson_append_decimal128 (
bson, key, key_length, &(value->value.v_decimal128));
break;
case BSON_TYPE_MAXKEY:
ret = bson_append_maxkey (bson, key, key_length);
break;
case BSON_TYPE_MINKEY:
ret = bson_append_minkey (bson, key, key_length);
break;
case BSON_TYPE_EOD:
default:
break;
}
return ret;
}
void
bson_init (bson_t *bson)
{
bson_impl_inline_t *impl = (bson_impl_inline_t *) bson;
BSON_ASSERT (bson);
#ifdef BSON_MEMCHECK
impl->canary = bson_malloc (1);
#endif
impl->flags = BSON_FLAG_INLINE | BSON_FLAG_STATIC;
impl->len = 5;
impl->data[0] = 5;
impl->data[1] = 0;
impl->data[2] = 0;
impl->data[3] = 0;
impl->data[4] = 0;
}
void
bson_reinit (bson_t *bson)
{
uint8_t *data;
BSON_ASSERT (bson);
data = _bson_data (bson);
bson->len = 5;
data[0] = 5;
data[1] = 0;
data[2] = 0;
data[3] = 0;
data[4] = 0;
}
bool
bson_init_static (bson_t *bson, const uint8_t *data, size_t length)
{
bson_impl_alloc_t *impl = (bson_impl_alloc_t *) bson;
uint32_t len_le;
BSON_ASSERT (bson);
BSON_ASSERT (data);
- if ((length < 5) || (length > INT_MAX)) {
+ if ((length < 5) || (length > BSON_MAX_SIZE)) {
return false;
}
memcpy (&len_le, data, sizeof (len_le));
if ((size_t) BSON_UINT32_FROM_LE (len_le) != length) {
return false;
}
if (data[length - 1]) {
return false;
}
impl->flags = BSON_FLAG_STATIC | BSON_FLAG_RDONLY;
impl->len = (uint32_t) length;
impl->parent = NULL;
impl->depth = 0;
impl->buf = &impl->alloc;
impl->buflen = &impl->alloclen;
impl->offset = 0;
impl->alloc = (uint8_t *) data;
impl->alloclen = length;
impl->realloc = NULL;
impl->realloc_func_ctx = NULL;
return true;
}
bson_t *
bson_new (void)
{
bson_impl_inline_t *impl;
bson_t *bson;
bson = bson_malloc (sizeof *bson);
impl = (bson_impl_inline_t *) bson;
impl->flags = BSON_FLAG_INLINE;
impl->len = 5;
#ifdef BSON_MEMCHECK
impl->canary = bson_malloc (1);
#endif
impl->data[0] = 5;
impl->data[1] = 0;
impl->data[2] = 0;
impl->data[3] = 0;
impl->data[4] = 0;
return bson;
}
bson_t *
bson_sized_new (size_t size)
{
bson_impl_alloc_t *impl_a;
bson_t *b;
- BSON_ASSERT (size <= INT32_MAX);
+ BSON_ASSERT (size <= BSON_MAX_SIZE);
b = bson_malloc (sizeof *b);
impl_a = (bson_impl_alloc_t *) b;
if (size <= BSON_INLINE_DATA_SIZE) {
bson_init (b);
b->flags &= ~BSON_FLAG_STATIC;
} else {
impl_a->flags = BSON_FLAG_NONE;
impl_a->len = 5;
impl_a->parent = NULL;
impl_a->depth = 0;
impl_a->buf = &impl_a->alloc;
impl_a->buflen = &impl_a->alloclen;
impl_a->offset = 0;
impl_a->alloclen = BSON_MAX (5, size);
impl_a->alloc = bson_malloc (impl_a->alloclen);
impl_a->alloc[0] = 5;
impl_a->alloc[1] = 0;
impl_a->alloc[2] = 0;
impl_a->alloc[3] = 0;
impl_a->alloc[4] = 0;
impl_a->realloc = bson_realloc_ctx;
impl_a->realloc_func_ctx = NULL;
}
return b;
}
bson_t *
bson_new_from_data (const uint8_t *data, size_t length)
{
uint32_t len_le;
bson_t *bson;
BSON_ASSERT (data);
- if ((length < 5) || (length > INT_MAX) || data[length - 1]) {
+ if ((length < 5) || (length > BSON_MAX_SIZE) || data[length - 1]) {
return NULL;
}
memcpy (&len_le, data, sizeof (len_le));
if (length != (size_t) BSON_UINT32_FROM_LE (len_le)) {
return NULL;
}
bson = bson_sized_new (length);
memcpy (_bson_data (bson), data, length);
bson->len = (uint32_t) length;
return bson;
}
bson_t *
bson_new_from_buffer (uint8_t **buf,
size_t *buf_len,
bson_realloc_func realloc_func,
void *realloc_func_ctx)
{
bson_impl_alloc_t *impl;
uint32_t len_le;
uint32_t length;
bson_t *bson;
BSON_ASSERT (buf);
BSON_ASSERT (buf_len);
if (!realloc_func) {
realloc_func = bson_realloc_ctx;
}
bson = bson_malloc0 (sizeof *bson);
impl = (bson_impl_alloc_t *) bson;
if (!*buf) {
length = 5;
len_le = BSON_UINT32_TO_LE (length);
*buf_len = 5;
*buf = realloc_func (*buf, *buf_len, realloc_func_ctx);
memcpy (*buf, &len_le, sizeof (len_le));
(*buf)[4] = '\0';
} else {
- if ((*buf_len < 5) || (*buf_len > INT_MAX)) {
+ if ((*buf_len < 5) || (*buf_len > BSON_MAX_SIZE)) {
bson_free (bson);
return NULL;
}
memcpy (&len_le, *buf, sizeof (len_le));
length = BSON_UINT32_FROM_LE (len_le);
}
if ((*buf)[length - 1]) {
bson_free (bson);
return NULL;
}
impl->flags = BSON_FLAG_NO_FREE;
impl->len = length;
impl->buf = buf;
impl->buflen = buf_len;
impl->realloc = realloc_func;
impl->realloc_func_ctx = realloc_func_ctx;
return bson;
}
bson_t *
bson_copy (const bson_t *bson)
{
const uint8_t *data;
BSON_ASSERT (bson);
data = _bson_data (bson);
return bson_new_from_data (data, bson->len);
}
void
bson_copy_to (const bson_t *src, bson_t *dst)
{
const uint8_t *data;
bson_impl_alloc_t *adst;
size_t len;
BSON_ASSERT (src);
BSON_ASSERT (dst);
if ((src->flags & BSON_FLAG_INLINE)) {
#ifdef BSON_MEMCHECK
dst->len = src->len;
dst->canary = malloc (1);
memcpy (dst->padding, src->padding, sizeof dst->padding);
#else
memcpy (dst, src, sizeof *dst);
#endif
dst->flags = (BSON_FLAG_STATIC | BSON_FLAG_INLINE);
return;
}
data = _bson_data (src);
len = bson_next_power_of_two ((size_t) src->len);
adst = (bson_impl_alloc_t *) dst;
adst->flags = BSON_FLAG_STATIC;
adst->len = src->len;
adst->parent = NULL;
adst->depth = 0;
adst->buf = &adst->alloc;
adst->buflen = &adst->alloclen;
adst->offset = 0;
adst->alloc = bson_malloc (len);
adst->alloclen = len;
adst->realloc = bson_realloc_ctx;
adst->realloc_func_ctx = NULL;
memcpy (adst->alloc, data, src->len);
}
static bool
should_ignore (const char *first_exclude, va_list args, const char *name)
{
bool ret = false;
const char *exclude = first_exclude;
va_list args_copy;
va_copy (args_copy, args);
do {
if (!strcmp (name, exclude)) {
ret = true;
break;
}
} while ((exclude = va_arg (args_copy, const char *)));
va_end (args_copy);
return ret;
}
void
bson_copy_to_excluding_noinit_va (const bson_t *src,
bson_t *dst,
const char *first_exclude,
va_list args)
{
bson_iter_t iter;
if (bson_iter_init (&iter, src)) {
while (bson_iter_next (&iter)) {
if (!should_ignore (first_exclude, args, bson_iter_key (&iter))) {
if (!bson_append_iter (dst, NULL, 0, &iter)) {
/*
* This should not be able to happen since we are copying
* from within a valid bson_t.
*/
BSON_ASSERT (false);
return;
}
}
}
}
}
void
bson_copy_to_excluding (const bson_t *src,
bson_t *dst,
const char *first_exclude,
...)
{
va_list args;
BSON_ASSERT (src);
BSON_ASSERT (dst);
BSON_ASSERT (first_exclude);
bson_init (dst);
va_start (args, first_exclude);
bson_copy_to_excluding_noinit_va (src, dst, first_exclude, args);
va_end (args);
}
void
bson_copy_to_excluding_noinit (const bson_t *src,
bson_t *dst,
const char *first_exclude,
...)
{
va_list args;
BSON_ASSERT (src);
BSON_ASSERT (dst);
BSON_ASSERT (first_exclude);
va_start (args, first_exclude);
bson_copy_to_excluding_noinit_va (src, dst, first_exclude, args);
va_end (args);
}
void
bson_destroy (bson_t *bson)
{
if (!bson) {
return;
}
if (!(bson->flags &
(BSON_FLAG_RDONLY | BSON_FLAG_INLINE | BSON_FLAG_NO_FREE))) {
bson_free (*((bson_impl_alloc_t *) bson)->buf);
}
#ifdef BSON_MEMCHECK
if (bson->flags & BSON_FLAG_INLINE) {
bson_free (bson->canary);
}
#endif
if (!(bson->flags & BSON_FLAG_STATIC)) {
bson_free (bson);
}
}
uint8_t *
bson_reserve_buffer (bson_t *bson, uint32_t size)
{
if (bson->flags &
(BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY)) {
return NULL;
}
if (!_bson_grow (bson, size)) {
return NULL;
}
if (bson->flags & BSON_FLAG_INLINE) {
/* bson_grow didn't spill over */
((bson_impl_inline_t *) bson)->len = size;
} else {
((bson_impl_alloc_t *) bson)->len = size;
}
return _bson_data (bson);
}
bool
bson_steal (bson_t *dst, bson_t *src)
{
bson_impl_inline_t *src_inline;
bson_impl_inline_t *dst_inline;
bson_impl_alloc_t *alloc;
BSON_ASSERT (dst);
BSON_ASSERT (src);
bson_init (dst);
if (src->flags & (BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY)) {
return false;
}
if (src->flags & BSON_FLAG_INLINE) {
src_inline = (bson_impl_inline_t *) src;
dst_inline = (bson_impl_inline_t *) dst;
dst_inline->len = src_inline->len;
memcpy (dst_inline->data, src_inline->data, sizeof src_inline->data);
/* for consistency, src is always invalid after steal, even if inline */
src->len = 0;
#ifdef BSON_MEMCHECK
bson_free (src->canary);
#endif
} else {
#ifdef BSON_MEMCHECK
bson_free (dst->canary);
#endif
memcpy (dst, src, sizeof (bson_t));
alloc = (bson_impl_alloc_t *) dst;
alloc->flags |= BSON_FLAG_STATIC;
alloc->buf = &alloc->alloc;
alloc->buflen = &alloc->alloclen;
}
if (!(src->flags & BSON_FLAG_STATIC)) {
bson_free (src);
} else {
/* src is invalid after steal */
src->len = 0;
}
return true;
}
uint8_t *
bson_destroy_with_steal (bson_t *bson, bool steal, uint32_t *length)
{
uint8_t *ret = NULL;
BSON_ASSERT (bson);
if (length) {
*length = bson->len;
}
if (!steal) {
bson_destroy (bson);
return NULL;
}
if ((bson->flags &
(BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY))) {
/* Do nothing */
} else if ((bson->flags & BSON_FLAG_INLINE)) {
bson_impl_inline_t *inl;
inl = (bson_impl_inline_t *) bson;
ret = bson_malloc (bson->len);
memcpy (ret, inl->data, bson->len);
} else {
bson_impl_alloc_t *alloc;
alloc = (bson_impl_alloc_t *) bson;
ret = *alloc->buf;
*alloc->buf = NULL;
}
bson_destroy (bson);
return ret;
}
const uint8_t *
bson_get_data (const bson_t *bson)
{
BSON_ASSERT (bson);
return _bson_data (bson);
}
uint32_t
bson_count_keys (const bson_t *bson)
{
uint32_t count = 0;
bson_iter_t iter;
BSON_ASSERT (bson);
if (bson_iter_init (&iter, bson)) {
while (bson_iter_next (&iter)) {
count++;
}
}
return count;
}
bool
bson_has_field (const bson_t *bson, const char *key)
{
bson_iter_t iter;
bson_iter_t child;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (NULL != strchr (key, '.')) {
return (bson_iter_init (&iter, bson) &&
bson_iter_find_descendant (&iter, key, &child));
}
return bson_iter_init_find (&iter, bson, key);
}
int
bson_compare (const bson_t *bson, const bson_t *other)
{
const uint8_t *data1;
const uint8_t *data2;
size_t len1;
size_t len2;
int64_t ret;
data1 = _bson_data (bson) + 4;
len1 = bson->len - 4;
data2 = _bson_data (other) + 4;
len2 = other->len - 4;
if (len1 == len2) {
return memcmp (data1, data2, len1);
}
ret = memcmp (data1, data2, BSON_MIN (len1, len2));
if (ret == 0) {
- ret = (int64_t) (len1 - len2);
+ ret = (int64_t) len1 - (int64_t) len2;
}
return (ret < 0) ? -1 : (ret > 0);
}
bool
bson_equal (const bson_t *bson, const bson_t *other)
{
return !bson_compare (bson, other);
}
static bool
_bson_as_json_visit_utf8 (const bson_iter_t *iter,
const char *key,
size_t v_utf8_len,
const char *v_utf8,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
escaped = bson_utf8_escape_for_json (v_utf8, v_utf8_len);
if (escaped) {
bson_string_append (state->str, "\"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\"");
bson_free (escaped);
return false;
}
return true;
}
static bool
_bson_as_json_visit_int32 (const bson_iter_t *iter,
const char *key,
int32_t v_int32,
void *data)
{
bson_json_state_t *state = data;
if (state->mode == BSON_JSON_MODE_CANONICAL) {
bson_string_append_printf (
state->str, "{ \"$numberInt\" : \"%" PRId32 "\" }", v_int32);
} else {
bson_string_append_printf (state->str, "%" PRId32, v_int32);
}
return false;
}
static bool
_bson_as_json_visit_int64 (const bson_iter_t *iter,
const char *key,
int64_t v_int64,
void *data)
{
bson_json_state_t *state = data;
if (state->mode == BSON_JSON_MODE_CANONICAL) {
bson_string_append_printf (
state->str, "{ \"$numberLong\" : \"%" PRId64 "\"}", v_int64);
} else {
bson_string_append_printf (state->str, "%" PRId64, v_int64);
}
return false;
}
static bool
_bson_as_json_visit_decimal128 (const bson_iter_t *iter,
const char *key,
const bson_decimal128_t *value,
void *data)
{
bson_json_state_t *state = data;
char decimal128_string[BSON_DECIMAL128_STRING];
bson_decimal128_to_string (value, decimal128_string);
bson_string_append (state->str, "{ \"$numberDecimal\" : \"");
bson_string_append (state->str, decimal128_string);
bson_string_append (state->str, "\" }");
return false;
}
static bool
_bson_as_json_visit_double (const bson_iter_t *iter,
const char *key,
double v_double,
void *data)
{
bson_json_state_t *state = data;
bson_string_t *str = state->str;
uint32_t start_len;
bool legacy;
/* Determine if legacy (i.e. unwrapped) output should be used. Relaxed mode
* will use this for nan and inf values, which we check manually since old
* platforms may not have isinf or isnan. */
legacy = state->mode == BSON_JSON_MODE_LEGACY ||
(state->mode == BSON_JSON_MODE_RELAXED &&
!(v_double != v_double || v_double * 0 != 0));
if (!legacy) {
bson_string_append (state->str, "{ \"$numberDouble\" : \"");
}
if (!legacy && v_double != v_double) {
bson_string_append (str, "NaN");
} else if (!legacy && v_double * 0 != 0) {
if (v_double > 0) {
bson_string_append (str, "Infinity");
} else {
bson_string_append (str, "-Infinity");
}
} else {
start_len = str->len;
bson_string_append_printf (str, "%.20g", v_double);
/* ensure trailing ".0" to distinguish "3" from "3.0" */
if (strspn (&str->str[start_len], "0123456789-") ==
str->len - start_len) {
bson_string_append (str, ".0");
}
}
if (!legacy) {
bson_string_append (state->str, "\" }");
}
return false;
}
static bool
_bson_as_json_visit_undefined (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "{ \"$undefined\" : true }");
return false;
}
static bool
_bson_as_json_visit_null (const bson_iter_t *iter, const char *key, void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "null");
return false;
}
static bool
_bson_as_json_visit_oid (const bson_iter_t *iter,
const char *key,
const bson_oid_t *oid,
void *data)
{
bson_json_state_t *state = data;
char str[25];
bson_oid_to_string (oid, str);
bson_string_append (state->str, "{ \"$oid\" : \"");
bson_string_append (state->str, str);
bson_string_append (state->str, "\" }");
return false;
}
static bool
_bson_as_json_visit_binary (const bson_iter_t *iter,
const char *key,
bson_subtype_t v_subtype,
size_t v_binary_len,
const uint8_t *v_binary,
void *data)
{
bson_json_state_t *state = data;
size_t b64_len;
char *b64;
- b64_len = (v_binary_len / 3 + 1) * 4 + 1;
+ b64_len = COMMON_PREFIX (bson_b64_ntop_calculate_target_size (v_binary_len));
b64 = bson_malloc0 (b64_len);
- BSON_ASSERT (bson_b64_ntop (v_binary, v_binary_len, b64, b64_len) != -1);
+ BSON_ASSERT (
+ COMMON_PREFIX (bson_b64_ntop (v_binary, v_binary_len, b64, b64_len) != -1));
if (state->mode == BSON_JSON_MODE_CANONICAL ||
state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str, "{ \"$binary\" : { \"base64\": \"");
bson_string_append (state->str, b64);
bson_string_append (state->str, "\", \"subType\" : \"");
bson_string_append_printf (state->str, "%02x", v_subtype);
bson_string_append (state->str, "\" } }");
} else {
bson_string_append (state->str, "{ \"$binary\" : \"");
bson_string_append (state->str, b64);
bson_string_append (state->str, "\", \"$type\" : \"");
bson_string_append_printf (state->str, "%02x", v_subtype);
bson_string_append (state->str, "\" }");
}
bson_free (b64);
return false;
}
static bool
_bson_as_json_visit_bool (const bson_iter_t *iter,
const char *key,
bool v_bool,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, v_bool ? "true" : "false");
return false;
}
static bool
_bson_as_json_visit_date_time (const bson_iter_t *iter,
const char *key,
int64_t msec_since_epoch,
void *data)
{
bson_json_state_t *state = data;
if (state->mode == BSON_JSON_MODE_CANONICAL ||
(state->mode == BSON_JSON_MODE_RELAXED && msec_since_epoch < 0)) {
bson_string_append (state->str, "{ \"$date\" : { \"$numberLong\" : \"");
bson_string_append_printf (state->str, "%" PRId64, msec_since_epoch);
bson_string_append (state->str, "\" } }");
} else if (state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str, "{ \"$date\" : \"");
_bson_iso8601_date_format (msec_since_epoch, state->str);
bson_string_append (state->str, "\" }");
} else {
bson_string_append (state->str, "{ \"$date\" : ");
bson_string_append_printf (state->str, "%" PRId64, msec_since_epoch);
bson_string_append (state->str, " }");
}
return false;
}
static bool
_bson_as_json_visit_regex (const bson_iter_t *iter,
const char *key,
const char *v_regex,
const char *v_options,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
escaped = bson_utf8_escape_for_json (v_regex, -1);
if (!escaped) {
return true;
}
if (state->mode == BSON_JSON_MODE_CANONICAL ||
state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str,
"{ \"$regularExpression\" : { \"pattern\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\", \"options\" : \"");
_bson_append_regex_options_sorted (state->str, v_options);
bson_string_append (state->str, "\" } }");
} else {
bson_string_append (state->str, "{ \"$regex\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\", \"$options\" : \"");
_bson_append_regex_options_sorted (state->str, v_options);
bson_string_append (state->str, "\" }");
}
bson_free (escaped);
return false;
}
static bool
_bson_as_json_visit_timestamp (const bson_iter_t *iter,
const char *key,
uint32_t v_timestamp,
uint32_t v_increment,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "{ \"$timestamp\" : { \"t\" : ");
bson_string_append_printf (state->str, "%u", v_timestamp);
bson_string_append (state->str, ", \"i\" : ");
bson_string_append_printf (state->str, "%u", v_increment);
bson_string_append (state->str, " } }");
return false;
}
static bool
_bson_as_json_visit_dbpointer (const bson_iter_t *iter,
const char *key,
size_t v_collection_len,
const char *v_collection,
const bson_oid_t *v_oid,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
char str[25];
escaped = bson_utf8_escape_for_json (v_collection, -1);
if (!escaped) {
return true;
}
if (state->mode == BSON_JSON_MODE_CANONICAL ||
state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str, "{ \"$dbPointer\" : { \"$ref\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\"");
if (v_oid) {
bson_oid_to_string (v_oid, str);
bson_string_append (state->str, ", \"$id\" : { \"$oid\" : \"");
bson_string_append (state->str, str);
bson_string_append (state->str, "\" }");
}
bson_string_append (state->str, " } }");
} else {
bson_string_append (state->str, "{ \"$ref\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\"");
if (v_oid) {
bson_oid_to_string (v_oid, str);
bson_string_append (state->str, ", \"$id\" : \"");
bson_string_append (state->str, str);
bson_string_append (state->str, "\"");
}
bson_string_append (state->str, " }");
}
bson_free (escaped);
return false;
}
static bool
_bson_as_json_visit_minkey (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "{ \"$minKey\" : 1 }");
return false;
}
static bool
_bson_as_json_visit_maxkey (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "{ \"$maxKey\" : 1 }");
return false;
}
static bool
_bson_as_json_visit_before (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
if (state->count) {
bson_string_append (state->str, ", ");
}
if (state->keys) {
escaped = bson_utf8_escape_for_json (key, -1);
if (escaped) {
bson_string_append (state->str, "\"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\" : ");
bson_free (escaped);
} else {
return true;
}
}
state->count++;
return false;
}
static void
_bson_as_json_visit_corrupt (const bson_iter_t *iter, void *data)
{
*(((bson_json_state_t *) data)->err_offset) = iter->off;
}
static bool
_bson_as_json_visit_code (const bson_iter_t *iter,
const char *key,
size_t v_code_len,
const char *v_code,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
escaped = bson_utf8_escape_for_json (v_code, v_code_len);
if (!escaped) {
return true;
}
bson_string_append (state->str, "{ \"$code\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\" }");
bson_free (escaped);
return false;
}
static bool
_bson_as_json_visit_symbol (const bson_iter_t *iter,
const char *key,
size_t v_symbol_len,
const char *v_symbol,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
escaped = bson_utf8_escape_for_json (v_symbol, v_symbol_len);
if (!escaped) {
return true;
}
if (state->mode == BSON_JSON_MODE_CANONICAL ||
state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str, "{ \"$symbol\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\" }");
} else {
bson_string_append (state->str, "\"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\"");
}
bson_free (escaped);
return false;
}
static bool
_bson_as_json_visit_codewscope (const bson_iter_t *iter,
const char *key,
size_t v_code_len,
const char *v_code,
const bson_t *v_scope,
void *data)
{
bson_json_state_t *state = data;
char *code_escaped;
char *scope;
code_escaped = bson_utf8_escape_for_json (v_code, v_code_len);
if (!code_escaped) {
return true;
}
/* Encode scope with the same mode */
scope = _bson_as_json_visit_all (v_scope, NULL, state->mode);
if (!scope) {
bson_free (code_escaped);
return true;
}
bson_string_append (state->str, "{ \"$code\" : \"");
bson_string_append (state->str, code_escaped);
bson_string_append (state->str, "\", \"$scope\" : ");
bson_string_append (state->str, scope);
bson_string_append (state->str, " }");
bson_free (code_escaped);
bson_free (scope);
return false;
}
static const bson_visitor_t bson_as_json_visitors = {
_bson_as_json_visit_before, NULL, /* visit_after */
_bson_as_json_visit_corrupt, _bson_as_json_visit_double,
_bson_as_json_visit_utf8, _bson_as_json_visit_document,
_bson_as_json_visit_array, _bson_as_json_visit_binary,
_bson_as_json_visit_undefined, _bson_as_json_visit_oid,
_bson_as_json_visit_bool, _bson_as_json_visit_date_time,
_bson_as_json_visit_null, _bson_as_json_visit_regex,
_bson_as_json_visit_dbpointer, _bson_as_json_visit_code,
_bson_as_json_visit_symbol, _bson_as_json_visit_codewscope,
_bson_as_json_visit_int32, _bson_as_json_visit_timestamp,
_bson_as_json_visit_int64, _bson_as_json_visit_maxkey,
_bson_as_json_visit_minkey, NULL, /* visit_unsupported_type */
_bson_as_json_visit_decimal128,
};
static bool
_bson_as_json_visit_document (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data)
{
bson_json_state_t *state = data;
bson_json_state_t child_state = {0, true, state->err_offset};
bson_iter_t child;
if (state->depth >= BSON_MAX_RECURSION) {
bson_string_append (state->str, "{ ... }");
return false;
}
if (bson_iter_init (&child, v_document)) {
child_state.str = bson_string_new ("{ ");
child_state.depth = state->depth + 1;
child_state.mode = state->mode;
if (bson_iter_visit_all (&child, &bson_as_json_visitors, &child_state)) {
bson_string_free (child_state.str, true);
return true;
}
bson_string_append (child_state.str, " }");
bson_string_append (state->str, child_state.str->str);
bson_string_free (child_state.str, true);
}
return false;
}
static bool
_bson_as_json_visit_array (const bson_iter_t *iter,
const char *key,
const bson_t *v_array,
void *data)
{
bson_json_state_t *state = data;
bson_json_state_t child_state = {0, false, state->err_offset};
bson_iter_t child;
if (state->depth >= BSON_MAX_RECURSION) {
bson_string_append (state->str, "{ ... }");
return false;
}
if (bson_iter_init (&child, v_array)) {
child_state.str = bson_string_new ("[ ");
child_state.depth = state->depth + 1;
child_state.mode = state->mode;
if (bson_iter_visit_all (&child, &bson_as_json_visitors, &child_state)) {
bson_string_free (child_state.str, true);
return true;
}
bson_string_append (child_state.str, " ]");
bson_string_append (state->str, child_state.str->str);
bson_string_free (child_state.str, true);
}
return false;
}
static char *
_bson_as_json_visit_all (const bson_t *bson,
size_t *length,
bson_json_mode_t mode)
{
bson_json_state_t state;
bson_iter_t iter;
ssize_t err_offset = -1;
BSON_ASSERT (bson);
if (length) {
*length = 0;
}
if (bson_empty0 (bson)) {
if (length) {
*length = 3;
}
return bson_strdup ("{ }");
}
if (!bson_iter_init (&iter, bson)) {
return NULL;
}
state.count = 0;
state.keys = true;
state.str = bson_string_new ("{ ");
state.depth = 0;
state.err_offset = &err_offset;
state.mode = mode;
if (bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) ||
err_offset != -1) {
/*
* We were prematurely exited due to corruption or failed visitor.
*/
bson_string_free (state.str, true);
if (length) {
*length = 0;
}
return NULL;
}
bson_string_append (state.str, " }");
if (length) {
*length = state.str->len;
}
return bson_string_free (state.str, false);
}
char *
bson_as_canonical_extended_json (const bson_t *bson, size_t *length)
{
return _bson_as_json_visit_all (bson, length, BSON_JSON_MODE_CANONICAL);
}
char *
bson_as_json (const bson_t *bson, size_t *length)
{
return _bson_as_json_visit_all (bson, length, BSON_JSON_MODE_LEGACY);
}
char *
bson_as_relaxed_extended_json (const bson_t *bson, size_t *length)
{
return _bson_as_json_visit_all (bson, length, BSON_JSON_MODE_RELAXED);
}
char *
bson_array_as_json (const bson_t *bson, size_t *length)
{
bson_json_state_t state;
bson_iter_t iter;
ssize_t err_offset = -1;
BSON_ASSERT (bson);
if (length) {
*length = 0;
}
if (bson_empty0 (bson)) {
if (length) {
*length = 3;
}
return bson_strdup ("[ ]");
}
if (!bson_iter_init (&iter, bson)) {
return NULL;
}
state.count = 0;
state.keys = false;
state.str = bson_string_new ("[ ");
state.depth = 0;
state.err_offset = &err_offset;
state.mode = BSON_JSON_MODE_LEGACY;
if (bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) ||
err_offset != -1) {
/*
* We were prematurely exited due to corruption or failed visitor.
*/
bson_string_free (state.str, true);
if (length) {
*length = 0;
}
return NULL;
}
bson_string_append (state.str, " ]");
if (length) {
*length = state.str->len;
}
return bson_string_free (state.str, false);
}
#define VALIDATION_ERR(_flag, _msg, ...) \
bson_set_error (&state->error, BSON_ERROR_INVALID, _flag, _msg, __VA_ARGS__)
static bool
_bson_iter_validate_utf8 (const bson_iter_t *iter,
const char *key,
size_t v_utf8_len,
const char *v_utf8,
void *data)
{
bson_validate_state_t *state = data;
bool allow_null;
if ((state->flags & BSON_VALIDATE_UTF8)) {
allow_null = !!(state->flags & BSON_VALIDATE_UTF8_ALLOW_NULL);
if (!bson_utf8_validate (v_utf8, v_utf8_len, allow_null)) {
state->err_offset = iter->off;
VALIDATION_ERR (
BSON_VALIDATE_UTF8, "invalid utf8 string for key \"%s\"", key);
return true;
}
}
if ((state->flags & BSON_VALIDATE_DOLLAR_KEYS)) {
if (state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8) {
state->phase = BSON_VALIDATE_PHASE_LF_ID_KEY;
} else if (state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
state->phase = BSON_VALIDATE_PHASE_NOT_DBREF;
}
}
return false;
}
static void
_bson_iter_validate_corrupt (const bson_iter_t *iter, void *data)
{
bson_validate_state_t *state = data;
state->err_offset = iter->err_off;
VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt BSON");
}
static bool
_bson_iter_validate_before (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_validate_state_t *state = data;
if ((state->flags & BSON_VALIDATE_EMPTY_KEYS)) {
if (key[0] == '\0') {
state->err_offset = iter->off;
VALIDATION_ERR (BSON_VALIDATE_EMPTY_KEYS, "%s", "empty key");
return true;
}
}
if ((state->flags & BSON_VALIDATE_DOLLAR_KEYS)) {
if (key[0] == '$') {
if (state->phase == BSON_VALIDATE_PHASE_LF_REF_KEY &&
strcmp (key, "$ref") == 0) {
state->phase = BSON_VALIDATE_PHASE_LF_REF_UTF8;
} else if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY &&
strcmp (key, "$id") == 0) {
state->phase = BSON_VALIDATE_PHASE_LF_DB_KEY;
} else if (state->phase == BSON_VALIDATE_PHASE_LF_DB_KEY &&
strcmp (key, "$db") == 0) {
state->phase = BSON_VALIDATE_PHASE_LF_DB_UTF8;
} else {
state->err_offset = iter->off;
VALIDATION_ERR (BSON_VALIDATE_DOLLAR_KEYS,
"keys cannot begin with \"$\": \"%s\"",
key);
return true;
}
} else if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY ||
state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8 ||
state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
state->err_offset = iter->off;
VALIDATION_ERR (BSON_VALIDATE_DOLLAR_KEYS,
"invalid key within DBRef subdocument: \"%s\"",
key);
return true;
} else {
state->phase = BSON_VALIDATE_PHASE_NOT_DBREF;
}
}
if ((state->flags & BSON_VALIDATE_DOT_KEYS)) {
if (strstr (key, ".")) {
state->err_offset = iter->off;
VALIDATION_ERR (
BSON_VALIDATE_DOT_KEYS, "keys cannot contain \".\": \"%s\"", key);
return true;
}
}
return false;
}
static bool
_bson_iter_validate_codewscope (const bson_iter_t *iter,
const char *key,
size_t v_code_len,
const char *v_code,
const bson_t *v_scope,
void *data)
{
bson_validate_state_t *state = data;
size_t offset = 0;
if (!bson_validate (v_scope, state->flags, &offset)) {
state->err_offset = iter->off + offset;
VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt code-with-scope");
return false;
}
return true;
}
static bool
_bson_iter_validate_document (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data);
static const bson_visitor_t bson_validate_funcs = {
_bson_iter_validate_before,
NULL, /* visit_after */
_bson_iter_validate_corrupt,
NULL, /* visit_double */
_bson_iter_validate_utf8,
_bson_iter_validate_document,
_bson_iter_validate_document, /* visit_array */
NULL, /* visit_binary */
NULL, /* visit_undefined */
NULL, /* visit_oid */
NULL, /* visit_bool */
NULL, /* visit_date_time */
NULL, /* visit_null */
NULL, /* visit_regex */
NULL, /* visit_dbpoint */
NULL, /* visit_code */
NULL, /* visit_symbol */
_bson_iter_validate_codewscope,
};
static bool
_bson_iter_validate_document (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data)
{
bson_validate_state_t *state = data;
bson_iter_t child;
bson_validate_phase_t phase = state->phase;
if (!bson_iter_init (&child, v_document)) {
state->err_offset = iter->off;
return true;
}
if (state->phase == BSON_VALIDATE_PHASE_START) {
state->phase = BSON_VALIDATE_PHASE_TOP;
} else {
state->phase = BSON_VALIDATE_PHASE_LF_REF_KEY;
}
(void) bson_iter_visit_all (&child, &bson_validate_funcs, state);
if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY ||
state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8 ||
state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
if (state->err_offset <= 0) {
state->err_offset = iter->off;
}
return true;
}
state->phase = phase;
return false;
}
static void
_bson_validate_internal (const bson_t *bson, bson_validate_state_t *state)
{
bson_iter_t iter;
state->err_offset = -1;
state->phase = BSON_VALIDATE_PHASE_START;
memset (&state->error, 0, sizeof state->error);
if (!bson_iter_init (&iter, bson)) {
state->err_offset = 0;
VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt BSON");
} else {
_bson_iter_validate_document (&iter, NULL, bson, state);
}
}
bool
bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset)
{
bson_validate_state_t state;
state.flags = flags;
_bson_validate_internal (bson, &state);
if (state.err_offset > 0 && offset) {
*offset = (size_t) state.err_offset;
}
return state.err_offset < 0;
}
bool
bson_validate_with_error (const bson_t *bson,
bson_validate_flags_t flags,
bson_error_t *error)
{
bson_validate_state_t state;
state.flags = flags;
_bson_validate_internal (bson, &state);
if (state.err_offset > 0 && error) {
memcpy (error, &state.error, sizeof *error);
}
return state.err_offset < 0;
}
bool
bson_concat (bson_t *dst, const bson_t *src)
{
BSON_ASSERT (dst);
BSON_ASSERT (src);
if (!bson_empty (src)) {
return _bson_append (
dst, 1, src->len - 5, src->len - 5, _bson_data (src) + 4);
}
return true;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson.h
index e2b9617f..3bd4169e 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libbson/src/bson/bson.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libbson/src/bson/bson.h
@@ -1,1150 +1,1150 @@
/*
* Copyright 2013 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.
*/
#ifndef BSON_H
#define BSON_H
#define BSON_INSIDE
#include "bson-compat.h"
#include <string.h>
#include <time.h>
#include "bson-macros.h"
#include "bson-config.h"
#include "bson-atomic.h"
#include "bson-context.h"
#include "bson-clock.h"
#include "bson-decimal128.h"
#include "bson-error.h"
#include "bson-iter.h"
#include "bson-json.h"
#include "bson-keys.h"
#include "bson-md5.h"
#include "bson-memory.h"
#include "bson-oid.h"
#include "bson-reader.h"
#include "bson-string.h"
#include "bson-types.h"
#include "bson-utf8.h"
#include "bson-value.h"
#include "bson-version.h"
#include "bson-version-functions.h"
#include "bson-writer.h"
#include "bcon.h"
#undef BSON_INSIDE
BSON_BEGIN_DECLS
/**
* bson_empty:
* @b: a bson_t.
*
* Checks to see if @b is an empty BSON document. An empty BSON document is
* a 5 byte document which contains the length (4 bytes) and a single NUL
* byte indicating end of fields.
*/
#define bson_empty(b) (((b)->len == 5) || !bson_get_data ((b))[4])
/**
* bson_empty0:
*
* Like bson_empty() but treats NULL the same as an empty bson_t document.
*/
#define bson_empty0(b) (!(b) || bson_empty (b))
/**
* bson_clear:
*
* Easily free a bson document and set it to NULL. Use like:
*
* bson_t *doc = bson_new();
* bson_clear (&doc);
* BSON_ASSERT (doc == NULL);
*/
#define bson_clear(bptr) \
do { \
if (*(bptr)) { \
bson_destroy (*(bptr)); \
*(bptr) = NULL; \
} \
} while (0)
/**
* BSON_MAX_SIZE:
*
* The maximum size in bytes of a BSON document.
*/
#define BSON_MAX_SIZE ((size_t) ((1U << 31) - 1))
#define BSON_APPEND_ARRAY(b, key, val) \
bson_append_array (b, key, (int) strlen (key), val)
#define BSON_APPEND_ARRAY_BEGIN(b, key, child) \
bson_append_array_begin (b, key, (int) strlen (key), child)
#define BSON_APPEND_BINARY(b, key, subtype, val, len) \
bson_append_binary (b, key, (int) strlen (key), subtype, val, len)
#define BSON_APPEND_BOOL(b, key, val) \
bson_append_bool (b, key, (int) strlen (key), val)
#define BSON_APPEND_CODE(b, key, val) \
bson_append_code (b, key, (int) strlen (key), val)
#define BSON_APPEND_CODE_WITH_SCOPE(b, key, val, scope) \
bson_append_code_with_scope (b, key, (int) strlen (key), val, scope)
#define BSON_APPEND_DBPOINTER(b, key, coll, oid) \
bson_append_dbpointer (b, key, (int) strlen (key), coll, oid)
#define BSON_APPEND_DOCUMENT_BEGIN(b, key, child) \
bson_append_document_begin (b, key, (int) strlen (key), child)
#define BSON_APPEND_DOUBLE(b, key, val) \
bson_append_double (b, key, (int) strlen (key), val)
#define BSON_APPEND_DOCUMENT(b, key, val) \
bson_append_document (b, key, (int) strlen (key), val)
#define BSON_APPEND_INT32(b, key, val) \
bson_append_int32 (b, key, (int) strlen (key), val)
#define BSON_APPEND_INT64(b, key, val) \
bson_append_int64 (b, key, (int) strlen (key), val)
#define BSON_APPEND_MINKEY(b, key) \
bson_append_minkey (b, key, (int) strlen (key))
#define BSON_APPEND_DECIMAL128(b, key, val) \
bson_append_decimal128 (b, key, (int) strlen (key), val)
#define BSON_APPEND_MAXKEY(b, key) \
bson_append_maxkey (b, key, (int) strlen (key))
#define BSON_APPEND_NULL(b, key) bson_append_null (b, key, (int) strlen (key))
#define BSON_APPEND_OID(b, key, val) \
bson_append_oid (b, key, (int) strlen (key), val)
#define BSON_APPEND_REGEX(b, key, val, opt) \
bson_append_regex (b, key, (int) strlen (key), val, opt)
#define BSON_APPEND_UTF8(b, key, val) \
bson_append_utf8 (b, key, (int) strlen (key), val, (int) strlen (val))
#define BSON_APPEND_SYMBOL(b, key, val) \
bson_append_symbol (b, key, (int) strlen (key), val, (int) strlen (val))
#define BSON_APPEND_TIME_T(b, key, val) \
bson_append_time_t (b, key, (int) strlen (key), val)
#define BSON_APPEND_TIMEVAL(b, key, val) \
bson_append_timeval (b, key, (int) strlen (key), val)
#define BSON_APPEND_DATE_TIME(b, key, val) \
bson_append_date_time (b, key, (int) strlen (key), val)
#define BSON_APPEND_TIMESTAMP(b, key, val, inc) \
bson_append_timestamp (b, key, (int) strlen (key), val, inc)
#define BSON_APPEND_UNDEFINED(b, key) \
bson_append_undefined (b, key, (int) strlen (key))
#define BSON_APPEND_VALUE(b, key, val) \
bson_append_value (b, key, (int) strlen (key), (val))
/**
* bson_new:
*
* Allocates a new bson_t structure. Call the various bson_append_*()
* functions to add fields to the bson. You can iterate the bson_t at any
* time using a bson_iter_t and bson_iter_init().
*
* Returns: A newly allocated bson_t that should be freed with bson_destroy().
*/
BSON_EXPORT (bson_t *)
bson_new (void);
BSON_EXPORT (bson_t *)
bson_new_from_json (const uint8_t *data, ssize_t len, bson_error_t *error);
BSON_EXPORT (bool)
bson_init_from_json (bson_t *bson,
const char *data,
ssize_t len,
bson_error_t *error);
/**
* bson_init_static:
* @b: A pointer to a bson_t.
* @data: The data buffer to use.
* @length: The length of @data.
*
* Initializes a bson_t using @data and @length. This is ideal if you would
* like to use a stack allocation for your bson and do not need to grow the
* buffer. @data must be valid for the life of @b.
*
* Returns: true if initialized successfully; otherwise false.
*/
BSON_EXPORT (bool)
bson_init_static (bson_t *b, const uint8_t *data, size_t length);
/**
* bson_init:
* @b: A pointer to a bson_t.
*
* Initializes a bson_t for use. This function is useful to those that want a
* stack allocated bson_t. The usefulness of a stack allocated bson_t is
* marginal as the target buffer for content will still require heap
* allocations. It can help reduce heap fragmentation on allocators that do
* not employ SLAB/magazine semantics.
*
* You must call bson_destroy() with @b to release resources when you are done
* using @b.
*/
BSON_EXPORT (void)
bson_init (bson_t *b);
/**
* bson_reinit:
* @b: (inout): A bson_t.
*
* This is equivalent to calling bson_destroy() and bson_init() on a #bson_t.
* However, it will try to persist the existing malloc'd buffer if one exists.
* This is useful in cases where you want to reduce malloc overhead while
* building many documents.
*/
BSON_EXPORT (void)
bson_reinit (bson_t *b);
/**
* bson_new_from_data:
* @data: A buffer containing a serialized bson document.
* @length: The length of the document in bytes.
*
* Creates a new bson_t structure using the data provided. @data should contain
* at least @length bytes that can be copied into the new bson_t structure.
*
* Returns: A newly allocated bson_t that should be freed with bson_destroy().
* If the first four bytes (little-endian) of data do not match @length,
* then NULL will be returned.
*/
BSON_EXPORT (bson_t *)
bson_new_from_data (const uint8_t *data, size_t length);
/**
* bson_new_from_buffer:
* @buf: A pointer to a buffer containing a serialized bson document.
* @buf_len: The length of the buffer in bytes.
* @realloc_fun: a realloc like function
* @realloc_fun_ctx: a context for the realloc function
*
* Creates a new bson_t structure using the data provided. @buf should contain
* a bson document, or null pointer should be passed for new allocations.
*
* Returns: A newly allocated bson_t that should be freed with bson_destroy().
* The underlying buffer will be used and not be freed in destroy.
*/
BSON_EXPORT (bson_t *)
bson_new_from_buffer (uint8_t **buf,
size_t *buf_len,
bson_realloc_func realloc_func,
void *realloc_func_ctx);
/**
* bson_sized_new:
* @size: A size_t containing the number of bytes to allocate.
*
* This will allocate a new bson_t with enough bytes to hold a buffer
* sized @size. @size must be smaller than INT_MAX bytes.
*
* Returns: A newly allocated bson_t that should be freed with bson_destroy().
*/
BSON_EXPORT (bson_t *)
bson_sized_new (size_t size);
/**
* bson_copy:
* @bson: A bson_t.
*
* Copies @bson into a newly allocated bson_t. You must call bson_destroy()
* when you are done with the resulting value to free its resources.
*
* Returns: A newly allocated bson_t that should be free'd with bson_destroy()
*/
BSON_EXPORT (bson_t *)
bson_copy (const bson_t *bson);
/**
* bson_copy_to:
* @src: The source bson_t.
* @dst: The destination bson_t.
*
* Initializes @dst and copies the content from @src into @dst.
*/
BSON_EXPORT (void)
bson_copy_to (const bson_t *src, bson_t *dst);
/**
* bson_copy_to_excluding:
* @src: A bson_t.
* @dst: A bson_t to initialize and copy into.
* @first_exclude: First field name to exclude.
*
* Copies @src into @dst excluding any field that is provided.
* This is handy for situations when you need to remove one or
* more fields in a bson_t. Note that bson_init() will be called
* on dst.
*/
BSON_EXPORT (void)
bson_copy_to_excluding (const bson_t *src,
bson_t *dst,
const char *first_exclude,
...) BSON_GNUC_NULL_TERMINATED
BSON_GNUC_DEPRECATED_FOR (bson_copy_to_excluding_noinit);
/**
* bson_copy_to_excluding_noinit:
* @src: A bson_t.
* @dst: A bson_t to initialize and copy into.
* @first_exclude: First field name to exclude.
*
* The same as bson_copy_to_excluding, but does not call bson_init()
* on the dst. This version should be preferred in new code, but the
* old function is left for backwards compatibility.
*/
BSON_EXPORT (void)
bson_copy_to_excluding_noinit (const bson_t *src,
bson_t *dst,
const char *first_exclude,
...) BSON_GNUC_NULL_TERMINATED;
BSON_EXPORT (void)
bson_copy_to_excluding_noinit_va (const bson_t *src,
bson_t *dst,
const char *first_exclude,
va_list args);
/**
* bson_destroy:
* @bson: A bson_t.
*
* Frees the resources associated with @bson.
*/
BSON_EXPORT (void)
bson_destroy (bson_t *bson);
BSON_EXPORT (uint8_t *)
bson_reserve_buffer (bson_t *bson, uint32_t size);
BSON_EXPORT (bool)
bson_steal (bson_t *dst, bson_t *src);
/**
* bson_destroy_with_steal:
* @bson: A #bson_t.
* @steal: If ownership of the data buffer should be transferred to caller.
* @length: (out): location for the length of the buffer.
*
* Destroys @bson similar to calling bson_destroy() except that the underlying
* buffer will be returned and ownership transferred to the caller if @steal
* is non-zero.
*
* If length is non-NULL, the length of @bson will be stored in @length.
*
* It is a programming error to call this function with any bson that has
* been initialized static, or is being used to create a subdocument with
* functions such as bson_append_document_begin() or bson_append_array_begin().
*
* Returns: a buffer owned by the caller if @steal is true. Otherwise NULL.
* If there was an error, NULL is returned.
*/
BSON_EXPORT (uint8_t *)
bson_destroy_with_steal (bson_t *bson, bool steal, uint32_t *length);
/**
* bson_get_data:
* @bson: A bson_t.
*
* Fetched the data buffer for @bson of @bson->len bytes in length.
*
* Returns: A buffer that should not be modified or freed.
*/
BSON_EXPORT (const uint8_t *)
bson_get_data (const bson_t *bson);
/**
* bson_count_keys:
* @bson: A bson_t.
*
* Counts the number of elements found in @bson.
*/
BSON_EXPORT (uint32_t)
bson_count_keys (const bson_t *bson);
/**
* bson_has_field:
* @bson: A bson_t.
* @key: The key to lookup.
*
* Checks to see if @bson contains a field named @key.
*
* This function is case-sensitive.
*
* Returns: true if @key exists in @bson; otherwise false.
*/
BSON_EXPORT (bool)
bson_has_field (const bson_t *bson, const char *key);
/**
* bson_compare:
* @bson: A bson_t.
* @other: A bson_t.
*
* Compares @bson to @other in a qsort() style comparison.
* See qsort() for information on how this function works.
*
* Returns: Less than zero, zero, or greater than zero.
*/
BSON_EXPORT (int)
bson_compare (const bson_t *bson, const bson_t *other);
/*
- * bson_compare:
+ * bson_equal:
* @bson: A bson_t.
* @other: A bson_t.
*
* Checks to see if @bson and @other are equal.
*
* Returns: true if equal; otherwise false.
*/
BSON_EXPORT (bool)
bson_equal (const bson_t *bson, const bson_t *other);
/**
* bson_validate:
* @bson: A bson_t.
* @offset: A location for the error offset.
*
* Validates a BSON document by walking through the document and inspecting
* the fields for valid content.
*
* Returns: true if @bson is valid; otherwise false and @offset is set.
*/
BSON_EXPORT (bool)
bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset);
/**
* bson_validate_with_error:
* @bson: A bson_t.
* @error: A location for the error info.
*
* Validates a BSON document by walking through the document and inspecting
* the fields for valid content.
*
* Returns: true if @bson is valid; otherwise false and @error is filled out.
*/
BSON_EXPORT (bool)
bson_validate_with_error (const bson_t *bson,
bson_validate_flags_t flags,
bson_error_t *error);
/**
* bson_as_canonical_extended_json:
* @bson: A bson_t.
* @length: A location for the string length, or NULL.
*
* Creates a new string containing @bson in canonical extended JSON format,
* conforming to the MongoDB Extended JSON Spec:
*
* github.com/mongodb/specifications/blob/master/source/extended-json.rst
*
* The caller is responsible for freeing the resulting string. If @length is
* non-NULL, then the length of the resulting string will be placed in @length.
*
* See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for
* more information on extended JSON.
*
* Returns: A newly allocated string that should be freed with bson_free().
*/
BSON_EXPORT (char *)
bson_as_canonical_extended_json (const bson_t *bson, size_t *length);
/**
* bson_as_json:
* @bson: A bson_t.
* @length: A location for the string length, or NULL.
*
* Creates a new string containing @bson in libbson's legacy JSON format.
* Superseded by bson_as_canonical_extended_json and
* bson_as_relaxed_extended_json. The caller is
* responsible for freeing the resulting string. If @length is non-NULL, then
* the length of the resulting string will be placed in @length.
*
* Returns: A newly allocated string that should be freed with bson_free().
*/
BSON_EXPORT (char *)
bson_as_json (const bson_t *bson, size_t *length);
/**
* bson_as_relaxed_extended_json:
* @bson: A bson_t.
* @length: A location for the string length, or NULL.
*
* Creates a new string containing @bson in relaxed extended JSON format,
* conforming to the MongoDB Extended JSON Spec:
*
* github.com/mongodb/specifications/blob/master/source/extended-json.rst
*
* The caller is responsible for freeing the resulting string. If @length is
* non-NULL, then the length of the resulting string will be placed in @length.
*
* See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for
* more information on extended JSON.
*
* Returns: A newly allocated string that should be freed with bson_free().
*/
BSON_EXPORT (char *)
bson_as_relaxed_extended_json (const bson_t *bson, size_t *length);
/* like bson_as_json() but for outermost arrays. */
BSON_EXPORT (char *)
bson_array_as_json (const bson_t *bson, size_t *length);
BSON_EXPORT (bool)
bson_append_value (bson_t *bson,
const char *key,
int key_length,
const bson_value_t *value);
/**
* bson_append_array:
* @bson: A bson_t.
* @key: The key for the field.
* @array: A bson_t containing the array.
*
* Appends a BSON array to @bson. BSON arrays are like documents where the
* key is the string version of the index. For example, the first item of the
* array would have the key "0". The second item would have the index "1".
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_array (bson_t *bson,
const char *key,
int key_length,
const bson_t *array);
/**
* bson_append_binary:
* @bson: A bson_t to append.
* @key: The key for the field.
* @subtype: The bson_subtype_t of the binary.
* @binary: The binary buffer to append.
* @length: The length of @binary.
*
* Appends a binary buffer to the BSON document.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_binary (bson_t *bson,
const char *key,
int key_length,
bson_subtype_t subtype,
const uint8_t *binary,
uint32_t length);
/**
* bson_append_bool:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The boolean value.
*
* Appends a new field to @bson of type BSON_TYPE_BOOL.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_bool (bson_t *bson, const char *key, int key_length, bool value);
/**
* bson_append_code:
* @bson: A bson_t.
* @key: The key for the document.
* @javascript: JavaScript code to be executed.
*
* Appends a field of type BSON_TYPE_CODE to the BSON document. @javascript
* should contain a script in javascript to be executed.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_code (bson_t *bson,
const char *key,
int key_length,
const char *javascript);
/**
* bson_append_code_with_scope:
* @bson: A bson_t.
* @key: The key for the document.
* @javascript: JavaScript code to be executed.
* @scope: A bson_t containing the scope for @javascript.
*
* Appends a field of type BSON_TYPE_CODEWSCOPE to the BSON document.
* @javascript should contain a script in javascript to be executed.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_code_with_scope (bson_t *bson,
const char *key,
int key_length,
const char *javascript,
const bson_t *scope);
/**
* bson_append_dbpointer:
* @bson: A bson_t.
* @key: The key for the field.
* @collection: The collection name.
* @oid: The oid to the reference.
*
* Appends a new field of type BSON_TYPE_DBPOINTER. This datum type is
* deprecated in the BSON spec and should not be used in new code.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_dbpointer (bson_t *bson,
const char *key,
int key_length,
const char *collection,
const bson_oid_t *oid);
/**
* bson_append_double:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a new field to @bson of the type BSON_TYPE_DOUBLE.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_double (bson_t *bson,
const char *key,
int key_length,
double value);
/**
* bson_append_document:
* @bson: A bson_t.
* @key: The key for the field.
* @value: A bson_t containing the subdocument.
*
* Appends a new field to @bson of the type BSON_TYPE_DOCUMENT.
* The documents contents will be copied into @bson.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_document (bson_t *bson,
const char *key,
int key_length,
const bson_t *value);
/**
* bson_append_document_begin:
* @bson: A bson_t.
* @key: The key for the field.
* @key_length: The length of @key in bytes not including NUL or -1
* if @key_length is NUL terminated.
* @child: A location to an uninitialized bson_t.
*
* Appends a new field named @key to @bson. The field is, however,
* incomplete. @child will be initialized so that you may add fields to the
* child document. Child will use a memory buffer owned by @bson and
* therefore grow the parent buffer as additional space is used. This allows
* a single malloc'd buffer to be used when building documents which can help
* reduce memory fragmentation.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_document_begin (bson_t *bson,
const char *key,
int key_length,
bson_t *child);
/**
* bson_append_document_end:
* @bson: A bson_t.
* @child: A bson_t supplied to bson_append_document_begin().
*
* Finishes the appending of a document to a @bson. @child is considered
* disposed after this call and should not be used any further.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_document_end (bson_t *bson, bson_t *child);
/**
* bson_append_array_begin:
* @bson: A bson_t.
* @key: The key for the field.
* @key_length: The length of @key in bytes not including NUL or -1
* if @key_length is NUL terminated.
* @child: A location to an uninitialized bson_t.
*
* Appends a new field named @key to @bson. The field is, however,
* incomplete. @child will be initialized so that you may add fields to the
* child array. Child will use a memory buffer owned by @bson and
* therefore grow the parent buffer as additional space is used. This allows
* a single malloc'd buffer to be used when building arrays which can help
* reduce memory fragmentation.
*
* The type of @child will be BSON_TYPE_ARRAY and therefore the keys inside
* of it MUST be "0", "1", etc.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_array_begin (bson_t *bson,
const char *key,
int key_length,
bson_t *child);
/**
* bson_append_array_end:
* @bson: A bson_t.
* @child: A bson_t supplied to bson_append_array_begin().
*
* Finishes the appending of a array to a @bson. @child is considered
* disposed after this call and should not be used any further.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_array_end (bson_t *bson, bson_t *child);
/**
* bson_append_int32:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The int32_t 32-bit integer value.
*
* Appends a new field of type BSON_TYPE_INT32 to @bson.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_int32 (bson_t *bson,
const char *key,
int key_length,
int32_t value);
/**
* bson_append_int64:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The int64_t 64-bit integer value.
*
* Appends a new field of type BSON_TYPE_INT64 to @bson.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_int64 (bson_t *bson,
const char *key,
int key_length,
int64_t value);
/**
* bson_append_decimal128:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The bson_decimal128_t decimal128 value.
*
* Appends a new field of type BSON_TYPE_DECIMAL128 to @bson.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_decimal128 (bson_t *bson,
const char *key,
int key_length,
const bson_decimal128_t *value);
/**
* bson_append_iter:
* @bson: A bson_t to append to.
* @key: The key name or %NULL to take current key from @iter.
* @key_length: The key length or -1 to use strlen().
* @iter: The iter located on the position of the element to append.
*
* Appends a new field to @bson that is equivalent to the field currently
* pointed to by @iter.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_iter (bson_t *bson,
const char *key,
int key_length,
const bson_iter_t *iter);
/**
* bson_append_minkey:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a new field of type BSON_TYPE_MINKEY to @bson. This is a special
* type that compares lower than all other possible BSON element values.
*
* See http://bsonspec.org for more information on this type.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_minkey (bson_t *bson, const char *key, int key_length);
/**
* bson_append_maxkey:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a new field of type BSON_TYPE_MAXKEY to @bson. This is a special
* type that compares higher than all other possible BSON element values.
*
* See http://bsonspec.org for more information on this type.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_maxkey (bson_t *bson, const char *key, int key_length);
/**
* bson_append_null:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a new field to @bson with NULL for the value.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_null (bson_t *bson, const char *key, int key_length);
/**
* bson_append_oid:
* @bson: A bson_t.
* @key: The key for the field.
* @oid: bson_oid_t.
*
* Appends a new field to the @bson of type BSON_TYPE_OID using the contents of
* @oid.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_oid (bson_t *bson,
const char *key,
int key_length,
const bson_oid_t *oid);
/**
* bson_append_regex:
* @bson: A bson_t.
* @key: The key of the field.
* @regex: The regex to append to the bson.
* @options: Options for @regex.
*
* Appends a new field to @bson of type BSON_TYPE_REGEX. @regex should
* be the regex string. @options should contain the options for the regex.
*
* Valid options for @options are:
*
* 'i' for case-insensitive.
* 'm' for multiple matching.
* 'x' for verbose mode.
* 'l' to make \w and \W locale dependent.
* 's' for dotall mode ('.' matches everything)
* 'u' to make \w and \W match unicode.
*
* For more detailed information about BSON regex elements, see bsonspec.org.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_regex (bson_t *bson,
const char *key,
int key_length,
const char *regex,
const char *options);
/**
* bson_append_regex:
* @bson: A bson_t.
* @key: The key of the field.
* @key_length: The length of the key string.
* @regex: The regex to append to the bson.
* @regex_length: The length of the regex string.
* @options: Options for @regex.
*
* Appends a new field to @bson of type BSON_TYPE_REGEX. @regex should
* be the regex string. @options should contain the options for the regex.
*
* Valid options for @options are:
*
* 'i' for case-insensitive.
* 'm' for multiple matching.
* 'x' for verbose mode.
* 'l' to make \w and \W locale dependent.
* 's' for dotall mode ('.' matches everything)
* 'u' to make \w and \W match unicode.
*
* For more detailed information about BSON regex elements, see bsonspec.org.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_regex_w_len (bson_t *bson,
const char *key,
int key_length,
const char *regex,
int regex_length,
const char *options);
/**
* bson_append_utf8:
* @bson: A bson_t.
* @key: The key for the field.
* @value: A UTF-8 encoded string.
* @length: The length of @value or -1 if it is NUL terminated.
*
* Appends a new field to @bson using @key as the key and @value as the UTF-8
* encoded value.
*
* It is the callers responsibility to ensure @value is valid UTF-8. You can
* use bson_utf8_validate() to perform this check.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_utf8 (bson_t *bson,
const char *key,
int key_length,
const char *value,
int length);
/**
* bson_append_symbol:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The symbol as a string.
* @length: The length of @value or -1 if NUL-terminated.
*
* Appends a new field to @bson of type BSON_TYPE_SYMBOL. This BSON type is
* deprecated and should not be used in new code.
*
* See http://bsonspec.org for more information on this type.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_symbol (bson_t *bson,
const char *key,
int key_length,
const char *value,
int length);
/**
* bson_append_time_t:
* @bson: A bson_t.
* @key: The key for the field.
* @value: A time_t.
*
* Appends a BSON_TYPE_DATE_TIME field to @bson using the time_t @value for the
* number of seconds since UNIX epoch in UTC.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_time_t (bson_t *bson,
const char *key,
int key_length,
time_t value);
/**
* bson_append_timeval:
* @bson: A bson_t.
* @key: The key for the field.
* @value: A struct timeval containing the date and time.
*
* Appends a BSON_TYPE_DATE_TIME field to @bson using the struct timeval
* provided. The time is persisted in milliseconds since the UNIX epoch in UTC.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_timeval (bson_t *bson,
const char *key,
int key_length,
struct timeval *value);
/**
* bson_append_date_time:
* @bson: A bson_t.
* @key: The key for the field.
* @key_length: The length of @key in bytes or -1 if \0 terminated.
* @value: The number of milliseconds elapsed since UNIX epoch.
*
* Appends a new field to @bson of type BSON_TYPE_DATE_TIME.
*
* Returns: true if successful; otherwise false.
*/
BSON_EXPORT (bool)
bson_append_date_time (bson_t *bson,
const char *key,
int key_length,
int64_t value);
/**
* bson_append_now_utc:
* @bson: A bson_t.
* @key: The key for the field.
* @key_length: The length of @key or -1 if it is NULL terminated.
*
* Appends a BSON_TYPE_DATE_TIME field to @bson using the current time in UTC
* as the field value.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_now_utc (bson_t *bson, const char *key, int key_length);
/**
* bson_append_timestamp:
* @bson: A bson_t.
* @key: The key for the field.
* @timestamp: 4 byte timestamp.
* @increment: 4 byte increment for timestamp.
*
* Appends a field of type BSON_TYPE_TIMESTAMP to @bson. This is a special type
* used by MongoDB replication and sharding. If you need generic time and date
* fields use bson_append_time_t() or bson_append_timeval().
*
* Setting @increment and @timestamp to zero has special semantics. See
* http://bsonspec.org for more information on this field type.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_timestamp (bson_t *bson,
const char *key,
int key_length,
uint32_t timestamp,
uint32_t increment);
/**
* bson_append_undefined:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a field of type BSON_TYPE_UNDEFINED. This type is deprecated in the
* spec and should not be used for new code. However, it is provided for those
* needing to interact with legacy systems.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_undefined (bson_t *bson, const char *key, int key_length);
BSON_EXPORT (bool)
bson_concat (bson_t *dst, const bson_t *src);
BSON_END_DECLS
#endif /* BSON_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c b/mongodb-1.8.1/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libbson/src/jsonsl/jsonsl.h b/mongodb-1.8.1/src/libmongoc/src/libbson/src/jsonsl/jsonsl.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libbson/src/jsonsl/jsonsl.h
rename to mongodb-1.8.1/src/libmongoc/src/libbson/src/jsonsl/jsonsl.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
index 81b3ee29..2b5e717f 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
@@ -1,195 +1,198 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_APM_PRIVATE_H
#define MONGOC_APM_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-apm.h"
BSON_BEGIN_DECLS
/* forward decl */
struct _mongoc_cmd_t;
struct _mongoc_apm_callbacks_t {
mongoc_apm_command_started_cb_t started;
mongoc_apm_command_succeeded_cb_t succeeded;
mongoc_apm_command_failed_cb_t failed;
mongoc_apm_server_changed_cb_t server_changed;
mongoc_apm_server_opening_cb_t server_opening;
mongoc_apm_server_closed_cb_t server_closed;
mongoc_apm_topology_changed_cb_t topology_changed;
mongoc_apm_topology_opening_cb_t topology_opening;
mongoc_apm_topology_closed_cb_t topology_closed;
mongoc_apm_server_heartbeat_started_cb_t server_heartbeat_started;
mongoc_apm_server_heartbeat_succeeded_cb_t server_heartbeat_succeeded;
mongoc_apm_server_heartbeat_failed_cb_t server_heartbeat_failed;
};
/*
* command monitoring events
*/
struct _mongoc_apm_command_started_t {
bson_t *command;
bool command_owned;
const char *database_name;
const char *command_name;
int64_t request_id;
int64_t operation_id;
const mongoc_host_list_t *host;
uint32_t server_id;
void *context;
};
struct _mongoc_apm_command_succeeded_t {
int64_t duration;
const bson_t *reply;
const char *command_name;
int64_t request_id;
int64_t operation_id;
const mongoc_host_list_t *host;
uint32_t server_id;
void *context;
};
struct _mongoc_apm_command_failed_t {
int64_t duration;
const char *command_name;
const bson_error_t *error;
const bson_t *reply;
int64_t request_id;
int64_t operation_id;
const mongoc_host_list_t *host;
uint32_t server_id;
void *context;
};
/*
* SDAM monitoring events
*/
struct _mongoc_apm_server_changed_t {
const mongoc_host_list_t *host;
bson_oid_t topology_id;
const mongoc_server_description_t *previous_description;
const mongoc_server_description_t *new_description;
void *context;
};
struct _mongoc_apm_server_opening_t {
const mongoc_host_list_t *host;
bson_oid_t topology_id;
void *context;
};
struct _mongoc_apm_server_closed_t {
const mongoc_host_list_t *host;
bson_oid_t topology_id;
void *context;
};
struct _mongoc_apm_topology_changed_t {
bson_oid_t topology_id;
const mongoc_topology_description_t *previous_description;
const mongoc_topology_description_t *new_description;
void *context;
};
struct _mongoc_apm_topology_opening_t {
bson_oid_t topology_id;
void *context;
};
struct _mongoc_apm_topology_closed_t {
bson_oid_t topology_id;
void *context;
};
struct _mongoc_apm_server_heartbeat_started_t {
const mongoc_host_list_t *host;
void *context;
+ bool awaited;
};
struct _mongoc_apm_server_heartbeat_succeeded_t {
int64_t duration_usec;
const bson_t *reply;
const mongoc_host_list_t *host;
void *context;
+ bool awaited;
};
struct _mongoc_apm_server_heartbeat_failed_t {
int64_t duration_usec;
const bson_error_t *error;
const mongoc_host_list_t *host;
void *context;
+ bool awaited;
};
void
mongoc_apm_command_started_init (mongoc_apm_command_started_t *event,
const bson_t *command,
const char *database_name,
const char *command_name,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
void *context);
void
mongoc_apm_command_started_init_with_cmd (mongoc_apm_command_started_t *event,
struct _mongoc_cmd_t *cmd,
int64_t request_id,
void *context);
void
mongoc_apm_command_started_cleanup (mongoc_apm_command_started_t *event);
void
mongoc_apm_command_succeeded_init (mongoc_apm_command_succeeded_t *event,
int64_t duration,
const bson_t *reply,
const char *command_name,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
void *context);
void
mongoc_apm_command_succeeded_cleanup (mongoc_apm_command_succeeded_t *event);
void
mongoc_apm_command_failed_init (mongoc_apm_command_failed_t *event,
int64_t duration,
const char *command_name,
const bson_error_t *error,
const bson_t *reply,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
void *context);
void
mongoc_apm_command_failed_cleanup (mongoc_apm_command_failed_t *event);
BSON_END_DECLS
#endif /* MONGOC_APM_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
index efb089b4..0273ce6b 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
@@ -1,757 +1,777 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-util-private.h"
#include "mongoc-apm-private.h"
#include "mongoc-cmd-private.h"
/*
* An Application Performance Management (APM) implementation, complying with
* MongoDB's Command Monitoring Spec:
*
* https://github.com/mongodb/specifications/tree/master/source/command-monitoring
*/
static void
append_documents_from_cmd (const mongoc_cmd_t *cmd,
mongoc_apm_command_started_t *event)
{
if (!cmd->payload || !cmd->payload_size) {
return;
}
if (!event->command_owned) {
event->command = bson_copy (event->command);
event->command_owned = true;
}
_mongoc_cmd_append_payload_as_array (cmd, event->command);
}
/*
* Private initializer / cleanup functions.
*/
void
mongoc_apm_command_started_init (mongoc_apm_command_started_t *event,
const bson_t *command,
const char *database_name,
const char *command_name,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
void *context)
{
bson_iter_t iter;
uint32_t len;
const uint8_t *data;
/* Command Monitoring Spec:
*
* In cases where queries or commands are embedded in a $query parameter
* when a read preference is provided, they MUST be unwrapped and the value
* of the $query attribute becomes the filter or the command in the started
* event. The read preference will subsequently be dropped as it is
* considered metadata and metadata is not currently provided in the command
* events.
*/
if (bson_has_field (command, "$readPreference")) {
if (bson_iter_init_find (&iter, command, "$query") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_iter_document (&iter, &len, &data);
event->command = bson_new_from_data (data, len);
event->command_owned = true;
} else {
/* Got $readPreference without $query, probably OP_MSG */
event->command = (bson_t *) command;
event->command_owned = false;
}
} else {
/* discard "const", we promise not to modify "command" */
event->command = (bson_t *) command;
event->command_owned = false;
}
event->database_name = database_name;
event->command_name = command_name;
event->request_id = request_id;
event->operation_id = operation_id;
event->host = host;
event->server_id = server_id;
event->context = context;
}
void
mongoc_apm_command_started_init_with_cmd (mongoc_apm_command_started_t *event,
mongoc_cmd_t *cmd,
int64_t request_id,
void *context)
{
mongoc_apm_command_started_init (event,
cmd->command,
cmd->db_name,
cmd->command_name,
request_id,
cmd->operation_id,
&cmd->server_stream->sd->host,
cmd->server_stream->sd->id,
context);
/* OP_MSG document sequence for insert, update, or delete? */
append_documents_from_cmd (cmd, event);
}
void
mongoc_apm_command_started_cleanup (mongoc_apm_command_started_t *event)
{
if (event->command_owned) {
bson_destroy (event->command);
}
}
void
mongoc_apm_command_succeeded_init (mongoc_apm_command_succeeded_t *event,
int64_t duration,
const bson_t *reply,
const char *command_name,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
void *context)
{
BSON_ASSERT (reply);
event->duration = duration;
event->reply = reply;
event->command_name = command_name;
event->request_id = request_id;
event->operation_id = operation_id;
event->host = host;
event->server_id = server_id;
event->context = context;
}
void
mongoc_apm_command_succeeded_cleanup (mongoc_apm_command_succeeded_t *event)
{
/* no-op */
}
void
mongoc_apm_command_failed_init (mongoc_apm_command_failed_t *event,
int64_t duration,
const char *command_name,
const bson_error_t *error,
const bson_t *reply,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
void *context)
{
BSON_ASSERT (reply);
event->duration = duration;
event->command_name = command_name;
event->error = error;
event->reply = reply;
event->request_id = request_id;
event->operation_id = operation_id;
event->host = host;
event->server_id = server_id;
event->context = context;
}
void
mongoc_apm_command_failed_cleanup (mongoc_apm_command_failed_t *event)
{
/* no-op */
}
/*
* event field accessors
*/
/* command-started event fields */
const bson_t *
mongoc_apm_command_started_get_command (
const mongoc_apm_command_started_t *event)
{
return event->command;
}
const char *
mongoc_apm_command_started_get_database_name (
const mongoc_apm_command_started_t *event)
{
return event->database_name;
}
const char *
mongoc_apm_command_started_get_command_name (
const mongoc_apm_command_started_t *event)
{
return event->command_name;
}
int64_t
mongoc_apm_command_started_get_request_id (
const mongoc_apm_command_started_t *event)
{
return event->request_id;
}
int64_t
mongoc_apm_command_started_get_operation_id (
const mongoc_apm_command_started_t *event)
{
return event->operation_id;
}
const mongoc_host_list_t *
mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event)
{
return event->host;
}
uint32_t
mongoc_apm_command_started_get_server_id (
const mongoc_apm_command_started_t *event)
{
return event->server_id;
}
void *
mongoc_apm_command_started_get_context (
const mongoc_apm_command_started_t *event)
{
return event->context;
}
/* command-succeeded event fields */
int64_t
mongoc_apm_command_succeeded_get_duration (
const mongoc_apm_command_succeeded_t *event)
{
return event->duration;
}
const bson_t *
mongoc_apm_command_succeeded_get_reply (
const mongoc_apm_command_succeeded_t *event)
{
return event->reply;
}
const char *
mongoc_apm_command_succeeded_get_command_name (
const mongoc_apm_command_succeeded_t *event)
{
return event->command_name;
}
int64_t
mongoc_apm_command_succeeded_get_request_id (
const mongoc_apm_command_succeeded_t *event)
{
return event->request_id;
}
int64_t
mongoc_apm_command_succeeded_get_operation_id (
const mongoc_apm_command_succeeded_t *event)
{
return event->operation_id;
}
const mongoc_host_list_t *
mongoc_apm_command_succeeded_get_host (
const mongoc_apm_command_succeeded_t *event)
{
return event->host;
}
uint32_t
mongoc_apm_command_succeeded_get_server_id (
const mongoc_apm_command_succeeded_t *event)
{
return event->server_id;
}
void *
mongoc_apm_command_succeeded_get_context (
const mongoc_apm_command_succeeded_t *event)
{
return event->context;
}
/* command-failed event fields */
int64_t
mongoc_apm_command_failed_get_duration (
const mongoc_apm_command_failed_t *event)
{
return event->duration;
}
const char *
mongoc_apm_command_failed_get_command_name (
const mongoc_apm_command_failed_t *event)
{
return event->command_name;
}
void
mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event,
bson_error_t *error)
{
memcpy (error, event->error, sizeof *event->error);
}
const bson_t *
mongoc_apm_command_failed_get_reply (const mongoc_apm_command_failed_t *event)
{
return event->reply;
}
int64_t
mongoc_apm_command_failed_get_request_id (
const mongoc_apm_command_failed_t *event)
{
return event->request_id;
}
int64_t
mongoc_apm_command_failed_get_operation_id (
const mongoc_apm_command_failed_t *event)
{
return event->operation_id;
}
const mongoc_host_list_t *
mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event)
{
return event->host;
}
uint32_t
mongoc_apm_command_failed_get_server_id (
const mongoc_apm_command_failed_t *event)
{
return event->server_id;
}
void *
mongoc_apm_command_failed_get_context (const mongoc_apm_command_failed_t *event)
{
return event->context;
}
/* server-changed event fields */
const mongoc_host_list_t *
mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event)
{
return event->host;
}
void
mongoc_apm_server_changed_get_topology_id (
const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
const mongoc_server_description_t *
mongoc_apm_server_changed_get_previous_description (
const mongoc_apm_server_changed_t *event)
{
return event->previous_description;
}
const mongoc_server_description_t *
mongoc_apm_server_changed_get_new_description (
const mongoc_apm_server_changed_t *event)
{
return event->new_description;
}
void *
mongoc_apm_server_changed_get_context (const mongoc_apm_server_changed_t *event)
{
return event->context;
}
/* server-opening event fields */
const mongoc_host_list_t *
mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event)
{
return event->host;
}
void
mongoc_apm_server_opening_get_topology_id (
const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
void *
mongoc_apm_server_opening_get_context (const mongoc_apm_server_opening_t *event)
{
return event->context;
}
/* server-closed event fields */
const mongoc_host_list_t *
mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event)
{
return event->host;
}
void
mongoc_apm_server_closed_get_topology_id (
const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
void *
mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event)
{
return event->context;
}
/* topology-changed event fields */
void
mongoc_apm_topology_changed_get_topology_id (
const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
const mongoc_topology_description_t *
mongoc_apm_topology_changed_get_previous_description (
const mongoc_apm_topology_changed_t *event)
{
return event->previous_description;
}
const mongoc_topology_description_t *
mongoc_apm_topology_changed_get_new_description (
const mongoc_apm_topology_changed_t *event)
{
return event->new_description;
}
void *
mongoc_apm_topology_changed_get_context (
const mongoc_apm_topology_changed_t *event)
{
return event->context;
}
/* topology-opening event field */
void
mongoc_apm_topology_opening_get_topology_id (
const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
void *
mongoc_apm_topology_opening_get_context (
const mongoc_apm_topology_opening_t *event)
{
return event->context;
}
/* topology-closed event field */
void
mongoc_apm_topology_closed_get_topology_id (
const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
void *
mongoc_apm_topology_closed_get_context (
const mongoc_apm_topology_closed_t *event)
{
return event->context;
}
/* heartbeat-started event field */
const mongoc_host_list_t *
mongoc_apm_server_heartbeat_started_get_host (
const mongoc_apm_server_heartbeat_started_t *event)
{
return event->host;
}
void *
mongoc_apm_server_heartbeat_started_get_context (
const mongoc_apm_server_heartbeat_started_t *event)
{
return event->context;
}
+bool
+mongoc_apm_server_heartbeat_started_get_awaited (
+ const mongoc_apm_server_heartbeat_started_t *event)
+{
+ return event->awaited;
+}
+
/* heartbeat-succeeded event fields */
int64_t
mongoc_apm_server_heartbeat_succeeded_get_duration (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->duration_usec;
}
const bson_t *
mongoc_apm_server_heartbeat_succeeded_get_reply (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->reply;
}
const mongoc_host_list_t *
mongoc_apm_server_heartbeat_succeeded_get_host (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->host;
}
void *
mongoc_apm_server_heartbeat_succeeded_get_context (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->context;
}
+bool
+mongoc_apm_server_heartbeat_succeeded_get_awaited (
+ const mongoc_apm_server_heartbeat_succeeded_t *event)
+{
+ return event->awaited;
+}
+
/* heartbeat-failed event fields */
int64_t
mongoc_apm_server_heartbeat_failed_get_duration (
const mongoc_apm_server_heartbeat_failed_t *event)
{
return event->duration_usec;
}
void
mongoc_apm_server_heartbeat_failed_get_error (
const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error)
{
memcpy (error, event->error, sizeof *event->error);
}
const mongoc_host_list_t *
mongoc_apm_server_heartbeat_failed_get_host (
const mongoc_apm_server_heartbeat_failed_t *event)
{
return event->host;
}
void *
mongoc_apm_server_heartbeat_failed_get_context (
const mongoc_apm_server_heartbeat_failed_t *event)
{
return event->context;
}
+bool
+mongoc_apm_server_heartbeat_failed_get_awaited (
+ const mongoc_apm_server_heartbeat_failed_t *event)
+{
+ return event->awaited;
+}
/*
* registering callbacks
*/
mongoc_apm_callbacks_t *
mongoc_apm_callbacks_new (void)
{
size_t s = sizeof (mongoc_apm_callbacks_t);
return (mongoc_apm_callbacks_t *) bson_malloc0 (s);
}
void
mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks)
{
bson_free (callbacks);
}
void
mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_started_cb_t cb)
{
callbacks->started = cb;
}
void
mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_succeeded_cb_t cb)
{
callbacks->succeeded = cb;
}
void
mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_failed_cb_t cb)
{
callbacks->failed = cb;
}
void
mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_changed_cb_t cb)
{
callbacks->server_changed = cb;
}
void
mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_opening_cb_t cb)
{
callbacks->server_opening = cb;
}
void
mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_closed_cb_t cb)
{
callbacks->server_closed = cb;
}
void
mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_changed_cb_t cb)
{
callbacks->topology_changed = cb;
}
void
mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_opening_cb_t cb)
{
callbacks->topology_opening = cb;
}
void
mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_closed_cb_t cb)
{
callbacks->topology_closed = cb;
}
void
mongoc_apm_set_server_heartbeat_started_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_started_cb_t cb)
{
callbacks->server_heartbeat_started = cb;
}
void
mongoc_apm_set_server_heartbeat_succeeded_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_succeeded_cb_t cb)
{
callbacks->server_heartbeat_succeeded = cb;
}
void
mongoc_apm_set_server_heartbeat_failed_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_failed_cb_t cb)
{
callbacks->server_heartbeat_failed = cb;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
index 61246da7..bc9b48ab 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
@@ -1,351 +1,360 @@
/*
* Copyright 2015 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_APM_H
#define MONGOC_APM_H
#include <bson/bson.h>
#include "mongoc-macros.h"
#include "mongoc-host-list.h"
#include "mongoc-server-description.h"
#include "mongoc-topology-description.h"
BSON_BEGIN_DECLS
/*
* Application Performance Management (APM) interface, complies with two specs.
* MongoDB's Command Monitoring Spec:
*
* https://github.com/mongodb/specifications/tree/master/source/command-monitoring
*
* MongoDB's Spec for Monitoring Server Discovery and Monitoring (SDAM) events:
*
* https://github.com/mongodb/specifications/tree/master/source/server-discovery-and-monitoring
*
*/
/*
* callbacks to receive APM events
*/
typedef struct _mongoc_apm_callbacks_t mongoc_apm_callbacks_t;
/*
* command monitoring events
*/
typedef struct _mongoc_apm_command_started_t mongoc_apm_command_started_t;
typedef struct _mongoc_apm_command_succeeded_t mongoc_apm_command_succeeded_t;
typedef struct _mongoc_apm_command_failed_t mongoc_apm_command_failed_t;
/*
* SDAM monitoring events
*/
typedef struct _mongoc_apm_server_changed_t mongoc_apm_server_changed_t;
typedef struct _mongoc_apm_server_opening_t mongoc_apm_server_opening_t;
typedef struct _mongoc_apm_server_closed_t mongoc_apm_server_closed_t;
typedef struct _mongoc_apm_topology_changed_t mongoc_apm_topology_changed_t;
typedef struct _mongoc_apm_topology_opening_t mongoc_apm_topology_opening_t;
typedef struct _mongoc_apm_topology_closed_t mongoc_apm_topology_closed_t;
typedef struct _mongoc_apm_server_heartbeat_started_t
mongoc_apm_server_heartbeat_started_t;
typedef struct _mongoc_apm_server_heartbeat_succeeded_t
mongoc_apm_server_heartbeat_succeeded_t;
typedef struct _mongoc_apm_server_heartbeat_failed_t
mongoc_apm_server_heartbeat_failed_t;
/*
* event field accessors
*/
/* command-started event fields */
MONGOC_EXPORT (const bson_t *)
mongoc_apm_command_started_get_command (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (const char *)
mongoc_apm_command_started_get_database_name (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (const char *)
mongoc_apm_command_started_get_command_name (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_started_get_request_id (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_started_get_operation_id (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (uint32_t)
mongoc_apm_command_started_get_server_id (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_command_started_get_context (
const mongoc_apm_command_started_t *event);
/* command-succeeded event fields */
MONGOC_EXPORT (int64_t)
mongoc_apm_command_succeeded_get_duration (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (const bson_t *)
mongoc_apm_command_succeeded_get_reply (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (const char *)
mongoc_apm_command_succeeded_get_command_name (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_succeeded_get_request_id (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_succeeded_get_operation_id (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_command_succeeded_get_host (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (uint32_t)
mongoc_apm_command_succeeded_get_server_id (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_command_succeeded_get_context (
const mongoc_apm_command_succeeded_t *event);
/* command-failed event fields */
MONGOC_EXPORT (int64_t)
mongoc_apm_command_failed_get_duration (
const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (const char *)
mongoc_apm_command_failed_get_command_name (
const mongoc_apm_command_failed_t *event);
/* retrieve the error by filling out the passed-in "error" struct */
MONGOC_EXPORT (void)
mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event,
bson_error_t *error);
MONGOC_EXPORT (const bson_t *)
mongoc_apm_command_failed_get_reply (const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_failed_get_request_id (
const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_failed_get_operation_id (
const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (uint32_t)
mongoc_apm_command_failed_get_server_id (
const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_command_failed_get_context (
const mongoc_apm_command_failed_t *event);
/* server-changed event fields */
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event);
MONGOC_EXPORT (void)
mongoc_apm_server_changed_get_topology_id (
const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (const mongoc_server_description_t *)
mongoc_apm_server_changed_get_previous_description (
const mongoc_apm_server_changed_t *event);
MONGOC_EXPORT (const mongoc_server_description_t *)
mongoc_apm_server_changed_get_new_description (
const mongoc_apm_server_changed_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_server_changed_get_context (
const mongoc_apm_server_changed_t *event);
/* server-opening event fields */
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event);
MONGOC_EXPORT (void)
mongoc_apm_server_opening_get_topology_id (
const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (void *)
mongoc_apm_server_opening_get_context (
const mongoc_apm_server_opening_t *event);
/* server-closed event fields */
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event);
MONGOC_EXPORT (void)
mongoc_apm_server_closed_get_topology_id (
const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (void *)
mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event);
/* topology-changed event fields */
MONGOC_EXPORT (void)
mongoc_apm_topology_changed_get_topology_id (
const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (const mongoc_topology_description_t *)
mongoc_apm_topology_changed_get_previous_description (
const mongoc_apm_topology_changed_t *event);
MONGOC_EXPORT (const mongoc_topology_description_t *)
mongoc_apm_topology_changed_get_new_description (
const mongoc_apm_topology_changed_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_topology_changed_get_context (
const mongoc_apm_topology_changed_t *event);
/* topology-opening event field */
MONGOC_EXPORT (void)
mongoc_apm_topology_opening_get_topology_id (
const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (void *)
mongoc_apm_topology_opening_get_context (
const mongoc_apm_topology_opening_t *event);
/* topology-closed event field */
MONGOC_EXPORT (void)
mongoc_apm_topology_closed_get_topology_id (
const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (void *)
mongoc_apm_topology_closed_get_context (
const mongoc_apm_topology_closed_t *event);
/* heartbeat-started event field */
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_heartbeat_started_get_host (
const mongoc_apm_server_heartbeat_started_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_server_heartbeat_started_get_context (
const mongoc_apm_server_heartbeat_started_t *event);
+MONGOC_EXPORT (bool)
+mongoc_apm_server_heartbeat_started_get_awaited (
+ const mongoc_apm_server_heartbeat_started_t *event);
/* heartbeat-succeeded event fields */
MONGOC_EXPORT (int64_t)
mongoc_apm_server_heartbeat_succeeded_get_duration (
const mongoc_apm_server_heartbeat_succeeded_t *event);
MONGOC_EXPORT (const bson_t *)
mongoc_apm_server_heartbeat_succeeded_get_reply (
const mongoc_apm_server_heartbeat_succeeded_t *event);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_heartbeat_succeeded_get_host (
const mongoc_apm_server_heartbeat_succeeded_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_server_heartbeat_succeeded_get_context (
const mongoc_apm_server_heartbeat_succeeded_t *event);
+MONGOC_EXPORT (bool)
+mongoc_apm_server_heartbeat_succeeded_get_awaited (
+ const mongoc_apm_server_heartbeat_succeeded_t *event);
/* heartbeat-failed event fields */
MONGOC_EXPORT (int64_t)
mongoc_apm_server_heartbeat_failed_get_duration (
const mongoc_apm_server_heartbeat_failed_t *event);
MONGOC_EXPORT (void)
mongoc_apm_server_heartbeat_failed_get_error (
const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_heartbeat_failed_get_host (
const mongoc_apm_server_heartbeat_failed_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_server_heartbeat_failed_get_context (
const mongoc_apm_server_heartbeat_failed_t *event);
+MONGOC_EXPORT (bool)
+mongoc_apm_server_heartbeat_failed_get_awaited (
+ const mongoc_apm_server_heartbeat_failed_t *event);
/*
* callbacks
*/
typedef void (*mongoc_apm_command_started_cb_t) (
const mongoc_apm_command_started_t *event);
typedef void (*mongoc_apm_command_succeeded_cb_t) (
const mongoc_apm_command_succeeded_t *event);
typedef void (*mongoc_apm_command_failed_cb_t) (
const mongoc_apm_command_failed_t *event);
typedef void (*mongoc_apm_server_changed_cb_t) (
const mongoc_apm_server_changed_t *event);
typedef void (*mongoc_apm_server_opening_cb_t) (
const mongoc_apm_server_opening_t *event);
typedef void (*mongoc_apm_server_closed_cb_t) (
const mongoc_apm_server_closed_t *event);
typedef void (*mongoc_apm_topology_changed_cb_t) (
const mongoc_apm_topology_changed_t *event);
typedef void (*mongoc_apm_topology_opening_cb_t) (
const mongoc_apm_topology_opening_t *event);
typedef void (*mongoc_apm_topology_closed_cb_t) (
const mongoc_apm_topology_closed_t *event);
typedef void (*mongoc_apm_server_heartbeat_started_cb_t) (
const mongoc_apm_server_heartbeat_started_t *event);
typedef void (*mongoc_apm_server_heartbeat_succeeded_cb_t) (
const mongoc_apm_server_heartbeat_succeeded_t *event);
typedef void (*mongoc_apm_server_heartbeat_failed_cb_t) (
const mongoc_apm_server_heartbeat_failed_t *event);
/*
* registering callbacks
*/
MONGOC_EXPORT (mongoc_apm_callbacks_t *)
mongoc_apm_callbacks_new (void);
MONGOC_EXPORT (void)
mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks);
MONGOC_EXPORT (void)
mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_started_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_succeeded_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_failed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_changed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_opening_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_closed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_changed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_opening_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_closed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_heartbeat_started_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_started_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_heartbeat_succeeded_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_succeeded_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_heartbeat_failed_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_failed_cb_t cb);
BSON_END_DECLS
#endif /* MONGOC_APM_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
index 8dc9bee5..03c68380 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
@@ -1,109 +1,109 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_ASYNC_CMD_PRIVATE_H
#define MONGOC_ASYNC_CMD_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-async-private.h"
#include "mongoc-array-private.h"
#include "mongoc-buffer-private.h"
#include "mongoc-rpc-private.h"
#include "mongoc-stream.h"
BSON_BEGIN_DECLS
typedef enum {
MONGOC_ASYNC_CMD_INITIATE,
MONGOC_ASYNC_CMD_SETUP,
MONGOC_ASYNC_CMD_SEND,
MONGOC_ASYNC_CMD_RECV_LEN,
MONGOC_ASYNC_CMD_RECV_RPC,
MONGOC_ASYNC_CMD_ERROR_STATE,
MONGOC_ASYNC_CMD_CANCELED_STATE,
} mongoc_async_cmd_state_t;
typedef struct _mongoc_async_cmd {
mongoc_stream_t *stream;
mongoc_async_t *async;
mongoc_async_cmd_state_t state;
int events;
mongoc_async_cmd_initiate_t initiator;
mongoc_async_cmd_setup_t setup;
void *setup_ctx;
mongoc_async_cmd_cb_t cb;
void *data;
bson_error_t error;
int64_t initiate_delay_ms;
int64_t connect_started;
int64_t cmd_started;
int64_t timeout_msec;
bson_t cmd;
mongoc_buffer_t buffer;
mongoc_array_t array;
mongoc_iovec_t *iovec;
size_t niovec;
size_t bytes_written;
size_t bytes_to_read;
mongoc_rpc_t rpc;
bson_t reply;
bool reply_needs_cleanup;
- char ns[MONGOC_NAMESPACE_MAX];
+ char *ns;
struct addrinfo *dns_result;
struct _mongoc_async_cmd *next;
struct _mongoc_async_cmd *prev;
} mongoc_async_cmd_t;
mongoc_async_cmd_t *
mongoc_async_cmd_new (mongoc_async_t *async,
mongoc_stream_t *stream,
bool is_setup_done,
struct addrinfo *dns_result,
mongoc_async_cmd_initiate_t initiator,
int64_t initiate_delay_ms,
mongoc_async_cmd_setup_t setup,
void *setup_ctx,
const char *dbname,
const bson_t *cmd,
mongoc_async_cmd_cb_t cb,
void *cb_data,
int64_t timeout_msec);
void
mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd);
bool
mongoc_async_cmd_run (mongoc_async_cmd_t *acmd);
#ifdef MONGOC_ENABLE_SSL
int
mongoc_async_cmd_tls_setup (mongoc_stream_t *stream,
int *events,
void *ctx,
int32_t timeout_msec,
bson_error_t *error);
#endif
BSON_END_DECLS
#endif /* MONGOC_ASYNC_CMD_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
index 483d8967..8048858d 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
@@ -1,485 +1,486 @@
/*
* Copyright 2014 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.
*/
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-async-cmd-private.h"
#include "mongoc-async-private.h"
#include "mongoc-error.h"
#include "mongoc-opcode.h"
#include "mongoc-rpc-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-server-description-private.h"
#include "mongoc-topology-scanner-private.h"
#include "mongoc-log.h"
#include "utlist.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-stream-tls.h"
#endif
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "async"
typedef mongoc_async_cmd_result_t (*_mongoc_async_cmd_phase_t) (
mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_initiate (mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_setup (mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_send (mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_recv_len (mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *cmd);
static const _mongoc_async_cmd_phase_t gMongocCMDPhases[] = {
_mongoc_async_cmd_phase_initiate,
_mongoc_async_cmd_phase_setup,
_mongoc_async_cmd_phase_send,
_mongoc_async_cmd_phase_recv_len,
_mongoc_async_cmd_phase_recv_rpc,
NULL, /* no callback for MONGOC_ASYNC_CMD_ERROR_STATE */
NULL, /* no callback for MONGOC_ASYNC_CMD_CANCELED_STATE */
};
#ifdef MONGOC_ENABLE_SSL
int
mongoc_async_cmd_tls_setup (mongoc_stream_t *stream,
int *events,
void *ctx,
int32_t timeout_msec,
bson_error_t *error)
{
mongoc_stream_t *tls_stream;
const char *host = (const char *) ctx;
int retry_events = 0;
for (tls_stream = stream; tls_stream->type != MONGOC_STREAM_TLS;
tls_stream = mongoc_stream_get_base_stream (tls_stream)) {
}
#if defined(MONGOC_ENABLE_SSL_OPENSSL) || \
defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL)
/* pass 0 for the timeout to begin / continue non-blocking handshake */
timeout_msec = 0;
#endif
if (mongoc_stream_tls_handshake (
tls_stream, host, timeout_msec, &retry_events, error)) {
return 1;
}
if (retry_events) {
*events = retry_events;
return 0;
}
return -1;
}
#endif
bool
mongoc_async_cmd_run (mongoc_async_cmd_t *acmd)
{
mongoc_async_cmd_result_t result;
int64_t duration_usec;
_mongoc_async_cmd_phase_t phase_callback;
BSON_ASSERT (acmd);
/* if we have successfully connected to the node, call the callback. */
if (acmd->state == MONGOC_ASYNC_CMD_SEND) {
acmd->cb (acmd, MONGOC_ASYNC_CMD_CONNECTED, NULL, 0);
}
phase_callback = gMongocCMDPhases[acmd->state];
if (phase_callback) {
result = phase_callback (acmd);
} else {
result = MONGOC_ASYNC_CMD_ERROR;
}
if (result == MONGOC_ASYNC_CMD_IN_PROGRESS) {
return true;
}
duration_usec = bson_get_monotonic_time () - acmd->cmd_started;
if (result == MONGOC_ASYNC_CMD_SUCCESS) {
acmd->cb (acmd, result, &acmd->reply, duration_usec);
} else {
/* we're in ERROR, TIMEOUT, or CANCELED */
acmd->cb (acmd, result, NULL, duration_usec);
}
mongoc_async_cmd_destroy (acmd);
return false;
}
void
_mongoc_async_cmd_init_send (mongoc_async_cmd_t *acmd, const char *dbname)
{
- bson_snprintf (acmd->ns, sizeof acmd->ns, "%s.$cmd", dbname);
+ acmd->ns = bson_strdup_printf ("%s.$cmd", dbname);
acmd->rpc.header.msg_len = 0;
acmd->rpc.header.request_id = ++acmd->async->request_id;
acmd->rpc.header.response_to = 0;
acmd->rpc.header.opcode = MONGOC_OPCODE_QUERY;
acmd->rpc.query.flags = MONGOC_QUERY_SLAVE_OK;
acmd->rpc.query.collection = acmd->ns;
acmd->rpc.query.skip = 0;
acmd->rpc.query.n_return = -1;
acmd->rpc.query.query = bson_get_data (&acmd->cmd);
acmd->rpc.query.fields = NULL;
/* This will always be isMaster, which are not allowed to be compressed */
_mongoc_rpc_gather (&acmd->rpc, &acmd->array);
acmd->iovec = (mongoc_iovec_t *) acmd->array.data;
acmd->niovec = acmd->array.len;
_mongoc_rpc_swab_to_le (&acmd->rpc);
acmd->bytes_written = 0;
}
void
_mongoc_async_cmd_state_start (mongoc_async_cmd_t *acmd, bool is_setup_done)
{
if (!acmd->stream) {
acmd->state = MONGOC_ASYNC_CMD_INITIATE;
} else if (acmd->setup && !is_setup_done) {
acmd->state = MONGOC_ASYNC_CMD_SETUP;
} else {
acmd->state = MONGOC_ASYNC_CMD_SEND;
}
acmd->events = POLLOUT;
}
mongoc_async_cmd_t *
mongoc_async_cmd_new (mongoc_async_t *async,
mongoc_stream_t *stream,
bool is_setup_done,
struct addrinfo *dns_result,
mongoc_async_cmd_initiate_t initiator,
int64_t initiate_delay_ms,
mongoc_async_cmd_setup_t setup,
void *setup_ctx,
const char *dbname,
const bson_t *cmd,
mongoc_async_cmd_cb_t cb,
void *cb_data,
int64_t timeout_msec)
{
mongoc_async_cmd_t *acmd;
BSON_ASSERT (cmd);
BSON_ASSERT (dbname);
acmd = (mongoc_async_cmd_t *) bson_malloc0 (sizeof (*acmd));
acmd->async = async;
acmd->dns_result = dns_result;
acmd->timeout_msec = timeout_msec;
acmd->stream = stream;
acmd->initiator = initiator;
acmd->initiate_delay_ms = initiate_delay_ms;
acmd->setup = setup;
acmd->setup_ctx = setup_ctx;
acmd->cb = cb;
acmd->data = cb_data;
acmd->connect_started = bson_get_monotonic_time ();
bson_copy_to (cmd, &acmd->cmd);
_mongoc_array_init (&acmd->array, sizeof (mongoc_iovec_t));
_mongoc_buffer_init (&acmd->buffer, NULL, 0, NULL, NULL);
_mongoc_async_cmd_init_send (acmd, dbname);
_mongoc_async_cmd_state_start (acmd, is_setup_done);
async->ncmds++;
DL_APPEND (async->cmds, acmd);
return acmd;
}
void
mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd)
{
BSON_ASSERT (acmd);
DL_DELETE (acmd->async->cmds, acmd);
acmd->async->ncmds--;
bson_destroy (&acmd->cmd);
if (acmd->reply_needs_cleanup) {
bson_destroy (&acmd->reply);
}
_mongoc_array_destroy (&acmd->array);
_mongoc_buffer_destroy (&acmd->buffer);
+ bson_free (acmd->ns);
bson_free (acmd);
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_initiate (mongoc_async_cmd_t *acmd)
{
acmd->stream = acmd->initiator (acmd);
if (!acmd->stream) {
return MONGOC_ASYNC_CMD_ERROR;
}
/* reset the connect started time after connection starts. */
acmd->connect_started = bson_get_monotonic_time ();
if (acmd->setup) {
acmd->state = MONGOC_ASYNC_CMD_SETUP;
} else {
acmd->state = MONGOC_ASYNC_CMD_SEND;
}
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_setup (mongoc_async_cmd_t *acmd)
{
int retval;
BSON_ASSERT (acmd->timeout_msec < INT32_MAX);
retval = acmd->setup (acmd->stream,
&acmd->events,
acmd->setup_ctx,
(int32_t) acmd->timeout_msec,
&acmd->error);
switch (retval) {
case -1:
return MONGOC_ASYNC_CMD_ERROR;
case 0:
break;
case 1:
acmd->state = MONGOC_ASYNC_CMD_SEND;
acmd->events = POLLOUT;
break;
default:
abort ();
}
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_send (mongoc_async_cmd_t *acmd)
{
size_t total_bytes = 0;
size_t offset;
ssize_t bytes;
int i;
/* if a continued write, then iovec will be set to a temporary copy */
bool used_temp_iovec = false;
mongoc_iovec_t *iovec = acmd->iovec;
size_t niovec = acmd->niovec;
for (i = 0; i < acmd->niovec; i++) {
total_bytes += acmd->iovec[i].iov_len;
}
if (acmd->bytes_written > 0) {
BSON_ASSERT (acmd->bytes_written < total_bytes);
/* if bytes have been written before, compute the offset in the next
* iovec entry to be written. */
offset = acmd->bytes_written;
/* subtract the lengths of all iovec entries written so far. */
for (i = 0; i < acmd->niovec; i++) {
if (offset < acmd->iovec[i].iov_len) {
break;
}
offset -= acmd->iovec[i].iov_len;
}
BSON_ASSERT (i < acmd->niovec);
/* create a new iovec with the remaining data to be written. */
niovec = acmd->niovec - i;
iovec = bson_malloc (niovec * sizeof (mongoc_iovec_t));
memcpy (iovec, acmd->iovec + i, niovec * sizeof (mongoc_iovec_t));
iovec[0].iov_base = (char *) iovec[0].iov_base + offset;
iovec[0].iov_len -= offset;
used_temp_iovec = true;
}
bytes = mongoc_stream_writev (acmd->stream, iovec, niovec, 0);
if (used_temp_iovec) {
bson_free (iovec);
}
if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) {
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
if (bytes < 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to write rpc bytes.");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->bytes_written += bytes;
if (acmd->bytes_written < total_bytes) {
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
acmd->state = MONGOC_ASYNC_CMD_RECV_LEN;
acmd->bytes_to_read = 4;
acmd->events = POLLIN;
acmd->cmd_started = bson_get_monotonic_time ();
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_recv_len (mongoc_async_cmd_t *acmd)
{
ssize_t bytes = _mongoc_buffer_try_append_from_stream (
&acmd->buffer, acmd->stream, acmd->bytes_to_read, 0);
uint32_t msg_len;
if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) {
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
if (bytes < 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to receive length header from server.");
return MONGOC_ASYNC_CMD_ERROR;
}
if (bytes == 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Server closed connection.");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->bytes_to_read = (size_t) (acmd->bytes_to_read - bytes);
if (!acmd->bytes_to_read) {
memcpy (&msg_len, acmd->buffer.data, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
if (msg_len < 16 || msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE ||
msg_len < acmd->buffer.len) {
bson_set_error (&acmd->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server.");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->bytes_to_read = msg_len - acmd->buffer.len;
acmd->state = MONGOC_ASYNC_CMD_RECV_RPC;
return _mongoc_async_cmd_phase_recv_rpc (acmd);
}
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *acmd)
{
ssize_t bytes = _mongoc_buffer_try_append_from_stream (
&acmd->buffer, acmd->stream, acmd->bytes_to_read, 0);
if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) {
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
if (bytes < 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to receive rpc bytes from server.");
return MONGOC_ASYNC_CMD_ERROR;
}
if (bytes == 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Server closed connection.");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->bytes_to_read = (size_t) (acmd->bytes_to_read - bytes);
if (!acmd->bytes_to_read) {
if (!_mongoc_rpc_scatter (
&acmd->rpc, acmd->buffer.data, acmd->buffer.len)) {
bson_set_error (&acmd->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server.");
return MONGOC_ASYNC_CMD_ERROR;
}
if (BSON_UINT32_FROM_LE (acmd->rpc.header.opcode) ==
MONGOC_OPCODE_COMPRESSED) {
uint8_t *buf = NULL;
size_t len =
BSON_UINT32_FROM_LE (acmd->rpc.compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
buf = bson_malloc0 (len);
if (!_mongoc_rpc_decompress (&acmd->rpc, buf, len)) {
bson_free (buf);
bson_set_error (&acmd->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress server reply");
return MONGOC_ASYNC_CMD_ERROR;
}
_mongoc_buffer_destroy (&acmd->buffer);
_mongoc_buffer_init (&acmd->buffer, buf, len, NULL, NULL);
}
_mongoc_rpc_swab_from_le (&acmd->rpc);
if (!_mongoc_rpc_get_first_document (&acmd->rpc, &acmd->reply)) {
bson_set_error (&acmd->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->reply_needs_cleanup = true;
return MONGOC_ASYNC_CMD_SUCCESS;
}
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c
similarity index 87%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c
index 0b944534..1952edbd 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c
@@ -1,352 +1,336 @@
/*
* Copyright 2013 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.
*/
#include <bson/bson.h>
#include <stdarg.h>
#include "mongoc-error.h"
#include "mongoc-buffer-private.h"
#include "mongoc-trace-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "buffer"
#ifndef MONGOC_BUFFER_DEFAULT_SIZE
#define MONGOC_BUFFER_DEFAULT_SIZE 1024
#endif
#define SPACE_FOR(_b, _sz) \
(((ssize_t) (_b)->datalen - (ssize_t) (_b)->len) >= (ssize_t) (_sz))
/**
* _mongoc_buffer_init:
* @buffer: A mongoc_buffer_t to initialize.
* @buf: A data buffer to attach to @buffer.
* @buflen: The size of @buflen.
* @realloc_func: A function to resize @buf.
*
* Initializes @buffer for use. If additional space is needed by @buffer, then
* @realloc_func will be called to resize @buf.
*
* @buffer takes ownership of @buf and will realloc it to zero bytes when
* cleaning up the data structure.
*/
void
_mongoc_buffer_init (mongoc_buffer_t *buffer,
uint8_t *buf,
size_t buflen,
bson_realloc_func realloc_func,
void *realloc_data)
{
- BSON_ASSERT (buffer);
+ BSON_ASSERT_PARAM (buffer);
BSON_ASSERT (buflen || !buf);
if (!realloc_func) {
realloc_func = bson_realloc_ctx;
}
if (!buflen) {
buflen = MONGOC_BUFFER_DEFAULT_SIZE;
}
if (!buf) {
buf = (uint8_t *) realloc_func (NULL, buflen, NULL);
}
memset (buffer, 0, sizeof *buffer);
buffer->data = buf;
buffer->datalen = buflen;
buffer->len = 0;
buffer->realloc_func = realloc_func;
buffer->realloc_data = realloc_data;
}
/**
* _mongoc_buffer_destroy:
* @buffer: A mongoc_buffer_t.
*
* Cleanup after @buffer and release any allocated resources.
*/
void
_mongoc_buffer_destroy (mongoc_buffer_t *buffer)
{
- BSON_ASSERT (buffer);
+ BSON_ASSERT_PARAM (buffer);
if (buffer->data && buffer->realloc_func) {
buffer->realloc_func (buffer->data, 0, buffer->realloc_data);
}
memset (buffer, 0, sizeof *buffer);
}
/**
* _mongoc_buffer_clear:
* @buffer: A mongoc_buffer_t.
* @zero: If the memory should be zeroed.
*
* Clears a buffers contents and resets it to initial state. You can request
* that the memory is zeroed, which might be useful if you know the contents
* contain security related information.
*/
void
_mongoc_buffer_clear (mongoc_buffer_t *buffer, bool zero)
{
- BSON_ASSERT (buffer);
+ BSON_ASSERT_PARAM (buffer);
if (zero) {
memset (buffer->data, 0, buffer->datalen);
}
buffer->len = 0;
}
bool
_mongoc_buffer_append (mongoc_buffer_t *buffer,
const uint8_t *data,
size_t data_size)
{
uint8_t *buf;
ENTRY;
- BSON_ASSERT (buffer);
+ BSON_ASSERT_PARAM (buffer);
BSON_ASSERT (data_size);
BSON_ASSERT (buffer->datalen);
- BSON_ASSERT ((buffer->datalen + data_size) < INT_MAX);
if (!SPACE_FOR (buffer, data_size)) {
- if (buffer->len) {
- memmove (&buffer->data[0], buffer->data, buffer->len);
- }
-
- if (!SPACE_FOR (buffer, data_size)) {
- buffer->datalen = bson_next_power_of_two (data_size + buffer->len);
- buffer->data = (uint8_t *) buffer->realloc_func (
- buffer->data, buffer->datalen, NULL);
- }
+ BSON_ASSERT ((buffer->datalen + data_size) < INT_MAX);
+ buffer->datalen = bson_next_power_of_two (data_size + buffer->len);
+ buffer->data =
+ (uint8_t *) buffer->realloc_func (buffer->data, buffer->datalen, NULL);
}
buf = &buffer->data[buffer->len];
BSON_ASSERT ((buffer->len + data_size) <= buffer->datalen);
memcpy (buf, data, data_size);
buffer->len += data_size;
RETURN (true);
}
/**
* mongoc_buffer_append_from_stream:
* @buffer; A mongoc_buffer_t.
* @stream: The stream to read from.
* @size: The number of bytes to read.
* @timeout_msec: The number of milliseconds to wait or -1 for the default
* @error: A location for a bson_error_t, or NULL.
*
* Reads from stream @size bytes and stores them in @buffer. This can be used
* in conjunction with reading RPCs from a stream. You read from the stream
* into this buffer and then scatter the buffer into the RPC.
*
* Returns: true if successful; otherwise false and @error is set.
*/
bool
_mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer,
mongoc_stream_t *stream,
size_t size,
int32_t timeout_msec,
bson_error_t *error)
{
uint8_t *buf;
ssize_t ret;
ENTRY;
- BSON_ASSERT (buffer);
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (buffer);
+ BSON_ASSERT_PARAM (stream);
BSON_ASSERT (size);
BSON_ASSERT (buffer->datalen);
- BSON_ASSERT ((buffer->datalen + size) < INT_MAX);
if (!SPACE_FOR (buffer, size)) {
- if (buffer->len) {
- memmove (&buffer->data[0], buffer->data, buffer->len);
- }
-
- if (!SPACE_FOR (buffer, size)) {
- buffer->datalen = bson_next_power_of_two (size + buffer->len);
- buffer->data = (uint8_t *) buffer->realloc_func (
- buffer->data, buffer->datalen, NULL);
- }
+ BSON_ASSERT ((buffer->datalen + size) < INT_MAX);
+ buffer->datalen = bson_next_power_of_two (size + buffer->len);
+ buffer->data =
+ (uint8_t *) buffer->realloc_func (buffer->data, buffer->datalen, NULL);
}
buf = &buffer->data[buffer->len];
BSON_ASSERT ((buffer->len + size) <= buffer->datalen);
ret = mongoc_stream_read (stream, buf, size, size, timeout_msec);
if (ret != size) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to read %" PRIu64
" bytes: socket error or timeout",
(uint64_t) size);
RETURN (false);
}
buffer->len += ret;
RETURN (true);
}
/**
* _mongoc_buffer_fill:
* @buffer: A mongoc_buffer_t.
* @stream: A stream to read from.
* @min_bytes: The minimum number of bytes to read.
* @error: A location for a bson_error_t or NULL.
*
* Attempts to fill the entire buffer, or at least @min_bytes.
*
* Returns: The number of buffered bytes, or -1 on failure.
*/
ssize_t
_mongoc_buffer_fill (mongoc_buffer_t *buffer,
mongoc_stream_t *stream,
size_t min_bytes,
int32_t timeout_msec,
bson_error_t *error)
{
ssize_t ret;
size_t avail_bytes;
ENTRY;
- BSON_ASSERT (buffer);
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (buffer);
+ BSON_ASSERT_PARAM (stream);
BSON_ASSERT (buffer->data);
BSON_ASSERT (buffer->datalen);
if (min_bytes <= buffer->len) {
RETURN (buffer->len);
}
min_bytes -= buffer->len;
- if (buffer->len) {
- memmove (&buffer->data[0], buffer->data, buffer->len);
- }
-
if (!SPACE_FOR (buffer, min_bytes)) {
buffer->datalen = bson_next_power_of_two (buffer->len + min_bytes);
buffer->data = (uint8_t *) buffer->realloc_func (
buffer->data, buffer->datalen, buffer->realloc_data);
}
avail_bytes = buffer->datalen - buffer->len;
ret = mongoc_stream_read (
stream, &buffer->data[buffer->len], avail_bytes, min_bytes, timeout_msec);
if (ret == -1) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to buffer %u bytes",
(unsigned) min_bytes);
RETURN (-1);
}
buffer->len += ret;
if (buffer->len < min_bytes) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Could only buffer %u of %u bytes",
(unsigned) buffer->len,
(unsigned) min_bytes);
RETURN (-1);
}
RETURN (buffer->len);
}
/**
* mongoc_buffer_try_append_from_stream:
* @buffer; A mongoc_buffer_t.
* @stream: The stream to read from.
* @size: The number of bytes to read.
* @timeout_msec: The number of milliseconds to wait or -1 for the default
*
* Reads from stream @size bytes and stores them in @buffer. This can be used
* in conjunction with reading RPCs from a stream. You read from the stream
* into this buffer and then scatter the buffer into the RPC.
*
* Returns: bytes read if successful; otherwise 0 or -1.
*/
ssize_t
_mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer,
mongoc_stream_t *stream,
size_t size,
int32_t timeout_msec)
{
uint8_t *buf;
ssize_t ret;
ENTRY;
- BSON_ASSERT (buffer);
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (buffer);
+ BSON_ASSERT_PARAM (stream);
BSON_ASSERT (size);
BSON_ASSERT (buffer->datalen);
- BSON_ASSERT ((buffer->datalen + size) < INT_MAX);
if (!SPACE_FOR (buffer, size)) {
+ BSON_ASSERT ((buffer->datalen + size) < INT_MAX);
buffer->datalen = bson_next_power_of_two (size + buffer->len);
buffer->data =
(uint8_t *) buffer->realloc_func (buffer->data, buffer->datalen, NULL);
}
buf = &buffer->data[buffer->len];
BSON_ASSERT ((buffer->len + size) <= buffer->datalen);
ret = mongoc_stream_read (stream, buf, size, 0, timeout_msec);
if (ret > 0) {
buffer->len += ret;
}
RETURN (ret);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
index a0b66954..97f498b8 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
@@ -1,943 +1,952 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-bulk-operation.h"
#include "mongoc-bulk-operation-private.h"
#include "mongoc-client-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-util-private.h"
#include "mongoc-opts-private.h"
#include "mongoc-write-command-private.h"
/*
* This is the implementation of both write commands and bulk write commands.
* They are all implemented as one contiguous set since we'd like to cut down
* on code duplication here.
*
* This implementation is currently naive.
*
* Some interesting optimizations might be:
*
* - If unordered mode, send operations as we get them instead of waiting
* for execute() to be called. This could save us memcpy()'s too.
* - If there is no acknowledgement desired, keep a count of how many
* replies we need and ask the socket layer to skip that many bytes
* when reading.
* - Try to use iovec to send write commands with subdocuments rather than
* copying them into the write command document.
*/
mongoc_bulk_operation_t *
mongoc_bulk_operation_new (bool ordered)
{
mongoc_bulk_operation_t *bulk;
bulk = (mongoc_bulk_operation_t *) bson_malloc0 (sizeof *bulk);
bulk->flags.bypass_document_validation = false;
bulk->flags.ordered = ordered;
bulk->server_id = 0;
_mongoc_array_init (&bulk->commands, sizeof (mongoc_write_command_t));
_mongoc_write_result_init (&bulk->result);
return bulk;
}
mongoc_bulk_operation_t *
_mongoc_bulk_operation_new (
mongoc_client_t *client, /* IN */
const char *database, /* IN */
const char *collection, /* IN */
mongoc_bulk_write_flags_t flags, /* IN */
const mongoc_write_concern_t *write_concern) /* IN */
{
mongoc_bulk_operation_t *bulk;
BSON_ASSERT (client);
BSON_ASSERT (collection);
bulk = mongoc_bulk_operation_new (flags.ordered);
bulk->client = client;
bulk->database = bson_strdup (database);
bulk->collection = bson_strdup (collection);
bulk->write_concern = mongoc_write_concern_copy (write_concern);
bulk->executed = false;
bulk->flags = flags;
bulk->operation_id = ++client->cluster.operation_id;
return bulk;
}
void
mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk) /* IN */
{
mongoc_write_command_t *command;
int i;
if (bulk) {
for (i = 0; i < bulk->commands.len; i++) {
command =
&_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i);
_mongoc_write_command_destroy (command);
}
bson_free (bulk->database);
bson_free (bulk->collection);
mongoc_write_concern_destroy (bulk->write_concern);
_mongoc_array_destroy (&bulk->commands);
_mongoc_write_result_destroy (&bulk->result);
bson_free (bulk);
}
}
/* already failed, e.g. a bad call to mongoc_bulk_operation_insert? */
#define BULK_EXIT_IF_PRIOR_ERROR \
do { \
if (bulk->result.error.domain) { \
EXIT; \
} \
} while (0)
#define BULK_RETURN_IF_PRIOR_ERROR \
do { \
if (bulk->result.error.domain) { \
if (error != &bulk->result.error) { \
bson_set_error (error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
"Bulk operation is invalid from prior error: %s", \
bulk->result.error.message); \
}; \
return false; \
}; \
} while (0)
bool
_mongoc_bulk_operation_remove_with_opts (
mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const mongoc_bulk_remove_opts_t *remove_opts,
int32_t limit,
bson_error_t *error) /* OUT */
{
mongoc_write_command_t command = {0};
mongoc_write_command_t *last;
bson_t opts;
bool has_collation;
bool ret = false;
+ bool has_delete_hint;
ENTRY;
BSON_ASSERT (bulk);
BSON_ASSERT (selector);
bson_init (&opts);
/* allow "limit" in opts, but it must be the correct limit */
if (remove_opts->limit != limit) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid \"limit\" in opts: %" PRId32 "."
" The value must be %" PRId32 ", or omitted.",
remove_opts->limit,
limit);
GOTO (done);
}
bson_append_int32 (&opts, "limit", 5, limit);
has_collation = !bson_empty (&remove_opts->collation);
if (has_collation) {
bson_append_document (&opts, "collation", 9, &remove_opts->collation);
}
+ has_delete_hint = !!(remove_opts->hint.value_type);
+ if (has_delete_hint) {
+ bson_append_value (&opts, "hint", 4, &remove_opts->hint);
+ }
+
if (bulk->commands.len) {
last = &_mongoc_array_index (
&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1);
if (last->type == MONGOC_WRITE_COMMAND_DELETE) {
last->flags.has_collation |= has_collation;
+ last->flags.has_delete_hint |= has_delete_hint;
last->flags.has_multi_write |= (remove_opts->limit == 0);
_mongoc_write_command_delete_append (last, selector, &opts);
ret = true;
GOTO (done);
}
}
_mongoc_write_command_init_delete (
&command, selector, NULL, &opts, bulk->flags, bulk->operation_id);
command.flags.has_collation = has_collation;
+ command.flags.has_delete_hint = has_delete_hint;
command.flags.has_multi_write = (remove_opts->limit == 0);
_mongoc_array_append_val (&bulk->commands, command);
ret = true;
done:
bson_destroy (&opts);
RETURN (ret);
}
bool
mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_remove_one_opts_t remove_opts;
bool ret;
ENTRY;
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_remove_one_opts_parse (
bulk->client, opts, &remove_opts, error)) {
_mongoc_bulk_remove_one_opts_cleanup (&remove_opts);
RETURN (false);
}
ret = _mongoc_bulk_operation_remove_with_opts (
bulk, selector, &remove_opts.remove, 1, error);
_mongoc_bulk_remove_one_opts_cleanup (&remove_opts);
RETURN (ret);
}
bool
mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_remove_many_opts_t remove_opts;
bool ret;
ENTRY;
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_remove_many_opts_parse (
bulk->client, opts, &remove_opts, error)) {
_mongoc_bulk_remove_many_opts_cleanup (&remove_opts);
RETURN (false);
}
ret = _mongoc_bulk_operation_remove_with_opts (
bulk, selector, &remove_opts.remove, 0, error);
_mongoc_bulk_remove_many_opts_cleanup (&remove_opts);
RETURN (ret);
}
void
mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, /* IN */
const bson_t *selector) /* IN */
{
bson_error_t *error = &bulk->result.error;
ENTRY;
BULK_EXIT_IF_PRIOR_ERROR;
if (!mongoc_bulk_operation_remove_many_with_opts (
bulk, selector, NULL, error)) {
MONGOC_WARNING ("%s", error->message);
}
if (error->domain) {
MONGOC_WARNING ("%s", error->message);
}
EXIT;
}
void
mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, /* IN */
const bson_t *selector) /* IN */
{
bson_error_t *error = &bulk->result.error;
ENTRY;
BULK_EXIT_IF_PRIOR_ERROR;
if (!mongoc_bulk_operation_remove_one_with_opts (
bulk, selector, NULL, error)) {
MONGOC_WARNING ("%s", error->message);
}
if (error->domain) {
MONGOC_WARNING ("%s", error->message);
}
EXIT;
}
void
mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk,
const bson_t *selector)
{
ENTRY;
mongoc_bulk_operation_remove (bulk, selector);
EXIT;
}
void
mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector)
{
ENTRY;
mongoc_bulk_operation_remove_one (bulk, selector);
EXIT;
}
void
mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk,
const bson_t *document)
{
ENTRY;
BSON_ASSERT (bulk);
BSON_ASSERT (document);
if (!mongoc_bulk_operation_insert_with_opts (
bulk, document, NULL /* opts */, &bulk->result.error)) {
MONGOC_WARNING ("%s", bulk->result.error.message);
}
EXIT;
}
bool
mongoc_bulk_operation_insert_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *document,
const bson_t *opts,
bson_error_t *error)
{
mongoc_bulk_insert_opts_t insert_opts;
mongoc_write_command_t command = {0};
mongoc_write_command_t *last;
bool ret = false;
ENTRY;
BSON_ASSERT (bulk);
BSON_ASSERT (document);
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_insert_opts_parse (
bulk->client, opts, &insert_opts, error)) {
GOTO (done);
}
if (!_mongoc_validate_new_document (document, insert_opts.validate, error)) {
GOTO (done);
}
if (bulk->commands.len) {
last = &_mongoc_array_index (
&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1);
if (last->type == MONGOC_WRITE_COMMAND_INSERT) {
_mongoc_write_command_insert_append (last, document);
ret = true;
GOTO (done);
}
}
_mongoc_write_command_init_insert (
&command, document, &insert_opts.extra, bulk->flags, bulk->operation_id);
_mongoc_array_append_val (&bulk->commands, command);
ret = true;
done:
_mongoc_bulk_insert_opts_cleanup (&insert_opts);
RETURN (ret);
}
static void
_mongoc_bulk_operation_update_append (
mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const mongoc_bulk_update_opts_t *update_opts,
const bson_t *array_filters,
const bson_t *extra_opts)
{
mongoc_write_command_t command = {0};
mongoc_write_command_t *last;
bson_t opts;
bool has_collation;
bool has_array_filters;
bool has_update_hint;
bson_init (&opts);
bson_append_bool (&opts, "upsert", 6, update_opts->upsert);
bson_append_bool (&opts, "multi", 5, update_opts->multi);
has_array_filters = !bson_empty0 (array_filters);
if (has_array_filters) {
bson_append_array (&opts, "arrayFilters", 12, array_filters);
}
has_collation = !bson_empty (&update_opts->collation);
if (has_collation) {
bson_append_document (&opts, "collation", 9, &update_opts->collation);
}
has_update_hint = !!(update_opts->hint.value_type);
if (has_update_hint) {
bson_append_value (&opts, "hint", 4, &update_opts->hint);
}
if (extra_opts) {
bson_concat (&opts, extra_opts);
}
if (bulk->commands.len) {
last = &_mongoc_array_index (
&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1);
if (last->type == MONGOC_WRITE_COMMAND_UPDATE) {
+ last->flags.has_array_filters |= has_array_filters;
last->flags.has_collation |= has_collation;
last->flags.has_update_hint |= has_update_hint;
last->flags.has_multi_write |= update_opts->multi;
_mongoc_write_command_update_append (last, selector, document, &opts);
bson_destroy (&opts);
return;
}
}
_mongoc_write_command_init_update (
&command, selector, document, &opts, bulk->flags, bulk->operation_id);
command.flags.has_array_filters = has_array_filters;
command.flags.has_collation = has_collation;
command.flags.has_update_hint = has_update_hint;
command.flags.has_multi_write = update_opts->multi;
_mongoc_array_append_val (&bulk->commands, command);
bson_destroy (&opts);
}
static bool
_mongoc_bulk_operation_update_with_opts (
mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const mongoc_bulk_update_opts_t *update_opts,
const bson_t *array_filters,
const bson_t *extra_opts,
bool multi,
bson_error_t *error) /* OUT */
{
ENTRY;
BSON_ASSERT (bulk);
BSON_ASSERT (selector);
BSON_ASSERT (document);
if (!_mongoc_validate_update (document, update_opts->validate, error)) {
RETURN (false);
}
/* allow "multi" in opts, but it must be the correct multi */
if (update_opts->multi != multi) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid \"multi\" in opts: %s."
" The value must be %s, or omitted.",
update_opts->multi ? "true" : "false",
multi ? "true" : "false");
RETURN (false);
}
_mongoc_bulk_operation_update_append (
bulk, selector, document, update_opts, array_filters, extra_opts);
RETURN (true);
}
bool
mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_update_one_opts_t update_opts;
bool ret;
ENTRY;
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_update_one_opts_parse (
bulk->client, opts, &update_opts, error)) {
_mongoc_bulk_update_one_opts_cleanup (&update_opts);
RETURN (false);
}
ret = _mongoc_bulk_operation_update_with_opts (bulk,
selector,
document,
&update_opts.update,
&update_opts.arrayFilters,
&update_opts.extra,
false /* multi */,
error);
_mongoc_bulk_update_one_opts_cleanup (&update_opts);
RETURN (ret);
}
bool
mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_update_many_opts_t update_opts;
bool ret;
ENTRY;
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_update_many_opts_parse (
bulk->client, opts, &update_opts, error)) {
_mongoc_bulk_update_many_opts_cleanup (&update_opts);
RETURN (false);
}
ret = _mongoc_bulk_operation_update_with_opts (bulk,
selector,
document,
&update_opts.update,
&update_opts.arrayFilters,
&update_opts.extra,
true /* multi */,
error);
_mongoc_bulk_update_many_opts_cleanup (&update_opts);
RETURN (ret);
}
void
mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert)
{
bson_t opts;
bson_error_t *error = &bulk->result.error;
ENTRY;
BULK_EXIT_IF_PRIOR_ERROR;
bson_init (&opts);
if (upsert) {
BSON_APPEND_BOOL (&opts, "upsert", upsert);
}
if (!mongoc_bulk_operation_update_many_with_opts (
bulk, selector, document, &opts, error)) {
MONGOC_WARNING ("%s", error->message);
}
bson_destroy (&opts);
if (error->domain) {
MONGOC_WARNING ("%s", error->message);
}
EXIT;
}
void
mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert)
{
bson_t opts;
bson_error_t *error = &bulk->result.error;
ENTRY;
BULK_EXIT_IF_PRIOR_ERROR;
bson_init (&opts);
BSON_APPEND_BOOL (&opts, "upsert", upsert);
if (!mongoc_bulk_operation_update_one_with_opts (
bulk, selector, document, &opts, error)) {
MONGOC_WARNING ("%s", error->message);
}
bson_destroy (&opts);
if (error->domain) {
MONGOC_WARNING ("%s", error->message);
}
EXIT;
}
bool
mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_replace_one_opts_t repl_opts;
mongoc_bulk_update_opts_t *update_opts = &repl_opts.update;
bool ret = false;
ENTRY;
BSON_ASSERT (bulk);
BSON_ASSERT (selector);
BSON_ASSERT (document);
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_replace_one_opts_parse (
bulk->client, opts, &repl_opts, error)) {
GOTO (done);
}
if (!_mongoc_validate_replace (document, update_opts->validate, error)) {
GOTO (done);
}
/* allow "multi" in opts, but it must be the correct multi */
if (update_opts->multi) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid \"multi\": true in opts for"
" mongoc_bulk_operation_replace_one_with_opts."
" The value must be true, or omitted.");
GOTO (done);
}
_mongoc_bulk_operation_update_append (
bulk, selector, document, update_opts, NULL, &repl_opts.extra);
ret = true;
done:
_mongoc_bulk_replace_one_opts_cleanup (&repl_opts);
RETURN (ret);
}
void
mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert)
{
bson_t opts = BSON_INITIALIZER;
bson_error_t *error = &bulk->result.error;
ENTRY;
BSON_APPEND_BOOL (&opts, "upsert", upsert);
if (!mongoc_bulk_operation_replace_one_with_opts (
bulk, selector, document, &opts, error)) {
MONGOC_WARNING ("%s", error->message);
}
bson_destroy (&opts);
EXIT;
}
uint32_t
mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */
bson_t *reply, /* OUT */
bson_error_t *error) /* OUT */
{
mongoc_cluster_t *cluster;
mongoc_write_command_t *command;
mongoc_server_stream_t *server_stream;
bool ret;
uint32_t offset = 0;
int i;
ENTRY;
BSON_ASSERT (bulk);
if (!bulk->client) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"mongoc_bulk_operation_execute() requires a client "
"and one has not been set.");
GOTO (err);
}
cluster = &bulk->client->cluster;
if (bulk->executed) {
_mongoc_write_result_destroy (&bulk->result);
_mongoc_write_result_init (&bulk->result);
}
bulk->executed = true;
if (!bulk->database) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"mongoc_bulk_operation_execute() requires a database "
"and one has not been set.");
GOTO (err);
} else if (!bulk->collection) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"mongoc_bulk_operation_execute() requires a collection "
"and one has not been set.");
GOTO (err);
}
/* error stored by functions like mongoc_bulk_operation_insert that
* can't report errors immediately */
if (bulk->result.error.domain) {
if (error) {
memcpy (error, &bulk->result.error, sizeof (bson_error_t));
}
GOTO (err);
}
if (!bulk->commands.len) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot do an empty bulk write");
GOTO (err);
}
for (i = 0; i < bulk->commands.len; i++) {
if (bulk->server_id) {
server_stream =
mongoc_cluster_stream_for_server (cluster,
bulk->server_id,
true /* reconnect_ok */,
bulk->session,
reply,
error);
} else {
server_stream = mongoc_cluster_stream_for_writes (
cluster, bulk->session, reply, error);
}
if (!server_stream) {
/* stream_for_server and stream_for_writes initialize reply on error */
RETURN (false);
}
command =
&_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i);
_mongoc_write_command_execute (command,
bulk->client,
server_stream,
bulk->database,
bulk->collection,
bulk->write_concern,
offset,
bulk->session,
&bulk->result);
bulk->server_id = server_stream->sd->id;
/* If a retryable error occurred and a new primary was selected, use it in
* subsequent commands. */
if (bulk->result.retry_server_id) {
bulk->server_id = bulk->result.retry_server_id;
}
if (bulk->result.failed &&
(bulk->flags.ordered || bulk->result.must_stop)) {
mongoc_server_stream_cleanup (server_stream);
GOTO (cleanup);
}
offset += command->n_documents;
mongoc_server_stream_cleanup (server_stream);
}
cleanup:
_mongoc_bson_init_if_set (reply);
ret = MONGOC_WRITE_RESULT_COMPLETE (&bulk->result,
bulk->client->error_api_version,
bulk->write_concern,
MONGOC_ERROR_COMMAND /* err domain */,
reply,
error);
RETURN (ret ? bulk->server_id : 0);
err:
_mongoc_bson_init_if_set (reply);
RETURN (false);
}
void
mongoc_bulk_operation_set_write_concern (
mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (bulk);
if (bulk->write_concern) {
mongoc_write_concern_destroy (bulk->write_concern);
}
if (write_concern) {
bulk->write_concern = mongoc_write_concern_copy (write_concern);
} else {
bulk->write_concern = mongoc_write_concern_new ();
}
}
const mongoc_write_concern_t *
mongoc_bulk_operation_get_write_concern (const mongoc_bulk_operation_t *bulk)
{
BSON_ASSERT (bulk);
return bulk->write_concern;
}
void
mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk,
const char *database)
{
BSON_ASSERT (bulk);
if (bulk->database) {
bson_free (bulk->database);
}
bulk->database = bson_strdup (database);
}
void
mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk,
const char *collection)
{
BSON_ASSERT (bulk);
if (bulk->collection) {
bson_free (bulk->collection);
}
bulk->collection = bson_strdup (collection);
}
void
mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk, void *client)
{
BSON_ASSERT (bulk);
BSON_ASSERT (client);
if (bulk->session) {
BSON_ASSERT (bulk->session->client == client);
}
bulk->client = (mongoc_client_t *) client;
/* if you call set_client, bulk was likely made by mongoc_bulk_operation_new,
* not mongoc_collection_create_bulk_operation_with_opts(), so operation_id
* is 0. */
if (!bulk->operation_id) {
bulk->operation_id = ++bulk->client->cluster.operation_id;
}
}
void
mongoc_bulk_operation_set_client_session (
mongoc_bulk_operation_t *bulk,
struct _mongoc_client_session_t *client_session)
{
BSON_ASSERT (bulk);
BSON_ASSERT (client_session);
if (bulk->client) {
BSON_ASSERT (bulk->client == client_session->client);
}
bulk->session = client_session;
}
uint32_t
mongoc_bulk_operation_get_hint (const mongoc_bulk_operation_t *bulk)
{
BSON_ASSERT (bulk);
return bulk->server_id;
}
void
mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk,
uint32_t server_id)
{
BSON_ASSERT (bulk);
bulk->server_id = server_id;
}
void
mongoc_bulk_operation_set_bypass_document_validation (
mongoc_bulk_operation_t *bulk, bool bypass)
{
BSON_ASSERT (bulk);
bulk->flags.bypass_document_validation = bypass;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
similarity index 94%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
index b73c3bc8..b8147e36 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
@@ -1,82 +1,85 @@
/*
* Copyright 2017-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
*
* 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CHANGE_STREAM_PRIVATE_H
#define MONGOC_CHANGE_STREAM_PRIVATE_H
#include "mongoc-change-stream.h"
#include "mongoc-client-session.h"
#include "mongoc-collection.h"
#include "mongoc-cursor.h"
#include "mongoc-opts-private.h"
#include "mongoc-opts-helpers-private.h"
typedef enum {
MONGOC_CHANGE_STREAM_COLLECTION,
MONGOC_CHANGE_STREAM_DATABASE,
MONGOC_CHANGE_STREAM_CLIENT
} mongoc_change_stream_type_t;
struct _mongoc_change_stream_t {
mongoc_change_stream_opts_t opts;
mongoc_timestamp_t operation_time;
bson_t pipeline_to_append;
bson_t resume_token;
bson_t *full_document;
bson_error_t err;
bson_t err_doc;
mongoc_cursor_t *cursor;
mongoc_client_t *client;
mongoc_read_prefs_t *read_prefs;
mongoc_read_concern_t *read_concern;
mongoc_change_stream_type_t change_stream_type;
- char db[140];
- char coll[140];
+ char *db;
+ char *coll;
int64_t max_await_time_ms;
int32_t batch_size;
bool has_returned_results;
/* Track whether the change stream has resumed after an error, as this
* determines how we construct an initial or resuming aggregate command. */
bool resumed;
mongoc_client_session_t *implicit_session;
+
+ /* The max_wire_version of the server the change stream is tied to. */
+ uint32_t max_wire_version;
};
mongoc_change_stream_t *
_mongoc_change_stream_new_from_collection (const mongoc_collection_t *coll,
const bson_t *pipeline,
const bson_t *opts);
mongoc_change_stream_t *
_mongoc_change_stream_new_from_database (const mongoc_database_t *db,
const bson_t *pipeline,
const bson_t *opts);
mongoc_change_stream_t *
_mongoc_change_stream_new_from_client (mongoc_client_t *client,
const bson_t *pipeline,
const bson_t *opts);
#endif /* MONGOC_CHANGE_STREAM_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
similarity index 92%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
index fa962fda..dedceef1 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
@@ -1,653 +1,661 @@
/*
* Copyright 2017-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
*
* 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.
*/
#include <bson/bson.h>
#include "mongoc-change-stream-private.h"
#include "mongoc-collection-private.h"
#include "mongoc-client-private.h"
#include "mongoc-client-session-private.h"
#include "mongoc-cursor-private.h"
#include "mongoc-database-private.h"
#include "mongoc-error.h"
+#include "mongoc-error-private.h"
#define CHANGE_STREAM_ERR(_str) \
bson_set_error (&stream->err, \
MONGOC_ERROR_CURSOR, \
MONGOC_ERROR_BSON, \
"Could not set " _str);
/* the caller knows either a client or server error has occurred.
* `reply` contains the server reply or an empty document. */
static bool
-_is_resumable_error (const bson_t *reply)
+_is_resumable_error (mongoc_change_stream_t *stream, const bson_t *reply)
{
bson_error_t error = {0};
/* Change Streams Spec resumable criteria: "any error encountered which is
* not a server error (e.g. a timeout error or network error)" */
if (bson_empty (reply)) {
return true;
}
if (_mongoc_cmd_check_ok (reply, MONGOC_ERROR_API_VERSION_2, &error)) {
return true;
}
- if (mongoc_error_has_label (reply, "NonResumableChangeStreamError")) {
- return false;
+ if (error.code == MONGOC_SERVER_ERR_CURSOR_NOT_FOUND) {
+ return true;
}
- /* Change Streams Spec resumable criteria: "a server error response with an
- * error message containing the substring 'not master' or 'node is
- * recovering' */
- if (strstr (error.message, "not master") ||
- strstr (error.message, "node is recovering")) {
- return true;
+ if (stream->max_wire_version >= WIRE_VERSION_4_4) {
+ return mongoc_error_has_label (reply, "ResumableChangeStreamError");
}
- /* Change Streams Spec resumable criteria: "any server error response from a
- * getMore command excluding those containing the following error codes" */
switch (error.code) {
- case 11601: /* Interrupted */
- case 136: /* CappedPositionLost */
- case 237: /* CursorKilled */
- case MONGOC_ERROR_QUERY_FAILURE: /* error code omitted */
- return false;
- default:
+ case MONGOC_SERVER_ERR_HOSTUNREACHABLE:
+ case MONGOC_SERVER_ERR_HOSTNOTFOUND:
+ case MONGOC_SERVER_ERR_NETWORKTIMEOUT:
+ case MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS:
+ case MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN:
+ case MONGOC_SERVER_ERR_EXCEEDEDTIMELIMIT:
+ case MONGOC_SERVER_ERR_SOCKETEXCEPTION:
+ case MONGOC_SERVER_ERR_NOTMASTER:
+ case MONGOC_SERVER_ERR_INTERRUPTEDATSHUTDOWN:
+ case MONGOC_SERVER_ERR_INTERRUPTEDDUETOREPLSTATECHANGE:
+ case MONGOC_SERVER_ERR_NOTMASTERNOSLAVEOK:
+ case MONGOC_SERVER_ERR_NOTMASTERORSECONDARY:
+ case MONGOC_SERVER_ERR_STALESHARDVERSION:
+ case MONGOC_SERVER_ERR_STALEEPOCH:
+ case MONGOC_SERVER_ERR_STALECONFIG:
+ case MONGOC_SERVER_ERR_RETRYCHANGESTREAM:
+ case MONGOC_SERVER_ERR_FAILEDTOSATISFYREADPREFERENCE:
return true;
+ default:
+ return false;
}
}
static void
_set_resume_token (mongoc_change_stream_t *stream, const bson_t *resume_token)
{
BSON_ASSERT (stream);
BSON_ASSERT (resume_token);
bson_destroy (&stream->resume_token);
bson_copy_to (resume_token, &stream->resume_token);
}
/* construct the aggregate command in cmd. looks like one of the following:
* for a collection change stream:
* { aggregate: collname, pipeline: [], cursor: { batchSize: x } }
* for a database change stream:
* { aggregate: 1, pipeline: [], cursor: { batchSize: x } }
* for a client change stream:
* { aggregate: 1, pipeline: [{$changeStream: {allChangesForCluster: true}}],
* cursor: { batchSize: x } }
*/
static void
-_make_command (mongoc_change_stream_t *stream,
- bson_t *command,
- int32_t max_wire_version)
+_make_command (mongoc_change_stream_t *stream, bson_t *command)
{
bson_iter_t iter;
bson_t change_stream_stage; /* { $changeStream: <change_stream_doc> } */
bson_t change_stream_doc;
bson_t pipeline;
bson_t cursor_doc;
if (stream->change_stream_type == MONGOC_CHANGE_STREAM_COLLECTION) {
bson_append_utf8 (
command, "aggregate", 9, stream->coll, (int) strlen (stream->coll));
} else {
bson_append_int32 (command, "aggregate", 9, 1);
}
bson_append_array_begin (command, "pipeline", 8, &pipeline);
/* append the $changeStream stage. */
bson_append_document_begin (&pipeline, "0", 1, &change_stream_stage);
bson_append_document_begin (
&change_stream_stage, "$changeStream", 13, &change_stream_doc);
bson_concat (&change_stream_doc, stream->full_document);
if (stream->resumed) {
/* Change stream spec: Resume Process */
/* If there is a cached resumeToken: */
if (!bson_empty (&stream->resume_token)) {
/* If the ChangeStream was started with startAfter
and has yet to return a result document: */
if (!bson_empty (&stream->opts.startAfter) &&
!stream->has_returned_results) {
/* The driver MUST set startAfter to the cached resumeToken */
BSON_APPEND_DOCUMENT (
&change_stream_doc, "startAfter", &stream->resume_token);
} else {
/* The driver MUST set resumeAfter to the cached resumeToken */
BSON_APPEND_DOCUMENT (
&change_stream_doc, "resumeAfter", &stream->resume_token);
}
} else if (!_mongoc_timestamp_empty (&stream->operation_time) &&
- max_wire_version >= 7) {
+ stream->max_wire_version >= WIRE_VERSION_4_0) {
/* Else if there is no cached resumeToken and the ChangeStream
has a saved operation time and the max wire version is >= 7,
the driver MUST set startAtOperationTime */
_mongoc_timestamp_append (&stream->operation_time,
&change_stream_doc,
"startAtOperationTime");
}
} else {
/* Change streams spec: "startAtOperationTime, resumeAfter, and startAfter
* are all mutually exclusive; if any two are set, the server will return
* an error. Drivers MUST NOT throw a custom error, and MUST defer to the
* server error." */
if (!bson_empty (&stream->opts.resumeAfter)) {
BSON_APPEND_DOCUMENT (
&change_stream_doc, "resumeAfter", &stream->opts.resumeAfter);
/* Update the cached resume token */
_set_resume_token (stream, &stream->opts.resumeAfter);
}
if (!bson_empty (&stream->opts.startAfter)) {
BSON_APPEND_DOCUMENT (
&change_stream_doc, "startAfter", &stream->opts.startAfter);
/* Update the cached resume token (take precedence over resumeAfter) */
_set_resume_token (stream, &stream->opts.startAfter);
}
if (!_mongoc_timestamp_empty (&stream->operation_time)) {
_mongoc_timestamp_append (&stream->operation_time,
&change_stream_doc,
"startAtOperationTime");
}
}
if (stream->change_stream_type == MONGOC_CHANGE_STREAM_CLIENT) {
bson_append_bool (&change_stream_doc, "allChangesForCluster", 20, true);
}
bson_append_document_end (&change_stream_stage, &change_stream_doc);
bson_append_document_end (&pipeline, &change_stream_stage);
/* Append user pipeline if it exists */
if (bson_iter_init_find (&iter, &stream->pipeline_to_append, "pipeline") &&
BSON_ITER_HOLDS_ARRAY (&iter)) {
bson_iter_t child_iter;
uint32_t key_int = 1;
char buf[16];
const char *key_str;
BSON_ASSERT (bson_iter_recurse (&iter, &child_iter));
while (bson_iter_next (&child_iter)) {
/* the user pipeline may consist of invalid stages or non-documents.
* append anyway, and rely on the server error. */
size_t keyLen =
bson_uint32_to_string (key_int, &key_str, buf, sizeof (buf));
bson_append_value (
&pipeline, key_str, (int) keyLen, bson_iter_value (&child_iter));
++key_int;
}
}
bson_append_array_end (command, &pipeline);
/* Add batch size if needed */
bson_append_document_begin (command, "cursor", 6, &cursor_doc);
if (stream->batch_size > 0) {
bson_append_int32 (&cursor_doc, "batchSize", 9, stream->batch_size);
}
bson_append_document_end (command, &cursor_doc);
}
/*---------------------------------------------------------------------------
*
* _make_cursor --
*
* Construct and send the aggregate command and create the resulting
* cursor. On error, stream->cursor remains NULL, otherwise it is
* created and must be destroyed.
*
* Return:
* False on error and sets stream->err.
*
*--------------------------------------------------------------------------
*/
static bool
_make_cursor (mongoc_change_stream_t *stream)
{
mongoc_client_session_t *cs = NULL;
bson_t command_opts;
bson_t command; /* { aggregate: "coll", pipeline: [], ... } */
bson_t reply;
bson_t getmore_opts = BSON_INITIALIZER;
bson_iter_t iter;
mongoc_server_description_t *sd;
uint32_t server_id;
- int32_t max_wire_version = -1;
BSON_ASSERT (stream);
BSON_ASSERT (!stream->cursor);
bson_init (&command);
bson_copy_to (&(stream->opts.extra), &command_opts);
sd = mongoc_client_select_server (
stream->client, false /* for_writes */, stream->read_prefs, &stream->err);
if (!sd) {
goto cleanup;
}
server_id = mongoc_server_description_id (sd);
bson_append_int32 (&command_opts, "serverId", 8, server_id);
bson_append_int32 (&getmore_opts, "serverId", 8, server_id);
- max_wire_version = sd->max_wire_version;
+ stream->max_wire_version = sd->max_wire_version;
mongoc_server_description_destroy (sd);
if (bson_iter_init_find (&iter, &command_opts, "sessionId")) {
if (!_mongoc_client_session_from_iter (
stream->client, &iter, &cs, &stream->err)) {
goto cleanup;
}
} else if (stream->implicit_session) {
/* If an implicit session was created before, and this cursor is now
* being recreated after resuming, then use the same session as before. */
cs = stream->implicit_session;
if (!mongoc_client_session_append (cs, &command_opts, &stream->err)) {
goto cleanup;
}
} else {
/* Create an implicit session. This session lsid must be the same for the
* agg command and the subsequent getMores. Thus, this implicit session is
* passed as if it were an explicit session to
* mongoc_client_read_command_with_opts and
* _mongoc_cursor_change_stream_new, but it is still implicit and its
* lifetime is owned by this change_stream_t. */
mongoc_session_opt_t *session_opts;
session_opts = mongoc_session_opts_new ();
mongoc_session_opts_set_causal_consistency (session_opts, false);
/* returns NULL if sessions aren't supported. ignore errors. */
cs = mongoc_client_start_session (stream->client, session_opts, NULL);
stream->implicit_session = cs;
mongoc_session_opts_destroy (session_opts);
if (cs &&
!mongoc_client_session_append (cs, &command_opts, &stream->err)) {
goto cleanup;
}
}
if (cs && !mongoc_client_session_append (cs, &getmore_opts, &stream->err)) {
goto cleanup;
}
if (stream->read_concern && !bson_has_field (&command_opts, "readConcern")) {
mongoc_read_concern_append (stream->read_concern, &command_opts);
}
- _make_command (stream, &command, max_wire_version);
+ _make_command (stream, &command);
/* even though serverId has already been set, still pass the read prefs.
* they are necessary for OP_MSG if sending to a secondary. */
if (!mongoc_client_read_command_with_opts (stream->client,
stream->db,
&command,
stream->read_prefs,
&command_opts,
&reply,
&stream->err)) {
bson_destroy (&stream->err_doc);
bson_copy_to (&reply, &stream->err_doc);
bson_destroy (&reply);
goto cleanup;
}
bson_append_bool (
&getmore_opts, MONGOC_CURSOR_TAILABLE, MONGOC_CURSOR_TAILABLE_LEN, true);
bson_append_bool (&getmore_opts,
MONGOC_CURSOR_AWAIT_DATA,
MONGOC_CURSOR_AWAIT_DATA_LEN,
true);
/* maxTimeMS is only appended to getMores if these are set in cursor opts. */
if (stream->max_await_time_ms > 0) {
bson_append_int64 (&getmore_opts,
MONGOC_CURSOR_MAX_AWAIT_TIME_MS,
MONGOC_CURSOR_MAX_AWAIT_TIME_MS_LEN,
stream->max_await_time_ms);
}
if (stream->batch_size > 0) {
bson_append_int32 (&getmore_opts,
MONGOC_CURSOR_BATCH_SIZE,
MONGOC_CURSOR_BATCH_SIZE_LEN,
stream->batch_size);
}
/* steals reply. */
stream->cursor =
_mongoc_cursor_change_stream_new (stream->client, &reply, &getmore_opts);
if (mongoc_cursor_error (stream->cursor, NULL)) {
goto cleanup;
}
/* Change stream spec: "When aggregate or getMore returns: If an empty batch
* was returned and a postBatchResumeToken was included, cache it." */
if (_mongoc_cursor_change_stream_end_of_batch (stream->cursor) &&
_mongoc_cursor_change_stream_has_post_batch_resume_token (
stream->cursor)) {
_set_resume_token (
stream,
_mongoc_cursor_change_stream_get_post_batch_resume_token (
stream->cursor));
}
/* Change stream spec: startAtOperationTime */
if (bson_empty (&stream->opts.resumeAfter) &&
bson_empty (&stream->opts.startAfter) &&
_mongoc_timestamp_empty (&stream->operation_time) &&
- max_wire_version >= 7 && bson_empty (&stream->resume_token) &&
+ stream->max_wire_version >= WIRE_VERSION_4_0 &&
+ bson_empty (&stream->resume_token) &&
bson_iter_init_find (
&iter,
_mongoc_cursor_change_stream_get_reply (stream->cursor),
"operationTime") &&
BSON_ITER_HOLDS_TIMESTAMP (&iter)) {
_mongoc_timestamp_set_from_bson (&stream->operation_time, &iter);
}
cleanup:
bson_destroy (&command);
bson_destroy (&command_opts);
bson_destroy (&getmore_opts);
return stream->err.code == 0;
}
/*---------------------------------------------------------------------------
*
* _change_stream_init --
*
* Called after @stream has the collection name, database name, read
* preferences, and read concern set. Creates the change streams
* cursor.
*
*--------------------------------------------------------------------------
*/
void
_change_stream_init (mongoc_change_stream_t *stream,
const bson_t *pipeline,
const bson_t *opts)
{
BSON_ASSERT (pipeline);
stream->max_await_time_ms = -1;
stream->batch_size = -1;
bson_init (&stream->pipeline_to_append);
bson_init (&stream->resume_token);
bson_init (&stream->err_doc);
if (!_mongoc_change_stream_opts_parse (
stream->client, opts, &stream->opts, &stream->err)) {
return;
}
stream->full_document = BCON_NEW ("fullDocument", stream->opts.fullDocument);
_mongoc_timestamp_set (&stream->operation_time,
&stream->opts.startAtOperationTime);
stream->batch_size = stream->opts.batchSize;
stream->max_await_time_ms = stream->opts.maxAwaitTimeMS;
/* Accept two forms of user pipeline:
* 1. A document like: { "pipeline": [...] }
* 2. An array-like document: { "0": {}, "1": {}, ... }
* If the passed pipeline is invalid, we pass it along and let the server
* error instead.
*/
if (!bson_empty (pipeline)) {
bson_iter_t iter;
if (bson_iter_init_find (&iter, pipeline, "pipeline") &&
BSON_ITER_HOLDS_ARRAY (&iter)) {
if (!BSON_APPEND_VALUE (&stream->pipeline_to_append,
"pipeline",
bson_iter_value (&iter))) {
CHANGE_STREAM_ERR ("pipeline");
}
} else {
if (!BSON_APPEND_ARRAY (
&stream->pipeline_to_append, "pipeline", pipeline)) {
CHANGE_STREAM_ERR ("pipeline");
}
}
}
if (stream->err.code == 0) {
(void) _make_cursor (stream);
}
}
mongoc_change_stream_t *
_mongoc_change_stream_new_from_collection (const mongoc_collection_t *coll,
const bson_t *pipeline,
const bson_t *opts)
{
mongoc_change_stream_t *stream;
BSON_ASSERT (coll);
stream =
(mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t));
- bson_strncpy (stream->db, coll->db, sizeof (stream->db));
- bson_strncpy (stream->coll, coll->collection, sizeof (stream->coll));
+ stream->db = bson_strdup (coll->db);
+ stream->coll = bson_strdup (coll->collection);
stream->read_prefs = mongoc_read_prefs_copy (coll->read_prefs);
stream->read_concern = mongoc_read_concern_copy (coll->read_concern);
stream->client = coll->client;
stream->change_stream_type = MONGOC_CHANGE_STREAM_COLLECTION;
_change_stream_init (stream, pipeline, opts);
return stream;
}
mongoc_change_stream_t *
_mongoc_change_stream_new_from_database (const mongoc_database_t *db,
const bson_t *pipeline,
const bson_t *opts)
{
mongoc_change_stream_t *stream;
BSON_ASSERT (db);
stream =
(mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t));
- bson_strncpy (stream->db, db->name, sizeof (stream->db));
- stream->coll[0] = '\0';
+ stream->db = bson_strdup (db->name);
+ stream->coll = NULL;
stream->read_prefs = mongoc_read_prefs_copy (db->read_prefs);
stream->read_concern = mongoc_read_concern_copy (db->read_concern);
stream->client = db->client;
stream->change_stream_type = MONGOC_CHANGE_STREAM_DATABASE;
_change_stream_init (stream, pipeline, opts);
return stream;
}
mongoc_change_stream_t *
_mongoc_change_stream_new_from_client (mongoc_client_t *client,
const bson_t *pipeline,
const bson_t *opts)
{
mongoc_change_stream_t *stream;
BSON_ASSERT (client);
stream =
(mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t));
- bson_strncpy (stream->db, "admin", sizeof (stream->db));
- stream->coll[0] = '\0';
+ stream->db = bson_strdup ("admin");
+ stream->coll = NULL;
stream->read_prefs = mongoc_read_prefs_copy (client->read_prefs);
stream->read_concern = mongoc_read_concern_copy (client->read_concern);
stream->client = client;
stream->change_stream_type = MONGOC_CHANGE_STREAM_CLIENT;
_change_stream_init (stream, pipeline, opts);
return stream;
}
const bson_t *
mongoc_change_stream_get_resume_token (mongoc_change_stream_t *stream)
{
if (!bson_empty (&stream->resume_token)) {
return &stream->resume_token;
}
return NULL;
}
bool
mongoc_change_stream_next (mongoc_change_stream_t *stream, const bson_t **bson)
{
bson_iter_t iter;
bson_t doc_resume_token;
uint32_t len;
const uint8_t *data;
bool ret = false;
BSON_ASSERT (stream);
BSON_ASSERT (bson);
if (stream->err.code != 0) {
goto end;
}
BSON_ASSERT (stream->cursor);
if (!mongoc_cursor_next (stream->cursor, bson)) {
const bson_t *err_doc;
bson_error_t err;
bool resumable = false;
if (!mongoc_cursor_error_document (stream->cursor, &err, &err_doc)) {
/* no error occurred, just no documents left. */
goto end;
}
- resumable = _is_resumable_error (err_doc);
+ resumable = _is_resumable_error (stream, err_doc);
while (resumable) {
/* recreate the cursor. */
mongoc_cursor_destroy (stream->cursor);
stream->cursor = NULL;
stream->resumed = true;
if (!_make_cursor (stream)) {
goto end;
}
if (mongoc_cursor_next (stream->cursor, bson)) {
break;
}
if (!mongoc_cursor_error_document (stream->cursor, &err, &err_doc)) {
goto end;
}
if (err_doc) {
- resumable = _is_resumable_error (err_doc);
+ resumable = _is_resumable_error (stream, err_doc);
} else {
resumable = false;
}
}
if (!resumable) {
stream->err = err;
bson_destroy (&stream->err_doc);
bson_copy_to (err_doc, &stream->err_doc);
goto end;
}
}
/* we have received documents, either from the first call to next or after a
* resume. */
stream->has_returned_results = true;
if (!bson_iter_init_find (&iter, *bson, "_id") ||
!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_set_error (&stream->err,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CHANGE_STREAM_NO_RESUME_TOKEN,
"Cannot provide resume functionality when the resume "
"token is missing");
goto end;
}
/* copy the resume token. */
bson_iter_document (&iter, &len, &data);
BSON_ASSERT (bson_init_static (&doc_resume_token, data, len));
_set_resume_token (stream, &doc_resume_token);
/* clear out the operation time, since we no longer need it to resume. */
_mongoc_timestamp_clear (&stream->operation_time);
ret = true;
end:
/* Change stream spec: Updating the Cached Resume Token */
if (stream->cursor && !mongoc_cursor_error (stream->cursor, NULL) &&
_mongoc_cursor_change_stream_end_of_batch (stream->cursor) &&
_mongoc_cursor_change_stream_has_post_batch_resume_token (
stream->cursor)) {
_set_resume_token (
stream,
_mongoc_cursor_change_stream_get_post_batch_resume_token (
stream->cursor));
}
/* Driver Sessions Spec: "When an implicit session is associated with a
* cursor for use with getMore operations, the session MUST be returned to
* the pool immediately following a getMore operation that indicates that the
* cursor has been exhausted." */
if (stream->implicit_session) {
/* if creating the change stream cursor errored, it may be null. */
if (!stream->cursor || stream->cursor->cursor_id == 0) {
mongoc_client_session_destroy (stream->implicit_session);
stream->implicit_session = NULL;
}
}
return ret;
}
bool
mongoc_change_stream_error_document (const mongoc_change_stream_t *stream,
bson_error_t *err,
const bson_t **bson)
{
BSON_ASSERT (stream);
if (stream->err.code != 0) {
if (err) {
*err = stream->err;
}
if (bson) {
*bson = &stream->err_doc;
}
return true;
}
if (bson) {
*bson = NULL;
}
return false;
}
void
mongoc_change_stream_destroy (mongoc_change_stream_t *stream)
{
if (!stream) {
return;
}
bson_destroy (&stream->pipeline_to_append);
bson_destroy (&stream->resume_token);
bson_destroy (stream->full_document);
bson_destroy (&stream->err_doc);
_mongoc_change_stream_opts_cleanup (&stream->opts);
mongoc_cursor_destroy (stream->cursor);
mongoc_client_session_destroy (stream->implicit_session);
mongoc_read_prefs_destroy (stream->read_prefs);
mongoc_read_concern_destroy (stream->read_concern);
+ bson_free (stream->db);
+ bson_free (stream->coll);
bson_free (stream);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c
similarity index 84%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c
index 6c4c6de8..176c8955 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c
@@ -1,466 +1,506 @@
/*
* Copyright 2013 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.
*/
-
#include "mongoc.h"
#include "mongoc-apm-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-client-pool-private.h"
#include "mongoc-client-pool.h"
#include "mongoc-client-private.h"
#include "mongoc-client-side-encryption-private.h"
#include "mongoc-queue-private.h"
#include "mongoc-thread-private.h"
#include "mongoc-topology-private.h"
+#include "mongoc-topology-background-monitoring-private.h"
#include "mongoc-trace-private.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-ssl-private.h"
#endif
struct _mongoc_client_pool_t {
bson_mutex_t mutex;
mongoc_cond_t cond;
mongoc_queue_t queue;
mongoc_topology_t *topology;
mongoc_uri_t *uri;
uint32_t min_pool_size;
uint32_t max_pool_size;
uint32_t size;
#ifdef MONGOC_ENABLE_SSL
bool ssl_opts_set;
mongoc_ssl_opt_t ssl_opts;
#endif
bool apm_callbacks_set;
mongoc_apm_callbacks_t apm_callbacks;
void *apm_context;
int32_t error_api_version;
bool error_api_set;
};
#ifdef MONGOC_ENABLE_SSL
void
mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool,
const mongoc_ssl_opt_t *opts)
{
- BSON_ASSERT (pool);
-
bson_mutex_lock (&pool->mutex);
- _mongoc_ssl_opts_cleanup (&pool->ssl_opts);
+ _mongoc_ssl_opts_cleanup (&pool->ssl_opts,
+ false /* don't free internal opts. */);
- memset (&pool->ssl_opts, 0, sizeof pool->ssl_opts);
pool->ssl_opts_set = false;
if (opts) {
- _mongoc_ssl_opts_copy_to (opts, &pool->ssl_opts);
+ _mongoc_ssl_opts_copy_to (
+ opts, &pool->ssl_opts, false /* don't overwrite internal opts. */);
pool->ssl_opts_set = true;
}
mongoc_topology_scanner_set_ssl_opts (pool->topology->scanner,
&pool->ssl_opts);
bson_mutex_unlock (&pool->mutex);
}
+
+void
+_mongoc_client_pool_set_internal_tls_opts (
+ mongoc_client_pool_t *pool, _mongoc_internal_tls_opts_t *internal)
+{
+ bson_mutex_lock (&pool->mutex);
+ if (!pool->ssl_opts_set) {
+ return;
+ }
+ pool->ssl_opts.internal = bson_malloc (sizeof (_mongoc_internal_tls_opts_t));
+ memcpy (
+ pool->ssl_opts.internal, internal, sizeof (_mongoc_internal_tls_opts_t));
+ bson_mutex_unlock (&pool->mutex);
+}
#endif
mongoc_client_pool_t *
mongoc_client_pool_new (const mongoc_uri_t *uri)
{
mongoc_topology_t *topology;
mongoc_client_pool_t *pool;
const bson_t *b;
bson_iter_t iter;
const char *appname;
ENTRY;
BSON_ASSERT (uri);
#ifndef MONGOC_ENABLE_SSL
if (mongoc_uri_get_tls (uri)) {
MONGOC_ERROR ("Can't create SSL client pool,"
" SSL not enabled in this build.");
return NULL;
}
#endif
pool = (mongoc_client_pool_t *) bson_malloc0 (sizeof *pool);
bson_mutex_init (&pool->mutex);
_mongoc_queue_init (&pool->queue);
pool->uri = mongoc_uri_copy (uri);
pool->min_pool_size = 0;
pool->max_pool_size = 100;
pool->size = 0;
topology = mongoc_topology_new (uri, false);
pool->topology = topology;
pool->error_api_version = MONGOC_ERROR_API_VERSION_LEGACY;
b = mongoc_uri_get_options (pool->uri);
if (bson_iter_init_find_case (&iter, b, MONGOC_URI_MINPOOLSIZE)) {
MONGOC_WARNING (
MONGOC_URI_MINPOOLSIZE
" is deprecated; its behavior does not match its name, and its actual"
" behavior will likely hurt performance.");
if (BSON_ITER_HOLDS_INT32 (&iter)) {
pool->min_pool_size = BSON_MAX (0, bson_iter_int32 (&iter));
}
}
if (bson_iter_init_find_case (&iter, b, MONGOC_URI_MAXPOOLSIZE)) {
if (BSON_ITER_HOLDS_INT32 (&iter)) {
pool->max_pool_size = BSON_MAX (1, bson_iter_int32 (&iter));
}
}
appname =
mongoc_uri_get_option_as_utf8 (pool->uri, MONGOC_URI_APPNAME, NULL);
if (appname) {
/* the appname should have already been validated */
BSON_ASSERT (mongoc_client_pool_set_appname (pool, appname));
}
#ifdef MONGOC_ENABLE_SSL
if (mongoc_uri_get_tls (pool->uri)) {
mongoc_ssl_opt_t ssl_opt = {0};
+ _mongoc_internal_tls_opts_t internal_tls_opts = {0};
- _mongoc_ssl_opts_from_uri (&ssl_opt, pool->uri);
+ _mongoc_ssl_opts_from_uri (&ssl_opt, &internal_tls_opts, pool->uri);
/* sets use_ssl = true */
mongoc_client_pool_set_ssl_opts (pool, &ssl_opt);
+ _mongoc_client_pool_set_internal_tls_opts (pool, &internal_tls_opts);
}
#endif
mongoc_counter_client_pools_active_inc ();
RETURN (pool);
}
void
mongoc_client_pool_destroy (mongoc_client_pool_t *pool)
{
mongoc_client_t *client;
ENTRY;
if (!pool) {
EXIT;
}
if (pool->topology->session_pool) {
client = mongoc_client_pool_pop (pool);
_mongoc_client_end_sessions (client);
mongoc_client_pool_push (pool, client);
}
while (
(client = (mongoc_client_t *) _mongoc_queue_pop_head (&pool->queue))) {
mongoc_client_destroy (client);
}
mongoc_topology_destroy (pool->topology);
mongoc_uri_destroy (pool->uri);
bson_mutex_destroy (&pool->mutex);
mongoc_cond_destroy (&pool->cond);
#ifdef MONGOC_ENABLE_SSL
- _mongoc_ssl_opts_cleanup (&pool->ssl_opts);
+ _mongoc_ssl_opts_cleanup (&pool->ssl_opts, true);
#endif
bson_free (pool);
mongoc_counter_client_pools_active_dec ();
mongoc_counter_client_pools_disposed_inc ();
EXIT;
}
/*
* Start the background topology scanner.
*
* This function assumes the pool's mutex is locked
*/
static void
_start_scanner_if_needed (mongoc_client_pool_t *pool)
{
- if (!_mongoc_topology_start_background_scanner (pool->topology)) {
- MONGOC_ERROR ("Background scanner did not start!");
- abort ();
+ if (!pool->topology->single_threaded) {
+ bson_mutex_lock (&pool->topology->mutex);
+ _mongoc_topology_background_monitoring_start (pool->topology);
+ bson_mutex_unlock (&pool->topology->mutex);
}
}
static void
_initialize_new_client (mongoc_client_pool_t *pool, mongoc_client_t *client)
{
/* for tests */
mongoc_client_set_stream_initiator (
client,
pool->topology->scanner->initiator,
pool->topology->scanner->initiator_context);
client->error_api_version = pool->error_api_version;
_mongoc_client_set_apm_callbacks_private (
client, &pool->apm_callbacks, pool->apm_context);
#ifdef MONGOC_ENABLE_SSL
if (pool->ssl_opts_set) {
mongoc_client_set_ssl_opts (client, &pool->ssl_opts);
}
#endif
}
mongoc_client_t *
mongoc_client_pool_pop (mongoc_client_pool_t *pool)
{
mongoc_client_t *client;
+ int32_t wait_queue_timeout_ms;
+ int64_t expire_at_ms = -1;
+ int64_t now_ms;
+ int r;
ENTRY;
BSON_ASSERT (pool);
+ wait_queue_timeout_ms = mongoc_uri_get_option_as_int32 (
+ pool->uri, MONGOC_URI_WAITQUEUETIMEOUTMS, -1);
+ if (wait_queue_timeout_ms > 0) {
+ expire_at_ms =
+ (bson_get_monotonic_time () / 1000) + wait_queue_timeout_ms;
+ }
bson_mutex_lock (&pool->mutex);
again:
if (!(client = (mongoc_client_t *) _mongoc_queue_pop_head (&pool->queue))) {
if (pool->size < pool->max_pool_size) {
client = _mongoc_client_new_from_uri (pool->topology);
_initialize_new_client (pool, client);
pool->size++;
} else {
- mongoc_cond_wait (&pool->cond, &pool->mutex);
+ if (wait_queue_timeout_ms > 0) {
+ now_ms = bson_get_monotonic_time () / 1000;
+ if (now_ms < expire_at_ms) {
+ r = mongoc_cond_timedwait (
+ &pool->cond, &pool->mutex, expire_at_ms - now_ms);
+ if (mongo_cond_ret_is_timedout (r)) {
+ GOTO (done);
+ }
+ } else {
+ GOTO (done);
+ }
+ } else {
+ mongoc_cond_wait (&pool->cond, &pool->mutex);
+ }
GOTO (again);
}
}
_start_scanner_if_needed (pool);
+done:
bson_mutex_unlock (&pool->mutex);
RETURN (client);
}
mongoc_client_t *
mongoc_client_pool_try_pop (mongoc_client_pool_t *pool)
{
mongoc_client_t *client;
ENTRY;
BSON_ASSERT (pool);
bson_mutex_lock (&pool->mutex);
if (!(client = (mongoc_client_t *) _mongoc_queue_pop_head (&pool->queue))) {
if (pool->size < pool->max_pool_size) {
client = _mongoc_client_new_from_uri (pool->topology);
_initialize_new_client (pool, client);
pool->size++;
}
}
if (client) {
_start_scanner_if_needed (pool);
}
bson_mutex_unlock (&pool->mutex);
RETURN (client);
}
void
mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client)
{
ENTRY;
BSON_ASSERT (pool);
BSON_ASSERT (client);
bson_mutex_lock (&pool->mutex);
_mongoc_queue_push_head (&pool->queue, client);
if (pool->min_pool_size &&
_mongoc_queue_get_length (&pool->queue) > pool->min_pool_size) {
mongoc_client_t *old_client;
old_client = (mongoc_client_t *) _mongoc_queue_pop_tail (&pool->queue);
if (old_client) {
mongoc_client_destroy (old_client);
pool->size--;
}
}
mongoc_cond_signal (&pool->cond);
bson_mutex_unlock (&pool->mutex);
EXIT;
}
/* for tests */
void
_mongoc_client_pool_set_stream_initiator (mongoc_client_pool_t *pool,
mongoc_stream_initiator_t si,
void *context)
{
mongoc_topology_scanner_set_stream_initiator (
pool->topology->scanner, si, context);
}
/* for tests */
size_t
mongoc_client_pool_get_size (mongoc_client_pool_t *pool)
{
size_t size = 0;
ENTRY;
bson_mutex_lock (&pool->mutex);
size = pool->size;
bson_mutex_unlock (&pool->mutex);
RETURN (size);
}
size_t
mongoc_client_pool_num_pushed (mongoc_client_pool_t *pool)
{
size_t num_pushed = 0;
ENTRY;
bson_mutex_lock (&pool->mutex);
num_pushed = pool->queue.length;
bson_mutex_unlock (&pool->mutex);
RETURN (num_pushed);
}
mongoc_topology_t *
_mongoc_client_pool_get_topology (mongoc_client_pool_t *pool)
{
return pool->topology;
}
void
mongoc_client_pool_max_size (mongoc_client_pool_t *pool, uint32_t max_pool_size)
{
ENTRY;
bson_mutex_lock (&pool->mutex);
pool->max_pool_size = max_pool_size;
bson_mutex_unlock (&pool->mutex);
EXIT;
}
void
mongoc_client_pool_min_size (mongoc_client_pool_t *pool, uint32_t min_pool_size)
{
ENTRY;
MONGOC_WARNING (
"mongoc_client_pool_min_size is deprecated; its behavior does not match"
" its name, and its actual behavior will likely hurt performance.");
bson_mutex_lock (&pool->mutex);
pool->min_pool_size = min_pool_size;
bson_mutex_unlock (&pool->mutex);
EXIT;
}
bool
mongoc_client_pool_set_apm_callbacks (mongoc_client_pool_t *pool,
mongoc_apm_callbacks_t *callbacks,
void *context)
{
mongoc_topology_t *topology;
topology = pool->topology;
if (pool->apm_callbacks_set) {
MONGOC_ERROR ("Can only set callbacks once");
return false;
}
bson_mutex_lock (&topology->mutex);
if (callbacks) {
memcpy (&topology->description.apm_callbacks,
callbacks,
sizeof (mongoc_apm_callbacks_t));
memcpy (&pool->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t));
}
mongoc_topology_set_apm_callbacks (topology, callbacks, context);
topology->description.apm_context = context;
pool->apm_context = context;
pool->apm_callbacks_set = true;
bson_mutex_unlock (&topology->mutex);
return true;
}
bool
mongoc_client_pool_set_error_api (mongoc_client_pool_t *pool, int32_t version)
{
if (version != MONGOC_ERROR_API_VERSION_LEGACY &&
version != MONGOC_ERROR_API_VERSION_2) {
MONGOC_ERROR ("Unsupported Error API Version: %" PRId32, version);
return false;
}
if (pool->error_api_set) {
MONGOC_ERROR ("Can only set Error API Version once");
return false;
}
pool->error_api_version = version;
pool->error_api_set = true;
return true;
}
bool
mongoc_client_pool_set_appname (mongoc_client_pool_t *pool, const char *appname)
{
bool ret;
bson_mutex_lock (&pool->mutex);
ret = _mongoc_topology_set_appname (pool->topology, appname);
bson_mutex_unlock (&pool->mutex);
return ret;
}
bool
mongoc_client_pool_enable_auto_encryption (mongoc_client_pool_t *pool,
mongoc_auto_encryption_opts_t *opts,
bson_error_t *error)
{
return _mongoc_cse_client_pool_enable_auto_encryption (
pool->topology, opts, error);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
similarity index 85%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
index 7eb80de9..b77ca610 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
@@ -1,223 +1,246 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CLIENT_PRIVATE_H
#define MONGOC_CLIENT_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-apm-private.h"
#include "mongoc-buffer-private.h"
#include "mongoc-client.h"
#include "mongoc-cluster-private.h"
#include "mongoc-config.h"
#include "mongoc-host-list.h"
#include "mongoc-read-prefs.h"
#include "mongoc-rpc-private.h"
#include "mongoc-opcode.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-ssl.h"
#endif
#include "mongoc-stream.h"
#include "mongoc-topology-private.h"
#include "mongoc-write-concern.h"
#include "mongoc-crypt-private.h"
BSON_BEGIN_DECLS
/* protocol versions this driver can speak */
#define WIRE_VERSION_MIN 3
-#define WIRE_VERSION_MAX 8
+#define WIRE_VERSION_MAX 9
/* first version that supported "find" and "getMore" commands */
#define WIRE_VERSION_FIND_CMD 4
/* first version with "killCursors" command */
#define WIRE_VERSION_KILLCURSORS_CMD 4
/* first version when findAndModify accepts writeConcern */
#define WIRE_VERSION_FAM_WRITE_CONCERN 4
/* first version to support readConcern */
#define WIRE_VERSION_READ_CONCERN 4
/* first version to support maxStalenessSeconds */
#define WIRE_VERSION_MAX_STALENESS 5
/* first version to support writeConcern */
#define WIRE_VERSION_CMD_WRITE_CONCERN 5
/* first version to support collation */
#define WIRE_VERSION_COLLATION 5
+/* first version to support server-side errors for unsupported hint options */
+#define WIRE_VERSION_HINT_SERVER_SIDE_ERROR 5
/* first version to support OP_MSG */
#define WIRE_VERSION_OP_MSG 6
/* first version to support array filters for "update" command */
#define WIRE_VERSION_ARRAY_FILTERS 6
/* first version to support retryable reads */
#define WIRE_VERSION_RETRY_READS 6
/* first version to support retryable writes */
#define WIRE_VERSION_RETRY_WRITES 6
/* version corresponding to server 4.0 release */
#define WIRE_VERSION_4_0 7
/* first version to support hint for "update" command */
#define WIRE_VERSION_UPDATE_HINT 8
/* version corresponding to server 4.2 release */
#define WIRE_VERSION_4_2 8
/* version corresponding to client side field level encryption support. */
#define WIRE_VERSION_CSE 8
+/* first version to throw server-side errors for unsupported hint in
+ * "findAndModify" command */
+#define WIRE_VERSION_FIND_AND_MODIFY_HINT_SERVER_SIDE_ERROR 8
+/* first version to support hint for "delete" command */
+#define WIRE_VERSION_DELETE_HINT 9
+/* first version to support hint for "findAndModify" command */
+#define WIRE_VERSION_FIND_AND_MODIFY_HINT 9
+/* version corresponding to server 4.4 release */
+#define WIRE_VERSION_4_4 9
+/* version corresponding to retryable writes error label */
+#define WIRE_VERSION_RETRYABLE_WRITE_ERROR_LABEL 9
+/* first version to support server hedged reads */
+#define WIRE_VERSION_HEDGED_READS 9
struct _mongoc_collection_t;
struct _mongoc_client_t {
mongoc_uri_t *uri;
mongoc_cluster_t cluster;
bool in_exhaust;
mongoc_stream_initiator_t initiator;
void *initiator_data;
#ifdef MONGOC_ENABLE_SSL
bool use_ssl;
mongoc_ssl_opt_t ssl_opts;
#endif
mongoc_topology_t *topology;
mongoc_read_prefs_t *read_prefs;
mongoc_read_concern_t *read_concern;
mongoc_write_concern_t *write_concern;
mongoc_apm_callbacks_t apm_callbacks;
void *apm_context;
int32_t error_api_version;
bool error_api_set;
/* mongoc_client_session_t's in use, to look up lsids and clusterTimes */
mongoc_set_t *client_sessions;
unsigned int csid_rand_seed;
uint32_t generation;
};
/* Defines whether _mongoc_client_command_with_opts() is acting as a read
* command helper for a command like "distinct", or a write command helper for
* a command like "createRole", or both, like "aggregate" with "$out".
*/
typedef enum {
MONGOC_CMD_RAW = 0,
MONGOC_CMD_READ = 1,
MONGOC_CMD_WRITE = 2,
MONGOC_CMD_RW = 3,
} mongoc_command_mode_t;
BSON_STATIC_ASSERT2 (mongoc_cmd_rw,
MONGOC_CMD_RW == (MONGOC_CMD_READ | MONGOC_CMD_WRITE));
typedef enum { MONGOC_RR_SRV, MONGOC_RR_TXT } mongoc_rr_type_t;
typedef struct _mongoc_rr_data_t {
/* Number of records returned by DNS. */
uint32_t count;
/* Set to lowest TTL found when polling SRV records. */
uint32_t min_ttl;
- /* Initialized with copy of uri->hosts prior to polling.
- * Any remaining records after DNS query are no longer active.
- */
+ /* Set to the resulting host list when polling SRV records */
mongoc_host_list_t *hosts;
+
+ /* Set to the TXT record when polling for TXT */
+ char *txt_record_opts;
} mongoc_rr_data_t;
bool
_mongoc_client_get_rr (const char *service,
mongoc_rr_type_t rr_type,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error);
mongoc_client_t *
_mongoc_client_new_from_uri (mongoc_topology_t *topology);
bool
_mongoc_client_set_apm_callbacks_private (mongoc_client_t *client,
mongoc_apm_callbacks_t *callbacks,
void *context);
mongoc_stream_t *
mongoc_client_default_stream_initiator (const mongoc_uri_t *uri,
const mongoc_host_list_t *host,
void *user_data,
bson_error_t *error);
mongoc_stream_t *
_mongoc_client_create_stream (mongoc_client_t *client,
const mongoc_host_list_t *host,
bson_error_t *error);
bool
_mongoc_client_recv (mongoc_client_t *client,
mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
mongoc_server_stream_t *server_stream,
bson_error_t *error);
void
_mongoc_client_kill_cursor (mongoc_client_t *client,
uint32_t server_id,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection,
mongoc_client_session_t *cs);
bool
_mongoc_client_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
mongoc_command_mode_t mode,
const bson_t *opts,
mongoc_query_flags_t flags,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
mongoc_read_concern_t *default_rc,
mongoc_write_concern_t *default_wc,
bson_t *reply,
bson_error_t *error);
mongoc_server_session_t *
_mongoc_client_pop_server_session (mongoc_client_t *client,
bson_error_t *error);
bool
_mongoc_client_lookup_session (const mongoc_client_t *client,
uint32_t client_session_id,
mongoc_client_session_t **cs,
bson_error_t *error);
void
_mongoc_client_unregister_session (mongoc_client_t *client,
mongoc_client_session_t *session);
void
_mongoc_client_push_server_session (mongoc_client_t *client,
mongoc_server_session_t *server_session);
void
_mongoc_client_end_sessions (mongoc_client_t *client);
mongoc_stream_t *
mongoc_client_connect_tcp (int32_t connecttimeoutms,
const mongoc_host_list_t *host,
bson_error_t *error);
+
+mongoc_stream_t *
+mongoc_client_connect (bool buffered,
+ bool use_ssl,
+ void *ssl_opts_void,
+ const mongoc_uri_t *uri,
+ const mongoc_host_list_t *host,
+ bson_error_t *error);
BSON_END_DECLS
#endif /* MONGOC_CLIENT_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h
index 363785ce..7ae0e941 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h
@@ -1,155 +1,156 @@
/*
* Copyright 2017 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CLIENT_SESSION_PRIVATE_H
#define MONGOC_CLIENT_SESSION_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client-session.h"
/* error labels: see Transactions Spec */
#define TRANSIENT_TXN_ERR "TransientTransactionError"
#define UNKNOWN_COMMIT_RESULT "UnknownTransactionCommitResult"
#define MAX_TIME_MS_EXPIRED "MaxTimeMSExpired"
#define DEFAULT_MAX_COMMIT_TIME_MS 0
+#define SESSION_NEVER_USED (-1)
#define MONGOC_DEFAULT_WTIMEOUT_FOR_COMMIT_RETRY 10000
struct _mongoc_transaction_opt_t {
mongoc_read_concern_t *read_concern;
mongoc_write_concern_t *write_concern;
mongoc_read_prefs_t *read_prefs;
int64_t max_commit_time_ms;
};
typedef enum {
MONGOC_SESSION_NO_OPTS = 0,
MONGOC_SESSION_CAUSAL_CONSISTENCY = (1 << 0),
} mongoc_session_flag_t;
struct _mongoc_session_opt_t {
mongoc_session_flag_t flags;
mongoc_transaction_opt_t default_txn_opts;
};
typedef struct _mongoc_server_session_t {
struct _mongoc_server_session_t *prev, *next;
int64_t last_used_usec;
bson_t lsid; /* logical session id */
int64_t txn_number; /* transaction number */
bool dirty;
} mongoc_server_session_t;
typedef enum {
MONGOC_INTERNAL_TRANSACTION_NONE,
MONGOC_INTERNAL_TRANSACTION_STARTING,
MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS,
MONGOC_INTERNAL_TRANSACTION_ENDING,
MONGOC_INTERNAL_TRANSACTION_COMMITTED,
MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY,
MONGOC_INTERNAL_TRANSACTION_ABORTED,
} mongoc_internal_transaction_state_t;
typedef struct _mongoc_transaction_t {
mongoc_internal_transaction_state_t state;
mongoc_transaction_opt_t opts;
} mongoc_transaction_t;
struct _mongoc_client_session_t {
mongoc_client_t *client;
mongoc_session_opt_t opts;
mongoc_server_session_t *server_session;
mongoc_transaction_t txn;
uint32_t client_session_id;
bson_t cluster_time;
uint32_t operation_timestamp;
uint32_t operation_increment;
uint32_t client_generation;
uint32_t server_id;
bson_t *recovery_token;
/* For testing only */
int64_t with_txn_timeout_ms;
const char *fail_commit_label;
};
bool
_mongoc_parse_cluster_time (const bson_t *cluster_time,
uint32_t *timestamp,
uint32_t *increment);
bool
_mongoc_cluster_time_greater (const bson_t *new, const bson_t *old);
void
_mongoc_client_session_handle_reply (mongoc_client_session_t *session,
bool is_acknowledged,
const bson_t *reply);
mongoc_server_session_t *
_mongoc_server_session_new (bson_error_t *error);
bool
_mongoc_server_session_timed_out (const mongoc_server_session_t *server_session,
int64_t session_timeout_minutes);
void
_mongoc_server_session_destroy (mongoc_server_session_t *server_session);
mongoc_client_session_t *
_mongoc_client_session_new (mongoc_client_t *client,
mongoc_server_session_t *server_session,
const mongoc_session_opt_t *opts,
uint32_t client_session_id);
bool
_mongoc_client_session_from_iter (mongoc_client_t *client,
const bson_iter_t *iter,
mongoc_client_session_t **cs,
bson_error_t *error);
bool
_mongoc_client_session_in_txn (const mongoc_client_session_t *session);
bool
_mongoc_client_session_in_txn_or_ending (
const mongoc_client_session_t *session);
bool
_mongoc_client_session_txn_in_progress (const mongoc_client_session_t *session);
bool
_mongoc_client_session_append_txn (mongoc_client_session_t *session,
bson_t *cmd,
bson_error_t *error);
void
_mongoc_client_session_append_read_concern (const mongoc_client_session_t *cs,
const bson_t *user_read_concern,
bool is_read_command,
bson_t *cmd);
void
_mongoc_client_session_unpin (mongoc_client_session_t *session);
void
_mongoc_client_session_pin (mongoc_client_session_t *session,
uint32_t server_id);
#endif /* MONGOC_CLIENT_SESSION_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c
index 79f4046c..6901fea9 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c
@@ -1,1646 +1,1615 @@
/*
* Copyright 2017 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.
*/
#include "mongoc-client-session-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-client-private.h"
#include "mongoc-rand-private.h"
#include "mongoc-util-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-read-prefs-private.h"
-
-#define SESSION_NEVER_USED (-1)
+#include "mongoc-error-private.h"
#define WITH_TXN_TIMEOUT_MS (120 * 1000)
static void
txn_opts_set (mongoc_transaction_opt_t *opts,
const mongoc_read_concern_t *read_concern,
const mongoc_write_concern_t *write_concern,
const mongoc_read_prefs_t *read_prefs,
int64_t max_commit_time_ms)
{
if (read_concern) {
mongoc_transaction_opts_set_read_concern (opts, read_concern);
}
if (write_concern) {
mongoc_transaction_opts_set_write_concern (opts, write_concern);
}
if (read_prefs) {
mongoc_transaction_opts_set_read_prefs (opts, read_prefs);
}
if (max_commit_time_ms != DEFAULT_MAX_COMMIT_TIME_MS) {
mongoc_transaction_opts_set_max_commit_time_ms (opts, max_commit_time_ms);
}
}
static void
txn_opts_cleanup (mongoc_transaction_opt_t *opts)
{
/* null inputs are ok */
mongoc_read_concern_destroy (opts->read_concern);
mongoc_write_concern_destroy (opts->write_concern);
mongoc_read_prefs_destroy (opts->read_prefs);
/* prepare opts for reuse */
opts->read_concern = NULL;
opts->write_concern = NULL;
opts->read_prefs = NULL;
opts->max_commit_time_ms = DEFAULT_MAX_COMMIT_TIME_MS;
}
static void
txn_opts_copy (const mongoc_transaction_opt_t *src,
mongoc_transaction_opt_t *dst)
{
txn_opts_cleanup (dst);
/* null inputs are ok for these copy functions */
dst->read_concern = mongoc_read_concern_copy (src->read_concern);
dst->write_concern = mongoc_write_concern_copy (src->write_concern);
dst->read_prefs = mongoc_read_prefs_copy (src->read_prefs);
dst->max_commit_time_ms = src->max_commit_time_ms;
}
-static void
-copy_labels_plus_unknown_commit_result (const bson_t *src, bson_t *dst)
-{
- bson_iter_t iter;
- bson_iter_t src_label;
- bson_t dst_labels;
- char str[16];
- uint32_t i = 0;
- const char *key;
-
- BSON_APPEND_ARRAY_BEGIN (dst, "errorLabels", &dst_labels);
- BSON_APPEND_UTF8 (&dst_labels, "0", UNKNOWN_COMMIT_RESULT);
-
- /* append any other errorLabels already in "src" */
- if (bson_iter_init_find (&iter, src, "errorLabels") &&
- bson_iter_recurse (&iter, &src_label)) {
- while (bson_iter_next (&src_label) && BSON_ITER_HOLDS_UTF8 (&src_label)) {
- if (strcmp (bson_iter_utf8 (&src_label, NULL),
- UNKNOWN_COMMIT_RESULT) != 0) {
- i++;
- bson_uint32_to_string (i, &key, str, sizeof str);
- BSON_APPEND_UTF8 (
- &dst_labels, key, bson_iter_utf8 (&src_label, NULL));
- }
- }
- }
-
- bson_append_array_end (dst, &dst_labels);
-}
-
-
static bool
txn_abort (mongoc_client_session_t *session, bson_t *reply, bson_error_t *error)
{
bson_t cmd = BSON_INITIALIZER;
bson_t opts = BSON_INITIALIZER;
bson_error_t err_local;
bson_error_t *err_ptr = error ? error : &err_local;
bson_t reply_local = BSON_INITIALIZER;
- mongoc_write_err_type_t error_type;
bool r = false;
_mongoc_bson_init_if_set (reply);
if (!mongoc_client_session_append (session, &opts, err_ptr)) {
GOTO (done);
}
if (session->txn.opts.write_concern) {
if (!mongoc_write_concern_append (session->txn.opts.write_concern,
&opts)) {
bson_set_error (err_ptr,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Invalid transaction write concern");
GOTO (done);
}
}
BSON_APPEND_INT32 (&cmd, "abortTransaction", 1);
if (session->recovery_token) {
BSON_APPEND_DOCUMENT (&cmd, "recoveryToken", session->recovery_token);
}
/* will be reinitialized by mongoc_client_write_command_with_opts */
bson_destroy (&reply_local);
r = mongoc_client_write_command_with_opts (
session->client, "admin", &cmd, &opts, &reply_local, err_ptr);
/* Transactions Spec: "Drivers MUST retry the commitTransaction command once
- * after it fails with a retryable error", same for abort */
- error_type = _mongoc_write_error_get_type (r, err_ptr, &reply_local);
- if (error_type == MONGOC_WRITE_ERR_RETRY) {
+ * after it fails with a retryable error", same for abort. Note that a
+ * RetryableWriteError label has already been appended here. */
+ if (mongoc_error_has_label (&reply_local, RETRYABLE_WRITE_ERROR)) {
_mongoc_client_session_unpin (session);
bson_destroy (&reply_local);
r = mongoc_client_write_command_with_opts (
session->client, "admin", &cmd, &opts, &reply_local, err_ptr);
}
if (!r) {
/* we won't return an error from abortTransaction, so warn */
MONGOC_WARNING ("Error in abortTransaction: %s", err_ptr->message);
_mongoc_client_session_unpin (session);
}
done:
bson_destroy (&reply_local);
bson_destroy (&cmd);
bson_destroy (&opts);
return r;
}
static mongoc_write_concern_t *
create_commit_retry_wc (const mongoc_write_concern_t *existing_wc)
{
mongoc_write_concern_t *wc;
wc = existing_wc ? mongoc_write_concern_copy (existing_wc)
: mongoc_write_concern_new ();
/* Transactions spec: "If the modified write concern does not include a
* wtimeout value, drivers MUST also apply wtimeout: 10000 to the write
* concern in order to avoid waiting forever if the majority write concern
* cannot be satisfied." */
if (mongoc_write_concern_get_wtimeout_int64 (wc) <= 0) {
mongoc_write_concern_set_wtimeout_int64 (
wc, MONGOC_DEFAULT_WTIMEOUT_FOR_COMMIT_RETRY);
}
/* Transactions spec: "If the transaction is using a write concern that is
* not the server default, any other write concern options MUST be left as-is
* when applying w:majority. */
mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_MAJORITY);
return wc;
}
static bool
txn_commit (mongoc_client_session_t *session,
bool explicitly_retrying,
bson_t *reply,
bson_error_t *error)
{
bson_t cmd = BSON_INITIALIZER;
bson_t opts = BSON_INITIALIZER;
bson_error_t err_local = {0};
bson_error_t *err_ptr = error ? error : &err_local;
bson_t reply_local = BSON_INITIALIZER;
mongoc_write_err_type_t error_type;
bool r = false;
bool retrying_after_error = false;
mongoc_write_concern_t *retry_wc = NULL;
_mongoc_bson_init_if_set (reply);
BSON_APPEND_INT32 (&cmd, "commitTransaction", 1);
if (session->recovery_token) {
BSON_APPEND_DOCUMENT (&cmd, "recoveryToken", session->recovery_token);
}
retry:
if (!mongoc_client_session_append (session, &opts, err_ptr)) {
GOTO (done);
}
if (session->txn.opts.max_commit_time_ms != DEFAULT_MAX_COMMIT_TIME_MS) {
if (!bson_append_int64 (
&opts, "maxTimeMS", -1, session->txn.opts.max_commit_time_ms)) {
bson_set_error (err_ptr,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"error appending maxCommitTimeMS");
GOTO (done);
}
}
/* Transactions Spec: "When commitTransaction is retried, either by the
* driver's internal retry-once logic or explicitly by the user calling
* commitTransaction again, drivers MUST apply w:majority to the write
* concern of the commitTransaction command." */
if (!retry_wc && (retrying_after_error || explicitly_retrying)) {
retry_wc = create_commit_retry_wc (session->txn.opts.write_concern
? session->txn.opts.write_concern
: session->client->write_concern);
}
if (retry_wc || session->txn.opts.write_concern) {
if (!mongoc_write_concern_append (
retry_wc ? retry_wc : session->txn.opts.write_concern, &opts)) {
bson_set_error (err_ptr,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Invalid transaction write concern");
GOTO (done);
}
}
/* will be reinitialized by mongoc_client_write_command_with_opts */
bson_destroy (&reply_local);
r = mongoc_client_write_command_with_opts (
session->client, "admin", &cmd, &opts, &reply_local, err_ptr);
/* Transactions Spec: "Drivers MUST retry the commitTransaction command once
- * after it fails with a retryable error", same for abort */
- error_type = _mongoc_write_error_get_type (r, err_ptr, &reply_local);
+ * after it fails with a retryable error", same for abort. Note that a
+ * RetryableWriteError label has already been appended here. */
+ error_type = _mongoc_write_error_get_type (&reply_local);
if (!retrying_after_error && error_type == MONGOC_WRITE_ERR_RETRY) {
retrying_after_error = true; /* retry after error only once */
_mongoc_client_session_unpin (session);
bson_reinit (&opts);
GOTO (retry);
}
/* Transactions Spec: "add the UnknownTransactionCommitResult error label
* when commitTransaction fails with a network error, server selection
* error, MaxTimeMSExpired error, or write concern failed / timeout." */
if (!r && (err_ptr->domain == MONGOC_ERROR_SERVER_SELECTION ||
error_type == MONGOC_WRITE_ERR_RETRY ||
error_type == MONGOC_WRITE_ERR_WRITE_CONCERN ||
err_ptr->code == MONGOC_ERROR_MAX_TIME_MS_EXPIRED)) {
/* Drivers MUST unpin a ClientSession when any individual
* commitTransaction command attempt fails with an
* UnknownTransactionCommitResult error label. Do this even if we won't
* actually apply the error label due to reply being NULL */
_mongoc_client_session_unpin (session);
if (reply) {
bson_copy_to_excluding_noinit (
&reply_local, reply, "errorLabels", NULL);
- copy_labels_plus_unknown_commit_result (&reply_local, reply);
+ _mongoc_error_copy_labels_and_upsert (
+ &reply_local, reply, UNKNOWN_COMMIT_RESULT);
}
} else if (reply) {
/* maintain invariants: reply & reply_local are valid until the end */
bson_destroy (reply);
bson_steal (reply, &reply_local);
bson_init (&reply_local);
}
done:
bson_destroy (&reply_local);
bson_destroy (&cmd);
bson_destroy (&opts);
if (retry_wc) {
mongoc_write_concern_destroy (retry_wc);
}
return r;
}
mongoc_transaction_opt_t *
mongoc_transaction_opts_new (void)
{
mongoc_transaction_opt_t *opts;
opts = (mongoc_transaction_opt_t *) bson_malloc0 (
sizeof (mongoc_transaction_opt_t));
opts->max_commit_time_ms = DEFAULT_MAX_COMMIT_TIME_MS;
return opts;
}
mongoc_transaction_opt_t *
mongoc_transaction_opts_clone (const mongoc_transaction_opt_t *opts)
{
mongoc_transaction_opt_t *cloned_opts;
ENTRY;
BSON_ASSERT (opts);
cloned_opts = mongoc_transaction_opts_new ();
txn_opts_copy (opts, cloned_opts);
RETURN (cloned_opts);
}
void
mongoc_transaction_opts_destroy (mongoc_transaction_opt_t *opts)
{
ENTRY;
if (!opts) {
EXIT;
}
txn_opts_cleanup (opts);
bson_free (opts);
EXIT;
}
void
mongoc_transaction_opts_set_max_commit_time_ms (mongoc_transaction_opt_t *opts,
int64_t max_commit_time_ms)
{
BSON_ASSERT (opts);
opts->max_commit_time_ms = max_commit_time_ms;
}
int64_t
mongoc_transaction_opts_get_max_commit_time_ms (mongoc_transaction_opt_t *opts)
{
BSON_ASSERT (opts);
return opts->max_commit_time_ms;
}
void
mongoc_transaction_opts_set_read_concern (
mongoc_transaction_opt_t *opts, const mongoc_read_concern_t *read_concern)
{
BSON_ASSERT (opts);
mongoc_read_concern_destroy (opts->read_concern);
opts->read_concern = mongoc_read_concern_copy (read_concern);
}
const mongoc_read_concern_t *
mongoc_transaction_opts_get_read_concern (const mongoc_transaction_opt_t *opts)
{
BSON_ASSERT (opts);
return opts->read_concern;
}
void
mongoc_transaction_opts_set_write_concern (
mongoc_transaction_opt_t *opts, const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (opts);
mongoc_write_concern_destroy (opts->write_concern);
opts->write_concern = mongoc_write_concern_copy (write_concern);
}
const mongoc_write_concern_t *
mongoc_transaction_opts_get_write_concern (const mongoc_transaction_opt_t *opts)
{
BSON_ASSERT (opts);
return opts->write_concern;
}
void
mongoc_transaction_opts_set_read_prefs (mongoc_transaction_opt_t *opts,
const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT (opts);
mongoc_read_prefs_destroy (opts->read_prefs);
opts->read_prefs = mongoc_read_prefs_copy (read_prefs);
}
const mongoc_read_prefs_t *
mongoc_transaction_opts_get_read_prefs (const mongoc_transaction_opt_t *opts)
{
BSON_ASSERT (opts);
return opts->read_prefs;
}
mongoc_session_opt_t *
mongoc_session_opts_new (void)
{
mongoc_session_opt_t *opts = bson_malloc0 (sizeof (mongoc_session_opt_t));
/* Driver Sessions Spec: causal consistency is true by default */
mongoc_session_opts_set_causal_consistency (opts, true);
return opts;
}
void
mongoc_session_opts_set_causal_consistency (mongoc_session_opt_t *opts,
bool causal_consistency)
{
ENTRY;
BSON_ASSERT (opts);
if (causal_consistency) {
opts->flags |= MONGOC_SESSION_CAUSAL_CONSISTENCY;
} else {
opts->flags &= ~MONGOC_SESSION_CAUSAL_CONSISTENCY;
}
EXIT;
}
bool
mongoc_session_opts_get_causal_consistency (const mongoc_session_opt_t *opts)
{
ENTRY;
BSON_ASSERT (opts);
RETURN (!!(opts->flags & MONGOC_SESSION_CAUSAL_CONSISTENCY));
}
void
mongoc_session_opts_set_default_transaction_opts (
mongoc_session_opt_t *opts, const mongoc_transaction_opt_t *txn_opts)
{
ENTRY;
BSON_ASSERT (opts);
BSON_ASSERT (txn_opts);
txn_opts_set (&opts->default_txn_opts,
txn_opts->read_concern,
txn_opts->write_concern,
txn_opts->read_prefs,
txn_opts->max_commit_time_ms);
EXIT;
}
const mongoc_transaction_opt_t *
mongoc_session_opts_get_default_transaction_opts (
const mongoc_session_opt_t *opts)
{
ENTRY;
BSON_ASSERT (opts);
RETURN (&opts->default_txn_opts);
}
mongoc_transaction_opt_t *
mongoc_session_opts_get_transaction_opts (
const mongoc_client_session_t *session)
{
ENTRY;
BSON_ASSERT (session);
if (mongoc_client_session_in_transaction (session)) {
RETURN (mongoc_transaction_opts_clone (&session->txn.opts));
}
RETURN (NULL);
}
static void
_mongoc_session_opts_copy (const mongoc_session_opt_t *src,
mongoc_session_opt_t *dst)
{
dst->flags = src->flags;
txn_opts_copy (&src->default_txn_opts, &dst->default_txn_opts);
}
mongoc_session_opt_t *
mongoc_session_opts_clone (const mongoc_session_opt_t *opts)
{
mongoc_session_opt_t *cloned_opts;
ENTRY;
BSON_ASSERT (opts);
cloned_opts = bson_malloc0 (sizeof (mongoc_session_opt_t));
_mongoc_session_opts_copy (opts, cloned_opts);
RETURN (cloned_opts);
}
void
mongoc_session_opts_destroy (mongoc_session_opt_t *opts)
{
ENTRY;
if (!opts) {
EXIT;
}
txn_opts_cleanup (&opts->default_txn_opts);
bson_free (opts);
EXIT;
}
static bool
_mongoc_server_session_uuid (uint8_t *data /* OUT */, bson_error_t *error)
{
#ifdef MONGOC_ENABLE_CRYPTO
/* https://tools.ietf.org/html/rfc4122#page-14
* o Set the two most significant bits (bits 6 and 7) of the
* clock_seq_hi_and_reserved to zero and one, respectively.
*
* o Set the four most significant bits (bits 12 through 15) of the
* time_hi_and_version field to the 4-bit version number from
* Section 4.1.3.
*
* o Set all the other bits to randomly (or pseudo-randomly) chosen
* values.
*/
if (!_mongoc_rand_bytes (data, 16)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_SESSION_FAILURE,
"Could not generate UUID for logical session id");
return false;
}
data[6] = (uint8_t) (0x40 | (data[6] & 0xf));
data[8] = (uint8_t) (0x80 | (data[8] & 0x3f));
return true;
#else
/* no _mongoc_rand_bytes without a crypto library */
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_SESSION_FAILURE,
"Could not generate UUID for logical session id, we need a"
" cryptography library like libcrypto, Common Crypto, or"
" CNG");
return false;
#endif
}
bool
_mongoc_parse_cluster_time (const bson_t *cluster_time,
uint32_t *timestamp,
uint32_t *increment)
{
bson_iter_t iter;
char *s;
if (!cluster_time ||
!bson_iter_init_find (&iter, cluster_time, "clusterTime") ||
!BSON_ITER_HOLDS_TIMESTAMP (&iter)) {
s = bson_as_json (cluster_time, NULL);
MONGOC_ERROR ("Cannot parse cluster time from %s\n", s);
bson_free (s);
return false;
}
bson_iter_timestamp (&iter, timestamp, increment);
return true;
}
bool
_mongoc_cluster_time_greater (const bson_t *new, const bson_t *old)
{
uint32_t new_t, new_i, old_t, old_i;
if (!_mongoc_parse_cluster_time (new, &new_t, &new_i) ||
!_mongoc_parse_cluster_time (old, &old_t, &old_i)) {
return false;
}
return (new_t > old_t) || (new_t == old_t && new_i > old_i);
}
void
_mongoc_client_session_handle_reply (mongoc_client_session_t *session,
bool is_acknowledged,
const bson_t *reply)
{
bson_iter_t iter;
uint32_t len;
const uint8_t *data;
bson_t cluster_time;
uint32_t t;
uint32_t i;
BSON_ASSERT (session);
if (!reply || !bson_iter_init (&iter, reply)) {
return;
}
if (mongoc_error_has_label (reply, "TransientTransactionError")) {
/* Transaction Spec: "Drivers MUST unpin a ClientSession when a command
* within a transaction, including commitTransaction and abortTransaction,
* fails with a TransientTransactionError". If the server reply included
* a TransientTransactionError, we unpin here. If a network error caused
* us to add a label client-side, we unpin in network_error_reply. */
session->server_id = 0;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "$clusterTime") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_iter_document (&iter, &len, &data);
BSON_ASSERT (bson_init_static (&cluster_time, data, (size_t) len));
mongoc_client_session_advance_cluster_time (session, &cluster_time);
} else if (!strcmp (bson_iter_key (&iter), "operationTime") &&
BSON_ITER_HOLDS_TIMESTAMP (&iter) && is_acknowledged) {
bson_iter_timestamp (&iter, &t, &i);
mongoc_client_session_advance_operation_time (session, t, i);
}
}
}
mongoc_server_session_t *
_mongoc_server_session_new (bson_error_t *error)
{
uint8_t uuid_data[16];
mongoc_server_session_t *s;
ENTRY;
if (!_mongoc_server_session_uuid (uuid_data, error)) {
RETURN (NULL);
}
s = bson_malloc0 (sizeof (mongoc_server_session_t));
s->last_used_usec = SESSION_NEVER_USED;
s->prev = NULL;
s->next = NULL;
bson_init (&s->lsid);
bson_append_binary (
&s->lsid, "id", 2, BSON_SUBTYPE_UUID, uuid_data, sizeof uuid_data);
/* transaction number is a positive integer and will be incremented before
* each use, so ensure it is initialized to zero. */
s->txn_number = 0;
RETURN (s);
}
bool
_mongoc_server_session_timed_out (const mongoc_server_session_t *server_session,
int64_t session_timeout_minutes)
{
int64_t timeout_usec;
const int64_t minute_to_usec = 60 * 1000 * 1000;
ENTRY;
if (session_timeout_minutes == MONGOC_NO_SESSIONS) {
/* not connected right now; keep the session */
return false;
}
if (server_session->last_used_usec == SESSION_NEVER_USED) {
return false;
}
/* Driver Sessions Spec: if a session has less than one minute left before
* becoming stale, discard it */
timeout_usec =
server_session->last_used_usec + session_timeout_minutes * minute_to_usec;
RETURN (timeout_usec - bson_get_monotonic_time () < 1 * minute_to_usec);
}
void
_mongoc_server_session_destroy (mongoc_server_session_t *server_session)
{
ENTRY;
bson_destroy (&server_session->lsid);
bson_free (server_session);
EXIT;
}
mongoc_client_session_t *
_mongoc_client_session_new (mongoc_client_t *client,
mongoc_server_session_t *server_session,
const mongoc_session_opt_t *opts,
uint32_t client_session_id)
{
mongoc_client_session_t *session;
ENTRY;
BSON_ASSERT (client);
session = bson_malloc0 (sizeof (mongoc_client_session_t));
session->client = client;
session->client_generation = client->generation;
session->server_session = server_session;
session->client_session_id = client_session_id;
bson_init (&session->cluster_time);
txn_opts_set (&session->opts.default_txn_opts,
client->read_concern,
client->write_concern,
client->read_prefs,
DEFAULT_MAX_COMMIT_TIME_MS);
if (opts) {
session->opts.flags = opts->flags;
txn_opts_set (&session->opts.default_txn_opts,
opts->default_txn_opts.read_concern,
opts->default_txn_opts.write_concern,
opts->default_txn_opts.read_prefs,
opts->default_txn_opts.max_commit_time_ms);
} else {
/* sessions are causally consistent by default */
session->opts.flags = MONGOC_SESSION_CAUSAL_CONSISTENCY;
}
/* these values are used for testing only. */
session->with_txn_timeout_ms = 0;
session->fail_commit_label = NULL;
RETURN (session);
}
mongoc_client_t *
mongoc_client_session_get_client (const mongoc_client_session_t *session)
{
BSON_ASSERT (session);
return session->client;
}
const mongoc_session_opt_t *
mongoc_client_session_get_opts (const mongoc_client_session_t *session)
{
BSON_ASSERT (session);
return &session->opts;
}
const bson_t *
mongoc_client_session_get_lsid (const mongoc_client_session_t *session)
{
BSON_ASSERT (session);
return &session->server_session->lsid;
}
const bson_t *
mongoc_client_session_get_cluster_time (const mongoc_client_session_t *session)
{
BSON_ASSERT (session);
if (bson_empty (&session->cluster_time)) {
return NULL;
}
return &session->cluster_time;
}
uint32_t
mongoc_client_session_get_server_id (const mongoc_client_session_t *session)
{
BSON_ASSERT (session);
return session->server_id;
}
void
mongoc_client_session_advance_cluster_time (mongoc_client_session_t *session,
const bson_t *cluster_time)
{
uint32_t t, i;
ENTRY;
if (bson_empty (&session->cluster_time) &&
_mongoc_parse_cluster_time (cluster_time, &t, &i)) {
bson_destroy (&session->cluster_time);
bson_copy_to (cluster_time, &session->cluster_time);
EXIT;
}
if (_mongoc_cluster_time_greater (cluster_time, &session->cluster_time)) {
bson_destroy (&session->cluster_time);
bson_copy_to (cluster_time, &session->cluster_time);
}
EXIT;
}
void
mongoc_client_session_get_operation_time (
const mongoc_client_session_t *session,
uint32_t *timestamp,
uint32_t *increment)
{
BSON_ASSERT (session);
BSON_ASSERT (timestamp);
BSON_ASSERT (increment);
*timestamp = session->operation_timestamp;
*increment = session->operation_increment;
}
void
mongoc_client_session_advance_operation_time (mongoc_client_session_t *session,
uint32_t timestamp,
uint32_t increment)
{
ENTRY;
BSON_ASSERT (session);
if (timestamp > session->operation_timestamp ||
(timestamp == session->operation_timestamp &&
increment > session->operation_increment)) {
session->operation_timestamp = timestamp;
session->operation_increment = increment;
}
EXIT;
}
static bool
timeout_exceeded (int64_t expire_at)
{
int64_t current_time = bson_get_monotonic_time ();
return current_time >= expire_at;
}
static bool
_max_time_ms_failure (bson_t *reply)
{
bson_iter_t iter;
bson_iter_t descendant;
if (!reply) {
return false;
}
/* We can fail with a maxTimeMS error with the error code at the top
level, or nested within a writeConcernError. */
if (bson_iter_init_find (&iter, reply, "codeName") &&
BSON_ITER_HOLDS_UTF8 (&iter) &&
0 == strcmp (bson_iter_utf8 (&iter, NULL), MAX_TIME_MS_EXPIRED)) {
return true;
}
bson_iter_init (&iter, reply);
if (bson_iter_find_descendant (
&iter, "writeConcernError.codeName", &descendant) &&
BSON_ITER_HOLDS_UTF8 (&descendant) &&
0 == strcmp (bson_iter_utf8 (&descendant, NULL), MAX_TIME_MS_EXPIRED)) {
return true;
}
return false;
}
bool
mongoc_client_session_with_transaction (
mongoc_client_session_t *session,
mongoc_client_session_with_transaction_cb_t cb,
const mongoc_transaction_opt_t *opts,
void *ctx,
bson_t *reply,
bson_error_t *error)
{
mongoc_internal_transaction_state_t state;
int64_t timeout;
int64_t expire_at;
bson_t local_reply;
bson_t *active_reply = NULL;
bool res;
ENTRY;
timeout = session->with_txn_timeout_ms > 0 ? session->with_txn_timeout_ms
: WITH_TXN_TIMEOUT_MS;
expire_at = bson_get_monotonic_time () + ((int64_t) timeout * 1000);
/* Attempt to wrap a user callback in start- and end- transaction semantics.
If this fails for transient reasons, restart, either from the very
beginning, or just retry committing the transaction. Will retry until
the timeout WITH_TXN_TIMEOUT_MS is exhausted.
At the top of this loop, active_reply should always be NULL, and
local_reply should always be uninitialized. */
while (true) {
res = mongoc_client_session_start_transaction (session, opts, error);
if (!res) {
GOTO (done);
}
res = cb (session, ctx, &active_reply, error);
state = session->txn.state;
/* If the user cb set a reply, use it. Otherwise, sub in local_reply
since we must have an active reply object one way or another. */
if (!active_reply) {
bson_init (&local_reply);
active_reply = &local_reply;
}
if (!res) {
if (state == MONGOC_INTERNAL_TRANSACTION_STARTING ||
state == MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS) {
BSON_ASSERT (
mongoc_client_session_abort_transaction (session, NULL));
}
if (mongoc_error_has_label (active_reply, TRANSIENT_TXN_ERR) &&
!timeout_exceeded (expire_at)) {
bson_destroy (active_reply);
active_reply = NULL;
continue;
}
/* Unknown error running callback, fail. */
GOTO (done);
}
if (state == MONGOC_INTERNAL_TRANSACTION_ABORTED ||
state == MONGOC_INTERNAL_TRANSACTION_NONE ||
state == MONGOC_INTERNAL_TRANSACTION_COMMITTED ||
state == MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY) {
GOTO (done);
}
/* Whether or not we used local_reply above, use it now, but access it
* through active_reply so cleanup in DONE is simpler. */
bson_destroy (active_reply);
active_reply = &local_reply;
/* Commit the transaction, retrying either from here or from the outer
loop on error.
At the top of this loop, active_reply should always be pointing to
an uninitialized stack-allocated bson_t, so we can pass it into
commit_transaction, which requires this like our other public
functions that take a bson_t reply. */
while (true) {
res = mongoc_client_session_commit_transaction (
session, active_reply, error);
if (!res) {
/* If we have a MaxTimeMsExpired error, fail and propogate
the error to the caller. */
if (_max_time_ms_failure (active_reply)) {
GOTO (done);
}
if (mongoc_error_has_label (active_reply, UNKNOWN_COMMIT_RESULT) &&
!timeout_exceeded (expire_at)) {
/* Commit_transaction applies majority write concern on retry
* attempts.
*
* Here, we don't want to set active_reply = NULL when we
* destroy, because we want it to point to an uninitialized
* bson_t at the top of this loop every time.*/
bson_destroy (active_reply);
continue;
}
if (mongoc_error_has_label (active_reply, TRANSIENT_TXN_ERR) &&
!timeout_exceeded (expire_at)) {
/* In the case of a transient txn error, go back to outside loop.
We must set the reply to NULL so it may be used by the cb. */
bson_destroy (active_reply);
active_reply = NULL;
break;
}
/* Unknown error committing transaction, fail. */
GOTO (done);
}
/* Transaction successfully committed! */
GOTO (done);
}
}
done:
/* At this point, active_reply is either pointing to the user's reply
object, or our local one on the stack, or is NULL. */
if (reply && active_reply) {
bson_copy_to (active_reply, reply);
} else if (reply) {
bson_init (reply);
}
bson_destroy (active_reply);
RETURN (res);
}
bool
mongoc_client_session_start_transaction (mongoc_client_session_t *session,
const mongoc_transaction_opt_t *opts,
bson_error_t *error)
{
mongoc_server_description_t *sd;
bool ret;
ENTRY;
BSON_ASSERT (session);
ret = true;
sd = mongoc_client_select_server (
session->client, true /* primary */, NULL, error);
if (!sd) {
ret = false;
GOTO (done);
}
if (sd->max_wire_version < 7 ||
(sd->max_wire_version < 8 && sd->type == MONGOC_SERVER_MONGOS)) {
bson_set_error (error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Multi-document transactions are not supported by this "
"server version");
ret = false;
GOTO (done);
}
/* use "switch" so that static checkers ensure we handle all states */
switch (session->txn.state) {
case MONGOC_INTERNAL_TRANSACTION_STARTING:
case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS:
bson_set_error (error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Transaction already in progress");
ret = false;
GOTO (done);
case MONGOC_INTERNAL_TRANSACTION_ENDING:
MONGOC_ERROR (
"starting txn in invalid state MONGOC_INTERNAL_TRANSACTION_ENDING");
abort ();
case MONGOC_INTERNAL_TRANSACTION_COMMITTED:
case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY:
case MONGOC_INTERNAL_TRANSACTION_ABORTED:
case MONGOC_INTERNAL_TRANSACTION_NONE:
default:
break;
}
session->server_session->txn_number++;
txn_opts_set (&session->txn.opts,
session->opts.default_txn_opts.read_concern,
session->opts.default_txn_opts.write_concern,
session->opts.default_txn_opts.read_prefs,
session->opts.default_txn_opts.max_commit_time_ms);
if (opts) {
txn_opts_set (&session->txn.opts,
opts->read_concern,
opts->write_concern,
opts->read_prefs,
opts->max_commit_time_ms);
}
if (!mongoc_write_concern_is_acknowledged (
session->txn.opts.write_concern)) {
bson_set_error (
error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Transactions do not support unacknowledged write concern");
ret = false;
GOTO (done);
}
/* Transactions Spec: Starting a new transaction on a pinned ClientSession
* MUST unpin the session. */
_mongoc_client_session_unpin (session);
session->txn.state = MONGOC_INTERNAL_TRANSACTION_STARTING;
/* Transactions spec: "Drivers MUST clear a session's cached
* 'recoveryToken' when transitioning to the 'no transaction' or
* 'starting transaction' state." */
bson_destroy (session->recovery_token);
session->recovery_token = NULL;
done:
mongoc_server_description_destroy (sd);
return ret;
}
bool
mongoc_client_session_in_transaction (const mongoc_client_session_t *session)
{
ENTRY;
BSON_ASSERT (session);
/* call the internal function, which would allow a NULL session */
RETURN (_mongoc_client_session_in_txn (session));
}
mongoc_transaction_state_t
mongoc_client_session_get_transaction_state (
const mongoc_client_session_t *session)
{
ENTRY;
BSON_ASSERT (session);
switch (session->txn.state) {
case MONGOC_INTERNAL_TRANSACTION_NONE:
RETURN (MONGOC_TRANSACTION_NONE);
case MONGOC_INTERNAL_TRANSACTION_STARTING:
RETURN (MONGOC_TRANSACTION_STARTING);
case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS:
RETURN (MONGOC_TRANSACTION_IN_PROGRESS);
case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY:
case MONGOC_INTERNAL_TRANSACTION_COMMITTED:
RETURN (MONGOC_TRANSACTION_COMMITTED);
case MONGOC_INTERNAL_TRANSACTION_ABORTED:
RETURN (MONGOC_TRANSACTION_ABORTED);
case MONGOC_INTERNAL_TRANSACTION_ENDING:
MONGOC_ERROR ("invalid state MONGOC_INTERNAL_TRANSACTION_ENDING when "
"getting transaction state");
abort ();
default:
MONGOC_ERROR ("invalid state %d when getting transaction state",
(int) session->txn.state);
abort ();
break;
}
}
bool
mongoc_client_session_commit_transaction (mongoc_client_session_t *session,
bson_t *reply,
bson_error_t *error)
{
bool r = false;
ENTRY;
BSON_ASSERT (session);
/* For testing only, mock out certain kinds of errors. */
if (session->fail_commit_label) {
bson_t labels;
BSON_ASSERT (reply);
bson_init (reply);
BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels);
BSON_APPEND_UTF8 (&labels, "0", session->fail_commit_label);
/* Waste the test timeout, if there is one set. */
if (session->with_txn_timeout_ms) {
_mongoc_usleep (session->with_txn_timeout_ms * 1000);
}
RETURN (r);
}
/* See Transactions Spec for state diagram. In COMMITTED state, user can call
* commit again to retry after network error */
switch (session->txn.state) {
case MONGOC_INTERNAL_TRANSACTION_NONE:
bson_set_error (error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"No transaction started");
_mongoc_bson_init_if_set (reply);
break;
case MONGOC_INTERNAL_TRANSACTION_STARTING:
case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY:
/* we sent no commands, not actually started on server */
session->txn.state = MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY;
_mongoc_bson_init_if_set (reply);
r = true;
break;
case MONGOC_INTERNAL_TRANSACTION_COMMITTED:
case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS: {
bool explicitly_retrying =
(session->txn.state == MONGOC_INTERNAL_TRANSACTION_COMMITTED);
/* in MONGOC_INTERNAL_TRANSACTION_ENDING we add txnNumber and autocommit:
* false to the commitTransaction command, but if it fails with network
* error we add UnknownTransactionCommitResult not
* TransientTransactionError */
session->txn.state = MONGOC_INTERNAL_TRANSACTION_ENDING;
r = txn_commit (session, explicitly_retrying, reply, error);
session->txn.state = MONGOC_INTERNAL_TRANSACTION_COMMITTED;
break;
}
case MONGOC_INTERNAL_TRANSACTION_ENDING:
MONGOC_ERROR (
"commit called in invalid state MONGOC_INTERNAL_TRANSACTION_ENDING");
abort ();
case MONGOC_INTERNAL_TRANSACTION_ABORTED:
default:
bson_set_error (
error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Cannot call commitTransaction after calling abortTransaction");
_mongoc_bson_init_if_set (reply);
break;
}
RETURN (r);
}
bool
mongoc_client_session_abort_transaction (mongoc_client_session_t *session,
bson_error_t *error)
{
ENTRY;
BSON_ASSERT (session);
switch (session->txn.state) {
case MONGOC_INTERNAL_TRANSACTION_STARTING:
/* we sent no commands, not actually started on server */
session->txn.state = MONGOC_INTERNAL_TRANSACTION_ABORTED;
txn_opts_cleanup (&session->txn.opts);
RETURN (true);
case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS:
session->txn.state = MONGOC_INTERNAL_TRANSACTION_ENDING;
/* Transactions Spec: ignore errors from abortTransaction command */
txn_abort (session, NULL, NULL);
session->txn.state = MONGOC_INTERNAL_TRANSACTION_ABORTED;
RETURN (true);
case MONGOC_INTERNAL_TRANSACTION_COMMITTED:
case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY:
bson_set_error (
error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Cannot call abortTransaction after calling commitTransaction");
RETURN (false);
case MONGOC_INTERNAL_TRANSACTION_ABORTED:
bson_set_error (error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Cannot call abortTransaction twice");
RETURN (false);
case MONGOC_INTERNAL_TRANSACTION_ENDING:
MONGOC_ERROR (
"abort called in invalid state MONGOC_INTERNAL_TRANSACTION_ENDING");
abort ();
case MONGOC_INTERNAL_TRANSACTION_NONE:
default:
bson_set_error (error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"No transaction started");
RETURN (false);
}
}
bool
_mongoc_client_session_from_iter (mongoc_client_t *client,
const bson_iter_t *iter,
mongoc_client_session_t **cs,
bson_error_t *error)
{
ENTRY;
/* must be int64 that fits in uint32 */
if (!BSON_ITER_HOLDS_INT64 (iter) || bson_iter_int64 (iter) > 0xffffffff) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid sessionId");
RETURN (false);
}
RETURN (_mongoc_client_lookup_session (
client, (uint32_t) bson_iter_int64 (iter), cs, error));
}
/* Returns true if in the middle of a transaction. Note: this returns false if
* the commit/abort is running. */
bool
_mongoc_client_session_in_txn (const mongoc_client_session_t *session)
{
if (!session) {
return false;
}
/* use "switch" so that static checkers ensure we handle all states */
switch (session->txn.state) {
case MONGOC_INTERNAL_TRANSACTION_STARTING:
case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS:
return true;
case MONGOC_INTERNAL_TRANSACTION_NONE:
case MONGOC_INTERNAL_TRANSACTION_ENDING:
case MONGOC_INTERNAL_TRANSACTION_COMMITTED:
case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY:
case MONGOC_INTERNAL_TRANSACTION_ABORTED:
default:
return false;
}
}
/* Like _mongoc_client_session_in_txn, but also returns true if running the
* commit/abort for this transaction. */
bool
_mongoc_client_session_in_txn_or_ending (const mongoc_client_session_t *session)
{
if (!session) {
return false;
}
/* use "switch" so that static checkers ensure we handle all states */
switch (session->txn.state) {
case MONGOC_INTERNAL_TRANSACTION_STARTING:
case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS:
case MONGOC_INTERNAL_TRANSACTION_ENDING:
return true;
case MONGOC_INTERNAL_TRANSACTION_NONE:
case MONGOC_INTERNAL_TRANSACTION_COMMITTED:
case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY:
case MONGOC_INTERNAL_TRANSACTION_ABORTED:
default:
return false;
}
}
bool
_mongoc_client_session_txn_in_progress (const mongoc_client_session_t *session)
{
if (!session) {
return false;
}
return session->txn.state == MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_session_append_txn --
*
* Add transaction fields besides "readConcern" to @cmd.
*
* Returns:
* Returns false and sets @error if @cmd is empty, otherwise returns
* true.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_session_append_txn (mongoc_client_session_t *session,
bson_t *cmd,
bson_error_t *error)
{
mongoc_transaction_t *txn;
ENTRY;
if (!session) {
RETURN (true);
}
if (bson_empty0 (cmd)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Empty command in transaction");
RETURN (false);
}
txn = &session->txn;
/* See Transactions Spec for state transitions. In COMMITTED / ABORTED, the
* next operation resets the session and moves to TRANSACTION_NONE */
switch (session->txn.state) {
case MONGOC_INTERNAL_TRANSACTION_STARTING:
txn->state = MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS;
bson_append_bool (cmd, "startTransaction", 16, true);
/* FALL THROUGH */
case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS:
case MONGOC_INTERNAL_TRANSACTION_ENDING:
bson_append_int64 (
cmd, "txnNumber", 9, session->server_session->txn_number);
bson_append_bool (cmd, "autocommit", 10, false);
RETURN (true);
case MONGOC_INTERNAL_TRANSACTION_COMMITTED:
if (!strcmp (_mongoc_get_command_name (cmd), "commitTransaction")) {
/* send commitTransaction again */
bson_append_int64 (
cmd, "txnNumber", 9, session->server_session->txn_number);
bson_append_bool (cmd, "autocommit", 10, false);
RETURN (true);
}
/* FALL THROUGH */
case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY:
case MONGOC_INTERNAL_TRANSACTION_ABORTED:
txn_opts_cleanup (&session->txn.opts);
txn->state = MONGOC_INTERNAL_TRANSACTION_NONE;
/* Transactions spec: "Drivers MUST clear a session's cached
* 'recoveryToken' when transitioning to the 'no transaction' or
* 'starting transaction' state." */
bson_destroy (session->recovery_token);
session->recovery_token = NULL;
RETURN (true);
case MONGOC_INTERNAL_TRANSACTION_NONE:
default:
RETURN (true);
}
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_session_append_read_concern --
*
* Add read concern if we're doing a read outside a transaction, or if
* we're starting a transaction, or if the user explicitly passed a read
* concern in some function's "opts". The contents of the read concern
* are "level" and/or "afterClusterTime" - if both are empty, don't add
* read concern.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_client_session_append_read_concern (const mongoc_client_session_t *cs,
const bson_t *rc,
bool is_read_command,
bson_t *cmd)
{
const mongoc_read_concern_t *txn_rc;
mongoc_internal_transaction_state_t txn_state;
bool user_rc_has_level;
bool txn_has_level;
bool has_timestamp;
bool has_level;
bson_t child;
ENTRY;
BSON_ASSERT (cs);
txn_state = cs->txn.state;
txn_rc = cs->txn.opts.read_concern;
if (txn_state == MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS) {
return;
}
has_timestamp =
(txn_state == MONGOC_INTERNAL_TRANSACTION_STARTING || is_read_command) &&
mongoc_session_opts_get_causal_consistency (&cs->opts) &&
cs->operation_timestamp;
user_rc_has_level = rc && bson_has_field (rc, "level");
txn_has_level = txn_state == MONGOC_INTERNAL_TRANSACTION_STARTING &&
!mongoc_read_concern_is_default (txn_rc);
has_level = user_rc_has_level || txn_has_level;
if (!has_timestamp && !has_level) {
return;
}
bson_append_document_begin (cmd, "readConcern", 11, &child);
if (rc) {
bson_concat (&child, rc);
}
if (txn_state == MONGOC_INTERNAL_TRANSACTION_STARTING) {
/* add transaction's read concern level unless user overrides */
if (txn_has_level && !user_rc_has_level) {
bson_append_utf8 (&child, "level", 5, txn_rc->level, -1);
}
}
if (has_timestamp) {
bson_append_timestamp (&child,
"afterClusterTime",
16,
cs->operation_timestamp,
cs->operation_increment);
}
bson_append_document_end (cmd, &child);
}
bool
mongoc_client_session_append (const mongoc_client_session_t *client_session,
bson_t *opts,
bson_error_t *error)
{
ENTRY;
BSON_ASSERT (client_session);
BSON_ASSERT (opts);
if (!bson_append_int64 (
opts, "sessionId", 9, client_session->client_session_id)) {
bson_set_error (
error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "invalid opts");
RETURN (false);
}
RETURN (true);
}
void
mongoc_client_session_destroy (mongoc_client_session_t *session)
{
ENTRY;
if (!session) {
EXIT;
}
if (session->client_generation == session->client->generation) {
if (mongoc_client_session_in_transaction (session)) {
mongoc_client_session_abort_transaction (session, NULL);
}
_mongoc_client_unregister_session (session->client, session);
_mongoc_client_push_server_session (session->client,
session->server_session);
} else {
/* If the client has been reset, destroy the server session instead of
pushing it back into the topology's pool. */
_mongoc_server_session_destroy (session->server_session);
}
txn_opts_cleanup (&session->opts.default_txn_opts);
txn_opts_cleanup (&session->txn.opts);
bson_destroy (&session->cluster_time);
bson_destroy (session->recovery_token);
bson_free (session);
EXIT;
}
void
_mongoc_client_session_unpin (mongoc_client_session_t *session)
{
BSON_ASSERT (session);
session->server_id = 0;
}
void
_mongoc_client_session_pin (mongoc_client_session_t *session,
uint32_t server_id)
{
BSON_ASSERT (session);
session->server_id = server_id;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h
index b845f4ef..70f70de3 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h
@@ -1,65 +1,65 @@
/*
* Copyright 2019-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
*
* 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CLIENT_SIDE_ENCRYPTION_PRIVATE_H
#define MONGOC_CLIENT_SIDE_ENCRYPTION_PRIVATE_H
#include "mongoc-client.h"
#include "mongoc-client-pool.h"
#include "mongoc-client-side-encryption.h"
#include "mongoc-cmd-private.h"
#include "mongoc-topology-private.h"
#include "bson/bson.h"
/* cse is an abbreviation for "Client Side Encryption" */
bool
_mongoc_cse_auto_encrypt (mongoc_client_t *client,
const mongoc_cmd_t *cmd,
mongoc_cmd_t *encrypted_cmd,
bson_t *encrypted,
bson_error_t *error);
bool
_mongoc_cse_auto_decrypt (mongoc_client_t *client,
const char *db_name,
const bson_t *reply,
bson_t *decrypted,
bson_error_t *error);
bool
_mongoc_cse_client_enable_auto_encryption (
mongoc_client_t *client,
mongoc_auto_encryption_opts_t *opts /* may be NULL */,
bson_error_t *error);
bool
_mongoc_cse_client_pool_enable_auto_encryption (
mongoc_topology_t *topology,
mongoc_auto_encryption_opts_t *opts /* may be NULL */,
bson_error_t *error);
/* If this returns true, client side encryption is enabled
* on the client (or it's parent client pool), and cannot
* be disabled. This check is done while holding the
* topology lock. So if this returns true, callers are
* guaranteed that CSE remains enabled afterwards. */
bool
_mongoc_cse_is_enabled (mongoc_client_t *client);
-#endif /* MONGOC_CLIENT_SIDE_ENCRYPTION_PRIVATE_H */
\ No newline at end of file
+#endif /* MONGOC_CLIENT_SIDE_ENCRYPTION_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
similarity index 93%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
index 34419d76..4b172489 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
@@ -1,2995 +1,3080 @@
/*
* Copyright 2013 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.
*/
#include <bson/bson.h>
#include "mongoc-config.h"
#ifdef MONGOC_HAVE_DNSAPI
/* for DnsQuery_UTF8 */
#include <Windows.h>
#include <WinDNS.h>
#include <ws2tcpip.h>
#else
#if defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH)
#include <netdb.h>
#include <netinet/tcp.h>
#include <arpa/nameser.h>
#include <resolv.h>
#define BSON_INSIDE
#include <bson/bson-string.h>
#undef BSON_INSIDE
#endif
#endif
#include "mongoc-client-private.h"
#include "mongoc-client-side-encryption-private.h"
#include "mongoc-collection-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-database-private.h"
#include "mongoc-gridfs-private.h"
#include "mongoc-error.h"
#include "mongoc-error-private.h"
#include "mongoc-log.h"
#include "mongoc-queue-private.h"
#include "mongoc-socket.h"
#include "mongoc-stream-buffered.h"
#include "mongoc-stream-socket.h"
#include "mongoc-thread-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-util-private.h"
#include "mongoc-set-private.h"
#include "mongoc-log.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-change-stream-private.h"
#include "mongoc-client-session-private.h"
#include "mongoc-cursor-private.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-stream-tls.h"
#include "mongoc-ssl-private.h"
#include "mongoc-cmd-private.h"
#include "mongoc-opts-private.h"
#endif
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "client"
static void
_mongoc_client_op_killcursors (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection);
static void
_mongoc_client_killcursors_command (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
const char *db,
const char *collection,
mongoc_client_session_t *cs);
#define DNS_ERROR(_msg, ...) \
do { \
bson_set_error (error, \
MONGOC_ERROR_STREAM, \
MONGOC_ERROR_STREAM_NAME_RESOLUTION, \
_msg, \
__VA_ARGS__); \
GOTO (done); \
} while (0)
#ifdef MONGOC_HAVE_DNSAPI
typedef bool (*mongoc_rr_callback_t) (const char *service,
PDNS_RECORD pdns,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error);
static bool
srv_callback (const char *service,
PDNS_RECORD pdns,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
+ mongoc_host_list_t new_host;
+
if (rr_data && rr_data->hosts) {
_mongoc_host_list_remove_host (
&(rr_data->hosts), pdns->Data.SRV.pNameTarget, pdns->Data.SRV.wPort);
}
- return mongoc_uri_upsert_host (
- uri, pdns->Data.SRV.pNameTarget, pdns->Data.SRV.wPort, error);
+ if (!_mongoc_host_list_from_hostport_with_err (
+ &new_host, pdns->Data.SRV.pNameTarget, pdns->Data.SRV.wPort, error)) {
+ return false;
+ }
+ _mongoc_host_list_upsert (&rr_data->hosts, &new_host);
+
+ return true;
}
/* rr_data is unused, but here to match srv_callback signature */
static bool
txt_callback (const char *service,
PDNS_RECORD pdns,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
DWORD i;
bson_string_t *txt;
- bool r;
txt = bson_string_new (NULL);
for (i = 0; i < pdns->Data.TXT.dwStringCount; i++) {
bson_string_append (txt, pdns->Data.TXT.pStringArray[i]);
}
- r = mongoc_uri_parse_options (uri, txt->str, true /* from_dns */, error);
+ rr_data->txt_record_opts = bson_strdup (txt->str);
bson_string_free (txt, true);
- return r;
+ return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_get_rr_dnsapi --
*
* Fetch SRV or TXT resource records using the Windows DNS API and
- * update @uri.
+ * put results in @rr_data.
*
* Returns:
* Success or failure.
*
* For an SRV lookup, returns false if there is any error.
*
- * For TXT lookup, ignores any error fetching the resource record, but
- * returns false if the resource record is found and there is an error
- * reading its contents as URI options.
+ * For TXT lookup, ignores any error fetching the resource record and
+ * always returns true.
*
* Side effects:
* @error is set if there is a failure.
+ * @rr_data->hosts may be set if querying SRV. Caller must destroy.
+ * @rr_data->txt_record_opts may be set if querying TXT. Caller must
+ * free.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_get_rr_dnsapi (const char *service,
mongoc_rr_type_t rr_type,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
const char *rr_type_name;
WORD nst;
mongoc_rr_callback_t callback;
PDNS_RECORD pdns = NULL;
DNS_STATUS res;
LPVOID lpMsgBuf = NULL;
bool dns_success;
bool callback_success = true;
int i;
ENTRY;
if (rr_type == MONGOC_RR_SRV) {
/* return true only if DNS succeeds */
dns_success = false;
rr_type_name = "SRV";
nst = DNS_TYPE_SRV;
callback = srv_callback;
} else {
/* return true whether or not DNS succeeds */
dns_success = true;
rr_type_name = "TXT";
nst = DNS_TYPE_TEXT;
callback = txt_callback;
}
res = DnsQuery_UTF8 (service,
nst,
DNS_QUERY_BYPASS_CACHE,
NULL /* IP Address */,
&pdns,
0 /* reserved */);
if (res) {
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
if (FormatMessage (flags,
0,
res,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
0)) {
DNS_ERROR ("Failed to look up %s record \"%s\": %s",
rr_type_name,
service,
(char *) lpMsgBuf);
}
DNS_ERROR ("Failed to look up %s record \"%s\": Unknown error",
rr_type_name,
service);
}
if (!pdns) {
DNS_ERROR ("No %s records for \"%s\"", rr_type_name, service);
}
- dns_success = true;
i = 0;
do {
/* DnsQuery can return additional records not of the requested type */
if ((rr_type == MONGOC_RR_TXT && pdns->wType == DNS_TYPE_TEXT) ||
(rr_type == MONGOC_RR_SRV && pdns->wType == DNS_TYPE_SRV)) {
if (i > 0 && rr_type == MONGOC_RR_TXT) {
/* Initial DNS Seedlist Discovery Spec: a client "MUST raise an
error when multiple TXT records are encountered". */
callback_success = false;
DNS_ERROR ("Multiple TXT records for \"%s\"", service);
}
if (rr_data) {
if ((i == 0) || (pdns->dwTtl < rr_data->min_ttl)) {
rr_data->min_ttl = pdns->dwTtl;
}
}
- if (!callback (service, pdns, uri, rr_data, error)) {
+ if (!callback (service, pdns, rr_data, error)) {
callback_success = false;
GOTO (done);
}
i++;
}
pdns = pdns->pNext;
} while (pdns);
- if (rr_data) {
- rr_data->count = i;
+
+ rr_data->count = i;
+ if (i == 0) {
+ DNS_ERROR ("No matching %s records for \"%s\"", rr_type_name, service);
}
+ dns_success = true;
done:
if (pdns) {
DnsRecordListFree (pdns, DnsFreeRecordList);
}
if (lpMsgBuf) {
LocalFree (lpMsgBuf);
}
RETURN (dns_success && callback_success);
}
#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH))
typedef bool (*mongoc_rr_callback_t) (const char *service,
ns_msg *ns_answer,
ns_rr *rr,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error);
static bool
srv_callback (const char *service,
ns_msg *ns_answer,
ns_rr *rr,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
const uint8_t *data;
char name[1024];
uint16_t port;
int size;
bool ret = false;
+ mongoc_host_list_t new_host;
data = ns_rr_rdata (*rr);
/* memcpy the network endian port before converting to host endian. we cannot
* cast (data + 4) directly as a uint16_t*, because it may not align on an
* 2-byte boundary. */
memcpy (&port, data + 4, sizeof (port));
port = ntohs (port);
size = dn_expand (ns_msg_base (*ns_answer),
ns_msg_end (*ns_answer),
data + 6,
name,
sizeof (name));
if (size < 1) {
DNS_ERROR ("Invalid record in SRV answer for \"%s\": \"%s\"",
service,
strerror (h_errno));
}
- if (rr_data && rr_data->hosts) {
- _mongoc_host_list_remove_host (&(rr_data->hosts), name, port);
+ if (!_mongoc_host_list_from_hostport_with_err (
+ &new_host, name, port, error)) {
+ GOTO (done);
}
- ret = mongoc_uri_upsert_host (uri, name, port, error);
-
+ _mongoc_host_list_upsert (&rr_data->hosts, &new_host);
+ ret = true;
done:
return ret;
}
-/* rr_data is unused, but here to match srv_callback signature */
static bool
txt_callback (const char *service,
ns_msg *ns_answer,
ns_rr *rr,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
char s[256];
const uint8_t *data;
bson_string_t *txt;
uint16_t pos, total;
uint8_t len;
- bool r = false;
+ bool ret = false;
total = (uint16_t) ns_rr_rdlen (*rr);
if (total < 1 || total > 255) {
DNS_ERROR ("Invalid TXT record size %hu for \"%s\"", total, service);
}
/* a TXT record has one or more strings, each up to 255 chars, each is
* prefixed by its length as 1 byte. thus endianness doesn't matter. */
txt = bson_string_new (NULL);
pos = 0;
data = ns_rr_rdata (*rr);
while (pos < total) {
memcpy (&len, data + pos, sizeof (uint8_t));
pos++;
bson_strncpy (s, (const char *) (data + pos), (size_t) len + 1);
bson_string_append (txt, s);
pos += len;
}
- r = mongoc_uri_parse_options (uri, txt->str, true /* from_dns */, error);
+ rr_data->txt_record_opts = bson_strdup (txt->str);
bson_string_free (txt, true);
+ ret = true;
done:
- return r;
+ return ret;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_get_rr_search --
*
- * Fetch SRV or TXT resource records using libresolv and update @uri.
+ * Fetch SRV or TXT resource records using libresolv and put results in
+ * @rr_data.
*
* Returns:
* Success or failure.
*
* For an SRV lookup, returns false if there is any error.
*
- * For TXT lookup, ignores any error fetching the resource record, but
- * returns false if the resource record is found and there is an error
- * reading its contents as URI options.
+ * For TXT lookup, ignores any error fetching the resource record and
+ * always returns true.
*
* Side effects:
* @error is set if there is a failure.
+ * @rr_data->hosts may be set if querying SRV. Caller must destroy.
+ * @rr_data->txt_record_opts may be set if querying TXT. Caller must
+ * free.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_get_rr_search (const char *service,
mongoc_rr_type_t rr_type,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
#ifdef MONGOC_HAVE_RES_NSEARCH
struct __res_state state = {0};
#endif
int size = 0;
unsigned char *search_buf = NULL;
size_t buffer_size = 1024;
ns_msg ns_answer;
int n;
int i;
const char *rr_type_name;
ns_type nst;
mongoc_rr_callback_t callback;
ns_rr resource_record;
bool dns_success;
bool callback_success = true;
+ int num_matching_records;
ENTRY;
if (rr_type == MONGOC_RR_SRV) {
/* return true only if DNS succeeds */
dns_success = false;
rr_type_name = "SRV";
nst = ns_t_srv;
callback = srv_callback;
} else {
/* return true whether or not DNS succeeds */
dns_success = true;
rr_type_name = "TXT";
nst = ns_t_txt;
callback = txt_callback;
}
do {
if (search_buf) {
bson_free (search_buf);
/* increase buffer size by the previous response size. This ensures
* that even if a subsequent response is larger, we'll still be able
* to fit it in the response buffer */
buffer_size = buffer_size + size;
}
search_buf = (unsigned char *) bson_malloc (buffer_size);
BSON_ASSERT (search_buf);
#ifdef MONGOC_HAVE_RES_NSEARCH
/* thread-safe */
res_ninit (&state);
size =
res_nsearch (&state, service, ns_c_in, nst, search_buf, buffer_size);
#elif defined(MONGOC_HAVE_RES_SEARCH)
size = res_search (service, ns_c_in, nst, search_buf, buffer_size);
#endif
if (size < 0) {
DNS_ERROR ("Failed to look up %s record \"%s\": %s",
rr_type_name,
service,
strerror (h_errno));
}
} while (size > buffer_size);
if (ns_initparse (search_buf, size, &ns_answer)) {
DNS_ERROR ("Invalid %s answer for \"%s\"", rr_type_name, service);
}
n = ns_msg_count (ns_answer, ns_s_an);
if (!n) {
DNS_ERROR ("No %s records for \"%s\"", rr_type_name, service);
}
- if (rr_data) {
- rr_data->count = n;
- }
-
+ rr_data->count = n;
+ num_matching_records = 0;
for (i = 0; i < n; i++) {
- if (i > 0 && rr_type == MONGOC_RR_TXT) {
- /* Initial DNS Seedlist Discovery Spec: a client "MUST raise an error
- * when multiple TXT records are encountered". */
- callback_success = false;
- DNS_ERROR ("Multiple TXT records for \"%s\"", service);
- }
-
if (ns_parserr (&ns_answer, ns_s_an, i, &resource_record)) {
DNS_ERROR ("Invalid record %d of %s answer for \"%s\": \"%s\"",
i,
rr_type_name,
service,
strerror (h_errno));
}
+ /* Skip records that don't match the ones we requested. CDRIVER-3628 shows
+ * that we can receive records that were not requested. */
+ if (rr_type == MONGOC_RR_TXT) {
+ if (ns_rr_type (resource_record) != ns_t_txt) {
+ continue;
+ }
+ } else if (rr_type == MONGOC_RR_SRV) {
+ if (ns_rr_type (resource_record) != ns_t_srv) {
+ continue;
+ }
+ }
+
+ if (num_matching_records > 0 && rr_type == MONGOC_RR_TXT) {
+ /* Initial DNS Seedlist Discovery Spec: a client "MUST raise an error
+ * when multiple TXT records are encountered". */
+ callback_success = false;
+ DNS_ERROR ("Multiple TXT records for \"%s\"", service);
+ }
+
+ num_matching_records++;
+
if (rr_data) {
uint32_t ttl;
ttl = ns_rr_ttl (resource_record);
if ((i == 0) || (ttl < rr_data->min_ttl)) {
rr_data->min_ttl = ttl;
}
}
- if (!callback (
- service, &ns_answer, &resource_record, uri, rr_data, error)) {
+ if (!callback (service, &ns_answer, &resource_record, rr_data, error)) {
callback_success = false;
GOTO (done);
}
}
+ if (num_matching_records == 0) {
+ DNS_ERROR ("No matching %s records for \"%s\"", rr_type_name, service);
+ }
+
dns_success = true;
done:
bson_free (search_buf);
#ifdef MONGOC_HAVE_RES_NDESTROY
/* defined on BSD/Darwin, and only if MONGOC_HAVE_RES_NSEARCH is defined */
res_ndestroy (&state);
#elif defined(MONGOC_HAVE_RES_NCLOSE)
/* defined on Linux, and only if MONGOC_HAVE_RES_NSEARCH is defined */
res_nclose (&state);
#endif
RETURN (dns_success && callback_success);
}
#endif
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_get_rr --
*
- * Fetch an SRV or TXT resource record and update @uri. See RFCs 1464
- * and 2782, and MongoDB's Initial DNS Seedlist Discovery Spec.
+ * Fetch an SRV or TXT resource record and update put results in
+ * @rr_data.
+ *
+ * See RFCs 1464 and 2782, MongoDB's "Initial DNS Seedlist Discovery"
+ * spec, and MongoDB's "Polling SRV Records for Mongos Discovery"
+ * spec.
*
* Returns:
* Success or failure.
*
* Side effects:
- * @error is set if there is a failure.
+ * @error is set if there is a failure. Errors fetching TXT are
+ * ignored.
+ * @rr_data->hosts may be set if querying SRV. Caller must destroy.
+ * @rr_data->txt_record_opts may be set if querying TXT. Caller must
+ * free.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_get_rr (const char *service,
mongoc_rr_type_t rr_type,
- mongoc_uri_t *uri,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
#ifdef MONGOC_HAVE_DNSAPI
- return _mongoc_get_rr_dnsapi (service, rr_type, uri, rr_data, error);
+ return _mongoc_get_rr_dnsapi (service, rr_type, rr_data, error);
#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH))
- return _mongoc_get_rr_search (service, rr_type, uri, rr_data, error);
+ return _mongoc_get_rr_search (service, rr_type, rr_data, error);
#else
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"libresolv unavailable, cannot use mongodb+srv URI");
return false;
#endif
}
#undef DNS_ERROR
/*
*--------------------------------------------------------------------------
*
* mongoc_client_connect_tcp --
*
* Connect to a host using a TCP socket.
*
* This will be performed synchronously and return a mongoc_stream_t
* that can be used to connect with the remote host.
*
* Returns:
* A newly allocated mongoc_stream_t if successful; otherwise
* NULL and @error is set.
*
* Side effects:
* @error is set if return value is NULL.
*
*--------------------------------------------------------------------------
*/
mongoc_stream_t *
mongoc_client_connect_tcp (int32_t connecttimeoutms,
const mongoc_host_list_t *host,
bson_error_t *error)
{
mongoc_socket_t *sock = NULL;
struct addrinfo hints;
struct addrinfo *result, *rp;
int64_t expire_at;
char portstr[8];
int s;
ENTRY;
BSON_ASSERT (connecttimeoutms);
BSON_ASSERT (host);
bson_snprintf (portstr, sizeof portstr, "%hu", host->port);
memset (&hints, 0, sizeof hints);
hints.ai_family = host->family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
+ TRACE ("DNS lookup for %s", host->host);
s = getaddrinfo (host->host, portstr, &hints, &result);
if (s != 0) {
mongoc_counter_dns_failure_inc ();
+ TRACE ("Failed to resolve %s", host->host);
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"Failed to resolve %s",
host->host);
RETURN (NULL);
}
mongoc_counter_dns_success_inc ();
for (rp = result; rp; rp = rp->ai_next) {
/*
* Create a new non-blocking socket.
*/
if (!(sock = mongoc_socket_new (
rp->ai_family, rp->ai_socktype, rp->ai_protocol))) {
continue;
}
/*
* Try to connect to the peer.
*/
expire_at = bson_get_monotonic_time () + (connecttimeoutms * 1000L);
if (0 !=
mongoc_socket_connect (
sock, rp->ai_addr, (mongoc_socklen_t) rp->ai_addrlen, expire_at)) {
mongoc_socket_destroy (sock);
sock = NULL;
continue;
}
break;
}
if (!sock) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"Failed to connect to target host: %s",
host->host_and_port);
freeaddrinfo (result);
RETURN (NULL);
}
freeaddrinfo (result);
return mongoc_stream_socket_new (sock);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_connect_unix --
*
* Connect to a MongoDB server using a UNIX domain socket.
*
* Returns:
* A newly allocated mongoc_stream_t if successful; otherwise
* NULL and @error is set.
*
* Side effects:
* @error is set if return value is NULL.
*
*--------------------------------------------------------------------------
*/
static mongoc_stream_t *
mongoc_client_connect_unix (const mongoc_host_list_t *host, bson_error_t *error)
{
#ifdef _WIN32
ENTRY;
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"UNIX domain sockets not supported on win32.");
RETURN (NULL);
#else
struct sockaddr_un saddr;
mongoc_socket_t *sock;
mongoc_stream_t *ret = NULL;
ENTRY;
BSON_ASSERT (host);
memset (&saddr, 0, sizeof saddr);
saddr.sun_family = AF_UNIX;
bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host);
sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0);
if (sock == NULL) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to create socket.");
RETURN (NULL);
}
if (-1 == mongoc_socket_connect (
sock, (struct sockaddr *) &saddr, sizeof saddr, -1)) {
mongoc_socket_destroy (sock);
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"Failed to connect to UNIX domain socket.");
RETURN (NULL);
}
ret = mongoc_stream_socket_new (sock);
RETURN (ret);
#endif
}
-
-/*
- *--------------------------------------------------------------------------
- *
- * mongoc_client_default_stream_initiator --
- *
- * A mongoc_stream_initiator_t that will handle the various type
- * of supported sockets by MongoDB including TCP and UNIX.
- *
- * Language binding authors may want to implement an alternate
- * version of this method to use their native stream format.
- *
- * Returns:
- * A mongoc_stream_t if successful; otherwise NULL and @error is set.
- *
- * Side effects:
- * @error is set if return value is NULL.
- *
- *--------------------------------------------------------------------------
- */
-
mongoc_stream_t *
-mongoc_client_default_stream_initiator (const mongoc_uri_t *uri,
- const mongoc_host_list_t *host,
- void *user_data,
- bson_error_t *error)
+mongoc_client_connect (bool buffered,
+ bool use_ssl,
+ void *ssl_opts_void,
+ const mongoc_uri_t *uri,
+ const mongoc_host_list_t *host,
+ bson_error_t *error)
{
mongoc_stream_t *base_stream = NULL;
int32_t connecttimeoutms;
-#ifdef MONGOC_ENABLE_SSL
- mongoc_client_t *client = (mongoc_client_t *) user_data;
- const char *mechanism;
-#endif
BSON_ASSERT (uri);
BSON_ASSERT (host);
#ifndef MONGOC_ENABLE_SSL
- if (mongoc_uri_get_tls (uri)) {
+ if (ssl_opts_void || mongoc_uri_get_tls (uri)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER,
- "SSL is not enabled in this build of mongo-c-driver.");
+ "TLS is not enabled in this build of mongo-c-driver.");
return NULL;
}
#endif
connecttimeoutms = mongoc_uri_get_option_as_int32 (
uri, MONGOC_URI_CONNECTTIMEOUTMS, MONGOC_DEFAULT_CONNECTTIMEOUTMS);
switch (host->family) {
case AF_UNSPEC:
#if defined(AF_INET6)
case AF_INET6:
#endif
case AF_INET:
base_stream = mongoc_client_connect_tcp (connecttimeoutms, host, error);
break;
case AF_UNIX:
base_stream = mongoc_client_connect_unix (host, error);
break;
default:
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_INVALID_TYPE,
"Invalid address family: 0x%02x",
host->family);
break;
}
#ifdef MONGOC_ENABLE_SSL
if (base_stream) {
+ mongoc_ssl_opt_t *ssl_opts;
+ const char *mechanism;
+
+ ssl_opts = (mongoc_ssl_opt_t *) ssl_opts_void;
mechanism = mongoc_uri_get_auth_mechanism (uri);
- if (client->use_ssl ||
- (mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) {
+ if (use_ssl || (mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) {
mongoc_stream_t *original = base_stream;
base_stream = mongoc_stream_tls_new_with_hostname (
- base_stream, host->host, &client->ssl_opts, true);
+ base_stream, host->host, ssl_opts, true);
if (!base_stream) {
mongoc_stream_destroy (original);
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed initialize TLS state.");
return NULL;
}
if (!mongoc_stream_tls_handshake_block (
base_stream, host->host, connecttimeoutms, error)) {
mongoc_stream_destroy (base_stream);
return NULL;
}
}
}
#endif
- return base_stream ? mongoc_stream_buffered_new (base_stream, 1024) : NULL;
+ if (!base_stream) {
+ return NULL;
+ }
+ if (buffered) {
+ return mongoc_stream_buffered_new (base_stream, 1024);
+ }
+ return base_stream;
}
+/*
+ *--------------------------------------------------------------------------
+ *
+ * mongoc_client_default_stream_initiator --
+ *
+ * A mongoc_stream_initiator_t that will handle the various type
+ * of supported sockets by MongoDB including TCP and UNIX.
+ *
+ * Language binding authors may want to implement an alternate
+ * version of this method to use their native stream format.
+ *
+ * Returns:
+ * A mongoc_stream_t if successful; otherwise NULL and @error is set.
+ *
+ * Side effects:
+ * @error is set if return value is NULL.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+mongoc_stream_t *
+mongoc_client_default_stream_initiator (const mongoc_uri_t *uri,
+ const mongoc_host_list_t *host,
+ void *user_data,
+ bson_error_t *error)
+{
+ void *ssl_opts_void = NULL;
+ bool use_ssl = false;
+#ifdef MONGOC_ENABLE_SSL
+ mongoc_client_t *client = (mongoc_client_t *) user_data;
+
+ use_ssl = client->use_ssl;
+ ssl_opts_void = (void *) &client->ssl_opts;
+
+#endif
+
+ return mongoc_client_connect (
+ true, use_ssl, ssl_opts_void, uri, host, error);
+}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_create_stream --
*
* INTERNAL API
*
* This function is used by the mongoc_cluster_t to initiate a
* new stream. This is done because cluster is private API and
* those using mongoc_client_t may need to override this process.
*
* This function calls the default initiator for new streams.
*
* Returns:
* A newly allocated mongoc_stream_t if successful; otherwise
* NULL and @error is set.
*
* Side effects:
* @error is set if return value is NULL.
*
*--------------------------------------------------------------------------
*/
mongoc_stream_t *
_mongoc_client_create_stream (mongoc_client_t *client,
const mongoc_host_list_t *host,
bson_error_t *error)
{
BSON_ASSERT (client);
BSON_ASSERT (host);
return client->initiator (client->uri, host, client->initiator_data, error);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_recv --
*
* Receives a RPC from a remote MongoDB cluster node.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @error is set if return value is false.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_recv (mongoc_client_t *client,
mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
mongoc_server_stream_t *server_stream,
bson_error_t *error)
{
BSON_ASSERT (client);
BSON_ASSERT (rpc);
BSON_ASSERT (buffer);
BSON_ASSERT (server_stream);
- if (!mongoc_cluster_try_recv (
- &client->cluster, rpc, buffer, server_stream, error)) {
- mongoc_topology_invalidate_server (
- client->topology, server_stream->sd->id, error);
- return false;
- }
- return true;
+ return mongoc_cluster_try_recv (
+ &client->cluster, rpc, buffer, server_stream, error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_new --
*
* Create a new mongoc_client_t using the URI provided.
*
* @uri should be a MongoDB URI string such as "mongodb://localhost/"
* More information on the format can be found at
* http://docs.mongodb.org/manual/reference/connection-string/
*
* Returns:
* A newly allocated mongoc_client_t or NULL if @uri_string is
* invalid.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_client_t *
mongoc_client_new (const char *uri_string)
{
mongoc_topology_t *topology;
mongoc_client_t *client;
mongoc_uri_t *uri;
if (!uri_string) {
uri_string = "mongodb://127.0.0.1/";
}
if (!(uri = mongoc_uri_new (uri_string))) {
return NULL;
}
topology = mongoc_topology_new (uri, true);
client = _mongoc_client_new_from_uri (topology);
if (!client) {
mongoc_topology_destroy (topology);
}
mongoc_uri_destroy (uri);
return client;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_set_ssl_opts
*
* set ssl opts for a client
*
* Returns:
* Nothing
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
#ifdef MONGOC_ENABLE_SSL
+/* Only called internally. Caller must ensure opts->internal is valid. */
+void
+_mongoc_client_set_internal_tls_opts (mongoc_client_t *client,
+ _mongoc_internal_tls_opts_t *internal)
+{
+ if (!client->use_ssl) {
+ return;
+ }
+ client->ssl_opts.internal =
+ bson_malloc (sizeof (_mongoc_internal_tls_opts_t));
+ memcpy (client->ssl_opts.internal,
+ internal,
+ sizeof (_mongoc_internal_tls_opts_t));
+}
+
void
mongoc_client_set_ssl_opts (mongoc_client_t *client,
const mongoc_ssl_opt_t *opts)
{
BSON_ASSERT (client);
BSON_ASSERT (opts);
- _mongoc_ssl_opts_cleanup (&client->ssl_opts);
+ _mongoc_ssl_opts_cleanup (&client->ssl_opts,
+ false /* don't free internal opts */);
client->use_ssl = true;
- _mongoc_ssl_opts_copy_to (opts, &client->ssl_opts);
+ _mongoc_ssl_opts_copy_to (
+ opts, &client->ssl_opts, false /* don't overwrite internal opts */);
if (client->topology->single_threaded) {
mongoc_topology_scanner_set_ssl_opts (client->topology->scanner,
&client->ssl_opts);
}
}
#endif
/*
*--------------------------------------------------------------------------
*
* mongoc_client_new_from_uri --
*
* Create a new mongoc_client_t for a mongoc_uri_t.
*
* Returns:
* A newly allocated mongoc_client_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_client_t *
mongoc_client_new_from_uri (const mongoc_uri_t *uri)
{
mongoc_topology_t *topology;
topology = mongoc_topology_new (uri, true);
/* topology->uri may be different from uri: if this is a mongodb+srv:// URI
* then mongoc_topology_new has fetched SRV and TXT records and updated its
* uri from them.
*/
return _mongoc_client_new_from_uri (topology);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_new_from_uri --
*
* Create a new mongoc_client_t for a given topology object.
*
* Returns:
* A newly allocated mongoc_client_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_client_t *
_mongoc_client_new_from_uri (mongoc_topology_t *topology)
{
mongoc_client_t *client;
const mongoc_read_prefs_t *read_prefs;
const mongoc_read_concern_t *read_concern;
const mongoc_write_concern_t *write_concern;
const char *appname;
BSON_ASSERT (topology);
#ifndef MONGOC_ENABLE_SSL
if (mongoc_uri_get_tls (topology->uri)) {
MONGOC_ERROR ("Can't create SSL client, SSL not enabled in this build.");
return NULL;
}
#endif
client = (mongoc_client_t *) bson_malloc0 (sizeof *client);
client->uri = mongoc_uri_copy (topology->uri);
client->initiator = mongoc_client_default_stream_initiator;
client->initiator_data = client;
client->topology = topology;
client->error_api_version = MONGOC_ERROR_API_VERSION_LEGACY;
client->error_api_set = false;
client->client_sessions = mongoc_set_new (8, NULL, NULL);
client->csid_rand_seed = (unsigned int) bson_get_monotonic_time ();
write_concern = mongoc_uri_get_write_concern (client->uri);
client->write_concern = mongoc_write_concern_copy (write_concern);
read_concern = mongoc_uri_get_read_concern (client->uri);
client->read_concern = mongoc_read_concern_copy (read_concern);
read_prefs = mongoc_uri_get_read_prefs_t (client->uri);
client->read_prefs = mongoc_read_prefs_copy (read_prefs);
appname =
mongoc_uri_get_option_as_utf8 (client->uri, MONGOC_URI_APPNAME, NULL);
if (appname && client->topology->single_threaded) {
/* the appname should have already been validated */
BSON_ASSERT (mongoc_client_set_appname (client, appname));
}
mongoc_cluster_init (&client->cluster, client->uri, client);
#ifdef MONGOC_ENABLE_SSL
client->use_ssl = false;
if (mongoc_uri_get_tls (client->uri)) {
mongoc_ssl_opt_t ssl_opt = {0};
+ _mongoc_internal_tls_opts_t internal_tls_opts = {0};
- _mongoc_ssl_opts_from_uri (&ssl_opt, client->uri);
+ _mongoc_ssl_opts_from_uri (&ssl_opt, &internal_tls_opts, client->uri);
/* sets use_ssl = true */
mongoc_client_set_ssl_opts (client, &ssl_opt);
+ _mongoc_client_set_internal_tls_opts (client, &internal_tls_opts);
}
#endif
mongoc_counter_clients_active_inc ();
return client;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_destroy --
*
* Destroys a mongoc_client_t and cleans up all resources associated
* with the client instance.
*
* Returns:
* None.
*
* Side effects:
* @client is destroyed.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_destroy (mongoc_client_t *client)
{
if (client) {
if (client->topology->single_threaded) {
_mongoc_client_end_sessions (client);
mongoc_topology_destroy (client->topology);
}
mongoc_write_concern_destroy (client->write_concern);
mongoc_read_concern_destroy (client->read_concern);
mongoc_read_prefs_destroy (client->read_prefs);
mongoc_cluster_destroy (&client->cluster);
mongoc_uri_destroy (client->uri);
mongoc_set_destroy (client->client_sessions);
#ifdef MONGOC_ENABLE_SSL
- _mongoc_ssl_opts_cleanup (&client->ssl_opts);
+ _mongoc_ssl_opts_cleanup (&client->ssl_opts, true);
#endif
bson_free (client);
mongoc_counter_clients_active_dec ();
mongoc_counter_clients_disposed_inc ();
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_uri --
*
* Fetch the URI used for @client.
*
* Returns:
* A mongoc_uri_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_uri_t *
mongoc_client_get_uri (const mongoc_client_t *client)
{
BSON_ASSERT (client);
return client->uri;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_start_session --
*
* Creates a structure to communicate in a session over @client.
*
* This structure should be freed when the caller is done with it
* using mongoc_client_session_destroy().
*
* Returns:
* A newly allocated mongoc_client_session_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_client_session_t *
mongoc_client_start_session (mongoc_client_t *client,
const mongoc_session_opt_t *opts,
bson_error_t *error)
{
mongoc_server_session_t *ss;
mongoc_client_session_t *cs;
uint32_t csid;
ENTRY;
ss = _mongoc_client_pop_server_session (client, error);
if (!ss) {
RETURN (NULL);
}
/* get a random internal id for the session, retrying on collision */
do {
csid = (uint32_t) _mongoc_rand_simple (&client->csid_rand_seed);
} while (mongoc_set_get (client->client_sessions, csid));
cs = _mongoc_client_session_new (client, ss, opts, csid);
/* remember session so if we see its client_session_id in a command, we can
* find its lsid and clusterTime */
mongoc_set_add (client->client_sessions, csid, cs);
RETURN (cs);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_database --
*
* Fetches a newly allocated database structure to communicate with
* a database over @client.
*
* @database should be a db name such as "test".
*
* This structure should be freed when the caller is done with it
* using mongoc_database_destroy().
*
* Returns:
* A newly allocated mongoc_database_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_database_t *
mongoc_client_get_database (mongoc_client_t *client, const char *name)
{
BSON_ASSERT (client);
BSON_ASSERT (name);
return _mongoc_database_new (client,
name,
client->read_prefs,
client->read_concern,
client->write_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_default_database --
*
* Get the database named in the MongoDB connection URI, or NULL
* if none was specified in the URI.
*
* This structure should be freed when the caller is done with it
* using mongoc_database_destroy().
*
* Returns:
* A newly allocated mongoc_database_t or NULL.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_database_t *
mongoc_client_get_default_database (mongoc_client_t *client)
{
const char *db;
BSON_ASSERT (client);
db = mongoc_uri_get_database (client->uri);
if (db) {
return mongoc_client_get_database (client, db);
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_collection --
*
* This function returns a newly allocated collection structure.
*
* @db should be the name of the database, such as "test".
* @collection should be the name of the collection such as "test".
*
* The above would result in the namespace "test.test".
*
* You should free this structure when you are done with it using
* mongoc_collection_destroy().
*
* Returns:
* A newly allocated mongoc_collection_t that should be freed with
* mongoc_collection_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_collection_t *
mongoc_client_get_collection (mongoc_client_t *client,
const char *db,
const char *collection)
{
BSON_ASSERT (client);
BSON_ASSERT (db);
BSON_ASSERT (collection);
return _mongoc_collection_new (client,
db,
collection,
client->read_prefs,
client->read_concern,
client->write_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_gridfs --
*
* This function returns a newly allocated collection structure.
*
* @db should be the name of the database, such as "test".
*
* @prefix optional prefix for GridFS collection names, or NULL. Default
* is "fs", thus the default collection names for GridFS are "fs.files"
* and "fs.chunks".
*
* Returns:
* A newly allocated mongoc_gridfs_t that should be freed with
* mongoc_gridfs_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_gridfs_t *
mongoc_client_get_gridfs (mongoc_client_t *client,
const char *db,
const char *prefix,
bson_error_t *error)
{
BSON_ASSERT (client);
BSON_ASSERT (db);
if (!prefix) {
prefix = "fs";
}
return _mongoc_gridfs_new (client, db, prefix, error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_write_concern --
*
* Fetches the default write concern for @client.
*
* Returns:
* A mongoc_write_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_write_concern_t *
mongoc_client_get_write_concern (const mongoc_client_t *client)
{
BSON_ASSERT (client);
return client->write_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_set_write_concern --
*
* Sets the default write concern for @client.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_set_write_concern (mongoc_client_t *client,
const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (client);
if (write_concern != client->write_concern) {
if (client->write_concern) {
mongoc_write_concern_destroy (client->write_concern);
}
client->write_concern = write_concern
? mongoc_write_concern_copy (write_concern)
: mongoc_write_concern_new ();
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_read_concern --
*
* Fetches the default read concern for @client.
*
* Returns:
* A mongoc_read_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_concern_t *
mongoc_client_get_read_concern (const mongoc_client_t *client)
{
BSON_ASSERT (client);
return client->read_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_set_read_concern --
*
* Sets the default read concern for @client.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_set_read_concern (mongoc_client_t *client,
const mongoc_read_concern_t *read_concern)
{
BSON_ASSERT (client);
if (read_concern != client->read_concern) {
if (client->read_concern) {
mongoc_read_concern_destroy (client->read_concern);
}
client->read_concern = read_concern
? mongoc_read_concern_copy (read_concern)
: mongoc_read_concern_new ();
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_read_prefs --
*
* Fetch the default read preferences for @client.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_prefs_t *
mongoc_client_get_read_prefs (const mongoc_client_t *client)
{
BSON_ASSERT (client);
return client->read_prefs;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_set_read_prefs --
*
* Set the default read preferences for @client.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_set_read_prefs (mongoc_client_t *client,
const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT (client);
if (read_prefs != client->read_prefs) {
if (client->read_prefs) {
mongoc_read_prefs_destroy (client->read_prefs);
}
client->read_prefs = read_prefs
? mongoc_read_prefs_copy (read_prefs)
: mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
}
}
mongoc_cursor_t *
mongoc_client_command (mongoc_client_t *client,
const char *db_name,
mongoc_query_flags_t flags,
uint32_t skip,
uint32_t limit,
uint32_t batch_size,
const bson_t *query,
const bson_t *fields,
const mongoc_read_prefs_t *read_prefs)
{
- char ns[MONGOC_NAMESPACE_MAX];
+ char *ns = NULL;
mongoc_cursor_t *cursor;
BSON_ASSERT (client);
BSON_ASSERT (db_name);
BSON_ASSERT (query);
/*
* Allow a caller to provide a fully qualified namespace
*/
if (NULL == strstr (db_name, "$cmd")) {
- bson_snprintf (ns, sizeof ns, "%s.$cmd", db_name);
+ ns = bson_strdup_printf ("%s.$cmd", db_name);
db_name = ns;
}
cursor =
_mongoc_cursor_cmd_deprecated_new (client, db_name, query, read_prefs);
+ bson_free (ns);
return cursor;
}
static bool
_mongoc_client_retryable_write_command_with_stream (
mongoc_client_t *client,
mongoc_cmd_parts_t *parts,
mongoc_server_stream_t *server_stream,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *retry_server_stream = NULL;
bson_iter_t txn_number_iter;
bool is_retryable = true;
bool ret;
ENTRY;
BSON_ASSERT (parts->is_retryable_write);
/* increment the transaction number for the first attempt of each retryable
* write command */
BSON_ASSERT (bson_iter_init_find (
&txn_number_iter, parts->assembled.command, "txnNumber"));
bson_iter_overwrite_int64 (
&txn_number_iter, ++parts->assembled.session->server_session->txn_number);
retry:
ret = mongoc_cluster_run_command_monitored (
&client->cluster, &parts->assembled, reply, error);
+ _mongoc_write_error_handle_labels (
+ ret, error, reply, server_stream->sd->max_wire_version);
+
if (is_retryable) {
_mongoc_write_error_update_if_unsupported_storage_engine (
ret, error, reply);
}
/* If a retryable error is encountered and the write is retryable, select
* a new writable stream and retry. If server selection fails or the selected
* server does not support retryable writes, fall through and allow the
* original error to be reported. */
if (is_retryable &&
- _mongoc_write_error_get_type (ret, error, reply) ==
- MONGOC_WRITE_ERR_RETRY) {
+ _mongoc_write_error_get_type (reply) == MONGOC_WRITE_ERR_RETRY) {
bson_error_t ignored_error;
/* each write command may be retried at most once */
is_retryable = false;
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
retry_server_stream = mongoc_cluster_stream_for_writes (
&client->cluster, parts->assembled.session, NULL, &ignored_error);
if (retry_server_stream &&
retry_server_stream->sd->max_wire_version >=
WIRE_VERSION_RETRY_WRITES) {
parts->assembled.server_stream = retry_server_stream;
bson_destroy (reply);
GOTO (retry);
}
}
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
if (ret && error) {
/* if a retry succeeded, clear the initial error */
memset (error, 0, sizeof (bson_error_t));
}
RETURN (ret);
}
static bool
_mongoc_client_retryable_read_command_with_stream (
mongoc_client_t *client,
mongoc_cmd_parts_t *parts,
mongoc_server_stream_t *server_stream,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *retry_server_stream = NULL;
bool is_retryable = true;
bool ret;
bson_t reply_local;
if (reply == NULL) {
reply = &reply_local;
}
ENTRY;
BSON_ASSERT (parts->is_retryable_read);
retry:
ret = mongoc_cluster_run_command_monitored (
&client->cluster, &parts->assembled, reply, error);
/* If a retryable error is encountered and the read is retryable, select
* a new readable stream and retry. If server selection fails or the selected
* server does not support retryable reads, fall through and allow the
* original error to be reported. */
if (is_retryable &&
_mongoc_read_error_get_type (ret, error, reply) ==
MONGOC_READ_ERR_RETRY) {
bson_error_t ignored_error;
/* each read command may be retried at most once */
is_retryable = false;
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
retry_server_stream =
mongoc_cluster_stream_for_reads (&client->cluster,
parts->read_prefs,
parts->assembled.session,
NULL,
&ignored_error);
if (retry_server_stream &&
retry_server_stream->sd->max_wire_version >=
WIRE_VERSION_RETRY_READS) {
parts->assembled.server_stream = retry_server_stream;
bson_destroy (reply);
GOTO (retry);
}
}
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
if (ret && error) {
/* if a retry succeeded, clear the initial error */
memset (error, 0, sizeof (bson_error_t));
}
RETURN (ret);
}
static bool
_mongoc_client_command_with_stream (mongoc_client_t *client,
mongoc_cmd_parts_t *parts,
const mongoc_read_prefs_t *read_prefs,
mongoc_server_stream_t *server_stream,
bson_t *reply,
bson_error_t *error)
{
ENTRY;
parts->assembled.operation_id = ++client->cluster.operation_id;
if (!mongoc_cmd_parts_assemble (parts, server_stream, error)) {
_mongoc_bson_init_if_set (reply);
return false;
};
if (parts->is_retryable_write) {
RETURN (_mongoc_client_retryable_write_command_with_stream (
client, parts, server_stream, reply, error));
}
if (parts->is_retryable_read) {
RETURN (_mongoc_client_retryable_read_command_with_stream (
client, parts, server_stream, reply, error));
}
RETURN (mongoc_cluster_run_command_monitored (
&client->cluster, &parts->assembled, reply, error));
}
bool
mongoc_client_command_simple (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
mongoc_cluster_t *cluster;
mongoc_server_stream_t *server_stream = NULL;
mongoc_cmd_parts_t parts;
bool ret;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (db_name);
BSON_ASSERT (command);
if (!_mongoc_read_prefs_validate (read_prefs, error)) {
RETURN (false);
}
cluster = &client->cluster;
mongoc_cmd_parts_init (&parts, client, db_name, MONGOC_QUERY_NONE, command);
parts.read_prefs = read_prefs;
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
server_stream =
mongoc_cluster_stream_for_reads (cluster, read_prefs, NULL, reply, error);
if (server_stream) {
ret = _mongoc_client_command_with_stream (
client, &parts, read_prefs, server_stream, reply, error);
} else {
/* reply initialized by mongoc_cluster_stream_for_reads */
ret = false;
}
mongoc_cmd_parts_cleanup (&parts);
mongoc_server_stream_cleanup (server_stream);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_command_with_opts --
*
* Execute a command on the server. If mode is MONGOC_CMD_READ or
* MONGOC_CMD_RW, then read concern is applied from @opts, or else from
* @default_rc, and read preferences are applied from @user_prefs, or else
* from @default_prefs. If mode is MONGOC_CMD_WRITE or MONGOC_CMD_RW, then
* write concern is applied from @opts if present, or else @default_wc.
*
* If mode is MONGOC_CMD_RAW, then read concern and write concern are
* applied from @opts only. Read preferences are applied from
* @user_prefs.
*
* The mongoc_client_t's read preference, read concern, and write concern
* are *NOT* applied.
*
* Returns:
* Success or failure.
* A write concern timeout or write concern error is considered a failure.
*
* Side effects:
* @reply is always initialized.
* @error is filled out if the command fails.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
mongoc_command_mode_t mode,
const bson_t *opts,
mongoc_query_flags_t flags,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
mongoc_read_concern_t *default_rc,
mongoc_write_concern_t *default_wc,
bson_t *reply,
bson_error_t *error)
{
mongoc_read_write_opts_t read_write_opts;
mongoc_cmd_parts_t parts;
const char *command_name;
const mongoc_read_prefs_t *prefs = COALESCE (user_prefs, default_prefs);
mongoc_server_stream_t *server_stream = NULL;
mongoc_cluster_t *cluster;
mongoc_client_session_t *cs;
bson_t reply_local;
bson_t *reply_ptr;
int32_t wire_version;
int32_t wc_wire_version;
bool reply_initialized = false;
bool ret = false;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (db_name);
BSON_ASSERT (command);
command_name = _mongoc_get_command_name (command);
cluster = &client->cluster;
reply_ptr = reply ? reply : &reply_local;
mongoc_cmd_parts_init (&parts, client, db_name, flags, command);
parts.is_read_command = (mode & MONGOC_CMD_READ);
parts.is_write_command = (mode & MONGOC_CMD_WRITE);
if (!_mongoc_read_write_opts_parse (client, opts, &read_write_opts, error)) {
GOTO (done);
}
cs = read_write_opts.client_session;
if (!command_name) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Empty command document");
GOTO (done);
}
if (_mongoc_client_session_in_txn (read_write_opts.client_session)) {
if ((mode == MONGOC_CMD_READ || mode == MONGOC_CMD_RAW) &&
!IS_PREF_PRIMARY (user_prefs)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Read preference in a transaction must be primary");
GOTO (done);
}
if (!bson_empty (&read_write_opts.readConcern)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set read concern after starting transaction");
GOTO (done);
}
if (read_write_opts.writeConcern &&
strcmp (command_name, "commitTransaction") != 0 &&
strcmp (command_name, "abortTransaction") != 0) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
GOTO (done);
}
}
if (mode == MONGOC_CMD_READ || mode == MONGOC_CMD_RAW) {
/* NULL read pref is ok */
if (!_mongoc_read_prefs_validate (prefs, error)) {
GOTO (done);
}
parts.read_prefs = prefs;
} else {
/* this is a command that writes */
prefs = NULL;
}
if (read_write_opts.serverId) {
/* "serverId" passed in opts */
server_stream =
mongoc_cluster_stream_for_server (cluster,
read_write_opts.serverId,
true /* reconnect ok */,
cs,
reply_ptr,
error);
if (server_stream && server_stream->sd->type != MONGOC_SERVER_MONGOS) {
parts.user_query_flags |= MONGOC_QUERY_SLAVE_OK;
}
} else if (parts.is_write_command) {
server_stream =
mongoc_cluster_stream_for_writes (cluster, cs, reply_ptr, error);
} else {
server_stream =
mongoc_cluster_stream_for_reads (cluster, prefs, cs, reply_ptr, error);
}
if (!server_stream) {
/* stream_for_reads/writes/server has initialized reply */
reply_initialized = true;
GOTO (done);
}
wire_version = server_stream->sd->max_wire_version;
if (!mongoc_cmd_parts_append_read_write (
&parts, &read_write_opts, wire_version, error)) {
GOTO (done);
}
if (mode & MONGOC_CMD_WRITE) {
wc_wire_version = !strcasecmp (command_name, "findandmodify")
? WIRE_VERSION_FAM_WRITE_CONCERN
: WIRE_VERSION_CMD_WRITE_CONCERN;
if (read_write_opts.write_concern_owned &&
wire_version < wc_wire_version) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"\"%s\" command does not support writeConcern with "
"wire version %d, wire version %d is required",
command_name,
wire_version,
wc_wire_version);
GOTO (done);
}
/* use default write concern unless it's in opts */
if (!mongoc_write_concern_is_default (default_wc) &&
!read_write_opts.write_concern_owned &&
wire_version >= wc_wire_version) {
if (!mongoc_cmd_parts_set_write_concern (
&parts, default_wc, wire_version, error)) {
GOTO (done);
}
}
}
/* use default read concern for read command, unless it's in opts */
if ((mode & MONGOC_CMD_READ) && bson_empty (&read_write_opts.readConcern)) {
if (!mongoc_cmd_parts_set_read_concern (
&parts, default_rc, wire_version, error)) {
GOTO (done);
}
}
ret = _mongoc_client_command_with_stream (
client, &parts, user_prefs, server_stream, reply_ptr, error);
reply_initialized = true;
if (ret && (mode & MONGOC_CMD_WRITE)) {
ret = !_mongoc_parse_wc_err (reply_ptr, error);
}
done:
if (reply_ptr == &reply_local) {
if (reply_initialized) {
bson_destroy (reply_ptr);
}
} else if (!reply_initialized) {
_mongoc_bson_init_if_set (reply);
}
if (server_stream) {
mongoc_server_stream_cleanup (server_stream);
}
mongoc_cmd_parts_cleanup (&parts);
_mongoc_read_write_opts_cleanup (&read_write_opts);
RETURN (ret);
}
bool
mongoc_client_read_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (client,
db_name,
command,
MONGOC_CMD_READ,
opts,
MONGOC_QUERY_NONE,
read_prefs,
client->read_prefs,
client->read_concern,
client->write_concern,
reply,
error);
}
bool
mongoc_client_write_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (client,
db_name,
command,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL,
client->read_prefs,
client->read_concern,
client->write_concern,
reply,
error);
}
bool
mongoc_client_read_write_command_with_opts (
mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs /* IGNORED */,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (client,
db_name,
command,
MONGOC_CMD_RW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
client->read_prefs,
client->read_concern,
client->write_concern,
reply,
error);
}
bool
mongoc_client_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (client,
db_name,
command,
MONGOC_CMD_RAW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
NULL,
client->read_concern,
client->write_concern,
reply,
error);
}
bool
mongoc_client_command_simple_with_server_id (
mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
uint32_t server_id,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *server_stream;
mongoc_cmd_parts_t parts;
bool ret;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (db_name);
BSON_ASSERT (command);
if (!_mongoc_read_prefs_validate (read_prefs, error)) {
RETURN (false);
}
server_stream = mongoc_cluster_stream_for_server (
&client->cluster, server_id, true /* reconnect ok */, NULL, reply, error);
if (server_stream) {
mongoc_cmd_parts_init (
&parts, client, db_name, MONGOC_QUERY_NONE, command);
parts.read_prefs = read_prefs;
ret = _mongoc_client_command_with_stream (
client, &parts, read_prefs, server_stream, reply, error);
mongoc_cmd_parts_cleanup (&parts);
mongoc_server_stream_cleanup (server_stream);
RETURN (ret);
} else {
/* stream_for_server initialized reply */
RETURN (false);
}
}
static void
_mongoc_client_prepare_killcursors_command (int64_t cursor_id,
const char *collection,
bson_t *command)
{
bson_t child;
bson_append_utf8 (command, "killCursors", 11, collection, -1);
bson_append_array_begin (command, "cursors", 7, &child);
bson_append_int64 (&child, "0", 1, cursor_id);
bson_append_array_end (command, &child);
}
void
_mongoc_client_kill_cursor (mongoc_client_t *client,
uint32_t server_id,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection,
mongoc_client_session_t *cs)
{
mongoc_server_stream_t *server_stream;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (cursor_id);
/* don't attempt reconnect if server unavailable, and ignore errors */
server_stream = mongoc_cluster_stream_for_server (
&client->cluster, server_id, false /* reconnect_ok */, NULL, NULL, NULL);
if (!server_stream) {
return;
}
if (db && collection &&
server_stream->sd->max_wire_version >= WIRE_VERSION_KILLCURSORS_CMD) {
_mongoc_client_killcursors_command (
&client->cluster, server_stream, cursor_id, db, collection, cs);
} else {
_mongoc_client_op_killcursors (&client->cluster,
server_stream,
cursor_id,
operation_id,
db,
collection);
}
mongoc_server_stream_cleanup (server_stream);
EXIT;
}
static void
_mongoc_client_monitor_op_killcursors (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection)
{
bson_t doc;
mongoc_client_t *client;
mongoc_apm_command_started_t event;
ENTRY;
client = cluster->client;
if (!client->apm_callbacks.started) {
return;
}
bson_init (&doc);
_mongoc_client_prepare_killcursors_command (cursor_id, collection, &doc);
mongoc_apm_command_started_init (&event,
&doc,
db,
"killCursors",
cluster->request_id,
operation_id,
&server_stream->sd->host,
server_stream->sd->id,
client->apm_context);
client->apm_callbacks.started (&event);
mongoc_apm_command_started_cleanup (&event);
bson_destroy (&doc);
EXIT;
}
static void
_mongoc_client_monitor_op_killcursors_succeeded (
mongoc_cluster_t *cluster,
int64_t duration,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
int64_t operation_id)
{
mongoc_client_t *client;
bson_t doc;
bson_t cursors_unknown;
mongoc_apm_command_succeeded_t event;
ENTRY;
client = cluster->client;
if (!client->apm_callbacks.succeeded) {
EXIT;
}
/* fake server reply to killCursors command: {ok: 1, cursorsUnknown: [42]} */
bson_init (&doc);
bson_append_int32 (&doc, "ok", 2, 1);
bson_append_array_begin (&doc, "cursorsUnknown", 14, &cursors_unknown);
bson_append_int64 (&cursors_unknown, "0", 1, cursor_id);
bson_append_array_end (&doc, &cursors_unknown);
mongoc_apm_command_succeeded_init (&event,
duration,
&doc,
"killCursors",
cluster->request_id,
operation_id,
&server_stream->sd->host,
server_stream->sd->id,
client->apm_context);
client->apm_callbacks.succeeded (&event);
mongoc_apm_command_succeeded_cleanup (&event);
bson_destroy (&doc);
}
static void
_mongoc_client_monitor_op_killcursors_failed (
mongoc_cluster_t *cluster,
int64_t duration,
mongoc_server_stream_t *server_stream,
const bson_error_t *error,
int64_t operation_id)
{
mongoc_client_t *client;
bson_t doc;
mongoc_apm_command_failed_t event;
ENTRY;
client = cluster->client;
if (!client->apm_callbacks.failed) {
EXIT;
}
/* fake server reply to killCursors command: {ok: 0} */
bson_init (&doc);
bson_append_int32 (&doc, "ok", 2, 0);
mongoc_apm_command_failed_init (&event,
duration,
"killCursors",
error,
&doc,
cluster->request_id,
operation_id,
&server_stream->sd->host,
server_stream->sd->id,
client->apm_context);
client->apm_callbacks.failed (&event);
mongoc_apm_command_failed_cleanup (&event);
bson_destroy (&doc);
}
static void
_mongoc_client_op_killcursors (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection)
{
int64_t started;
mongoc_rpc_t rpc = {{0}};
bson_error_t error;
bool has_ns;
bool r;
/* called by old mongoc_client_kill_cursor without db/collection? */
has_ns = (db && collection);
started = bson_get_monotonic_time ();
++cluster->request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = cluster->request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_KILL_CURSORS;
rpc.kill_cursors.zero = 0;
rpc.kill_cursors.cursors = &cursor_id;
rpc.kill_cursors.n_cursors = 1;
if (has_ns) {
_mongoc_client_monitor_op_killcursors (
cluster, server_stream, cursor_id, operation_id, db, collection);
}
r = mongoc_cluster_legacy_rpc_sendv_to_server (
cluster, &rpc, server_stream, &error);
if (has_ns) {
if (r) {
_mongoc_client_monitor_op_killcursors_succeeded (
cluster,
bson_get_monotonic_time () - started,
server_stream,
cursor_id,
operation_id);
} else {
_mongoc_client_monitor_op_killcursors_failed (
cluster,
bson_get_monotonic_time () - started,
server_stream,
&error,
operation_id);
}
}
}
static void
_mongoc_client_killcursors_command (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
const char *db,
const char *collection,
mongoc_client_session_t *cs)
{
bson_t command = BSON_INITIALIZER;
mongoc_cmd_parts_t parts;
ENTRY;
_mongoc_client_prepare_killcursors_command (cursor_id, collection, &command);
mongoc_cmd_parts_init (
&parts, cluster->client, db, MONGOC_QUERY_SLAVE_OK, &command);
parts.assembled.operation_id = ++cluster->operation_id;
mongoc_cmd_parts_set_session (&parts, cs);
if (mongoc_cmd_parts_assemble (&parts, server_stream, NULL)) {
/* Find, getMore And killCursors Commands Spec: "The result from the
* killCursors command MAY be safely ignored."
*/
(void) mongoc_cluster_run_command_monitored (
cluster, &parts.assembled, NULL, NULL);
}
mongoc_cmd_parts_cleanup (&parts);
bson_destroy (&command);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_kill_cursor --
*
* Destroy a cursor on the server.
*
* NOTE: this is only reliable when connected to a single mongod or
* mongos. If connected to a replica set, the driver attempts to
* kill the cursor on the primary. If connected to multiple mongoses
* the kill-cursors message is sent to a *random* mongos.
*
* If no primary, mongos, or standalone server is known, return
* without attempting to reconnect.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id)
{
mongoc_topology_t *topology;
mongoc_server_description_t *selected_server;
mongoc_read_prefs_t *read_prefs;
bson_error_t error;
uint32_t server_id = 0;
topology = client->topology;
read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
bson_mutex_lock (&topology->mutex);
if (!mongoc_topology_compatible (&topology->description, NULL, &error)) {
MONGOC_ERROR ("Could not kill cursor: %s", error.message);
bson_mutex_unlock (&topology->mutex);
mongoc_read_prefs_destroy (read_prefs);
return;
}
/* see if there's a known writable server - do no I/O or retries */
selected_server =
mongoc_topology_description_select (&topology->description,
MONGOC_SS_WRITE,
read_prefs,
topology->local_threshold_msec);
if (selected_server) {
server_id = selected_server->id;
}
bson_mutex_unlock (&topology->mutex);
if (server_id) {
_mongoc_client_kill_cursor (client,
server_id,
cursor_id,
0 /* operation_id */,
NULL /* db */,
NULL /* collection */,
NULL /* session */);
} else {
MONGOC_INFO ("No server available for mongoc_client_kill_cursor");
}
mongoc_read_prefs_destroy (read_prefs);
}
char **
mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error)
{
return mongoc_client_get_database_names_with_opts (client, NULL, error);
}
char **
mongoc_client_get_database_names_with_opts (mongoc_client_t *client,
const bson_t *opts,
bson_error_t *error)
{
bson_iter_t iter;
const char *name;
char **ret = NULL;
int i = 0;
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t cmd = BSON_INITIALIZER;
BSON_ASSERT (client);
BSON_APPEND_INT32 (&cmd, "listDatabases", 1);
BSON_APPEND_BOOL (&cmd, "nameOnly", true);
/* ignore client read prefs */
cursor = _mongoc_cursor_array_new (client, "admin", &cmd, opts, "databases");
bson_destroy (&cmd);
while (mongoc_cursor_next (cursor, &doc)) {
if (bson_iter_init (&iter, doc) && bson_iter_find (&iter, "name") &&
BSON_ITER_HOLDS_UTF8 (&iter) &&
(name = bson_iter_utf8 (&iter, NULL))) {
ret = (char **) bson_realloc (ret, sizeof (char *) * (i + 2));
ret[i] = bson_strdup (name);
ret[++i] = NULL;
}
}
if (!ret && !mongoc_cursor_error (cursor, error)) {
ret = (char **) bson_malloc0 (sizeof (void *));
}
mongoc_cursor_destroy (cursor);
return ret;
}
mongoc_cursor_t *
mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error)
{
/* existing bug in this deprecated API: error pointer is unused */
return mongoc_client_find_databases_with_opts (client, NULL);
}
mongoc_cursor_t *
mongoc_client_find_databases_with_opts (mongoc_client_t *client,
const bson_t *opts)
{
bson_t cmd = BSON_INITIALIZER;
mongoc_cursor_t *cursor;
BSON_ASSERT (client);
BSON_APPEND_INT32 (&cmd, "listDatabases", 1);
cursor = _mongoc_cursor_array_new (client, "admin", &cmd, opts, "databases");
bson_destroy (&cmd);
return cursor;
}
int32_t
mongoc_client_get_max_message_size (mongoc_client_t *client) /* IN */
{
BSON_ASSERT (client);
return mongoc_cluster_get_max_msg_size (&client->cluster);
}
int32_t
mongoc_client_get_max_bson_size (mongoc_client_t *client) /* IN */
{
BSON_ASSERT (client);
return mongoc_cluster_get_max_bson_obj_size (&client->cluster);
}
bool
mongoc_client_get_server_status (mongoc_client_t *client, /* IN */
mongoc_read_prefs_t *read_prefs, /* IN */
bson_t *reply, /* OUT */
bson_error_t *error) /* OUT */
{
bson_t cmd = BSON_INITIALIZER;
bool ret = false;
BSON_ASSERT (client);
BSON_APPEND_INT32 (&cmd, "serverStatus", 1);
ret = mongoc_client_command_simple (
client, "admin", &cmd, read_prefs, reply, error);
bson_destroy (&cmd);
return ret;
}
void
mongoc_client_set_stream_initiator (mongoc_client_t *client,
mongoc_stream_initiator_t initiator,
void *user_data)
{
BSON_ASSERT (client);
if (!initiator) {
initiator = mongoc_client_default_stream_initiator;
user_data = client;
} else {
MONGOC_DEBUG ("Using custom stream initiator.");
}
client->initiator = initiator;
client->initiator_data = user_data;
if (client->topology->single_threaded) {
mongoc_topology_scanner_set_stream_initiator (
client->topology->scanner, initiator, user_data);
}
}
bool
_mongoc_client_set_apm_callbacks_private (mongoc_client_t *client,
mongoc_apm_callbacks_t *callbacks,
void *context)
{
if (callbacks) {
memcpy (
&client->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t));
} else {
memset (&client->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t));
}
client->apm_context = context;
- mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
+
+ /* A client pool sets APM callbacks for the entire pool. */
+ if (client->topology->single_threaded) {
+ mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
+ }
return true;
}
bool
mongoc_client_set_apm_callbacks (mongoc_client_t *client,
mongoc_apm_callbacks_t *callbacks,
void *context)
{
if (!client->topology->single_threaded) {
MONGOC_ERROR ("Cannot set callbacks on a pooled client, use "
"mongoc_client_pool_set_apm_callbacks");
return false;
}
return _mongoc_client_set_apm_callbacks_private (client, callbacks, context);
}
mongoc_server_description_t *
mongoc_client_get_server_description (mongoc_client_t *client,
uint32_t server_id)
{
/* the error info isn't useful */
return mongoc_topology_server_by_id (client->topology, server_id, NULL);
}
mongoc_server_description_t **
mongoc_client_get_server_descriptions (const mongoc_client_t *client,
size_t *n /* OUT */)
{
mongoc_topology_t *topology;
mongoc_server_description_t **sds;
BSON_ASSERT (client);
BSON_ASSERT (n);
topology = client->topology;
/* in case the client is pooled */
bson_mutex_lock (&topology->mutex);
sds = mongoc_topology_description_get_servers (&topology->description, n);
bson_mutex_unlock (&topology->mutex);
return sds;
}
void
mongoc_server_descriptions_destroy_all (mongoc_server_description_t **sds,
size_t n)
{
size_t i;
for (i = 0; i < n; ++i) {
mongoc_server_description_destroy (sds[i]);
}
bson_free (sds);
}
mongoc_server_description_t *
mongoc_client_select_server (mongoc_client_t *client,
bool for_writes,
const mongoc_read_prefs_t *prefs,
bson_error_t *error)
{
mongoc_ss_optype_t optype = for_writes ? MONGOC_SS_WRITE : MONGOC_SS_READ;
mongoc_server_description_t *sd;
if (for_writes && prefs) {
bson_set_error (error,
MONGOC_ERROR_SERVER_SELECTION,
MONGOC_ERROR_SERVER_SELECTION_FAILURE,
"Cannot use read preferences with for_writes = true");
return NULL;
}
if (!_mongoc_read_prefs_validate (prefs, error)) {
return NULL;
}
sd = mongoc_topology_select (client->topology, optype, prefs, error);
if (!sd) {
return NULL;
}
if (mongoc_cluster_check_interval (&client->cluster, sd->id)) {
/* check not required, or it succeeded */
return sd;
}
/* check failed, retry once */
mongoc_server_description_destroy (sd);
sd = mongoc_topology_select (client->topology, optype, prefs, error);
if (sd) {
return sd;
}
return NULL;
}
bool
mongoc_client_set_error_api (mongoc_client_t *client, int32_t version)
{
if (!client->topology->single_threaded) {
MONGOC_ERROR ("Cannot set Error API Version on a pooled client, use "
"mongoc_client_pool_set_error_api");
return false;
}
if (version != MONGOC_ERROR_API_VERSION_LEGACY &&
version != MONGOC_ERROR_API_VERSION_2) {
MONGOC_ERROR ("Unsupported Error API Version: %" PRId32, version);
return false;
}
if (client->error_api_set) {
MONGOC_ERROR ("Can only set Error API Version once");
return false;
}
client->error_api_version = version;
client->error_api_set = true;
return true;
}
bool
mongoc_client_set_appname (mongoc_client_t *client, const char *appname)
{
if (!client->topology->single_threaded) {
MONGOC_ERROR ("Cannot call set_appname on a client from a pool");
return false;
}
return _mongoc_topology_set_appname (client->topology, appname);
}
mongoc_server_session_t *
_mongoc_client_pop_server_session (mongoc_client_t *client, bson_error_t *error)
{
return _mongoc_topology_pop_server_session (client->topology, error);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_lookup_session --
*
* Retrieve a mongoc_client_session_t associated with @client_session_id.
* Use this to find the "lsid" and "$clusterTime" to send in the server
* command.
*
* Returns:
* True on success, false on error and @error is set. Will return false
* if the session is from an outdated client generation, a holdover
* from before a call to mongoc_client_reset.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_lookup_session (const mongoc_client_t *client,
uint32_t client_session_id,
mongoc_client_session_t **cs /* OUT */,
bson_error_t *error /* OUT */)
{
ENTRY;
*cs = mongoc_set_get (client->client_sessions, client_session_id);
if (*cs) {
RETURN (true);
}
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid sessionId");
RETURN (false);
}
void
_mongoc_client_unregister_session (mongoc_client_t *client,
mongoc_client_session_t *session)
{
mongoc_set_rm (client->client_sessions, session->client_session_id);
}
void
_mongoc_client_push_server_session (mongoc_client_t *client,
mongoc_server_session_t *server_session)
{
_mongoc_topology_push_server_session (client->topology, server_session);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_end_sessions --
*
* End all server sessions in the topology's server session pool.
* Don't block long: if server selection or connecting fails, quit.
*
* The server session pool becomes invalid, but may not be empty.
* Destroy the topology after this without using any sessions.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_client_end_sessions (mongoc_client_t *client)
{
mongoc_topology_t *t = client->topology;
mongoc_read_prefs_t *prefs;
bson_error_t error;
uint32_t server_id;
bson_t cmd;
mongoc_server_stream_t *stream;
mongoc_cmd_parts_t parts;
mongoc_cluster_t *cluster = &client->cluster;
bool r;
if (t->session_pool) {
prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED);
server_id =
mongoc_topology_select_server_id (t, MONGOC_SS_READ, prefs, &error);
mongoc_read_prefs_destroy (prefs);
if (!server_id) {
MONGOC_WARNING ("Couldn't send \"endSessions\": %s", error.message);
return;
}
stream = mongoc_cluster_stream_for_server (
cluster, server_id, false /* reconnect_ok */, NULL, NULL, &error);
if (!stream) {
MONGOC_WARNING ("Couldn't send \"endSessions\": %s", error.message);
return;
}
/* end sessions in chunks */
while (_mongoc_topology_end_sessions_cmd (t, &cmd)) {
mongoc_cmd_parts_init (
&parts, client, "admin", MONGOC_QUERY_SLAVE_OK, &cmd);
parts.assembled.operation_id = ++cluster->operation_id;
parts.prohibit_lsid = true;
r = mongoc_cmd_parts_assemble (&parts, stream, &error);
if (!r) {
MONGOC_WARNING ("Couldn't construct \"endSessions\" command: %s",
error.message);
} else {
r = mongoc_cluster_run_command_monitored (
cluster, &parts.assembled, NULL, &error);
if (!r) {
MONGOC_WARNING ("Couldn't send \"endSessions\": %s",
error.message);
}
}
- bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
+
+ if (!mongoc_cluster_stream_valid (cluster, stream)) {
+ /* The stream was invalidated as a result of a network error, so we
+ * stop sending commands. */
+ break;
+ }
+
+ bson_destroy (&cmd);
}
bson_destroy (&cmd);
mongoc_server_stream_cleanup (stream);
}
}
void
mongoc_client_reset (mongoc_client_t *client)
{
BSON_ASSERT (client);
client->generation++;
/* Client sessions are owned and destroyed by the user, but we keep
local pointers to them for reference. On reset, clear our local
set without destroying the sessions or calling endSessions.
client_sessions has no dtor, so it won't destroy its items.
Destroying the local cache of client sessions here ensures they
cannot be used by future operations--lookup for them will fail. */
mongoc_set_destroy (client->client_sessions);
client->client_sessions = mongoc_set_new (8, NULL, NULL);
/* Server sessions are owned by us, so we clear the pool on reset. */
_mongoc_topology_clear_session_pool (client->topology);
}
mongoc_change_stream_t *
mongoc_client_watch (mongoc_client_t *client,
const bson_t *pipeline,
const bson_t *opts)
{
return _mongoc_change_stream_new_from_client (client, pipeline, opts);
}
bool
mongoc_client_enable_auto_encryption (mongoc_client_t *client,
mongoc_auto_encryption_opts_t *opts,
bson_error_t *error)
{
if (!client->topology->single_threaded) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Cannot enable auto encryption on a pooled client, use "
"mongoc_client_pool_enable_auto_encryption");
return false;
}
return _mongoc_cse_client_enable_auto_encryption (client, opts, error);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h
index 4eb5d3eb..80404482 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h
@@ -1,273 +1,274 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CLIENT_H
#define MONGOC_CLIENT_H
#include <bson/bson.h>
#include "mongoc-apm.h"
#include "mongoc-client-side-encryption.h"
#include "mongoc-collection.h"
#include "mongoc-config.h"
#include "mongoc-cursor.h"
#include "mongoc-database.h"
#include "mongoc-gridfs.h"
#include "mongoc-index.h"
#include "mongoc-macros.h"
#include "mongoc-read-prefs.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-ssl.h"
#endif
#include "mongoc-stream.h"
#include "mongoc-uri.h"
#include "mongoc-write-concern.h"
#include "mongoc-read-concern.h"
#include "mongoc-server-description.h"
BSON_BEGIN_DECLS
-
+/* This define is part of our public API. But per MongoDB 4.4, there is no
+ * longer a size limit on collection names. */
#define MONGOC_NAMESPACE_MAX 128
#ifndef MONGOC_DEFAULT_CONNECTTIMEOUTMS
#define MONGOC_DEFAULT_CONNECTTIMEOUTMS (10 * 1000L)
#endif
#ifndef MONGOC_DEFAULT_SOCKETTIMEOUTMS
/*
* NOTE: The default socket timeout for connections is 5 minutes. This
* means that if your MongoDB server dies or becomes unavailable
* it will take 5 minutes to detect this.
*
* You can change this by providing sockettimeoutms= in your
* connection URI.
*/
#define MONGOC_DEFAULT_SOCKETTIMEOUTMS (1000L * 60L * 5L)
#endif
/**
* mongoc_client_t:
*
* The mongoc_client_t structure maintains information about a connection to
* a MongoDB server.
*/
typedef struct _mongoc_client_t mongoc_client_t;
typedef struct _mongoc_client_session_t mongoc_client_session_t;
typedef struct _mongoc_session_opt_t mongoc_session_opt_t;
typedef struct _mongoc_transaction_opt_t mongoc_transaction_opt_t;
/**
* mongoc_stream_initiator_t:
* @uri: The uri and options for the stream.
* @host: The host and port (or UNIX domain socket path) to connect to.
* @user_data: The pointer passed to mongoc_client_set_stream_initiator.
* @error: A location for an error.
*
* Creates a new mongoc_stream_t for the host and port. Begin a
* non-blocking connect and return immediately.
*
* This can be used by language bindings to create network transports other
* than those built into libmongoc. An example of such would be the streams
* API provided by PHP.
*
* Returns: A newly allocated mongoc_stream_t or NULL on failure.
*/
typedef mongoc_stream_t *(*mongoc_stream_initiator_t) (
const mongoc_uri_t *uri,
const mongoc_host_list_t *host,
void *user_data,
bson_error_t *error);
MONGOC_EXPORT (mongoc_client_t *)
mongoc_client_new (const char *uri_string);
MONGOC_EXPORT (mongoc_client_t *)
mongoc_client_new_from_uri (const mongoc_uri_t *uri);
MONGOC_EXPORT (const mongoc_uri_t *)
mongoc_client_get_uri (const mongoc_client_t *client);
MONGOC_EXPORT (void)
mongoc_client_set_stream_initiator (mongoc_client_t *client,
mongoc_stream_initiator_t initiator,
void *user_data);
MONGOC_EXPORT (mongoc_cursor_t *)
mongoc_client_command (mongoc_client_t *client,
const char *db_name,
mongoc_query_flags_t flags,
uint32_t skip,
uint32_t limit,
uint32_t batch_size,
const bson_t *query,
const bson_t *fields,
const mongoc_read_prefs_t *read_prefs);
MONGOC_EXPORT (void)
mongoc_client_kill_cursor (mongoc_client_t *client,
int64_t cursor_id) BSON_GNUC_DEPRECATED;
MONGOC_EXPORT (bool)
mongoc_client_command_simple (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error);
MONGOC_EXPORT (bool)
mongoc_client_read_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error);
MONGOC_EXPORT (bool)
mongoc_client_write_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bson_error_t *error);
MONGOC_EXPORT (bool)
mongoc_client_read_write_command_with_opts (
mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs /* IGNORED */,
const bson_t *opts,
bson_t *reply,
bson_error_t *error);
MONGOC_EXPORT (bool)
mongoc_client_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error);
MONGOC_EXPORT (bool)
mongoc_client_command_simple_with_server_id (
mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
uint32_t server_id,
bson_t *reply,
bson_error_t *error);
MONGOC_EXPORT (void)
mongoc_client_destroy (mongoc_client_t *client);
MONGOC_EXPORT (mongoc_client_session_t *)
mongoc_client_start_session (mongoc_client_t *client,
const mongoc_session_opt_t *opts,
bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (mongoc_database_t *)
mongoc_client_get_database (mongoc_client_t *client, const char *name);
MONGOC_EXPORT (mongoc_database_t *)
mongoc_client_get_default_database (mongoc_client_t *client);
MONGOC_EXPORT (mongoc_gridfs_t *)
mongoc_client_get_gridfs (mongoc_client_t *client,
const char *db,
const char *prefix,
bson_error_t *error);
MONGOC_EXPORT (mongoc_collection_t *)
mongoc_client_get_collection (mongoc_client_t *client,
const char *db,
const char *collection);
MONGOC_EXPORT (char **)
mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error)
BSON_GNUC_DEPRECATED_FOR (mongoc_client_get_database_names_with_opts);
MONGOC_EXPORT (char **)
mongoc_client_get_database_names_with_opts (mongoc_client_t *client,
const bson_t *opts,
bson_error_t *error);
MONGOC_EXPORT (mongoc_cursor_t *)
mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error)
BSON_GNUC_DEPRECATED_FOR (mongoc_client_find_databases_with_opts);
MONGOC_EXPORT (mongoc_cursor_t *)
mongoc_client_find_databases_with_opts (mongoc_client_t *client,
const bson_t *opts);
MONGOC_EXPORT (bool)
mongoc_client_get_server_status (mongoc_client_t *client,
mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error) BSON_GNUC_DEPRECATED;
MONGOC_EXPORT (int32_t)
mongoc_client_get_max_message_size (mongoc_client_t *client)
BSON_GNUC_DEPRECATED;
MONGOC_EXPORT (int32_t)
mongoc_client_get_max_bson_size (mongoc_client_t *client) BSON_GNUC_DEPRECATED;
MONGOC_EXPORT (const mongoc_write_concern_t *)
mongoc_client_get_write_concern (const mongoc_client_t *client);
MONGOC_EXPORT (void)
mongoc_client_set_write_concern (mongoc_client_t *client,
const mongoc_write_concern_t *write_concern);
MONGOC_EXPORT (const mongoc_read_concern_t *)
mongoc_client_get_read_concern (const mongoc_client_t *client);
MONGOC_EXPORT (void)
mongoc_client_set_read_concern (mongoc_client_t *client,
const mongoc_read_concern_t *read_concern);
MONGOC_EXPORT (const mongoc_read_prefs_t *)
mongoc_client_get_read_prefs (const mongoc_client_t *client);
MONGOC_EXPORT (void)
mongoc_client_set_read_prefs (mongoc_client_t *client,
const mongoc_read_prefs_t *read_prefs);
#ifdef MONGOC_ENABLE_SSL
MONGOC_EXPORT (void)
mongoc_client_set_ssl_opts (mongoc_client_t *client,
const mongoc_ssl_opt_t *opts);
#endif
MONGOC_EXPORT (bool)
mongoc_client_set_apm_callbacks (mongoc_client_t *client,
mongoc_apm_callbacks_t *callbacks,
void *context);
MONGOC_EXPORT (mongoc_server_description_t *)
mongoc_client_get_server_description (mongoc_client_t *client,
uint32_t server_id);
MONGOC_EXPORT (mongoc_server_description_t **)
mongoc_client_get_server_descriptions (const mongoc_client_t *client,
size_t *n);
MONGOC_EXPORT (void)
mongoc_server_descriptions_destroy_all (mongoc_server_description_t **sds,
size_t n);
MONGOC_EXPORT (mongoc_server_description_t *)
mongoc_client_select_server (mongoc_client_t *client,
bool for_writes,
const mongoc_read_prefs_t *prefs,
bson_error_t *error);
MONGOC_EXPORT (bool)
mongoc_client_set_error_api (mongoc_client_t *client, int32_t version);
MONGOC_EXPORT (bool)
mongoc_client_set_appname (mongoc_client_t *client, const char *appname);
MONGOC_EXPORT (mongoc_change_stream_t *)
mongoc_client_watch (mongoc_client_t *client,
const bson_t *pipeline,
const bson_t *opts);
MONGOC_EXPORT (void)
mongoc_client_reset (mongoc_client_t *client);
MONGOC_EXPORT (bool)
mongoc_client_enable_auto_encryption (mongoc_client_t *client,
mongoc_auto_encryption_opts_t *opts,
bson_error_t *error);
BSON_END_DECLS
#endif /* MONGOC_CLIENT_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h
new file mode 100644
index 00000000..3b49cb0e
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "mongoc-prelude.h"
+
+#ifndef MONGOC_CLUSTER_AWS_PRIVATE_H
+#define MONGOC_CLUSTER_AWS_PRIVATE_H
+
+#include "bson/bson.h"
+#include "mongoc/mongoc-cluster-private.h"
+
+bool
+_mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ mongoc_server_description_t *sd,
+ bson_error_t *error);
+
+/* The following are declared in the private header for testing. It is only used
+ * in test-mongoc-aws.c and mongoc-cluster.aws.c */
+typedef struct {
+ char *access_key_id;
+ char *secret_access_key;
+ char *session_token;
+} _mongoc_aws_credentials_t;
+
+bool
+_mongoc_aws_credentials_obtain (mongoc_uri_t *uri,
+ _mongoc_aws_credentials_t *creds,
+ bson_error_t *error);
+
+void
+_mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds);
+
+bool
+_mongoc_validate_and_derive_region (char *sts_fqdn,
+ uint32_t sts_fqdn_len,
+ char **region,
+ bson_error_t *error);
+
+#endif /* MONGOC_CLUSTER_AWS_PRIVATE_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c
new file mode 100644
index 00000000..ab2c0373
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c
@@ -0,0 +1,1021 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+/* All interaction with kms_message is limited to this file. */
+
+#include "common-b64-private.h"
+#include "mongoc-cluster-aws-private.h"
+#include "mongoc-client-private.h"
+#include "mongoc-host-list-private.h"
+#include "mongoc-rand-private.h"
+#include "mongoc-stream-private.h"
+#include "mongoc-trace-private.h"
+#include "mongoc-uri-private.h"
+#include "mongoc-util-private.h"
+#include "mongoc-http-private.h"
+
+#undef MONGOC_LOG_DOMAIN
+#define MONGOC_LOG_DOMAIN "aws_auth"
+
+#define AUTH_ERROR_AND_FAIL(...) \
+ do { \
+ bson_set_error (error, \
+ MONGOC_ERROR_CLIENT, \
+ MONGOC_ERROR_CLIENT_AUTHENTICATE, \
+ __VA_ARGS__); \
+ goto fail; \
+ } while (0)
+
+
+#ifdef MONGOC_ENABLE_MONGODB_AWS_AUTH
+#include "kms_message/kms_message.h"
+
+/*
+ * Run a single command on a stream.
+ *
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * reply is always initialized.
+ */
+static bool
+_run_command (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ mongoc_server_description_t *sd,
+ bson_t *command,
+ bson_t *reply,
+ bson_error_t *error)
+{
+ mongoc_cmd_parts_t parts;
+ mongoc_server_stream_t *server_stream;
+ bool ret;
+
+ mongoc_cmd_parts_init (&parts,
+ cluster->client,
+ "$external",
+ MONGOC_QUERY_NONE /* unused for OP_MSG */,
+ command);
+ /* Drivers must not append session ids to auth commands per sessions spec. */
+ parts.prohibit_lsid = true;
+ server_stream = _mongoc_cluster_create_server_stream (
+ cluster->client->topology, sd->id, stream, error);
+ if (!server_stream) {
+ /* error was set by mongoc_topology_description_server_by_id */
+ bson_init (reply);
+ return false;
+ }
+ ret = mongoc_cluster_run_command_parts (
+ cluster, server_stream, &parts, reply, error);
+ mongoc_server_stream_cleanup (server_stream);
+ return ret;
+}
+
+/*
+ * Utility function to parse out a server reply's payload.
+ *
+ * Given a server reply like { ok: 1, payload: <BSON data>, ... } parse out the
+ * payload into a bson_t.
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * payload is always initialized.
+ */
+static bool
+_sasl_reply_parse_payload_as_bson (const bson_t *reply,
+ bson_t *payload,
+ bson_error_t *error)
+{
+ bson_iter_t iter;
+ bson_subtype_t payload_subtype;
+ const uint8_t *payload_data;
+ uint32_t payload_len;
+ bool ret = false;
+
+ bson_init (payload);
+
+ if (!bson_iter_init_find (&iter, reply, "payload") ||
+ !BSON_ITER_HOLDS_BINARY (&iter)) {
+ AUTH_ERROR_AND_FAIL ("server reply did not contain binary payload");
+ }
+
+ bson_iter_binary (&iter, &payload_subtype, &payload_len, &payload_data);
+
+ if (payload_subtype != BSON_SUBTYPE_BINARY) {
+ AUTH_ERROR_AND_FAIL ("server reply contained unexpected binary subtype");
+ }
+
+ bson_destroy (payload);
+ if (!bson_init_static (payload, payload_data, payload_len)) {
+ AUTH_ERROR_AND_FAIL ("server payload is invalid BSON");
+ }
+
+ ret = true;
+fail:
+ return ret;
+}
+
+
+/*
+ * Send an HTTP request and get a response.
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * headers is a \r\n delimitted list of headers (or an empty string).
+ * http_response_body is always set, and must be freed.
+ * http_response_headers is always set, and must be freed. This may be used for
+ * error reporting since the response headers should not include sensitive
+ * credentials.
+ */
+static bool
+_send_http_request (const char *ip,
+ int port,
+ const char *method,
+ const char *path,
+ const char *headers,
+ char **http_response_body,
+ char **http_response_headers,
+ bson_error_t *error)
+{
+ mongoc_http_request_t req;
+ mongoc_http_response_t res;
+ const int socket_timeout_ms = 10000;
+ bool ret;
+
+ *http_response_body = NULL;
+ *http_response_headers = NULL;
+ _mongoc_http_request_init (&req);
+ _mongoc_http_response_init (&res);
+
+ req.host = ip;
+ req.port = port;
+ req.method = method;
+ req.path = path;
+ req.extra_headers = headers;
+ ret = _mongoc_http_send (&req,
+ socket_timeout_ms,
+ false /* use_tls */,
+ NULL /* ssl_opts */,
+ &res,
+ error);
+
+ if (ret) {
+ *http_response_headers = bson_strndup (res.headers, res.headers_len);
+ *http_response_body = (char *) bson_malloc0 (res.body_len + 1);
+ memcpy (*http_response_body, res.body, res.body_len);
+ }
+
+ _mongoc_http_response_cleanup (&res);
+ return ret;
+}
+
+
+static bool
+_creds_empty (_mongoc_aws_credentials_t *creds)
+{
+ return creds->access_key_id == NULL && creds->secret_access_key == NULL &&
+ creds->session_token == NULL;
+}
+
+/*
+ * Helper to validate and possibly set credentials.
+ *
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * Caller should use _creds_empty to determine whether credentials have been
+ * set.
+ */
+static bool
+_validate_and_set_creds (const char *access_key_id,
+ const char *secret_access_key,
+ const char *session_token,
+ _mongoc_aws_credentials_t *creds,
+ bson_error_t *error)
+{
+ bool has_access_key_id = access_key_id && strlen (access_key_id) != 0;
+ bool has_secret_access_key =
+ secret_access_key && strlen (secret_access_key) != 0;
+ bool has_session_token = session_token && strlen (session_token) != 0;
+ bool ret = false;
+
+ /* Check for invalid combinations of URI parameters. */
+ if (has_access_key_id && !has_secret_access_key) {
+ AUTH_ERROR_AND_FAIL (
+ "ACCESS_KEY_ID is set, but SECRET_ACCESS_KEY is missing");
+ }
+
+ if (!has_access_key_id && has_secret_access_key) {
+ AUTH_ERROR_AND_FAIL (
+ "SECRET_ACCESS_KEY is set, but ACCESS_KEY_ID is missing");
+ }
+
+ if (!has_access_key_id && !has_secret_access_key && has_session_token) {
+ AUTH_ERROR_AND_FAIL ("AWS_SESSION_TOKEN is set, but ACCESS_KEY_ID and "
+ "SECRET_ACCESS_KEY are missing");
+ }
+
+ creds->access_key_id = bson_strdup (access_key_id);
+ creds->secret_access_key = bson_strdup (secret_access_key);
+ creds->session_token = session_token ? bson_strdup (session_token) : NULL;
+
+ ret = true;
+fail:
+ return ret;
+}
+
+/*
+ * Validate and possibly set credentials.
+ *
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * Caller should use _creds_empty to determine whether credentials have been
+ * set.
+ */
+static bool
+_obtain_creds_from_uri (_mongoc_aws_credentials_t *creds,
+ mongoc_uri_t *uri,
+ bson_error_t *error)
+{
+ bool ret = false;
+ bson_t auth_mechanism_props;
+ const char *uri_session_token = NULL;
+
+ if (mongoc_uri_get_mechanism_properties (uri, &auth_mechanism_props)) {
+ bson_iter_t iter;
+ if (bson_iter_init_find_case (
+ &iter, &auth_mechanism_props, "AWS_SESSION_TOKEN") &&
+ BSON_ITER_HOLDS_UTF8 (&iter)) {
+ uri_session_token = bson_iter_utf8 (&iter, NULL);
+ }
+ }
+
+ if (!_validate_and_set_creds (mongoc_uri_get_username (uri),
+ mongoc_uri_get_password (uri),
+ uri_session_token,
+ creds,
+ error)) {
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ return ret;
+}
+
+static bool
+_obtain_creds_from_env (_mongoc_aws_credentials_t *creds, bson_error_t *error)
+{
+ bool ret = false;
+ char *env_access_key_id = NULL;
+ char *env_secret_access_key = NULL;
+ char *env_session_token = NULL;
+
+ /* Check environment variables. */
+ env_access_key_id = _mongoc_getenv ("AWS_ACCESS_KEY_ID");
+ env_secret_access_key = _mongoc_getenv ("AWS_SECRET_ACCESS_KEY");
+ env_session_token = _mongoc_getenv ("AWS_SESSION_TOKEN");
+
+ if (!_validate_and_set_creds (env_access_key_id,
+ env_secret_access_key,
+ env_session_token,
+ creds,
+ error)) {
+ goto fail;
+ }
+ ret = true;
+fail:
+ bson_free (env_access_key_id);
+ bson_free (env_secret_access_key);
+ bson_free (env_session_token);
+ return ret;
+}
+
+static bool
+_obtain_creds_from_ecs (_mongoc_aws_credentials_t *creds, bson_error_t *error)
+{
+ bool ret = false;
+ char *http_response_headers = NULL;
+ char *http_response_body = NULL;
+ char *relative_ecs_uri = NULL;
+ bson_t *response_json = NULL;
+ bson_iter_t iter;
+ const char *ecs_access_key_id = NULL;
+ const char *ecs_secret_access_key = NULL;
+ const char *ecs_session_token = NULL;
+ bson_error_t http_error;
+
+ relative_ecs_uri = _mongoc_getenv ("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI");
+ if (!relative_ecs_uri || strlen (relative_ecs_uri) == 0) {
+ bson_free (relative_ecs_uri);
+ return true;
+ }
+
+ if (!_send_http_request ("169.254.170.2",
+ 80,
+ "GET",
+ relative_ecs_uri,
+ "",
+ &http_response_body,
+ &http_response_headers,
+ &http_error)) {
+ AUTH_ERROR_AND_FAIL ("failed to contact ECS link local server: %s",
+ http_error.message);
+ }
+
+ response_json = bson_new_from_json (
+ (const uint8_t *) http_response_body, strlen (http_response_body), error);
+ if (!response_json) {
+ AUTH_ERROR_AND_FAIL ("invalid JSON in ECS response. Response headers: %s",
+ http_response_headers);
+ }
+
+ if (bson_iter_init_find_case (&iter, response_json, "AccessKeyId") &&
+ BSON_ITER_HOLDS_UTF8 (&iter)) {
+ ecs_access_key_id = bson_iter_utf8 (&iter, NULL);
+ }
+
+ if (bson_iter_init_find_case (&iter, response_json, "SecretAccessKey") &&
+ BSON_ITER_HOLDS_UTF8 (&iter)) {
+ ecs_secret_access_key = bson_iter_utf8 (&iter, NULL);
+ }
+
+ if (bson_iter_init_find_case (&iter, response_json, "Token") &&
+ BSON_ITER_HOLDS_UTF8 (&iter)) {
+ ecs_session_token = bson_iter_utf8 (&iter, NULL);
+ }
+
+ if (!_validate_and_set_creds (ecs_access_key_id,
+ ecs_secret_access_key,
+ ecs_session_token,
+ creds,
+ error)) {
+ goto fail;
+ }
+
+
+ ret = true;
+fail:
+ bson_destroy (response_json);
+ bson_free (http_response_headers);
+ bson_free (http_response_body);
+ bson_free (relative_ecs_uri);
+ return ret;
+}
+
+static bool
+_obtain_creds_from_ec2 (_mongoc_aws_credentials_t *creds, bson_error_t *error)
+{
+ bool ret = false;
+ char *http_response_headers = NULL;
+ char *http_response_body = NULL;
+ char *token_header = NULL;
+ char *token = NULL;
+ char *role_name = NULL;
+ char *relative_ecs_uri = NULL;
+ char *path_with_role = NULL;
+ bson_t *response_json = NULL;
+ bson_iter_t iter;
+ const char *ec2_access_key_id = NULL;
+ const char *ec2_secret_access_key = NULL;
+ const char *ec2_session_token = NULL;
+ bson_error_t http_error;
+ const char *ip = "169.254.169.254";
+
+ /* Get the token. */
+ if (!_send_http_request (ip,
+ 80,
+ "PUT",
+ "/latest/api/token",
+ "X-aws-ec2-metadata-token-ttl-seconds: 30\r\n",
+ &token,
+ &http_response_headers,
+ &http_error)) {
+ AUTH_ERROR_AND_FAIL ("failed to contact EC2 link local server: %s",
+ http_error.message);
+ }
+
+ if (0 == strlen (token)) {
+ AUTH_ERROR_AND_FAIL (
+ "unable to retrieve token from EC2 metadata. Headers: %s",
+ http_response_headers);
+ }
+
+ bson_free (http_response_headers);
+ http_response_headers = NULL;
+ token_header =
+ bson_strdup_printf ("X-aws-ec2-metadata-token: %s\r\n", token);
+
+ /* Get the role name. */
+ if (!_send_http_request (ip,
+ 80,
+ "GET",
+ "/latest/meta-data/iam/security-credentials/",
+ token_header,
+ &role_name,
+ &http_response_headers,
+ &http_error)) {
+ AUTH_ERROR_AND_FAIL ("failed to contact EC2 link local server: %s",
+ http_error.message);
+ }
+
+ if (0 == strlen (role_name)) {
+ AUTH_ERROR_AND_FAIL (
+ "unable to retrieve role_name from EC2 metadata. Headers: %s",
+ http_response_headers);
+ }
+
+ /* Get the creds. */
+ path_with_role = bson_strdup_printf (
+ "/latest/meta-data/iam/security-credentials/%s", role_name);
+ bson_free (http_response_headers);
+ http_response_headers = NULL;
+ if (!_send_http_request (ip,
+ 80,
+ "GET",
+ path_with_role,
+ token_header,
+ &http_response_body,
+ &http_response_headers,
+ &http_error)) {
+ AUTH_ERROR_AND_FAIL ("failed to contact EC2 link local server: %s",
+ http_error.message);
+ }
+
+ response_json = bson_new_from_json (
+ (const uint8_t *) http_response_body, strlen (http_response_body), error);
+ if (!response_json) {
+ AUTH_ERROR_AND_FAIL ("invalid JSON in EC2 response. Response headers: %s",
+ http_response_headers);
+ }
+
+ if (bson_iter_init_find_case (&iter, response_json, "AccessKeyId") &&
+ BSON_ITER_HOLDS_UTF8 (&iter)) {
+ ec2_access_key_id = bson_iter_utf8 (&iter, NULL);
+ }
+
+ if (bson_iter_init_find_case (&iter, response_json, "SecretAccessKey") &&
+ BSON_ITER_HOLDS_UTF8 (&iter)) {
+ ec2_secret_access_key = bson_iter_utf8 (&iter, NULL);
+ }
+
+ if (bson_iter_init_find_case (&iter, response_json, "Token") &&
+ BSON_ITER_HOLDS_UTF8 (&iter)) {
+ ec2_session_token = bson_iter_utf8 (&iter, NULL);
+ }
+
+ if (!_validate_and_set_creds (ec2_access_key_id,
+ ec2_secret_access_key,
+ ec2_session_token,
+ creds,
+ error)) {
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ bson_destroy (response_json);
+ bson_free (http_response_headers);
+ bson_free (http_response_body);
+ bson_free (token);
+ bson_free (role_name);
+ bson_free (token_header);
+ bson_free (relative_ecs_uri);
+ bson_free (path_with_role);
+ return ret;
+}
+
+/*
+ * Attempt to obtain AWS credentials.
+ *
+ * Credentials may be passed in multiple ways. The precedence is as follows:
+ * 1. Username/password in the URI (and authMechanismProperty for session token)
+ * 2. From environment variables.
+ * 3. From querying the ECS local HTTP server.
+ * 4. From querying the EC2 local HTTP server.
+ *
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ */
+bool
+_mongoc_aws_credentials_obtain (mongoc_uri_t *uri,
+ _mongoc_aws_credentials_t *creds,
+ bson_error_t *error)
+{
+ bool ret = false;
+
+ creds->access_key_id = NULL;
+ creds->secret_access_key = NULL;
+ creds->session_token = NULL;
+
+ TRACE ("%s", "checking URI for credentials");
+ if (!_obtain_creds_from_uri (creds, uri, error)) {
+ goto fail;
+ }
+ if (!_creds_empty (creds)) {
+ goto succeed;
+ }
+
+ TRACE ("%s", "checking environment variables for credentials");
+ if (!_obtain_creds_from_env (creds, error)) {
+ goto fail;
+ }
+ if (!_creds_empty (creds)) {
+ goto succeed;
+ }
+
+ TRACE ("%s", "checking ECS metadata for credentials");
+ if (!_obtain_creds_from_ecs (creds, error)) {
+ goto fail;
+ }
+ if (!_creds_empty (creds)) {
+ goto succeed;
+ }
+
+ TRACE ("%s", "checking EC2 metadata for credentials");
+ if (!_obtain_creds_from_ec2 (creds, error)) {
+ goto fail;
+ }
+ if (!_creds_empty (creds)) {
+ goto succeed;
+ }
+
+ AUTH_ERROR_AND_FAIL ("unable to get credentials\n");
+
+succeed:
+ ret = true;
+fail:
+ return ret;
+}
+
+void
+_mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds)
+{
+ bson_free (creds->access_key_id);
+ bson_free (creds->secret_access_key);
+ bson_free (creds->session_token);
+}
+
+/*
+ * Validate the STS host returned by the server and derive the region.
+ *
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * region is always set and must be freed by caller.
+ */
+bool
+_mongoc_validate_and_derive_region (char *sts_fqdn,
+ uint32_t sts_fqdn_len,
+ char **region,
+ bson_error_t *error)
+{
+ bool ret = false;
+ char *ptr;
+ char *ptr_prev;
+ char *second_part = NULL;
+
+ /* Default to us-east-1. */
+ *region = bson_strdup ("us-east-1");
+
+ /* Drivers must also validate that the host is greater than 0 and less than
+ * or equal to 255 bytes per RFC 1035 */
+ if (sts_fqdn_len == 0) {
+ AUTH_ERROR_AND_FAIL ("invalid STS host: empty");
+ }
+
+ if (sts_fqdn_len > 255) {
+ AUTH_ERROR_AND_FAIL ("invalid STS host: too large");
+ }
+
+ /* If sts.amazonaws.com, then use default region. */
+ if (0 == bson_strcasecmp ("sts.amazonaws.com", sts_fqdn)) {
+ goto succeed;
+ }
+
+ /* Drivers MUST reject FQDN names with empty labels, e.g., "abc..def" */
+ ptr_prev = sts_fqdn;
+ ptr = strstr (sts_fqdn, ".");
+ if (ptr) {
+ second_part = ptr + 1;
+ }
+ if (0 == ptr - sts_fqdn) {
+ AUTH_ERROR_AND_FAIL ("invalid STS host: empty part");
+ }
+ while (ptr) {
+ if (1 == ptr - ptr_prev) {
+ AUTH_ERROR_AND_FAIL ("invalid STS host: empty part");
+ }
+ ptr_prev = ptr;
+ ptr = strstr (ptr + 1, ".");
+ }
+ if (strlen (ptr_prev + 1) == 0) {
+ AUTH_ERROR_AND_FAIL ("invalid STS host: empty part");
+ }
+
+ if (second_part) {
+ char *second_part_end;
+
+ second_part_end = strstr (second_part, ".");
+ bson_free (*region);
+ if (!second_part_end) {
+ *region = bson_strdup (second_part);
+ } else {
+ *region = bson_strndup (second_part, second_part_end - second_part);
+ }
+ }
+
+succeed:
+ ret = true;
+fail:
+ return ret;
+}
+
+/* --------------------------------------------------------------------------
+ * Step 1
+ * --------------------------------------------------------------------------
+ * Client sends BSON payload:
+ * {
+ * "r": <32 byte client nonce>,
+ * "p": 110
+ * }
+ * Server responds with BSON payload:
+ * {
+ * "s": <32 byte client nonce + 32 byte server nonce>,
+ * "h": <domain name of STS service>
+ * }
+ *
+ * Payloads are wrapped in SASL commands. The command a client sends is like:
+ * { "saslStart": 1, "mechanism": "MONGODB-AWS", "payload": <BSON payload> }
+ * And similar for server responses:
+ * { "ok": 1, "conversationId": 1, "done": false, "payload": <BSON payload> }
+ *
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * --------------------------------------------------------------------------
+ */
+static bool
+_client_first (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ mongoc_server_description_t *sd,
+ uint8_t *server_nonce,
+ char **sts_fqdn,
+ char **region,
+ int *conv_id,
+ bson_error_t *error)
+{
+ bool ret = false;
+ uint8_t client_nonce[32];
+ bson_t client_payload = BSON_INITIALIZER;
+ bson_t client_command = BSON_INITIALIZER;
+ bson_t server_payload = BSON_INITIALIZER;
+ bson_t server_reply = BSON_INITIALIZER;
+ bson_iter_t iter;
+ bson_subtype_t reply_nonce_subtype;
+ const uint8_t *reply_nonce_data;
+ uint32_t reply_nonce_len;
+ uint32_t sts_fqdn_len;
+
+ /* Reset out params. */
+ memset (server_nonce, 0, 32);
+ *sts_fqdn = NULL;
+ *region = NULL;
+ *conv_id = 0;
+
+#ifdef MONGOC_ENABLE_CRYPTO
+ /* Generate secure random nonce. */
+ if (!_mongoc_rand_bytes (client_nonce, 32)) {
+ AUTH_ERROR_AND_FAIL ("Could not generate client nonce");
+ }
+#else
+ AUTH_ERROR_AND_FAIL ("libmongoc requires a cryptography library (libcrypto, "
+ "Common Crypto, or cng) to support MONGODB-AWS");
+#endif
+
+ BCON_APPEND (&client_payload,
+ "r",
+ BCON_BIN (BSON_SUBTYPE_BINARY, client_nonce, 32),
+ "p",
+ BCON_INT32 (110));
+
+ BCON_APPEND (&client_command,
+ "saslStart",
+ BCON_INT32 (1),
+ "mechanism",
+ "MONGODB-AWS",
+ "payload",
+ BCON_BIN (BSON_SUBTYPE_BINARY,
+ bson_get_data (&client_payload),
+ client_payload.len));
+
+ bson_destroy (&server_reply);
+ if (!_run_command (
+ cluster, stream, sd, &client_command, &server_reply, error)) {
+ goto fail;
+ }
+
+ *conv_id = _mongoc_cluster_get_conversation_id (&server_reply);
+ if (!*conv_id) {
+ AUTH_ERROR_AND_FAIL ("server reply did not contain conversationId");
+ }
+
+ bson_destroy (&server_payload);
+ if (!_sasl_reply_parse_payload_as_bson (
+ &server_reply, &server_payload, error)) {
+ goto fail;
+ }
+
+ if (!bson_iter_init_find (&iter, &server_payload, "h") ||
+ !BSON_ITER_HOLDS_UTF8 (&iter)) {
+ AUTH_ERROR_AND_FAIL ("server payload did not contain string STS FQDN");
+ }
+ *sts_fqdn = bson_strdup (bson_iter_utf8 (&iter, &sts_fqdn_len));
+
+ if (!_mongoc_validate_and_derive_region (
+ *sts_fqdn, sts_fqdn_len, region, error)) {
+ goto fail;
+ }
+
+ if (!bson_iter_init_find (&iter, &server_payload, "s") ||
+ !BSON_ITER_HOLDS_BINARY (&iter)) {
+ AUTH_ERROR_AND_FAIL ("server payload did not contain nonce");
+ }
+
+ bson_iter_binary (
+ &iter, &reply_nonce_subtype, &reply_nonce_len, &reply_nonce_data);
+ if (reply_nonce_len != 64) {
+ AUTH_ERROR_AND_FAIL ("server reply nonce was not 64 bytes");
+ }
+
+ if (0 != memcmp (reply_nonce_data, client_nonce, 32)) {
+ AUTH_ERROR_AND_FAIL (
+ "server reply nonce prefix did not match client nonce");
+ }
+
+ /* Drivers MUST error on any additional fields */
+ bson_iter_init (&iter, &server_payload);
+ while (bson_iter_next (&iter)) {
+ const char *field;
+
+ field = bson_iter_key (&iter);
+ if (0 == strcmp (field, "h")) {
+ continue;
+ }
+ if (0 == strcmp (field, "s")) {
+ continue;
+ }
+ AUTH_ERROR_AND_FAIL ("unexpected field from server's reply: %s", field);
+ }
+
+ memcpy (server_nonce, reply_nonce_data, 64);
+
+ ret = true;
+fail:
+ bson_destroy (&client_payload);
+ bson_destroy (&client_command);
+ bson_destroy (&server_reply);
+ bson_destroy (&server_payload);
+ return ret;
+}
+
+#define KMS_REQUEST_ADD_HEADER(key, value) \
+ do { \
+ if (!kms_request_add_header_field (request, key, value)) { \
+ AUTH_ERROR_AND_FAIL ("Failed to add header '%s'", key); \
+ } \
+ } while (0)
+
+#define KMS_REQUEST_SET(fn, name, value) \
+ do { \
+ if (!fn (request, value)) { \
+ AUTH_ERROR_AND_FAIL ("Failed to set %s", name); \
+ } \
+ } while (0)
+
+/* --------------------------------------------------------------------------
+ * Step 2
+ * --------------------------------------------------------------------------
+ * Client sends BSON payload:
+ * {
+ * "a": <signed headers>,
+ * "d": <current date in UTC>
+ * "t": <optional security token>
+ * }
+ *
+ * Server responds with final result.
+ *
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * --------------------------------------------------------------------------
+ */
+static bool
+_client_second (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ mongoc_server_description_t *sd,
+ _mongoc_aws_credentials_t *creds,
+ const uint8_t *server_nonce,
+ const char *sts_fqdn,
+ const char *region,
+ int conv_id,
+ bson_error_t *error)
+{
+ bool ret = false;
+ kms_request_t *request = NULL;
+ char *signature = NULL;
+ const char *date = NULL;
+ const size_t server_nonce_str_len =
+ COMMON_PREFIX (bson_b64_ntop_calculate_target_size (64));
+ char *server_nonce_str = NULL;
+ const char *body = "Action=GetCallerIdentity&Version=2011-06-15";
+ bson_t client_payload = BSON_INITIALIZER;
+ bson_t client_command = BSON_INITIALIZER;
+ bson_t server_reply = BSON_INITIALIZER;
+
+ BSON_ASSERT (cluster);
+ BSON_ASSERT (stream);
+ BSON_ASSERT (sd);
+ BSON_ASSERT (creds);
+ BSON_ASSERT (server_nonce);
+ BSON_ASSERT (sts_fqdn);
+ BSON_ASSERT (conv_id);
+ BSON_ASSERT (creds->access_key_id);
+ BSON_ASSERT (creds->secret_access_key);
+
+ server_nonce_str = bson_malloc (server_nonce_str_len);
+
+ request = kms_request_new ("POST", "/", NULL);
+ if (kms_request_get_error (request)) {
+ AUTH_ERROR_AND_FAIL ("Failed to create new KMS request: %s",
+ kms_request_get_error (request));
+ }
+
+ if (COMMON_PREFIX (bson_b64_ntop) (
+ server_nonce, 64, server_nonce_str, server_nonce_str_len) == -1) {
+ AUTH_ERROR_AND_FAIL ("Failed to parse server nonce");
+ }
+
+ if (!kms_request_append_payload (request, body, -1)) {
+ AUTH_ERROR_AND_FAIL ("Failed to append payload");
+ }
+
+ KMS_REQUEST_SET (
+ kms_request_set_access_key_id, "access key ID", creds->access_key_id);
+ KMS_REQUEST_SET (
+ kms_request_set_secret_key, "secret key", creds->secret_access_key);
+ KMS_REQUEST_SET (kms_request_set_date, "date", NULL /* use current time */);
+ KMS_REQUEST_SET (kms_request_set_region, "region", region);
+ KMS_REQUEST_SET (kms_request_set_service, "service", "sts");
+
+ KMS_REQUEST_ADD_HEADER ("Content-Type", "application/x-www-form-urlencoded");
+ KMS_REQUEST_ADD_HEADER ("Host", sts_fqdn);
+ KMS_REQUEST_ADD_HEADER ("X-MongoDB-Server-Nonce", server_nonce_str);
+ KMS_REQUEST_ADD_HEADER ("X-MongoDB-GS2-CB-Flag", "n");
+ if (creds->session_token) {
+ KMS_REQUEST_ADD_HEADER ("X-Amz-Security-Token", creds->session_token);
+ }
+
+ signature = kms_request_get_signature (request);
+ if (kms_request_get_error (request)) {
+ AUTH_ERROR_AND_FAIL ("Failed to get signature: %s",
+ kms_request_get_error (request));
+ }
+
+ date = kms_request_get_canonical_header (request, "X-Amz-Date");
+ if (kms_request_get_error (request)) {
+ AUTH_ERROR_AND_FAIL ("Failed to get canonical header: %s",
+ kms_request_get_error (request));
+ }
+
+ BCON_APPEND (
+ &client_payload, "a", BCON_UTF8 (signature), "d", BCON_UTF8 (date));
+ if (creds->session_token) {
+ BCON_APPEND (&client_payload, "t", BCON_UTF8 (creds->session_token));
+ }
+
+ BCON_APPEND (&client_command,
+ "saslContinue",
+ BCON_INT32 (1),
+ "conversationId",
+ BCON_INT32 (conv_id),
+ "payload",
+ BCON_BIN (BSON_SUBTYPE_BINARY,
+ bson_get_data (&client_payload),
+ client_payload.len));
+
+ bson_destroy (&server_reply);
+ if (!_run_command (
+ cluster, stream, sd, &client_command, &server_reply, error)) {
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ bson_destroy (&client_payload);
+ bson_destroy (&client_command);
+ bson_destroy (&server_reply);
+ kms_request_destroy (request);
+ free (signature);
+ bson_free (server_nonce_str);
+ return ret;
+}
+
+bool
+_mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ mongoc_server_description_t *sd,
+ bson_error_t *error)
+{
+ bool ret = false;
+ uint8_t server_nonce[64];
+ char *sts_fqdn = NULL;
+ char *region = NULL;
+ int conv_id = 0;
+ _mongoc_aws_credentials_t creds = {0};
+
+ if (!_mongoc_aws_credentials_obtain (cluster->client->uri, &creds, error)) {
+ goto fail;
+ }
+
+ if (!_client_first (cluster,
+ stream,
+ sd,
+ server_nonce,
+ &sts_fqdn,
+ &region,
+ &conv_id,
+ error)) {
+ goto fail;
+ }
+
+ if (!_client_second (cluster,
+ stream,
+ sd,
+ &creds,
+ server_nonce,
+ sts_fqdn,
+ region,
+ conv_id,
+ error)) {
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ _mongoc_aws_credentials_cleanup (&creds);
+ bson_free (sts_fqdn);
+ bson_free (region);
+ return ret;
+}
+
+#else
+
+bool
+_mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ mongoc_server_description_t *sd,
+ bson_error_t *error)
+{
+ AUTH_ERROR_AND_FAIL ("AWS auth not supported, configure libmongoc with "
+ "ENABLE_MONGODB_AWS_AUTH=ON");
+fail:
+ return false;
+}
+
+
+bool
+_mongoc_aws_credentials_obtain (mongoc_uri_t *uri,
+ _mongoc_aws_credentials_t *creds,
+ bson_error_t *error)
+{
+ AUTH_ERROR_AND_FAIL ("AWS auth not supported, configure libmongoc with "
+ "ENABLE_MONGODB_AWS_AUTH=ON");
+fail:
+ return false;
+}
+
+void
+_mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds)
+{
+ return;
+}
+
+bool
+_mongoc_validate_and_derive_region (char *sts_fqdn,
+ uint32_t sts_fqdn_len,
+ char **region,
+ bson_error_t *error)
+{
+ AUTH_ERROR_AND_FAIL ("AWS auth not supported, configure libmongoc with "
+ "ENABLE_MONGODB_AWS_AUTH=ON");
+fail:
+ return false;
+}
+
+#endif /* MONGOC_ENABLE_MONGODB_AWS_AUTH */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c
similarity index 76%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c
index d1d423f0..78d7dec9 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c
@@ -1,140 +1,151 @@
/*
* Copyright 2017 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SASL_CYRUS
#include "mongoc-client-private.h"
#include "mongoc-cyrus-private.h"
#include "mongoc-cluster-cyrus-private.h"
#include "mongoc-error.h"
#include "mongoc-trace-private.h"
bool
_mongoc_cluster_auth_node_cyrus (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
- uint32_t buflen = 0;
mongoc_cyrus_t sasl;
bson_iter_t iter;
bool ret = false;
const char *tmpstr;
- uint8_t buf[4096] = {0};
+ /* input into cyrus */
+ uint8_t *inbuf = NULL;
+ uint32_t inbuf_len = 0;
+ /* output from cyrus */
+ uint8_t *outbuf = NULL;
+ uint32_t outbuf_len = 0;
+
bson_t cmd;
bson_t reply;
int conv_id = 0;
mongoc_server_stream_t *server_stream;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
if (!_mongoc_cyrus_new_from_cluster (
&sasl, cluster, stream, sd->host.host, error)) {
return false;
}
for (;;) {
mongoc_cmd_parts_init (
&parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &cmd);
+ /* If this is the first step, input buffer is NULL. */
+ bson_free (outbuf);
+ outbuf = NULL;
+ outbuf_len = 0;
if (!_mongoc_cyrus_step (
- &sasl, buf, buflen, buf, sizeof buf, &buflen, error)) {
+ &sasl, inbuf, inbuf_len, &outbuf, &outbuf_len, error)) {
goto failure;
}
bson_init (&cmd);
if (sasl.step == 1) {
- _mongoc_cluster_build_sasl_start (
- &cmd, sasl.credentials.mechanism, (const char *) buf, buflen);
+ _mongoc_cluster_build_sasl_start (&cmd,
+ sasl.credentials.mechanism,
+ (const char *) outbuf,
+ outbuf_len);
} else {
_mongoc_cluster_build_sasl_continue (
- &cmd, conv_id, (const char *) buf, buflen);
+ &cmd, conv_id, (const char *) outbuf, outbuf_len);
}
TRACE ("SASL: authenticating (step %d)", sasl.step);
server_stream = _mongoc_cluster_create_server_stream (
cluster->client->topology, sd->id, stream, error);
+ if (!server_stream) {
+ bson_destroy (&cmd);
+ goto failure;
+ }
+
if (!mongoc_cmd_parts_assemble (&parts, server_stream, error)) {
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&cmd);
goto failure;
}
if (!mongoc_cluster_run_command_private (
cluster, &parts.assembled, &reply, error)) {
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&cmd);
bson_destroy (&reply);
goto failure;
}
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&cmd);
if (bson_iter_init_find (&iter, &reply, "done") &&
bson_iter_as_bool (&iter)) {
bson_destroy (&reply);
break;
}
conv_id = _mongoc_cluster_get_conversation_id (&reply);
if (!bson_iter_init_find (&iter, &reply, "payload") ||
!BSON_ITER_HOLDS_UTF8 (&iter)) {
MONGOC_DEBUG ("SASL: authentication failed");
bson_destroy (&reply);
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Received invalid SASL reply from MongoDB server.");
goto failure;
}
- tmpstr = bson_iter_utf8 (&iter, &buflen);
-
- if (buflen > sizeof buf) {
- bson_set_error (error,
- MONGOC_ERROR_CLIENT,
- MONGOC_ERROR_CLIENT_AUTHENTICATE,
- "SASL reply from MongoDB is too large.");
-
- bson_destroy (&reply);
- goto failure;
- }
-
- memcpy (buf, tmpstr, buflen);
+ tmpstr = bson_iter_utf8 (&iter, &inbuf_len);
+ bson_free (inbuf);
+ /* include the trailing NULL byte, since base64 decoding expects a NULL
+ * terminates string. */
+ inbuf = bson_malloc (inbuf_len + 1);
+ memcpy (inbuf, tmpstr, inbuf_len + 1);
bson_destroy (&reply);
mongoc_cmd_parts_cleanup (&parts);
}
TRACE ("%s", "SASL: authenticated");
ret = true;
failure:
+ bson_free (inbuf);
+ bson_free (outbuf);
_mongoc_cyrus_destroy (&sasl);
mongoc_cmd_parts_cleanup (&parts);
return ret;
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
similarity index 83%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
index fdf19492..43b1d991 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
@@ -1,179 +1,201 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CLUSTER_PRIVATE_H
#define MONGOC_CLUSTER_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-array-private.h"
#include "mongoc-buffer-private.h"
#include "mongoc-config.h"
#include "mongoc-client.h"
#include "mongoc-list-private.h"
#include "mongoc-opcode.h"
#include "mongoc-rpc-private.h"
#include "mongoc-server-stream-private.h"
#include "mongoc-set-private.h"
#include "mongoc-stream.h"
#include "mongoc-topology-private.h"
#include "mongoc-topology-description-private.h"
#include "mongoc-write-concern.h"
#include "mongoc-scram-private.h"
#include "mongoc-cmd-private.h"
+#include "mongoc-crypto-private.h"
BSON_BEGIN_DECLS
typedef struct _mongoc_cluster_node_t {
mongoc_stream_t *stream;
char *connection_address;
+ uint32_t generation;
+ /* TODO CDRIVER-3653, these fields are unused. */
int32_t max_wire_version;
int32_t min_wire_version;
int32_t max_write_batch_size;
int32_t max_bson_obj_size;
int32_t max_msg_size;
-
- int64_t timestamp;
} mongoc_cluster_node_t;
typedef struct _mongoc_cluster_t {
int64_t operation_id;
uint32_t request_id;
uint32_t sockettimeoutms;
uint32_t socketcheckintervalms;
mongoc_uri_t *uri;
unsigned requires_auth : 1;
mongoc_client_t *client;
mongoc_set_t *nodes;
mongoc_array_t iov;
mongoc_scram_cache_t *scram_cache;
} mongoc_cluster_t;
void
mongoc_cluster_init (mongoc_cluster_t *cluster,
const mongoc_uri_t *uri,
void *client);
void
mongoc_cluster_destroy (mongoc_cluster_t *cluster);
void
-mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster,
- uint32_t id,
- bool invalidate,
- const bson_error_t *why);
+mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster, uint32_t id);
int32_t
mongoc_cluster_get_max_bson_obj_size (mongoc_cluster_t *cluster);
int32_t
mongoc_cluster_get_max_msg_size (mongoc_cluster_t *cluster);
size_t
_mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov,
size_t iovcnt,
int skip,
char *buffer);
bool
mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id);
bool
mongoc_cluster_legacy_rpc_sendv_to_server (
mongoc_cluster_t *cluster,
mongoc_rpc_t *rpcs,
mongoc_server_stream_t *server_stream,
bson_error_t *error);
bool
mongoc_cluster_try_recv (mongoc_cluster_t *cluster,
mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
mongoc_server_stream_t *server_stream,
bson_error_t *error);
mongoc_server_stream_t *
mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster,
const mongoc_read_prefs_t *read_prefs,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error);
mongoc_server_stream_t *
mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error);
mongoc_server_stream_t *
mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error);
+bool
+mongoc_cluster_stream_valid (mongoc_cluster_t *cluster,
+ mongoc_server_stream_t *server_stream);
+
bool
mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error);
bool
mongoc_cluster_run_command_parts (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
mongoc_cmd_parts_t *parts,
bson_t *reply,
bson_error_t *error);
bool
mongoc_cluster_run_command_private (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error);
void
_mongoc_cluster_build_sasl_start (bson_t *cmd,
const char *mechanism,
const char *buf,
uint32_t buflen);
void
_mongoc_cluster_build_sasl_continue (bson_t *cmd,
int conv_id,
const char *buf,
uint32_t buflen);
int
_mongoc_cluster_get_conversation_id (const bson_t *reply);
mongoc_server_stream_t *
_mongoc_cluster_create_server_stream (mongoc_topology_t *topology,
uint32_t server_id,
mongoc_stream_t *stream,
bson_error_t *error /* OUT */);
+
+bool
+_mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri,
+ const mongoc_ssl_opt_t *ssl_opts,
+ bson_t *cmd /* OUT */,
+ bson_error_t *error /* OUT */);
+
+#ifdef MONGOC_ENABLE_CRYPTO
+void
+_mongoc_cluster_init_scram (const mongoc_cluster_t *cluster,
+ mongoc_scram_t *scram,
+ mongoc_crypto_hash_algorithm_t algo);
+
+bool
+_mongoc_cluster_get_auth_cmd_scram (mongoc_crypto_hash_algorithm_t algo,
+ mongoc_scram_t *scram,
+ bson_t *cmd /* OUT */,
+ bson_error_t *error /* OUT */);
+#endif /* MONGOC_ENABLE_CRYPTO */
+
BSON_END_DECLS
#endif /* MONGOC_CLUSTER_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c
index 81de1eaf..fd9f3acb 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c
@@ -1,108 +1,109 @@
/*
* Copyright 2017 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.
*/
/* for size_t */
#include <bson/bson.h>
#include "mongoc-config.h"
#include "mongoc-cluster-private.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-socket.h"
#include "mongoc-error.h"
#include "mongoc-util-private.h"
#ifdef MONGOC_ENABLE_SASL
#ifdef MONGOC_ENABLE_SASL_CYRUS
#include "mongoc-cluster-cyrus-private.h"
#endif
#ifdef MONGOC_ENABLE_SASL_SSPI
#include "mongoc-cluster-sspi-private.h"
#endif
+#endif
+
void
_mongoc_cluster_build_sasl_start (bson_t *cmd,
const char *mechanism,
const char *buf,
uint32_t buflen)
{
BSON_APPEND_INT32 (cmd, "saslStart", 1);
- BSON_APPEND_UTF8 (cmd, "mechanism", "GSSAPI");
+ BSON_APPEND_UTF8 (cmd, "mechanism", mechanism);
bson_append_utf8 (cmd, "payload", 7, buf, buflen);
BSON_APPEND_INT32 (cmd, "autoAuthorize", 1);
}
void
_mongoc_cluster_build_sasl_continue (bson_t *cmd,
int conv_id,
const char *buf,
uint32_t buflen)
{
BSON_APPEND_INT32 (cmd, "saslContinue", 1);
BSON_APPEND_INT32 (cmd, "conversationId", conv_id);
bson_append_utf8 (cmd, "payload", 7, buf, buflen);
}
int
_mongoc_cluster_get_conversation_id (const bson_t *reply)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, reply, "conversationId") &&
BSON_ITER_HOLDS_INT32 (&iter)) {
return bson_iter_int32 (&iter);
}
return 0;
}
-#endif
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node_sasl --
*
* Perform authentication for a cluster node using SASL. This is
* only supported for GSSAPI at the moment.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* error may be set.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cluster_auth_node_sasl (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
#ifndef MONGOC_ENABLE_SASL
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"The GSSAPI authentication mechanism requires libmongoc "
"built with ENABLE_SASL");
return false;
#elif defined(MONGOC_ENABLE_SASL_CYRUS)
return _mongoc_cluster_auth_node_cyrus (cluster, stream, sd, error);
#elif defined(MONGOC_ENABLE_SASL_SSPI)
return _mongoc_cluster_auth_node_sspi (cluster, stream, sd, error);
#endif
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c
index 4e661bcd..baae966e 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c
@@ -1,290 +1,283 @@
/*
* Copyright 2017 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SASL_SSPI
#include "mongoc-client-private.h"
#include "mongoc-cluster-sspi-private.h"
#include "mongoc-cluster-sasl-private.h"
#include "mongoc-sasl-private.h"
#include "mongoc-sspi-private.h"
#include "mongoc-error.h"
#include "mongoc-util-private.h"
static mongoc_sspi_client_state_t *
_mongoc_cluster_sspi_new (mongoc_uri_t *uri,
mongoc_stream_t *stream,
const char *hostname)
{
WCHAR *service; /* L"serviceName@hostname@REALM" */
const char *service_name = "mongodb";
ULONG flags = ISC_REQ_MUTUAL_AUTH;
const char *service_realm = NULL;
char *service_ascii = NULL;
mongoc_sspi_client_state_t *state;
size_t service_ascii_len;
size_t tmp_creds_len;
bson_t properties;
bson_iter_t iter;
char real_name[BSON_HOST_NAME_MAX + 1];
int service_len;
WCHAR *pass = NULL;
WCHAR *user = NULL;
size_t user_len = 0;
size_t pass_len = 0;
int res;
state = (mongoc_sspi_client_state_t *) bson_malloc0 (sizeof *state);
_mongoc_sasl_set_properties (&state->sasl, uri);
if (state->sasl.canonicalize_host_name &&
_mongoc_sasl_get_canonicalized_name (
stream, real_name, sizeof real_name)) {
hostname = real_name;
}
/* service realm is an SSPI-specific feature */
if (mongoc_uri_get_mechanism_properties (uri, &properties) &&
bson_iter_init_find_case (&iter, &properties, "SERVICE_REALM") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
service_realm = bson_iter_utf8 (&iter, NULL);
service_ascii =
bson_strdup_printf ("%s@%s@%s", service_name, hostname, service_realm);
} else {
service_ascii = bson_strdup_printf ("%s@%s", service_name, hostname);
}
service_ascii_len = strlen (service_ascii);
/* this is donated to the sspi */
service = calloc (service_ascii_len + 1, sizeof (WCHAR));
service_len = MultiByteToWideChar (CP_UTF8,
0,
service_ascii,
(int) service_ascii_len,
service,
(int) service_ascii_len);
service[service_len] = L'\0';
bson_free (service_ascii);
if (state->sasl.pass) {
tmp_creds_len = strlen (state->sasl.pass);
/* this is donated to the sspi */
pass = calloc (tmp_creds_len + 1, sizeof (WCHAR));
pass_len = MultiByteToWideChar (CP_UTF8,
0,
state->sasl.pass,
(int) tmp_creds_len,
pass,
(int) tmp_creds_len);
pass[pass_len] = L'\0';
}
if (state->sasl.user) {
tmp_creds_len = strlen (state->sasl.user);
/* this is donated to the sspi */
user = calloc (tmp_creds_len + 1, sizeof (WCHAR));
user_len = MultiByteToWideChar (CP_UTF8,
0,
state->sasl.user,
(int) tmp_creds_len,
user,
(int) tmp_creds_len);
user[user_len] = L'\0';
}
res = _mongoc_sspi_auth_sspi_client_init (service,
flags,
user,
(ULONG) user_len,
NULL,
0,
pass,
(ULONG) pass_len,
state);
if (res != MONGOC_SSPI_AUTH_GSS_ERROR) {
return state;
}
bson_free (state);
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node_sspi --
*
* Perform authentication for a cluster node using SSPI
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* error may be set.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cluster_auth_node_sspi (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
mongoc_sspi_client_state_t *state;
- SEC_CHAR buf[4096] = {0};
+ SEC_CHAR* buf = NULL;
bson_iter_t iter;
uint32_t buflen;
bson_t reply;
const char *tmpstr;
int conv_id;
bson_t cmd;
int res = MONGOC_SSPI_AUTH_GSS_CONTINUE;
int step;
mongoc_server_stream_t *server_stream;
bool ret = false;
state = _mongoc_cluster_sspi_new (cluster->uri, stream, sd->host.host);
if (!state) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Couldn't initialize SSPI service.");
goto failure;
}
for (step = 0;; step++) {
mongoc_cmd_parts_init (
&parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &cmd);
bson_init (&cmd);
if (res == MONGOC_SSPI_AUTH_GSS_CONTINUE) {
res = _mongoc_sspi_auth_sspi_client_step (state, buf);
} else if (res == MONGOC_SSPI_AUTH_GSS_COMPLETE) {
char *response;
size_t tmp_creds_len = strlen (state->sasl.user);
res = _mongoc_sspi_auth_sspi_client_unwrap (state, buf);
response = bson_strdup (state->response);
_mongoc_sspi_auth_sspi_client_wrap (state,
response,
(SEC_CHAR *) state->sasl.user,
(ULONG) tmp_creds_len,
0);
bson_free (response);
}
if (res == MONGOC_SSPI_AUTH_GSS_ERROR) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Received invalid SSPI data.");
mongoc_cmd_parts_cleanup (&parts);
bson_destroy (&cmd);
goto failure;
}
if (step == 0) {
_mongoc_cluster_build_sasl_start (&cmd,
"GSSAPI",
state->response,
(uint32_t) strlen (state->response));
} else {
if (state->response) {
_mongoc_cluster_build_sasl_continue (
&cmd,
conv_id,
state->response,
(uint32_t) strlen (state->response));
} else {
_mongoc_cluster_build_sasl_continue (&cmd, conv_id, "", 0);
}
}
server_stream = _mongoc_cluster_create_server_stream (
cluster->client->topology, sd->id, stream, error);
if (!server_stream ||
!mongoc_cmd_parts_assemble (&parts, server_stream, error)) {
mongoc_server_stream_cleanup (server_stream);
mongoc_cmd_parts_cleanup (&parts);
bson_destroy (&cmd);
goto failure;
}
if (!mongoc_cluster_run_command_private (
cluster, &parts.assembled, &reply, error)) {
mongoc_server_stream_cleanup (server_stream);
mongoc_cmd_parts_cleanup (&parts);
bson_destroy (&cmd);
bson_destroy (&reply);
goto failure;
}
mongoc_server_stream_cleanup (server_stream);
mongoc_cmd_parts_cleanup (&parts);
bson_destroy (&cmd);
if (bson_iter_init_find (&iter, &reply, "done") &&
bson_iter_as_bool (&iter)) {
bson_destroy (&reply);
break;
}
conv_id = _mongoc_cluster_get_conversation_id (&reply);
if (!bson_iter_init_find (&iter, &reply, "payload") ||
!BSON_ITER_HOLDS_UTF8 (&iter)) {
bson_destroy (&reply);
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Received invalid SASL reply from MongoDB server.");
goto failure;
}
tmpstr = bson_iter_utf8 (&iter, &buflen);
-
- if (buflen > sizeof buf) {
- bson_set_error (error,
- MONGOC_ERROR_CLIENT,
- MONGOC_ERROR_CLIENT_AUTHENTICATE,
- "SASL reply from MongoDB is too large.");
-
- bson_destroy (&reply);
- goto failure;
- }
-
+ bson_free (buf);
+ buf = bson_malloc (sizeof (SEC_CHAR) * (buflen + 1));
memcpy (buf, tmpstr, buflen);
+ buf[buflen] = (SEC_CHAR) 0;
bson_destroy (&reply);
}
ret = true;
failure:
+ bson_free (buf);
bson_free (state);
return ret;
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
similarity index 74%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
index 880254bc..d64e5a78 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
@@ -1,3066 +1,3540 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-config.h"
#include <string.h>
#include "mongoc-cluster-private.h"
#include "mongoc-client-private.h"
#include "mongoc-client-side-encryption-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-config.h"
#include "mongoc-error.h"
+#include "mongoc-flags-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-log.h"
#include "mongoc-cluster-sasl-private.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-ssl.h"
#include "mongoc-ssl-private.h"
#include "mongoc-stream-tls.h"
#endif
#include "common-b64-private.h"
#include "mongoc-scram-private.h"
#include "mongoc-set-private.h"
#include "mongoc-socket.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-socket.h"
#include "mongoc-stream-tls.h"
#include "mongoc-thread-private.h"
#include "mongoc-topology-private.h"
+#include "mongoc-topology-background-monitoring-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-rpc-private.h"
#include "mongoc-compression-private.h"
#include "mongoc-cmd-private.h"
#include "utlist.h"
#include "mongoc-handshake-private.h"
+#include "mongoc-cluster-aws-private.h"
+#include "mongoc-error-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "cluster"
#define CHECK_CLOSED_DURATION_MSEC 1000
-#define DB_AND_CMD_FROM_COLLECTION(outstr, name) \
- do { \
- const char *dot = strchr (name, '.'); \
- if (!dot || ((dot - name) > (sizeof outstr - 6))) { \
- bson_snprintf (outstr, sizeof outstr, "admin.$cmd"); \
- } else { \
- memcpy (outstr, name, dot - name); \
- memcpy (outstr + (dot - name), ".$cmd", 6); \
- } \
- } while (0)
-
#define IS_NOT_COMMAND(_name) (!!strcasecmp (cmd->command_name, _name))
-/**
- * mongoc_op_msg_flags_t:
- * @MONGOC_MSG_CHECKSUM_PRESENT: The message ends with 4 bytes containing a
- * CRC-32C checksum.
- * @MONGOC_MSG_MORE_TO_COME: If set to 0, wait for a server response. If set to
- * 1, do not expect a server response.
- * @MONGOC_MSG_EXHAUST_ALLOWED: If set, allows multiple replies to this request
- * using the moreToCome bit.
- */
-typedef enum {
- MONGOC_MSG_NONE = 0,
- MONGOC_MSG_CHECKSUM_PRESENT = 1 << 0,
- MONGOC_MSG_MORE_TO_COME = 1 << 1,
- MONGOC_EXHAUST_ALLOWED = 1 << 16,
-} mongoc_op_msg_flags_t;
-
static mongoc_server_stream_t *
mongoc_cluster_fetch_stream_single (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error);
static mongoc_server_stream_t *
mongoc_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error);
static bool
mongoc_cluster_run_opmsg (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error);
static void
_bson_error_message_printf (bson_error_t *error, const char *format, ...)
BSON_GNUC_PRINTF (2, 3);
+static void
+_handle_not_master_error (mongoc_cluster_t *cluster,
+ const mongoc_server_stream_t *server_stream,
+ const bson_t *reply)
+{
+ uint32_t server_id;
+
+ server_id = server_stream->sd->id;
+ bson_mutex_lock (&cluster->client->topology->mutex);
+ if (_mongoc_topology_handle_app_error (cluster->client->topology,
+ server_id,
+ true /* handshake complete */,
+ MONGOC_SDAM_APP_ERROR_COMMAND,
+ reply,
+ NULL,
+ server_stream->sd->max_wire_version,
+ server_stream->sd->generation)) {
+ mongoc_cluster_disconnect_node (cluster, server_id);
+ }
+ bson_mutex_unlock (&cluster->client->topology->mutex);
+}
+
+/* Called when a network error occurs on an application socket.
+ */
+static void
+_handle_network_error (mongoc_cluster_t *cluster,
+ mongoc_server_stream_t *server_stream,
+ bool handshake_complete,
+ const bson_error_t *why)
+{
+ mongoc_topology_t *topology;
+ uint32_t server_id;
+ _mongoc_sdam_app_error_type_t type;
+
+ BSON_ASSERT (server_stream);
+
+ ENTRY;
+ topology = cluster->client->topology;
+ server_id = server_stream->sd->id;
+ type = MONGOC_SDAM_APP_ERROR_NETWORK;
+ if (mongoc_stream_timed_out (server_stream->stream)) {
+ type = MONGOC_SDAM_APP_ERROR_TIMEOUT;
+ }
+
+ bson_mutex_lock (&topology->mutex);
+ _mongoc_topology_handle_app_error (topology,
+ server_id,
+ handshake_complete,
+ type,
+ NULL,
+ why,
+ server_stream->sd->max_wire_version,
+ server_stream->sd->generation);
+ bson_mutex_unlock (&topology->mutex);
+ /* Always disconnect the current connection on network error. */
+ mongoc_cluster_disconnect_node (cluster, server_id);
+
+ EXIT;
+}
+
size_t
_mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov,
size_t iovcnt,
int skip,
char *buffer)
{
int n;
size_t buffer_offset = 0;
int total_iov_len = 0;
int difference = 0;
for (n = 0; n < iovcnt; n++) {
total_iov_len += iov[n].iov_len;
if (total_iov_len <= skip) {
continue;
}
/* If this iovec starts before the skip, and takes the total count
* beyond the skip, we need to figure out the portion of the iovec
* we should skip passed */
if (total_iov_len - iov[n].iov_len < skip) {
difference = skip - (total_iov_len - iov[n].iov_len);
} else {
difference = 0;
}
memcpy (buffer + buffer_offset,
((char *) iov[n].iov_base) + difference,
iov[n].iov_len - difference);
buffer_offset += iov[n].iov_len - difference;
}
return buffer_offset;
}
/* Allows caller to safely overwrite error->message with a formatted string,
* even if the formatted string includes original error->message. */
static void
_bson_error_message_printf (bson_error_t *error, const char *format, ...)
{
va_list args;
char error_message[sizeof error->message];
if (error) {
va_start (args, format);
bson_vsnprintf (error_message, sizeof error->message, format, args);
va_end (args);
bson_strncpy (error->message, error_message, sizeof error->message);
}
}
#define RUN_CMD_ERR_DECORATE \
do { \
_bson_error_message_printf ( \
error, \
"Failed to send \"%s\" command with database \"%s\": %s", \
cmd->command_name, \
cmd->db_name, \
error->message); \
} while (0)
#define RUN_CMD_ERR(_domain, _code, ...) \
do { \
bson_set_error (error, _domain, _code, __VA_ARGS__); \
RUN_CMD_ERR_DECORATE; \
} while (0)
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_run_command_opquery --
*
* Internal function to run a command on a given stream. @error and
* @reply are optional out-pointers.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @reply is set and should ALWAYS be released with bson_destroy().
* On failure, @error is filled out. If this was a network error
* and server_id is nonzero, the cluster disconnects from the server.
*
*--------------------------------------------------------------------------
*/
static bool
mongoc_cluster_run_command_opquery (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
- mongoc_stream_t *stream,
int32_t compressor_id,
bson_t *reply,
bson_error_t *error)
{
const size_t reply_header_size = sizeof (mongoc_rpc_reply_header_t);
uint8_t reply_header_buf[sizeof (mongoc_rpc_reply_header_t)];
uint8_t *reply_buf; /* reply body */
mongoc_rpc_t rpc; /* sent to server */
bson_t reply_local;
bson_t *reply_ptr;
- char cmd_ns[MONGOC_NAMESPACE_MAX];
+ char *cmd_ns;
uint32_t request_id;
int32_t msg_len;
size_t doc_len;
bool ret = false;
char *output = NULL;
- uint32_t server_id;
+ mongoc_stream_t *stream;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (cmd);
- BSON_ASSERT (stream);
+ BSON_ASSERT (cmd->server_stream);
+ stream = cmd->server_stream->stream;
/*
* setup
*/
reply_ptr = reply ? reply : &reply_local;
bson_init (reply_ptr);
error->code = 0;
/*
* prepare the request
*/
_mongoc_array_clear (&cluster->iov);
- bson_snprintf (cmd_ns, sizeof cmd_ns, "%s.$cmd", cmd->db_name);
+ cmd_ns = bson_strdup_printf ("%s.$cmd", cmd->db_name);
request_id = ++cluster->request_id;
_mongoc_rpc_prep_command (&rpc, cmd_ns, cmd);
rpc.header.request_id = request_id;
- server_id = cmd->server_stream->sd->id;
_mongoc_rpc_gather (&rpc, &cluster->iov);
_mongoc_rpc_swab_to_le (&rpc);
if (compressor_id != -1 && IS_NOT_COMMAND ("ismaster") &&
IS_NOT_COMMAND ("saslstart") && IS_NOT_COMMAND ("saslcontinue") &&
IS_NOT_COMMAND ("getnonce") && IS_NOT_COMMAND ("authenticate") &&
IS_NOT_COMMAND ("createuser") && IS_NOT_COMMAND ("updateuser")) {
output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error);
if (output == NULL) {
GOTO (done);
}
}
if (cluster->client->in_exhaust) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_IN_EXHAUST,
"A cursor derived from this client is in exhaust.");
GOTO (done);
}
/*
* send and receive
*/
if (!_mongoc_stream_writev_full (stream,
cluster->iov.data,
cluster->iov.len,
cluster->sockettimeoutms,
error)) {
- mongoc_cluster_disconnect_node (cluster, server_id, true, error);
+ _handle_network_error (
+ cluster, cmd->server_stream, true /* handshake complete */, error);
/* add info about the command to writev_full's error message */
RUN_CMD_ERR_DECORATE;
GOTO (done);
}
if (reply_header_size != mongoc_stream_read (stream,
&reply_header_buf,
reply_header_size,
reply_header_size,
cluster->sockettimeoutms)) {
RUN_CMD_ERR (MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"socket error or timeout");
- mongoc_cluster_disconnect_node (
- cluster, server_id, !mongoc_stream_timed_out (stream), error);
+ _handle_network_error (
+ cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
memcpy (&msg_len, reply_header_buf, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
if ((msg_len < reply_header_size) ||
(msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE)) {
- mongoc_cluster_disconnect_node (cluster, server_id, true, error);
+ _handle_network_error (
+ cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
if (!_mongoc_rpc_scatter_reply_header_only (
&rpc, reply_header_buf, reply_header_size)) {
- mongoc_cluster_disconnect_node (cluster, server_id, true, error);
+ _handle_network_error (
+ cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
doc_len = (size_t) msg_len - reply_header_size;
if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) {
bson_t tmp = BSON_INITIALIZER;
uint8_t *buf = NULL;
size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
reply_buf = bson_malloc0 (msg_len);
memcpy (reply_buf, reply_header_buf, reply_header_size);
if (doc_len != mongoc_stream_read (stream,
reply_buf + reply_header_size,
doc_len,
doc_len,
cluster->sockettimeoutms)) {
RUN_CMD_ERR (MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"socket error or timeout");
- mongoc_cluster_disconnect_node (cluster, server_id, true, error);
+ _handle_network_error (
+ cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
if (!_mongoc_rpc_scatter (&rpc, reply_buf, msg_len)) {
GOTO (done);
}
buf = bson_malloc0 (len);
if (!_mongoc_rpc_decompress (&rpc, buf, len)) {
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress server reply");
bson_free (reply_buf);
bson_free (buf);
GOTO (done);
}
_mongoc_rpc_swab_from_le (&rpc);
if (!_mongoc_rpc_get_first_document (&rpc, &tmp)) {
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Corrupt compressed OP_QUERY reply from server");
bson_free (reply_buf);
bson_free (buf);
GOTO (done);
}
bson_copy_to (&tmp, reply_ptr);
bson_free (reply_buf);
bson_free (buf);
} else if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_REPLY &&
BSON_UINT32_FROM_LE (rpc.reply_header.n_returned) == 1) {
reply_buf = bson_reserve_buffer (reply_ptr, (uint32_t) doc_len);
BSON_ASSERT (reply_buf);
if (doc_len != mongoc_stream_read (stream,
(void *) reply_buf,
doc_len,
doc_len,
cluster->sockettimeoutms)) {
RUN_CMD_ERR (MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"socket error or timeout");
- mongoc_cluster_disconnect_node (cluster, server_id, true, error);
+ _handle_network_error (
+ cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
_mongoc_rpc_swab_from_le (&rpc);
} else {
GOTO (done);
}
if (!_mongoc_cmd_check_ok (
reply_ptr, cluster->client->error_api_version, error)) {
GOTO (done);
}
ret = true;
done:
if (!ret && error->code == 0) {
/* generic error */
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server.");
}
if (reply_ptr == &reply_local) {
bson_destroy (reply_ptr);
}
bson_free (output);
+ bson_free (cmd_ns);
RETURN (ret);
}
-
-typedef enum {
- MONGOC_REPLY_ERR_TYPE_NONE,
- MONGOC_REPLY_ERR_TYPE_NOT_MASTER,
- MONGOC_REPLY_ERR_TYPE_SHUTDOWN,
- MONGOC_REPLY_ERR_TYPE_NODE_IS_RECOVERING
-} reply_error_type_t;
-
-
-/*---------------------------------------------------------------------------
- *
- * _check_not_master_or_recovering_error --
- *
- * Checks @reply for a "not master" or "node is recovering" error and
- * sets @error.
- *
- * Return:
- * A reply_error_type_t indicating if @reply contained a "not master"
- * or "node is recovering" error.
- *
- *--------------------------------------------------------------------------
- */
-static reply_error_type_t
-_check_not_master_or_recovering_error (const mongoc_client_t *client,
- const bson_t *reply,
- bson_error_t *error)
+bool
+_in_sharded_txn (const mongoc_client_session_t *session)
{
- if (_mongoc_cmd_check_ok_no_wce (reply, client->error_api_version, error)) {
- return MONGOC_REPLY_ERR_TYPE_NONE;
- }
-
- switch (error->code) {
- case 11600: /* InterruptedAtShutdown */
- case 91: /* ShutdownInProgress */
- return MONGOC_REPLY_ERR_TYPE_SHUTDOWN;
- case 11602: /* InterruptedDueToReplStateChange */
- case 13436: /* NotMasterOrSecondary */
- case 189: /* PrimarySteppedDown */
- return MONGOC_REPLY_ERR_TYPE_NODE_IS_RECOVERING;
- case 10107: /* NotMaster */
- case 13435: /* NotMasterNoSlaveOk */
- return MONGOC_REPLY_ERR_TYPE_NOT_MASTER;
- default:
- if (strstr (error->message, "not master")) {
- return MONGOC_REPLY_ERR_TYPE_NOT_MASTER;
- } else if (strstr (error->message, "node is recovering")) {
- return MONGOC_REPLY_ERR_TYPE_NODE_IS_RECOVERING;
- }
- return MONGOC_REPLY_ERR_TYPE_NONE;
- }
+ return session && _mongoc_client_session_in_txn_or_ending (session) &&
+ _mongoc_topology_get_type (session->client->topology) ==
+ MONGOC_TOPOLOGY_SHARDED;
}
-
static void
-handle_not_master_error (mongoc_cluster_t *cluster,
- uint32_t server_id,
- const bson_t *reply)
+_handle_txn_error_labels (bool cmd_ret,
+ const bson_error_t *cmd_err,
+ const mongoc_cmd_t *cmd,
+ bson_t *reply)
{
- mongoc_topology_t *topology = cluster->client->topology;
- mongoc_server_description_t *sd;
- bson_error_t error;
- reply_error_type_t error_type =
- _check_not_master_or_recovering_error (cluster->client, reply, &error);
-
- if (error_type != MONGOC_REPLY_ERR_TYPE_NONE) {
- /* Server Discovery and Monitoring Spec: "When the client sees a 'not
- * master' or 'node is recovering' error it MUST replace the server's
- * description with a default ServerDescription of type Unknown."
- *
- * The client MUST clear its connection pool for the server
- * if the server is 4.0 or earlier, and MUST NOT clear its connection
- * pool for the server if the server is 4.2 or later. */
- sd = mongoc_topology_server_by_id (topology, server_id, &error);
- if (sd->max_wire_version <= WIRE_VERSION_4_0 ||
- error_type == MONGOC_REPLY_ERR_TYPE_SHUTDOWN) {
- mongoc_cluster_disconnect_node (cluster, server_id, false, NULL);
- }
- mongoc_server_description_destroy (sd);
-
- mongoc_topology_invalidate_server (topology, server_id, &error);
-
- if (topology->single_threaded) {
- /* SDAM Spec: "For single-threaded clients, in the case of a 'not
- * master' error, the client MUST check the server immediately... For a
- * 'node is recovering' error, single-threaded clients MUST NOT check
- * the server, as an immediate server check is unlikely to find a
- * usable server."
- * Instead of an immediate check, mark the topology as stale so the
- * next command scans all servers (to find the new primary). */
- if (error_type == MONGOC_REPLY_ERR_TYPE_NOT_MASTER) {
- cluster->client->topology->stale = true;
- }
- } else {
- /* SDAM Spec: "Multi-threaded and asynchronous clients MUST request an
- * immediate check of the server."
- * Instead of requesting a check of the one server, request a scan
- * to all servers (to find the new primary). */
- _mongoc_topology_request_scan (topology);
- }
+ if (!cmd->is_txn_finish) {
+ return;
}
-}
-bool
-_in_sharded_txn (const mongoc_client_session_t *session)
-{
- return session && _mongoc_client_session_in_txn_or_ending (session) &&
- _mongoc_topology_get_type (session->client->topology) ==
- MONGOC_TOPOLOGY_SHARDED;
+ _mongoc_write_error_handle_labels (
+ cmd_ret, cmd_err, reply, cmd->server_stream->sd->max_wire_version);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_run_command_monitored --
*
* Internal function to run a command on a given stream.
* @error and @reply are optional out-pointers.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* If the client's APM callbacks are set, they are executed.
* @reply is set and should ALWAYS be released with bson_destroy().
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error)
{
bool retval;
uint32_t request_id = ++cluster->request_id;
uint32_t server_id;
mongoc_apm_callbacks_t *callbacks;
mongoc_apm_command_started_t started_event;
mongoc_apm_command_succeeded_t succeeded_event;
mongoc_apm_command_failed_t failed_event;
int64_t started = bson_get_monotonic_time ();
const mongoc_server_stream_t *server_stream;
bson_t reply_local;
bson_error_t error_local;
int32_t compressor_id;
bson_iter_t iter;
bson_t encrypted = BSON_INITIALIZER;
bson_t decrypted = BSON_INITIALIZER;
mongoc_cmd_t encrypted_cmd;
server_stream = cmd->server_stream;
server_id = server_stream->sd->id;
compressor_id = mongoc_server_description_compressor_id (server_stream->sd);
callbacks = &cluster->client->apm_callbacks;
if (!reply) {
reply = &reply_local;
}
if (!error) {
error = &error_local;
}
if (_mongoc_cse_is_enabled (cluster->client)) {
bson_destroy (&encrypted);
retval = _mongoc_cse_auto_encrypt (
cluster->client, cmd, &encrypted_cmd, &encrypted, error);
cmd = &encrypted_cmd;
if (!retval) {
bson_init (reply);
goto fail_no_events;
}
}
if (callbacks->started) {
mongoc_apm_command_started_init_with_cmd (
&started_event, cmd, request_id, cluster->client->apm_context);
callbacks->started (&started_event);
mongoc_apm_command_started_cleanup (&started_event);
}
if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error);
} else {
retval = mongoc_cluster_run_command_opquery (
- cluster, cmd, server_stream->stream, compressor_id, reply, error);
+ cluster, cmd, compressor_id, reply, error);
}
if (_mongoc_cse_is_enabled (cluster->client)) {
bson_destroy (&decrypted);
retval = _mongoc_cse_auto_decrypt (
cluster->client, cmd->db_name, reply, &decrypted, error);
bson_destroy (reply);
bson_steal (reply, &decrypted);
bson_init (&decrypted);
if (!retval) {
goto fail_no_events;
}
}
if (retval && callbacks->succeeded) {
bson_t fake_reply = BSON_INITIALIZER;
/*
* Unacknowledged writes must provide a CommandSucceededEvent with an
* {ok: 1} reply.
* https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#unacknowledged-acknowledged-writes
*/
if (!cmd->is_acknowledged) {
bson_append_int32 (&fake_reply, "ok", 2, 1);
}
mongoc_apm_command_succeeded_init (&succeeded_event,
bson_get_monotonic_time () - started,
cmd->is_acknowledged ? reply
: &fake_reply,
cmd->command_name,
request_id,
cmd->operation_id,
&server_stream->sd->host,
server_id,
cluster->client->apm_context);
callbacks->succeeded (&succeeded_event);
mongoc_apm_command_succeeded_cleanup (&succeeded_event);
bson_destroy (&fake_reply);
}
if (!retval && callbacks->failed) {
mongoc_apm_command_failed_init (&failed_event,
bson_get_monotonic_time () - started,
cmd->command_name,
error,
reply,
request_id,
cmd->operation_id,
&server_stream->sd->host,
server_id,
cluster->client->apm_context);
callbacks->failed (&failed_event);
mongoc_apm_command_failed_cleanup (&failed_event);
}
- handle_not_master_error (cluster, server_id, reply);
+ _handle_not_master_error (cluster, server_stream, reply);
+
+ _handle_txn_error_labels (retval, error, cmd, reply);
if (retval && _in_sharded_txn (cmd->session) &&
bson_iter_init_find (&iter, reply, "recoveryToken")) {
bson_destroy (cmd->session->recovery_token);
if (BSON_ITER_HOLDS_DOCUMENT (&iter)) {
cmd->session->recovery_token =
bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data,
bson_iter_value (&iter)->value.v_doc.data_len);
} else {
MONGOC_ERROR ("Malformed recovery token from server");
cmd->session->recovery_token = NULL;
}
}
fail_no_events:
if (reply == &reply_local) {
bson_destroy (&reply_local);
}
bson_destroy (&encrypted);
bson_destroy (&decrypted);
_mongoc_topology_update_last_used (cluster->client->topology, server_id);
return retval;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_run_command_private --
*
* Internal function to run a command on a given stream.
* @error and @reply are optional out-pointers.
* The client's APM callbacks are not executed.
* Automatic encryption/decryption is not performed.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @reply is set and should ALWAYS be released with bson_destroy().
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_run_command_private (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error)
{
bool retval;
const mongoc_server_stream_t *server_stream;
bson_t reply_local;
bson_error_t error_local;
if (!error) {
error = &error_local;
}
if (!reply) {
reply = &reply_local;
}
server_stream = cmd->server_stream;
if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error);
} else {
- retval = mongoc_cluster_run_command_opquery (
- cluster, cmd, cmd->server_stream->stream, -1, reply, error);
+ retval =
+ mongoc_cluster_run_command_opquery (cluster, cmd, -1, reply, error);
}
- handle_not_master_error (cluster, server_stream->sd->id, reply);
+ _handle_not_master_error (cluster, server_stream, reply);
if (reply == &reply_local) {
bson_destroy (&reply_local);
}
_mongoc_topology_update_last_used (cluster->client->topology,
server_stream->sd->id);
return retval;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_run_command_parts --
*
* Internal function to assemble command parts and run a command
* on a given stream. @error and @reply are optional out-pointers.
* The client's APM callbacks are not executed.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @reply is set and should ALWAYS be released with bson_destroy().
* mongoc_cmd_parts_cleanup will be always be called on parts. The
* caller should *not* call cleanup on the parts.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_run_command_parts (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
mongoc_cmd_parts_t *parts,
bson_t *reply,
bson_error_t *error)
{
bool ret;
if (!mongoc_cmd_parts_assemble (parts, server_stream, error)) {
_mongoc_bson_init_if_set (reply);
mongoc_cmd_parts_cleanup (parts);
return false;
}
ret = mongoc_cluster_run_command_private (
cluster, &parts->assembled, reply, error);
mongoc_cmd_parts_cleanup (parts);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_run_ismaster --
*
* Run an ismaster command on the given stream. If
* @negotiate_sasl_supported_mechs is true, then saslSupportedMechs is
* added to the ismaster command.
*
* Returns:
* A mongoc_server_description_t you must destroy or NULL. If the call
* failed its error is set and its type is MONGOC_SERVER_UNKNOWN.
*
*--------------------------------------------------------------------------
*/
static mongoc_server_description_t *
_mongoc_stream_run_ismaster (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
const char *address,
uint32_t server_id,
bool negotiate_sasl_supported_mechs,
+ mongoc_scram_cache_t *scram_cache,
+ mongoc_scram_t *scram,
+ bson_t *speculative_auth_response /* OUT */,
bson_error_t *error)
{
const bson_t *command;
mongoc_cmd_t ismaster_cmd;
bson_t reply;
int64_t start;
int64_t rtt_msec;
mongoc_server_description_t *sd;
mongoc_server_stream_t *server_stream;
bson_t *copied_command = NULL;
bool r;
bson_iter_t iter;
+ mongoc_ssl_opt_t *ssl_opts = NULL;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
command = _mongoc_topology_get_ismaster (cluster->client->topology);
- if (negotiate_sasl_supported_mechs) {
+ if (cluster->requires_auth || negotiate_sasl_supported_mechs) {
copied_command = bson_copy (command);
+ command = copied_command;
+ }
+
+ if (cluster->requires_auth && speculative_auth_response) {
+#ifdef MONGOC_ENABLE_SSL
+ ssl_opts = &cluster->client->ssl_opts;
+#endif
+
+ _mongoc_topology_scanner_add_speculative_authentication (
+ copied_command, cluster->uri, ssl_opts, scram_cache, scram);
+ }
+
+ if (negotiate_sasl_supported_mechs) {
_mongoc_handshake_append_sasl_supported_mechs (cluster->uri,
copied_command);
- command = copied_command;
}
start = bson_get_monotonic_time ();
+ /* TODO CDRIVER-3654: do not use a mongoc_server_stream here.
+ * Instead, use a plain stream. If a network error occurs, check the cluster
+ * node's generation (which is the generation of the created connection) to
+ * determine if the error should be handled.
+ * The current behavior may double invalidate.
+ * If a network error occurs in mongoc_cluster_run_command_private below,
+ * that invalidates (thinking the error is a post-handshake network error).
+ * Then _mongoc_cluster_stream_for_server also handles the error, and
+ * invalidates again.
+ */
server_stream = _mongoc_cluster_create_server_stream (
cluster->client->topology, server_id, stream, error);
if (!server_stream) {
bson_destroy (copied_command);
RETURN (NULL);
}
/* Always use OP_QUERY for the isMaster handshake, regardless of whether the
* last known ismaster indicates the server supports a newer wire protocol.
*/
server_stream->sd->max_wire_version = WIRE_VERSION_MIN;
memset (&ismaster_cmd, 0, sizeof (ismaster_cmd));
ismaster_cmd.db_name = "admin";
ismaster_cmd.command = command;
ismaster_cmd.command_name = _mongoc_get_command_name (command);
ismaster_cmd.query_flags = MONGOC_QUERY_SLAVE_OK;
ismaster_cmd.server_stream = server_stream;
if (!mongoc_cluster_run_command_private (
cluster, &ismaster_cmd, &reply, error)) {
if (negotiate_sasl_supported_mechs) {
if (bson_iter_init_find (&iter, &reply, "ok") &&
!bson_iter_as_bool (&iter)) {
/* ismaster response returned ok: 0. According to auth spec: "If the
* isMaster of the MongoDB Handshake fails with an error, drivers
* MUST treat this an authentication error." */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
}
}
bson_destroy (copied_command);
bson_destroy (&reply);
mongoc_server_stream_cleanup (server_stream);
RETURN (NULL);
}
rtt_msec = (bson_get_monotonic_time () - start) / 1000;
sd = (mongoc_server_description_t *) bson_malloc0 (
sizeof (mongoc_server_description_t));
mongoc_server_description_init (sd, address, server_id);
/* send the error from run_command IN to handle_ismaster */
mongoc_server_description_handle_ismaster (sd, &reply, rtt_msec, error);
+ if (cluster->requires_auth && speculative_auth_response) {
+ _mongoc_topology_scanner_parse_speculative_authentication (
+ &reply, speculative_auth_response);
+ }
+
bson_destroy (&reply);
r = _mongoc_topology_update_from_handshake (cluster->client->topology, sd);
if (!r) {
mongoc_server_description_reset (sd);
bson_set_error (&sd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"\"%s\" removed from topology",
address);
}
mongoc_server_stream_cleanup (server_stream);
if (copied_command) {
bson_destroy (copied_command);
}
RETURN (sd);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_run_ismaster --
*
* Run an initial ismaster command for the given node and handle result.
*
* Returns:
* mongoc_server_description_t on success, NULL otherwise.
* the mongoc_server_description_t MUST BE DESTROYED BY THE CALLER.
*
* Side effects:
* Makes a blocking I/O call, updates cluster->topology->description
* with ismaster result.
*
*--------------------------------------------------------------------------
*/
static mongoc_server_description_t *
_mongoc_cluster_run_ismaster (mongoc_cluster_t *cluster,
mongoc_cluster_node_t *node,
uint32_t server_id,
+ mongoc_scram_cache_t *scram_cache,
+ mongoc_scram_t *scram /* OUT */,
+ bson_t *speculative_auth_response /* OUT */,
bson_error_t *error /* OUT */)
{
mongoc_server_description_t *sd;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (node);
BSON_ASSERT (node->stream);
sd = _mongoc_stream_run_ismaster (
cluster,
node->stream,
node->connection_address,
server_id,
_mongoc_uri_requires_auth_negotiation (cluster->uri),
+ scram_cache,
+ scram,
+ speculative_auth_response,
error);
if (!sd) {
return NULL;
}
if (sd->type == MONGOC_SERVER_UNKNOWN) {
memcpy (error, &sd->error, sizeof (bson_error_t));
mongoc_server_description_destroy (sd);
return NULL;
} else {
node->max_write_batch_size = sd->max_write_batch_size;
node->min_wire_version = sd->min_wire_version;
node->max_wire_version = sd->max_wire_version;
node->max_bson_obj_size = sd->max_bson_obj_size;
node->max_msg_size = sd->max_msg_size;
}
return sd;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_build_basic_auth_digest --
*
* Computes the Basic Authentication digest using the credentials
* configured for @cluster and the @nonce provided.
*
* The result should be freed by the caller using bson_free() when
* they are finished with it.
*
* Returns:
* A newly allocated string containing the digest.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static char *
_mongoc_cluster_build_basic_auth_digest (mongoc_cluster_t *cluster,
const char *nonce)
{
const char *username;
const char *password;
char *password_digest;
char *password_md5;
char *digest_in;
char *ret;
ENTRY;
/*
* The following generates the digest to be used for basic authentication
* with a MongoDB server. More information on the format can be found
* at the following location:
*
* http://docs.mongodb.org/meta-driver/latest/legacy/
* implement-authentication-in-driver/
*/
BSON_ASSERT (cluster);
BSON_ASSERT (cluster->uri);
username = mongoc_uri_get_username (cluster->uri);
password = mongoc_uri_get_password (cluster->uri);
password_digest = bson_strdup_printf ("%s:mongo:%s", username, password);
password_md5 = _mongoc_hex_md5 (password_digest);
digest_in = bson_strdup_printf ("%s%s%s", nonce, username, password_md5);
ret = _mongoc_hex_md5 (digest_in);
bson_free (digest_in);
bson_free (password_md5);
bson_free (password_digest);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node_cr --
*
* Performs authentication of @node using the credentials provided
* when configuring the @cluster instance.
*
* This is the Challenge-Response mode of authentication.
*
* Returns:
* true if authentication was successful; otherwise false and
* @error is set.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_node_cr (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
bson_iter_t iter;
const char *auth_source;
bson_t command;
bson_t reply;
char *digest;
char *nonce;
bool ret;
mongoc_server_stream_t *server_stream;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
if (!(auth_source = mongoc_uri_get_auth_source (cluster->uri)) ||
(*auth_source == '\0')) {
auth_source = "admin";
}
/*
* To authenticate a node using basic authentication, we need to first
* get the nonce from the server. We use that to hash our password which
* is sent as a reply to the server. If everything went good we get a
* success notification back from the server.
*/
/*
* Execute the getnonce command to fetch the nonce used for generating
* md5 digest of our password information.
*/
bson_init (&command);
bson_append_int32 (&command, "getnonce", 8, 1);
mongoc_cmd_parts_init (
&parts, cluster->client, auth_source, MONGOC_QUERY_SLAVE_OK, &command);
parts.prohibit_lsid = true;
server_stream = _mongoc_cluster_create_server_stream (
cluster->client->topology, sd->id, stream, error);
+ if (!server_stream) {
+ bson_destroy (&command);
+ bson_destroy (&reply);
+ RETURN (false);
+ }
if (!mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, &reply, error)) {
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&command);
bson_destroy (&reply);
RETURN (false);
}
bson_destroy (&command);
if (!bson_iter_init_find_case (&iter, &reply, "nonce")) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_GETNONCE,
"Invalid reply from getnonce");
bson_destroy (&reply);
RETURN (false);
}
/*
* Build our command to perform the authentication.
*/
nonce = bson_iter_dup_utf8 (&iter, NULL);
digest = _mongoc_cluster_build_basic_auth_digest (cluster, nonce);
bson_init (&command);
bson_append_int32 (&command, "authenticate", 12, 1);
bson_append_utf8 (
&command, "user", 4, mongoc_uri_get_username (cluster->uri), -1);
bson_append_utf8 (&command, "nonce", 5, nonce, -1);
bson_append_utf8 (&command, "key", 3, digest, -1);
bson_destroy (&reply);
bson_free (nonce);
bson_free (digest);
/*
* Execute the authenticate command. mongoc_cluster_run_command_private
* checks for {ok: 1} in the response.
*/
mongoc_cmd_parts_init (
&parts, cluster->client, auth_source, MONGOC_QUERY_SLAVE_OK, &command);
parts.prohibit_lsid = true;
ret = mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, &reply, error);
if (!ret) {
/* error->message is already set */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
}
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&command);
bson_destroy (&reply);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node_plain --
*
* Perform SASL PLAIN authentication for @node. We do this manually
- * instead of using the SASL module because its rather simplistic.
+ * instead of using the SASL module because it is rather simplistic.
*
* Returns:
* true if successful; otherwise false and error is set.
*
* Side effects:
* error may be set.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_node_plain (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
char buf[4096];
int buflen = 0;
const char *username;
const char *password;
bson_t b = BSON_INITIALIZER;
bson_t reply;
size_t len;
char *str;
bool ret;
mongoc_server_stream_t *server_stream;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
username = mongoc_uri_get_username (cluster->uri);
if (!username) {
username = "";
}
password = mongoc_uri_get_password (cluster->uri);
if (!password) {
password = "";
}
str = bson_strdup_printf ("%c%s%c%s", '\0', username, '\0', password);
len = strlen (username) + strlen (password) + 2;
- buflen = bson_b64_ntop ((const uint8_t *) str, len, buf, sizeof buf);
+ buflen = COMMON_PREFIX (
+ bson_b64_ntop ((const uint8_t *) str, len, buf, sizeof buf));
bson_free (str);
if (buflen == -1) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"failed base64 encoding message");
return false;
}
BSON_APPEND_INT32 (&b, "saslStart", 1);
BSON_APPEND_UTF8 (&b, "mechanism", "PLAIN");
bson_append_utf8 (&b, "payload", 7, (const char *) buf, buflen);
BSON_APPEND_INT32 (&b, "autoAuthorize", 1);
mongoc_cmd_parts_init (
&parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &b);
parts.prohibit_lsid = true;
server_stream = _mongoc_cluster_create_server_stream (
cluster->client->topology, sd->id, stream, error);
+ if (!server_stream) {
+ bson_destroy (&b);
+ bson_destroy (&reply);
+ return false;
+ }
+
ret = mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, &reply, error);
mongoc_server_stream_cleanup (server_stream);
if (!ret) {
/* error->message is already set */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
}
bson_destroy (&b);
bson_destroy (&reply);
return ret;
}
-
-static bool
-_mongoc_cluster_auth_node_x509 (mongoc_cluster_t *cluster,
- mongoc_stream_t *stream,
- mongoc_server_description_t *sd,
- bson_error_t *error)
+bool
+_mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri,
+ const mongoc_ssl_opt_t *ssl_opts,
+ bson_t *cmd /* OUT */,
+ bson_error_t *error /* OUT */)
{
#ifndef MONGOC_ENABLE_SSL
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"The MONGODB-X509 authentication mechanism requires "
"libmongoc built with ENABLE_SSL");
return false;
#else
- mongoc_cmd_parts_t parts;
const char *username_from_uri = NULL;
char *username_from_subject = NULL;
- bson_t cmd;
- bson_t reply;
- bool ret;
- mongoc_server_stream_t *server_stream;
- BSON_ASSERT (cluster);
- BSON_ASSERT (stream);
+ BSON_ASSERT (uri);
- username_from_uri = mongoc_uri_get_username (cluster->uri);
+ username_from_uri = mongoc_uri_get_username (uri);
if (username_from_uri) {
TRACE ("%s", "X509: got username from URI");
} else {
- if (!cluster->client->ssl_opts.pem_file) {
+ if (!ssl_opts || !ssl_opts->pem_file) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"cannot determine username for "
"X-509 authentication.");
return false;
}
- username_from_subject = mongoc_ssl_extract_subject (
- cluster->client->ssl_opts.pem_file, cluster->client->ssl_opts.pem_pwd);
+ username_from_subject =
+ mongoc_ssl_extract_subject (ssl_opts->pem_file, ssl_opts->pem_pwd);
if (!username_from_subject) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"No username provided for X509 authentication.");
return false;
}
TRACE ("%s", "X509: got username from certificate");
}
- bson_init (&cmd);
- BSON_APPEND_INT32 (&cmd, "authenticate", 1);
- BSON_APPEND_UTF8 (&cmd, "mechanism", "MONGODB-X509");
- BSON_APPEND_UTF8 (&cmd,
+ bson_init (cmd);
+ BSON_APPEND_INT32 (cmd, "authenticate", 1);
+ BSON_APPEND_UTF8 (cmd, "mechanism", "MONGODB-X509");
+ BSON_APPEND_UTF8 (cmd,
"user",
username_from_uri ? username_from_uri
: username_from_subject);
- mongoc_cmd_parts_init (
- &parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &cmd);
- parts.prohibit_lsid = true;
- server_stream = _mongoc_cluster_create_server_stream (
- cluster->client->topology, sd->id, stream, error);
- ret = mongoc_cluster_run_command_parts (
- cluster, server_stream, &parts, &reply, error);
- mongoc_server_stream_cleanup (server_stream);
- if (!ret) {
- /* error->message is already set */
- error->domain = MONGOC_ERROR_CLIENT;
- error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
+ bson_free (username_from_subject);
+
+ return true;
+#endif
+}
+
+
+static bool
+_mongoc_cluster_auth_node_x509 (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ mongoc_server_description_t *sd,
+ bson_error_t *error)
+{
+#ifndef MONGOC_ENABLE_SSL
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_AUTHENTICATE,
+ "The MONGODB-X509 authentication mechanism requires "
+ "libmongoc built with ENABLE_SSL");
+ return false;
+#else
+ mongoc_cmd_parts_t parts;
+ bson_t cmd;
+ bson_t reply;
+ bool ret;
+ mongoc_server_stream_t *server_stream;
+
+ BSON_ASSERT (cluster);
+ BSON_ASSERT (stream);
+
+ if (!_mongoc_cluster_get_auth_cmd_x509 (
+ cluster->uri, &cluster->client->ssl_opts, &cmd, error)) {
+ return false;
+ }
+
+ mongoc_cmd_parts_init (
+ &parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &cmd);
+ parts.prohibit_lsid = true;
+ server_stream = _mongoc_cluster_create_server_stream (
+ cluster->client->topology, sd->id, stream, error);
+ if (!server_stream) {
+ bson_destroy (&cmd);
+ bson_destroy (&reply);
+ return false;
+ }
+
+ ret = mongoc_cluster_run_command_parts (
+ cluster, server_stream, &parts, &reply, error);
+ mongoc_server_stream_cleanup (server_stream);
+ if (!ret) {
+ /* error->message is already set */
+ error->domain = MONGOC_ERROR_CLIENT;
+ error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
+ }
+
+ bson_destroy (&cmd);
+ bson_destroy (&reply);
+
+ return ret;
+#endif
+}
+
+#ifdef MONGOC_ENABLE_CRYPTO
+void
+_mongoc_cluster_init_scram (const mongoc_cluster_t *cluster,
+ mongoc_scram_t *scram,
+ mongoc_crypto_hash_algorithm_t algo)
+{
+ _mongoc_uri_init_scram (cluster->uri, scram, algo);
+
+ /* Apply previously cached SCRAM secrets if available */
+ if (cluster->scram_cache) {
+ _mongoc_scram_set_cache (scram, cluster->scram_cache);
+ }
+}
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _mongoc_cluster_get_auth_cmd_scram --
+ *
+ * Generates the saslStart command for scram authentication. Used
+ * during explicit authentication as well as speculative
+ * authentication during isMaster.
+ *
+ *
+ * Returns:
+ * true if the command could be generated, false otherwise
+ *
+ * Side effects:
+ * @error is set on failure.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+_mongoc_cluster_get_auth_cmd_scram (mongoc_crypto_hash_algorithm_t algo,
+ mongoc_scram_t *scram,
+ bson_t *cmd /* OUT */,
+ bson_error_t *error /* OUT */)
+{
+ uint8_t buf[4096] = {0};
+ uint32_t buflen = 0;
+ bson_t options;
+
+ if (!_mongoc_scram_step (
+ scram, buf, buflen, buf, sizeof buf, &buflen, error)) {
+ return false;
+ }
+
+ BSON_ASSERT (scram->step == 1);
+
+ bson_init (cmd);
+
+ BSON_APPEND_INT32 (cmd, "saslStart", 1);
+ if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_1) {
+ BSON_APPEND_UTF8 (cmd, "mechanism", "SCRAM-SHA-1");
+ } else if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_256) {
+ BSON_APPEND_UTF8 (cmd, "mechanism", "SCRAM-SHA-256");
+ } else {
+ BSON_ASSERT (false);
+ }
+ bson_append_binary (cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen);
+ BSON_APPEND_INT32 (cmd, "autoAuthorize", 1);
+
+ BSON_APPEND_DOCUMENT_BEGIN (cmd, "options", &options);
+ BSON_APPEND_BOOL (&options, "skipEmptyExchange", true);
+ bson_append_document_end (cmd, &options);
+
+ bson_destroy (&options);
+
+ return true;
+}
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _mongoc_cluster_run_scram_command --
+ *
+ * Runs a scram authentication command, handling auth_source and
+ * errors during the command.
+ *
+ *
+ * Returns:
+ * true if the command was successful, false otherwise
+ *
+ * Side effects:
+ * @error is set on failure.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_mongoc_cluster_run_scram_command (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ uint32_t server_id,
+ const bson_t *cmd,
+ bson_t *reply,
+ bson_error_t *error)
+{
+ mongoc_cmd_parts_t parts;
+ mongoc_server_stream_t *server_stream;
+ const char *auth_source;
+
+ BSON_ASSERT (cluster);
+
+ if (!(auth_source = mongoc_uri_get_auth_source (cluster->uri)) ||
+ (*auth_source == '\0')) {
+ auth_source = "admin";
+ }
+
+ mongoc_cmd_parts_init (
+ &parts, cluster->client, auth_source, MONGOC_QUERY_SLAVE_OK, cmd);
+ parts.prohibit_lsid = true;
+ server_stream = _mongoc_cluster_create_server_stream (
+ cluster->client->topology, server_id, stream, error);
+ if (!server_stream) {
+ bson_destroy (reply);
+ return false;
+ }
+
+ if (!mongoc_cluster_run_command_parts (
+ cluster, server_stream, &parts, reply, error)) {
+ mongoc_server_stream_cleanup (server_stream);
+ bson_destroy (reply);
+
+ /* error->message is already set */
+ error->domain = MONGOC_ERROR_CLIENT;
+ error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
+
+ return false;
+ }
+
+ mongoc_server_stream_cleanup (server_stream);
+
+ return true;
+}
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _mongoc_cluster_auth_scram_start --
+ *
+ * Starts scram authentication by generating and sending the saslStart
+ * command. The conversation can then be resumed using
+ * _mongoc_cluster_auth_scram_continue.
+ *
+ *
+ * Returns:
+ * true if the saslStart command was successful, false otherwise
+ *
+ * Side effects:
+ * @error is set on failure.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_mongoc_cluster_auth_scram_start (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ uint32_t server_id,
+ mongoc_crypto_hash_algorithm_t algo,
+ mongoc_scram_t *scram,
+ bson_t *reply,
+ bson_error_t *error)
+{
+ bson_t cmd;
+
+ BSON_ASSERT (scram->step == 0);
+
+ if (!_mongoc_cluster_get_auth_cmd_scram (algo, scram, &cmd, error)) {
+ /* error->message is already set */
+ error->domain = MONGOC_ERROR_CLIENT;
+ error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
+
+ return false;
+ }
+
+ if (!_mongoc_cluster_run_scram_command (
+ cluster, stream, server_id, &cmd, reply, error)) {
+ bson_destroy (&cmd);
+
+ return false;
+ }
+
+ bson_destroy (&cmd);
+
+ return true;
+}
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _mongoc_cluster_scram_handle_reply --
+ *
+ * Handles replies from _mongoc_cluster_run_scram_command. The @done
+ * argument will be set to true if the scram conversation was
+ * completed successfully.
+ *
+ *
+ * Returns:
+ * true if the reply was handled successfully, false if there was an
+ * error. Note that the return value itself does not indicate whether
+ * authentication was completed successfully.
+ *
+ * Side effects:
+ * @error is set on failure. @done, @conv_id, @buf, and @buflen are
+ * set for use in the next scram step.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_mongoc_cluster_scram_handle_reply (mongoc_scram_t *scram,
+ const bson_t *reply,
+ bool *done /* OUT */,
+ int *conv_id /* OUT */,
+ uint8_t *buf /* OUT */,
+ uint32_t bufmax,
+ uint32_t *buflen /* OUT */,
+ bson_error_t *error)
+{
+ bson_iter_t iter;
+ bson_subtype_t btype;
+ const char *tmpstr;
+
+ BSON_ASSERT (scram);
+
+ if (bson_iter_init_find (&iter, reply, "done") &&
+ bson_iter_as_bool (&iter)) {
+ if (scram->step < 2) {
+ /* Prior to step 2, we haven't even received server proof. */
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_AUTHENTICATE,
+ "Incorrect step for 'done'");
+ return false;
+ }
+ *done = true;
+ if (scram->step >= 3) {
+ return true;
+ }
+ }
+
+ if (!bson_iter_init_find (&iter, reply, "conversationId") ||
+ !BSON_ITER_HOLDS_INT32 (&iter) ||
+ !(*conv_id = bson_iter_int32 (&iter)) ||
+ !bson_iter_init_find (&iter, reply, "payload") ||
+ !BSON_ITER_HOLDS_BINARY (&iter)) {
+ const char *errmsg = "Received invalid SCRAM reply from MongoDB server.";
+
+ MONGOC_DEBUG ("SCRAM: authentication failed");
+
+ if (bson_iter_init_find (&iter, reply, "errmsg") &&
+ BSON_ITER_HOLDS_UTF8 (&iter)) {
+ errmsg = bson_iter_utf8 (&iter, NULL);
+ }
+
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_AUTHENTICATE,
+ "%s",
+ errmsg);
+ return false;
}
- if (username_from_subject) {
- bson_free (username_from_subject);
+ bson_iter_binary (&iter, &btype, buflen, (const uint8_t **) &tmpstr);
+
+ if (*buflen > bufmax) {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_AUTHENTICATE,
+ "SCRAM reply from MongoDB is too large.");
+ return false;
}
- bson_destroy (&cmd);
- bson_destroy (&reply);
+ memcpy (buf, tmpstr, *buflen);
- return ret;
-#endif
+ return true;
}
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _mongoc_cluster_auth_scram_continue --
+ *
+ * Continues the scram conversation from the reply to a saslStart
+ * command, either sent explicitly or received through speculative
+ * authentication during isMaster.
+ *
+ *
+ * Returns:
+ * true if authenticated. false on failure and @error is set.
+ *
+ * Side effects:
+ * @error is set on failure.
+ *
+ *--------------------------------------------------------------------------
+ */
-#ifdef MONGOC_ENABLE_CRYPTO
static bool
-_mongoc_cluster_auth_node_scram (mongoc_cluster_t *cluster,
- mongoc_stream_t *stream,
- mongoc_server_description_t *sd,
- mongoc_crypto_hash_algorithm_t algo,
- bson_error_t *error)
+_mongoc_cluster_auth_scram_continue (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ uint32_t server_id,
+ mongoc_scram_t *scram,
+ const bson_t *sasl_start_reply,
+ bson_error_t *error)
{
- mongoc_cmd_parts_t parts;
- uint32_t buflen = 0;
- mongoc_scram_t scram;
- bson_iter_t iter;
- bool ret = false;
- const char *tmpstr;
- const char *auth_source;
- uint8_t buf[4096] = {0};
bson_t cmd;
- bson_t reply;
+ uint8_t buf[4096] = {0};
+ uint32_t buflen = 0;
int conv_id = 0;
- bson_subtype_t btype;
- mongoc_server_stream_t *server_stream;
bool done = false;
+ bson_t reply_local;
- BSON_ASSERT (cluster);
- BSON_ASSERT (stream);
-
- if (!(auth_source = mongoc_uri_get_auth_source (cluster->uri)) ||
- (*auth_source == '\0')) {
- auth_source = "admin";
- }
-
- _mongoc_scram_init (&scram, algo);
-
- _mongoc_scram_set_pass (&scram, mongoc_uri_get_password (cluster->uri));
- _mongoc_scram_set_user (&scram, mongoc_uri_get_username (cluster->uri));
-
- /* Apply previously cached SCRAM secrets if available */
- if (cluster->scram_cache) {
- _mongoc_scram_set_cache (&scram, cluster->scram_cache);
+ if (!_mongoc_cluster_scram_handle_reply (scram,
+ sasl_start_reply,
+ &done,
+ &conv_id,
+ buf,
+ sizeof buf,
+ &buflen,
+ error)) {
+ return false;
}
for (;;) {
if (!_mongoc_scram_step (
- &scram, buf, buflen, buf, sizeof buf, &buflen, error)) {
- goto failure;
+ scram, buf, buflen, buf, sizeof buf, &buflen, error)) {
+ return false;
}
- if (done && (scram.step >= 3)) {
+ if (done && (scram->step >= 3)) {
break;
}
bson_init (&cmd);
- if (scram.step == 1) {
- BSON_APPEND_INT32 (&cmd, "saslStart", 1);
- if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_1) {
- BSON_APPEND_UTF8 (&cmd, "mechanism", "SCRAM-SHA-1");
- } else if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_256) {
- BSON_APPEND_UTF8 (&cmd, "mechanism", "SCRAM-SHA-256");
- } else {
- BSON_ASSERT (false);
- }
- bson_append_binary (
- &cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen);
- BSON_APPEND_INT32 (&cmd, "autoAuthorize", 1);
- } else {
- BSON_APPEND_INT32 (&cmd, "saslContinue", 1);
- BSON_APPEND_INT32 (&cmd, "conversationId", conv_id);
- bson_append_binary (
- &cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen);
- }
+ BSON_APPEND_INT32 (&cmd, "saslContinue", 1);
+ BSON_APPEND_INT32 (&cmd, "conversationId", conv_id);
+ bson_append_binary (&cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen);
- TRACE ("SCRAM: authenticating (step %d)", scram.step);
+ TRACE ("SCRAM: authenticating (step %d)", scram->step);
- mongoc_cmd_parts_init (
- &parts, cluster->client, auth_source, MONGOC_QUERY_SLAVE_OK, &cmd);
- parts.prohibit_lsid = true;
- server_stream = _mongoc_cluster_create_server_stream (
- cluster->client->topology, sd->id, stream, error);
- if (!mongoc_cluster_run_command_parts (
- cluster, server_stream, &parts, &reply, error)) {
- mongoc_server_stream_cleanup (server_stream);
+ if (!_mongoc_cluster_run_scram_command (
+ cluster, stream, server_id, &cmd, &reply_local, error)) {
bson_destroy (&cmd);
- bson_destroy (&reply);
-
- /* error->message is already set */
- error->domain = MONGOC_ERROR_CLIENT;
- error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
- goto failure;
+ return false;
}
- mongoc_server_stream_cleanup (server_stream);
bson_destroy (&cmd);
- if (bson_iter_init_find (&iter, &reply, "done") &&
- bson_iter_as_bool (&iter)) {
- if (scram.step < 2) {
- /* Prior to step 2, we haven't even received server proof. */
- bson_destroy (&reply);
- bson_set_error (error,
- MONGOC_ERROR_CLIENT,
- MONGOC_ERROR_CLIENT_AUTHENTICATE,
- "Incorrect step for 'done'");
- goto failure;
- }
- done = true;
- if (scram.step >= 3) {
- bson_destroy (&reply);
- break;
- }
+ if (!_mongoc_cluster_scram_handle_reply (scram,
+ &reply_local,
+ &done,
+ &conv_id,
+ buf,
+ sizeof buf,
+ &buflen,
+ error)) {
+ bson_destroy (&reply_local);
+ return false;
}
- if (!bson_iter_init_find (&iter, &reply, "conversationId") ||
- !BSON_ITER_HOLDS_INT32 (&iter) ||
- !(conv_id = bson_iter_int32 (&iter)) ||
- !bson_iter_init_find (&iter, &reply, "payload") ||
- !BSON_ITER_HOLDS_BINARY (&iter)) {
- const char *errmsg =
- "Received invalid SCRAM reply from MongoDB server.";
+ bson_destroy (&reply_local);
- MONGOC_DEBUG ("SCRAM: authentication failed");
+ if (done && (scram->step >= 3)) {
+ break;
+ }
+ }
- if (bson_iter_init_find (&iter, &reply, "errmsg") &&
- BSON_ITER_HOLDS_UTF8 (&iter)) {
- errmsg = bson_iter_utf8 (&iter, NULL);
- }
+ TRACE ("%s", "SCRAM: authenticated");
- bson_set_error (error,
- MONGOC_ERROR_CLIENT,
- MONGOC_ERROR_CLIENT_AUTHENTICATE,
- "%s",
- errmsg);
- bson_destroy (&reply);
- goto failure;
- }
+ /* Save cached SCRAM secrets for future use */
+ if (cluster->scram_cache) {
+ _mongoc_scram_cache_destroy (cluster->scram_cache);
+ }
- bson_iter_binary (&iter, &btype, &buflen, (const uint8_t **) &tmpstr);
+ cluster->scram_cache = _mongoc_scram_get_cache (scram);
- if (buflen > sizeof buf) {
- bson_set_error (error,
- MONGOC_ERROR_CLIENT,
- MONGOC_ERROR_CLIENT_AUTHENTICATE,
- "SCRAM reply from MongoDB is too large.");
- bson_destroy (&reply);
- goto failure;
- }
+ return true;
+}
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _mongoc_cluster_auth_node_scram --
+ *
+ * Invokes scram authentication by sending a saslStart command and
+ * handling all replies.
+ *
+ *
+ * Returns:
+ * true if authenticated. false on failure and @error is set.
+ *
+ * Side effects:
+ * @error is set on failure.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_mongoc_cluster_auth_node_scram (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ uint32_t server_id,
+ mongoc_crypto_hash_algorithm_t algo,
+ bson_error_t *error)
+{
+ mongoc_scram_t scram;
+ bool ret = false;
+ bson_t reply;
+
+ BSON_ASSERT (cluster);
+
+ _mongoc_cluster_init_scram (cluster, &scram, algo);
- memcpy (buf, tmpstr, buflen);
+ if (!_mongoc_cluster_auth_scram_start (
+ cluster, stream, server_id, algo, &scram, &reply, error)) {
+ goto failure;
+ }
+ if (!_mongoc_cluster_auth_scram_continue (
+ cluster, stream, server_id, &scram, &reply, error)) {
bson_destroy (&reply);
+
+ goto failure;
}
TRACE ("%s", "SCRAM: authenticated");
ret = true;
- /* Save cached SCRAM secrets for future use */
- if (cluster->scram_cache) {
- _mongoc_scram_cache_destroy (cluster->scram_cache);
- }
-
- cluster->scram_cache = _mongoc_scram_get_cache (&scram);
+ bson_destroy (&reply);
failure:
_mongoc_scram_destroy (&scram);
return ret;
}
#endif
static bool
_mongoc_cluster_auth_node_scram_sha_1 (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
#ifndef MONGOC_ENABLE_CRYPTO
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"The SCRAM_SHA_1 authentication mechanism requires "
"libmongoc built with ENABLE_SSL");
return false;
#else
return _mongoc_cluster_auth_node_scram (
- cluster, stream, sd, MONGOC_CRYPTO_ALGORITHM_SHA_1, error);
+ cluster, stream, sd->id, MONGOC_CRYPTO_ALGORITHM_SHA_1, error);
#endif
}
static bool
_mongoc_cluster_auth_node_scram_sha_256 (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
#ifndef MONGOC_ENABLE_CRYPTO
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"The SCRAM_SHA_256 authentication mechanism requires "
"libmongoc built with ENABLE_SSL");
return false;
#else
return _mongoc_cluster_auth_node_scram (
- cluster, stream, sd, MONGOC_CRYPTO_ALGORITHM_SHA_256, error);
+ cluster, stream, sd->id, MONGOC_CRYPTO_ALGORITHM_SHA_256, error);
#endif
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node --
*
* Authenticate a cluster node depending on the required mechanism.
*
* Returns:
* true if authenticated. false on failure and @error is set.
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_node (
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
const mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs,
bson_error_t *error)
{
bool ret = false;
const char *mechanism;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
mechanism = mongoc_uri_get_auth_mechanism (cluster->uri);
if (!mechanism) {
if (sasl_supported_mechs->scram_sha_256) {
/* Auth spec: "If SCRAM-SHA-256 is present in the list of mechanisms,
* then it MUST be used as the default; otherwise, SCRAM-SHA-1 MUST be
* used as the default, regardless of whether SCRAM-SHA-1 is in the
* list. Drivers MUST NOT attempt to use any other mechanism (e.g.
* PLAIN) as the default." [...] "If saslSupportedMechs is not present
* in the isMaster results for mechanism negotiation, then SCRAM-SHA-1
* MUST be used when talking to servers >= 3.0." */
mechanism = "SCRAM-SHA-256";
} else {
mechanism = "SCRAM-SHA-1";
}
}
if (0 == strcasecmp (mechanism, "MONGODB-CR")) {
ret = _mongoc_cluster_auth_node_cr (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "MONGODB-X509")) {
ret = _mongoc_cluster_auth_node_x509 (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "SCRAM-SHA-1")) {
ret = _mongoc_cluster_auth_node_scram_sha_1 (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "SCRAM-SHA-256")) {
ret =
_mongoc_cluster_auth_node_scram_sha_256 (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "GSSAPI")) {
ret = _mongoc_cluster_auth_node_sasl (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "PLAIN")) {
ret = _mongoc_cluster_auth_node_plain (cluster, stream, sd, error);
+ } else if (0 == strcasecmp (mechanism, "MONGODB-AWS")) {
+ ret = _mongoc_cluster_auth_node_aws (cluster, stream, sd, error);
} else {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Unknown authentication mechanism \"%s\".",
mechanism);
}
if (!ret) {
mongoc_counter_auth_failure_inc ();
MONGOC_DEBUG ("Authentication failed: %s", error->message);
} else {
mongoc_counter_auth_success_inc ();
TRACE ("%s", "Authentication succeeded");
}
RETURN (ret);
}
/*
- *--------------------------------------------------------------------------
- *
- * mongoc_cluster_disconnect_node --
+ * Close the connection associated with this server.
*
- * Remove a node from the set of nodes. This should be done if
- * a stream in the set is found to be invalid. If @invalidate is
- * true, also mark the server Unknown in the topology description,
- * passing the error information from @why as the reason.
- *
- * WARNING: pointers to a disconnected mongoc_cluster_node_t or
- * its stream are now invalid, be careful of dangling pointers.
- *
- * Returns:
- * None.
- *
- * Side effects:
- * Removes node from cluster's set of nodes, and frees the
- * mongoc_cluster_node_t if pooled.
- *
- *--------------------------------------------------------------------------
+ * Called when a network error occurs, or to close connection tied to an exhaust
+ * cursor.
+ * If the cluster is pooled, removes the node from cluster's set of nodes.
+ * WARNING: pointers to a disconnected mongoc_cluster_node_t or its stream are
+ * now invalid, be careful of dangling pointers.
*/
void
-mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster,
- uint32_t server_id,
- bool invalidate,
- const bson_error_t *why /* IN */)
+mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster, uint32_t server_id)
{
mongoc_topology_t *topology = cluster->client->topology;
ENTRY;
if (topology->single_threaded) {
mongoc_topology_scanner_node_t *scanner_node;
scanner_node =
mongoc_topology_scanner_get_node (topology->scanner, server_id);
/* might never actually have connected */
if (scanner_node && scanner_node->stream) {
mongoc_topology_scanner_node_disconnect (scanner_node, true);
}
} else {
mongoc_set_rm (cluster->nodes, server_id);
}
- if (invalidate) {
- mongoc_topology_invalidate_server (topology, server_id, why);
- }
-
EXIT;
}
static void
_mongoc_cluster_node_destroy (mongoc_cluster_node_t *node)
{
/* Failure, or Replica Set reconfigure without this node */
mongoc_stream_failed (node->stream);
bson_free (node->connection_address);
bson_free (node);
}
static void
_mongoc_cluster_node_dtor (void *data_, void *ctx_)
{
mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) data_;
_mongoc_cluster_node_destroy (node);
}
static mongoc_cluster_node_t *
_mongoc_cluster_node_new (mongoc_stream_t *stream,
+ uint32_t generation,
const char *connection_address)
{
mongoc_cluster_node_t *node;
if (!stream) {
return NULL;
}
node = (mongoc_cluster_node_t *) bson_malloc0 (sizeof *node);
node->stream = stream;
node->connection_address = bson_strdup (connection_address);
- node->timestamp = bson_get_monotonic_time ();
+ node->generation = generation;
node->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION;
node->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION;
node->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE;
node->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE;
node->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE;
return node;
}
+static bool
+_mongoc_cluster_finish_speculative_auth (mongoc_cluster_t *cluster,
+ mongoc_stream_t *stream,
+ mongoc_server_description_t *sd,
+ bson_t *speculative_auth_response,
+ mongoc_scram_t *scram,
+ bson_error_t *error)
+{
+ const char *mechanism =
+ _mongoc_topology_scanner_get_speculative_auth_mechanism (cluster->uri);
+ bool ret = false;
+ bool auth_handled = false;
+
+ BSON_ASSERT (sd);
+ BSON_ASSERT (speculative_auth_response);
+
+ if (!mechanism) {
+ return false;
+ }
+
+ if (bson_empty (speculative_auth_response)) {
+ return false;
+ }
+
+#ifdef MONGOC_ENABLE_SSL
+ if (strcasecmp (mechanism, "MONGODB-X509") == 0) {
+ /* For X509, a successful ismaster with speculativeAuthenticate field
+ * indicates successful auth */
+ ret = true;
+ auth_handled = true;
+ }
+#endif
+
+#ifdef MONGOC_ENABLE_CRYPTO
+ if (strcasecmp (mechanism, "SCRAM-SHA-1") == 0 ||
+ strcasecmp (mechanism, "SCRAM-SHA-256") == 0) {
+ /* Don't attempt authentication if scram objects have advanced past
+ * saslStart */
+ if (scram->step != 1) {
+ return false;
+ }
+
+ auth_handled = true;
+
+ ret = _mongoc_cluster_auth_scram_continue (
+ cluster, stream, sd->id, scram, speculative_auth_response, error);
+ }
+#endif
+
+ if (auth_handled) {
+ if (!ret) {
+ mongoc_counter_auth_failure_inc ();
+ MONGOC_DEBUG ("Speculative authentication failed: %s", error->message);
+ } else {
+ mongoc_counter_auth_success_inc ();
+ TRACE ("%s", "Speculative authentication succeeded");
+ }
+ }
+
+ bson_reinit (speculative_auth_response);
+
+ return ret;
+}
+
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_add_node --
*
* Add a new node to this cluster for the given server description.
*
* NOTE: does NOT check if this server is already in the cluster.
*
* Returns:
* A stream connected to the server, or NULL on failure.
*
* Side effects:
* Adds a cluster node, or sets error on failure.
*
*--------------------------------------------------------------------------
*/
static mongoc_stream_t *
_mongoc_cluster_add_node (mongoc_cluster_t *cluster,
+ uint32_t generation,
uint32_t server_id,
bson_error_t *error /* OUT */)
{
mongoc_host_list_t *host = NULL;
mongoc_cluster_node_t *cluster_node = NULL;
mongoc_stream_t *stream;
mongoc_server_description_t *sd;
mongoc_handshake_sasl_supported_mechs_t sasl_supported_mechs;
+ mongoc_scram_t scram = {0};
+ bson_t speculative_auth_response = BSON_INITIALIZER;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (!cluster->client->topology->single_threaded);
host =
_mongoc_topology_host_by_id (cluster->client->topology, server_id, error);
if (!host) {
GOTO (error);
}
TRACE ("Adding new server to cluster: %s", host->host_and_port);
stream = _mongoc_client_create_stream (cluster->client, host, error);
if (!stream) {
MONGOC_WARNING (
"Failed connection to %s (%s)", host->host_and_port, error->message);
GOTO (error);
+ /* TODO CDRIVER-3654: if this is a non-timeout network error and the
+ * generation is not stale, mark the server unknown and increment the
+ * generation. */
}
/* take critical fields from a fresh ismaster */
- cluster_node = _mongoc_cluster_node_new (stream, host->host_and_port);
+ cluster_node =
+ _mongoc_cluster_node_new (stream, generation, host->host_and_port);
- sd = _mongoc_cluster_run_ismaster (cluster, cluster_node, server_id, error);
+ sd = _mongoc_cluster_run_ismaster (cluster,
+ cluster_node,
+ server_id,
+ cluster->scram_cache,
+ &scram,
+ &speculative_auth_response,
+ error);
if (!sd) {
GOTO (error);
}
_mongoc_handshake_parse_sasl_supported_mechs (&sd->last_is_master,
&sasl_supported_mechs);
if (cluster->requires_auth) {
- if (!_mongoc_cluster_auth_node (
+ /* Complete speculative authentication */
+ bool is_auth = _mongoc_cluster_finish_speculative_auth (
+ cluster, stream, sd, &speculative_auth_response, &scram, error);
+
+ if (!is_auth &&
+ !_mongoc_cluster_auth_node (
cluster, cluster_node->stream, sd, &sasl_supported_mechs, error)) {
MONGOC_WARNING ("Failed authentication to %s (%s)",
host->host_and_port,
error->message);
mongoc_server_description_destroy (sd);
GOTO (error);
}
}
mongoc_server_description_destroy (sd);
+ bson_destroy (&speculative_auth_response);
mongoc_set_add (cluster->nodes, server_id, cluster_node);
_mongoc_host_list_destroy_all (host);
+#ifdef MONGOC_ENABLE_CRYPTO
+ _mongoc_scram_destroy (&scram);
+#endif
+
RETURN (stream);
error:
+ bson_destroy (&speculative_auth_response);
_mongoc_host_list_destroy_all (host); /* null ok */
+#ifdef MONGOC_ENABLE_CRYPTO
+ _mongoc_scram_destroy (&scram);
+#endif
+
if (cluster_node) {
_mongoc_cluster_node_destroy (cluster_node); /* also destroys stream */
}
RETURN (NULL);
}
static void
node_not_found (mongoc_topology_t *topology,
uint32_t server_id,
bson_error_t *error /* OUT */)
{
mongoc_server_description_t *sd;
if (!error) {
return;
}
sd = mongoc_topology_server_by_id (topology, server_id, error);
if (!sd) {
return;
}
if (sd->error.code) {
memcpy (error, &sd->error, sizeof *error);
} else {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"Could not find node %s",
sd->host.host_and_port);
}
mongoc_server_description_destroy (sd);
}
static void
stream_not_found (mongoc_topology_t *topology,
uint32_t server_id,
const char *connection_address,
bson_error_t *error /* OUT */)
{
mongoc_server_description_t *sd;
sd = mongoc_topology_server_by_id (topology, server_id, error);
if (error) {
if (sd && sd->error.code) {
memcpy (error, &sd->error, sizeof *error);
} else {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"Could not find stream for node %s",
connection_address);
}
}
if (sd) {
mongoc_server_description_destroy (sd);
}
}
mongoc_server_stream_t *
_mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
const mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error /* OUT */)
{
mongoc_topology_t *topology;
mongoc_server_stream_t *server_stream;
bson_error_t err_local;
/* if fetch_stream fails we need a place to receive error details and pass
* them to mongoc_topology_invalidate_server. */
bson_error_t *err_ptr = error ? error : &err_local;
ENTRY;
topology = cluster->client->topology;
/* in the single-threaded use case we share topology's streams */
if (topology->single_threaded) {
server_stream = mongoc_cluster_fetch_stream_single (
cluster, server_id, reconnect_ok, err_ptr);
} else {
server_stream = mongoc_cluster_fetch_stream_pooled (
cluster, server_id, reconnect_ok, err_ptr);
}
if (!server_stream) {
- /* Server Discovery And Monitoring Spec: "When an application operation
- * fails because of any network error besides a socket timeout, the
- * client MUST replace the server's description with a default
- * ServerDescription of type Unknown, and fill the ServerDescription's
- * error field with useful information."
- *
- * error was filled by fetch_stream_single/pooled, pass it to disconnect()
+ /* TODO CDRIVER-3654. A null server stream could be due to:
+ * 1. Network error during handshake.
+ * 2. Failure to retrieve server description (if it was removed from
+ * topology).
+ * 3. Auth error during handshake.
+ * Only (1) should mark the server unknown and clear the pool.
+ * Network errors should be checked at a lower layer than this, when an
+ * operation on a stream fails, and should take the connection generation
+ * into account.
*/
- mongoc_cluster_disconnect_node (cluster, server_id, true, err_ptr);
+
+ mongoc_topology_invalidate_server (topology, server_id, err_ptr);
+ mongoc_cluster_disconnect_node (cluster, server_id);
+ bson_mutex_lock (&topology->mutex);
+ _mongoc_topology_clear_connection_pool (topology, server_id);
+ if (!topology->single_threaded) {
+ _mongoc_topology_background_monitoring_cancel_check (topology,
+ server_id);
+ }
+ bson_mutex_unlock (&topology->mutex);
_mongoc_bson_init_with_transient_txn_error (cs, reply);
}
RETURN (server_stream);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_stream_for_server --
*
* Fetch the stream for @server_id. If @reconnect_ok and there is no
* valid stream, attempts to reconnect; if not @reconnect_ok then only
* an existing stream can be returned, or NULL.
*
* Returns:
* A mongoc_server_stream_t, or NULL
*
* Side effects:
* May add a node or reconnect one, if @reconnect_ok.
* Authenticates the stream if needed.
* Sets @error and initializes @reply on error.
*
*--------------------------------------------------------------------------
*/
mongoc_server_stream_t *
mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *server_stream = NULL;
bson_error_t err_local = {0};
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (server_id);
if (cs && cs->server_id && cs->server_id != server_id) {
_mongoc_bson_init_if_set (reply);
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_SERVER_SELECTION_INVALID_ID,
"Requested server id does not matched pinned server id");
RETURN (NULL);
}
if (!error) {
error = &err_local;
}
server_stream = _mongoc_cluster_stream_for_server (
cluster, server_id, reconnect_ok, cs, reply, error);
- if (!server_stream) {
- /* failed */
- mongoc_cluster_disconnect_node (cluster, server_id, true, error);
- }
if (_in_sharded_txn (cs)) {
_mongoc_client_session_pin (cs, server_id);
} else {
/* Transactions Spec: Additionally, any non-transaction operation using
* a pinned ClientSession MUST unpin the session and the operation MUST
* perform normal server selection. */
if (cs && !_mongoc_client_session_in_txn_or_ending (cs)) {
_mongoc_client_session_unpin (cs);
}
}
RETURN (server_stream);
}
static mongoc_server_stream_t *
mongoc_cluster_fetch_stream_single (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error /* OUT */)
{
mongoc_topology_t *topology;
mongoc_server_description_t *sd;
mongoc_topology_scanner_node_t *scanner_node;
char *address;
topology = cluster->client->topology;
scanner_node =
mongoc_topology_scanner_get_node (topology->scanner, server_id);
/* This could happen if a user explicitly passes a bad server id. */
if (!scanner_node) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Could not find server with id: %d",
server_id);
return NULL;
}
/* Retired scanner nodes are removed at the end of a scan. If the node was
* retired, that would indicate a bug. */
if (scanner_node->retired) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Unexpected, selecting server marked for removal: %s",
scanner_node->host.host_and_port);
return NULL;
}
if (scanner_node->stream) {
sd = mongoc_topology_server_by_id (topology, server_id, error);
if (!sd) {
return NULL;
}
} else {
if (!reconnect_ok) {
stream_not_found (
topology, server_id, scanner_node->host.host_and_port, error);
return NULL;
}
/* save the scanner node address in case it is removed during the scan. */
address = bson_strdup (scanner_node->host.host_and_port);
_mongoc_topology_do_blocking_scan (topology, error);
if (error->code) {
bson_free (address);
return NULL;
}
scanner_node =
mongoc_topology_scanner_get_node (topology->scanner, server_id);
if (!scanner_node || !scanner_node->stream) {
stream_not_found (topology, server_id, address, error);
bson_free (address);
return NULL;
}
bson_free (address);
sd = mongoc_topology_server_by_id (topology, server_id, error);
if (!sd) {
return NULL;
}
}
if (sd->type == MONGOC_SERVER_UNKNOWN) {
memcpy (error, &sd->error, sizeof *error);
mongoc_server_description_destroy (sd);
return NULL;
}
/* stream open but not auth'ed: first use since connect or reconnect */
if (cluster->requires_auth && !scanner_node->has_auth) {
- if (!_mongoc_cluster_auth_node (cluster,
+ /* Complete speculative authentication */
+ bool has_speculative_auth = _mongoc_cluster_finish_speculative_auth (
+ cluster,
+ scanner_node->stream,
+ sd,
+ &scanner_node->speculative_auth_response,
+ &scanner_node->scram,
+ &sd->error);
+
+#ifdef MONGOC_ENABLE_CRYPTO
+ _mongoc_scram_destroy (&scanner_node->scram);
+#endif
+
+ if (!has_speculative_auth &&
+ !_mongoc_cluster_auth_node (cluster,
scanner_node->stream,
sd,
&scanner_node->sasl_supported_mechs,
&sd->error)) {
memcpy (error, &sd->error, sizeof *error);
mongoc_server_description_destroy (sd);
return NULL;
}
scanner_node->has_auth = true;
}
return mongoc_server_stream_new (
&topology->description, sd, scanner_node->stream);
}
+/*
+ *--------------------------------------------------------------------------
+ *
+ * mongoc_cluster_stream_valid --
+ *
+ * Internal function to determine if @server_stream is valid and
+ * associated with the given cluster.
+ *
+ * Returns:
+ * true if @server_stream is not NULL, hasn't been freed or changed;
+ * otherwise false.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+mongoc_cluster_stream_valid (mongoc_cluster_t *cluster,
+ mongoc_server_stream_t *server_stream)
+{
+ mongoc_server_stream_t *tmp_stream = NULL;
+ mongoc_topology_t *topology;
+ mongoc_server_description_t *sd;
+ bool ret = false;
+ bson_error_t error;
+
+ BSON_ASSERT (cluster);
+
+ if (!server_stream) {
+ goto done;
+ }
+
+ tmp_stream = mongoc_cluster_stream_for_server (
+ cluster, server_stream->sd->id, false, NULL, NULL, NULL);
+ if (!tmp_stream || tmp_stream->stream != server_stream->stream) {
+ /* stream was freed, or has changed. */
+ goto done;
+ }
+
+ topology = cluster->client->topology;
+ bson_mutex_lock (&topology->mutex);
+ sd = mongoc_topology_description_server_by_id (
+ &topology->description, server_stream->sd->id, &error);
+ if (!sd || server_stream->sd->generation < sd->generation) {
+ /* No server description, or the pool has been cleared. */
+ bson_mutex_unlock (&topology->mutex);
+ goto done;
+ }
+ bson_mutex_unlock (&topology->mutex);
+
+ ret = true;
+done:
+ mongoc_server_stream_cleanup (tmp_stream);
+ return ret;
+}
+
mongoc_server_stream_t *
_mongoc_cluster_create_server_stream (mongoc_topology_t *topology,
uint32_t server_id,
mongoc_stream_t *stream,
bson_error_t *error /* OUT */)
{
mongoc_server_description_t *sd;
mongoc_server_stream_t *server_stream = NULL;
/* can't just use mongoc_topology_server_by_id(), since we must hold the
* lock while copying topology->description.logical_time below */
bson_mutex_lock (&topology->mutex);
sd = mongoc_server_description_new_copy (
mongoc_topology_description_server_by_id (
&topology->description, server_id, error));
if (sd) {
server_stream =
mongoc_server_stream_new (&topology->description, sd, stream);
}
bson_mutex_unlock (&topology->mutex);
return server_stream;
}
static mongoc_server_stream_t *
mongoc_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error /* OUT */)
{
mongoc_topology_t *topology;
mongoc_stream_t *stream;
mongoc_cluster_node_t *cluster_node;
- int64_t timestamp;
+ mongoc_server_description_t *sd;
+ bool has_server_description = false;
+ uint32_t generation = 0;
cluster_node =
(mongoc_cluster_node_t *) mongoc_set_get (cluster->nodes, server_id);
topology = cluster->client->topology;
+ bson_mutex_lock (&topology->mutex);
+ sd = mongoc_topology_description_server_by_id (
+ &topology->description, server_id, error);
+ if (sd) {
+ has_server_description = true;
+ generation = sd->generation;
+ }
+ bson_mutex_unlock (&topology->mutex);
if (cluster_node) {
BSON_ASSERT (cluster_node->stream);
- timestamp = mongoc_topology_server_timestamp (topology, server_id);
- if (timestamp == -1 || cluster_node->timestamp < timestamp) {
- /* topology change or net error during background scan made us remove
- * or replace server description since node's birth. destroy node. */
- mongoc_cluster_disconnect_node (
- cluster, server_id, false /* invalidate */, NULL);
+ if (!has_server_description || cluster_node->generation < generation) {
+ /* Since the stream was created, connections to this server were
+ * invalidated.
+ * This may have happened if:
+ * - A background scan removed the server description.
+ * - A network error or a "not master"/"node is recovering" error
+ * occurred on an app connection.
+ * - A network error occurred on the monitor connection.
+ */
+ mongoc_cluster_disconnect_node (cluster, server_id);
} else {
return _mongoc_cluster_create_server_stream (
topology, server_id, cluster_node->stream, error);
}
}
/* no node, or out of date */
if (!reconnect_ok) {
node_not_found (topology, server_id, error);
return NULL;
}
- stream = _mongoc_cluster_add_node (cluster, server_id, error);
+ stream = _mongoc_cluster_add_node (cluster, generation, server_id, error);
if (stream) {
return _mongoc_cluster_create_server_stream (
topology, server_id, stream, error);
} else {
return NULL;
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_init --
*
* Initializes @cluster using the @uri and @client provided. The
* @uri is used to determine the "mode" of the cluster. Based on the
* uri we can determine if we are connected to a single host, a
* replicaSet, or a shardedCluster.
*
* Returns:
* None.
*
* Side effects:
* @cluster is initialized.
*
*--------------------------------------------------------------------------
*/
void
mongoc_cluster_init (mongoc_cluster_t *cluster,
const mongoc_uri_t *uri,
void *client)
{
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (uri);
memset (cluster, 0, sizeof *cluster);
cluster->uri = mongoc_uri_copy (uri);
cluster->client = (mongoc_client_t *) client;
cluster->requires_auth =
(mongoc_uri_get_username (uri) || mongoc_uri_get_auth_mechanism (uri));
cluster->sockettimeoutms = mongoc_uri_get_option_as_int32 (
uri, MONGOC_URI_SOCKETTIMEOUTMS, MONGOC_DEFAULT_SOCKETTIMEOUTMS);
cluster->socketcheckintervalms =
mongoc_uri_get_option_as_int32 (uri,
MONGOC_URI_SOCKETCHECKINTERVALMS,
MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS);
/* TODO for single-threaded case we don't need this */
cluster->nodes = mongoc_set_new (8, _mongoc_cluster_node_dtor, NULL);
_mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t));
cluster->operation_id = rand ();
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_destroy --
*
* Clean up after @cluster and destroy all active connections.
* All resources for @cluster are released.
*
* Returns:
* None.
*
* Side effects:
* Everything.
*
*--------------------------------------------------------------------------
*/
void
mongoc_cluster_destroy (mongoc_cluster_t *cluster) /* INOUT */
{
ENTRY;
BSON_ASSERT (cluster);
mongoc_uri_destroy (cluster->uri);
mongoc_set_destroy (cluster->nodes);
_mongoc_array_destroy (&cluster->iov);
#ifdef MONGOC_ENABLE_CRYPTO
if (cluster->scram_cache) {
_mongoc_scram_cache_destroy (cluster->scram_cache);
}
#endif
EXIT;
}
static uint32_t
_mongoc_cluster_select_server_id (mongoc_client_session_t *cs,
mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error)
{
uint32_t server_id;
if (_in_sharded_txn (cs)) {
server_id = cs->server_id;
if (!server_id) {
server_id = mongoc_topology_select_server_id (
topology, optype, read_prefs, error);
if (server_id) {
_mongoc_client_session_pin (cs, server_id);
}
}
} else {
server_id =
mongoc_topology_select_server_id (topology, optype, read_prefs, error);
/* Transactions Spec: Additionally, any non-transaction operation using a
* pinned ClientSession MUST unpin the session and the operation MUST
* perform normal server selection. */
if (cs && !_mongoc_client_session_in_txn_or_ending (cs)) {
_mongoc_client_session_unpin (cs);
}
}
return server_id;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_stream_for_optype --
*
* Internal server selection.
*
* Returns:
* A mongoc_server_stream_t on which you must call
* mongoc_server_stream_cleanup, or NULL on failure (sets @error)
*
* Side effects:
* May add or disconnect nodes in @cluster->nodes.
* Sets @error and initializes @reply on error.
*
*--------------------------------------------------------------------------
*/
static mongoc_server_stream_t *
_mongoc_cluster_stream_for_optype (mongoc_cluster_t *cluster,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *server_stream;
uint32_t server_id;
mongoc_topology_t *topology = cluster->client->topology;
ENTRY;
BSON_ASSERT (cluster);
server_id = _mongoc_cluster_select_server_id (
cs, topology, optype, read_prefs, error);
if (!server_id) {
_mongoc_bson_init_with_transient_txn_error (cs, reply);
RETURN (NULL);
}
if (!mongoc_cluster_check_interval (cluster, server_id)) {
/* Server Selection Spec: try once more */
server_id = _mongoc_cluster_select_server_id (
cs, topology, optype, read_prefs, error);
if (!server_id) {
_mongoc_bson_init_with_transient_txn_error (cs, reply);
RETURN (NULL);
}
}
/* connect or reconnect to server if necessary */
server_stream = _mongoc_cluster_stream_for_server (
cluster, server_id, true /* reconnect_ok */, cs, reply, error);
RETURN (server_stream);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_stream_for_reads --
*
* Internal server selection.
*
* Returns:
* A mongoc_server_stream_t on which you must call
* mongoc_server_stream_cleanup, or NULL on failure (sets @error)
*
* Side effects:
* Sets @error and initializes @reply on error.
* May add new nodes to @cluster->nodes.
*
*--------------------------------------------------------------------------
*/
mongoc_server_stream_t *
mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster,
const mongoc_read_prefs_t *read_prefs,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error)
{
const mongoc_read_prefs_t *prefs_override = read_prefs;
if (_mongoc_client_session_in_txn (cs)) {
prefs_override = cs->txn.opts.read_prefs;
}
return _mongoc_cluster_stream_for_optype (
cluster, MONGOC_SS_READ, prefs_override, cs, reply, error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_stream_for_writes --
*
* Get a stream for write operations.
*
* Returns:
* A mongoc_server_stream_t on which you must call
* mongoc_server_stream_cleanup, or NULL on failure (sets @error)
*
* Side effects:
* Sets @error and initializes @reply on error.
* May add new nodes to @cluster->nodes.
*
*--------------------------------------------------------------------------
*/
mongoc_server_stream_t *
mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_cluster_stream_for_optype (
cluster, MONGOC_SS_WRITE, NULL, cs, reply, error);
}
static bool
_mongoc_cluster_min_of_max_obj_size_sds (void *item, void *ctx)
{
mongoc_server_description_t *sd = (mongoc_server_description_t *) item;
int32_t *current_min = (int32_t *) ctx;
if (sd->max_bson_obj_size < *current_min) {
*current_min = sd->max_bson_obj_size;
}
return true;
}
static bool
_mongoc_cluster_min_of_max_obj_size_nodes (void *item, void *ctx)
{
mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) item;
int32_t *current_min = (int32_t *) ctx;
if (node->max_bson_obj_size < *current_min) {
*current_min = node->max_bson_obj_size;
}
return true;
}
static bool
_mongoc_cluster_min_of_max_msg_size_sds (void *item, void *ctx)
{
mongoc_server_description_t *sd = (mongoc_server_description_t *) item;
int32_t *current_min = (int32_t *) ctx;
if (sd->max_msg_size < *current_min) {
*current_min = sd->max_msg_size;
}
return true;
}
static bool
_mongoc_cluster_min_of_max_msg_size_nodes (void *item, void *ctx)
{
mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) item;
int32_t *current_min = (int32_t *) ctx;
if (node->max_msg_size < *current_min) {
*current_min = node->max_msg_size;
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_get_max_bson_obj_size --
*
* Return the minimum max_bson_obj_size across all servers in cluster.
*
* NOTE: this method uses the topology's mutex.
*
* Returns:
* The minimum max_bson_obj_size.
*
* Side effects:
* None
*
*--------------------------------------------------------------------------
*/
int32_t
mongoc_cluster_get_max_bson_obj_size (mongoc_cluster_t *cluster)
{
int32_t max_bson_obj_size = -1;
max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE;
if (!cluster->client->topology->single_threaded) {
mongoc_set_for_each (cluster->nodes,
_mongoc_cluster_min_of_max_obj_size_nodes,
&max_bson_obj_size);
} else {
mongoc_set_for_each (cluster->client->topology->description.servers,
_mongoc_cluster_min_of_max_obj_size_sds,
&max_bson_obj_size);
}
return max_bson_obj_size;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_get_max_msg_size --
*
* Return the minimum max msg size across all servers in cluster.
*
* NOTE: this method uses the topology's mutex.
*
* Returns:
* The minimum max_msg_size
*
* Side effects:
* None
*
*--------------------------------------------------------------------------
*/
int32_t
mongoc_cluster_get_max_msg_size (mongoc_cluster_t *cluster)
{
int32_t max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE;
if (!cluster->client->topology->single_threaded) {
mongoc_set_for_each (cluster->nodes,
_mongoc_cluster_min_of_max_msg_size_nodes,
&max_msg_size);
} else {
mongoc_set_for_each (cluster->client->topology->description.servers,
_mongoc_cluster_min_of_max_msg_size_sds,
&max_msg_size);
}
return max_msg_size;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_check_interval --
*
* Server Selection Spec:
*
* Only for single-threaded drivers.
*
* If a server is selected that has an existing connection that has been
* idle for socketCheckIntervalMS, the driver MUST check the connection
* with the "ping" command. If the ping succeeds, use the selected
* connection. If not, set the server's type to Unknown and update the
* Topology Description according to the Server Discovery and Monitoring
* Spec, and attempt once more to select a server.
*
* Returns:
* True if the check succeeded or no check was required, false if the
* check failed.
*
* Side effects:
* If a check fails, closes stream and may set server type Unknown.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id)
{
mongoc_cmd_parts_t parts;
mongoc_topology_t *topology;
mongoc_topology_scanner_node_t *scanner_node;
mongoc_stream_t *stream;
int64_t now;
bson_t command;
bson_error_t error;
bool r = true;
mongoc_server_stream_t *server_stream;
topology = cluster->client->topology;
if (!topology->single_threaded) {
return true;
}
scanner_node =
mongoc_topology_scanner_get_node (topology->scanner, server_id);
if (!scanner_node) {
return false;
}
BSON_ASSERT (!scanner_node->retired);
stream = scanner_node->stream;
if (!stream) {
return false;
}
now = bson_get_monotonic_time ();
if (scanner_node->last_used + (1000 * CHECK_CLOSED_DURATION_MSEC) < now) {
if (mongoc_stream_check_closed (stream)) {
bson_set_error (&error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"connection closed");
- mongoc_cluster_disconnect_node (cluster, server_id, true, &error);
+ mongoc_cluster_disconnect_node (cluster, server_id);
+ mongoc_topology_invalidate_server (topology, server_id, &error);
return false;
}
}
if (scanner_node->last_used + (1000 * cluster->socketcheckintervalms) <
now) {
bson_init (&command);
BSON_APPEND_INT32 (&command, "ping", 1);
mongoc_cmd_parts_init (
&parts, cluster->client, "admin", MONGOC_QUERY_SLAVE_OK, &command);
parts.prohibit_lsid = true;
server_stream = _mongoc_cluster_create_server_stream (
cluster->client->topology, server_id, stream, &error);
+ if (!server_stream) {
+ bson_destroy (&command);
+ return false;
+ }
r = mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, NULL, &error);
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&command);
if (!r) {
- mongoc_cluster_disconnect_node (cluster, server_id, true, &error);
+ mongoc_cluster_disconnect_node (cluster, server_id);
+ mongoc_topology_invalidate_server (topology, server_id, &error);
}
}
return r;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_legacy_rpc_sendv_to_server --
*
* Sends the given RPCs to the given server. Used for OP_QUERY cursors,
* OP_KILLCURSORS, and legacy writes with OP_INSERT, OP_UPDATE, and
* OP_DELETE. This function is *not* in the OP_QUERY command path.
*
* Returns:
* True if successful.
*
* Side effects:
* @rpc may be mutated and should be considered invalid after calling
* this method.
*
* @error may be set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_legacy_rpc_sendv_to_server (
mongoc_cluster_t *cluster,
mongoc_rpc_t *rpc,
mongoc_server_stream_t *server_stream,
bson_error_t *error)
{
uint32_t server_id;
int32_t max_msg_size;
bool ret = false;
int32_t compressor_id = 0;
char *output = NULL;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (rpc);
BSON_ASSERT (server_stream);
server_id = server_stream->sd->id;
if (cluster->client->in_exhaust) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_IN_EXHAUST,
"A cursor derived from this client is in exhaust.");
GOTO (done);
}
_mongoc_array_clear (&cluster->iov);
compressor_id = mongoc_server_description_compressor_id (server_stream->sd);
_mongoc_rpc_gather (rpc, &cluster->iov);
_mongoc_rpc_swab_to_le (rpc);
if (compressor_id != -1) {
output = _mongoc_rpc_compress (cluster, compressor_id, rpc, error);
if (output == NULL) {
GOTO (done);
}
}
max_msg_size = mongoc_server_stream_max_msg_size (server_stream);
if (BSON_UINT32_FROM_LE (rpc->header.msg_len) > max_msg_size) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_TOO_BIG,
"Attempted to send an RPC larger than the "
"max allowed message size. Was %u, allowed %u.",
BSON_UINT32_FROM_LE (rpc->header.msg_len),
max_msg_size);
GOTO (done);
}
if (!_mongoc_stream_writev_full (server_stream->stream,
cluster->iov.data,
cluster->iov.len,
cluster->sockettimeoutms,
error)) {
GOTO (done);
}
_mongoc_topology_update_last_used (cluster->client->topology, server_id);
ret = true;
done:
if (compressor_id) {
bson_free (output);
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_try_recv --
*
* Tries to receive the next event from the MongoDB server.
* The contents are loaded into @buffer and then
* scattered into the @rpc structure. @rpc is valid as long as
* @buffer contains the contents read into it.
*
* Callers that can optimize a reuse of @buffer should do so. It
* can save many memory allocations.
*
* Returns:
* True if successful.
*
* Side effects:
* @rpc is set on success, @error on failure.
* @buffer will be filled with the input data.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_try_recv (mongoc_cluster_t *cluster,
mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
mongoc_server_stream_t *server_stream,
bson_error_t *error)
{
- uint32_t server_id;
bson_error_t err_local;
int32_t msg_len;
int32_t max_msg_size;
off_t pos;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (rpc);
BSON_ASSERT (buffer);
BSON_ASSERT (server_stream);
- server_id = server_stream->sd->id;
- TRACE ("Waiting for reply from server_id \"%u\"", server_id);
+ TRACE ("Waiting for reply from server_id \"%u\"", server_stream->sd->id);
if (!error) {
error = &err_local;
}
/*
* Buffer the message length to determine how much more to read.
*/
pos = buffer->len;
if (!_mongoc_buffer_append_from_stream (
buffer, server_stream->stream, 4, cluster->sockettimeoutms, error)) {
MONGOC_DEBUG (
"Could not read 4 bytes, stream probably closed or timed out");
mongoc_counter_protocol_ingress_error_inc ();
- mongoc_cluster_disconnect_node (
- cluster,
- server_id,
- !mongoc_stream_timed_out (server_stream->stream),
- error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
RETURN (false);
}
/*
* Read the msg length from the buffer.
*/
memcpy (&msg_len, &buffer->data[pos], 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
max_msg_size = mongoc_server_stream_max_msg_size (server_stream);
if ((msg_len < 16) || (msg_len > max_msg_size)) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Corrupt or malicious reply received.");
- mongoc_cluster_disconnect_node (cluster, server_id, true, error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
mongoc_counter_protocol_ingress_error_inc ();
RETURN (false);
}
/*
* Read the rest of the message from the stream.
*/
if (!_mongoc_buffer_append_from_stream (buffer,
server_stream->stream,
msg_len - 4,
cluster->sockettimeoutms,
error)) {
- mongoc_cluster_disconnect_node (
- cluster,
- server_id,
- !mongoc_stream_timed_out (server_stream->stream),
- error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
mongoc_counter_protocol_ingress_error_inc ();
RETURN (false);
}
/*
* Scatter the buffer into the rpc structure.
*/
if (!_mongoc_rpc_scatter (rpc, &buffer->data[pos], msg_len)) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Failed to decode reply from server.");
- mongoc_cluster_disconnect_node (cluster, server_id, true, error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
mongoc_counter_protocol_ingress_error_inc ();
RETURN (false);
}
if (BSON_UINT32_FROM_LE (rpc->header.opcode) == MONGOC_OPCODE_COMPRESSED) {
uint8_t *buf = NULL;
size_t len = BSON_UINT32_FROM_LE (rpc->compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
buf = bson_malloc0 (len);
if (!_mongoc_rpc_decompress (rpc, buf, len)) {
bson_free (buf);
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress server reply");
RETURN (false);
}
_mongoc_buffer_destroy (buffer);
_mongoc_buffer_init (buffer, buf, len, NULL, NULL);
}
_mongoc_rpc_swab_from_le (rpc);
RETURN (true);
}
static void
network_error_reply (bson_t *reply, mongoc_cmd_t *cmd)
{
bson_t labels;
if (reply) {
bson_init (reply);
}
if (cmd->session) {
if (cmd->session->server_session) {
cmd->session->server_session->dirty = true;
}
/* Transactions Spec defines TransientTransactionError: "Any
- * network error or server selection error encountered running any
- * command besides commitTransaction in a transaction. In the case
- * of command errors, the server adds the label; in the case of
- * network errors or server selection errors where the client
- * receives no server reply, the client adds the label." */
+ * network error or server selection error encountered running any
+ * command besides commitTransaction in a transaction. In the case
+ * of command errors, the server adds the label; in the case of
+ * network errors or server selection errors where the client
+ * receives no server reply, the client adds the label." */
if (_mongoc_client_session_in_txn (cmd->session) && !cmd->is_txn_finish) {
/* Transaction Spec: "Drivers MUST unpin a ClientSession when a command
- * within a transaction, including commitTransaction and abortTransaction,
- * fails with a TransientTransactionError". If we're about to add
- * a TransientTransactionError label due to a client side error then we
- * unpin. If commitTransaction/abortTransation includes a label in the
- * server reply, we unpin in _mongoc_client_session_handle_reply. */
+ * within a transaction, including commitTransaction and
+ * abortTransaction,
+ * fails with a TransientTransactionError". If we're about to add
+ * a TransientTransactionError label due to a client side error then we
+ * unpin. If commitTransaction/abortTransation includes a label in the
+ * server reply, we unpin in _mongoc_client_session_handle_reply. */
cmd->session->server_id = 0;
if (!reply) {
return;
}
BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels);
BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR);
bson_append_array_end (reply, &labels);
}
}
}
static bool
mongoc_cluster_run_opmsg (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error)
{
mongoc_rpc_section_t section[2];
mongoc_buffer_t buffer;
bson_t reply_local; /* only statically initialized */
char *output = NULL;
mongoc_rpc_t rpc;
int32_t msg_len;
bool ok;
- const mongoc_server_stream_t *server_stream;
+ mongoc_server_stream_t *server_stream;
server_stream = cmd->server_stream;
if (!cmd->command_name) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Empty command document");
_mongoc_bson_init_if_set (reply);
return false;
}
if (cluster->client->in_exhaust) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_IN_EXHAUST,
"A cursor derived from this client is in exhaust.");
_mongoc_bson_init_if_set (reply);
return false;
}
_mongoc_array_clear (&cluster->iov);
_mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL);
rpc.header.msg_len = 0;
rpc.header.request_id = ++cluster->request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_MSG;
if (cmd->is_acknowledged) {
rpc.msg.flags = 0;
} else {
rpc.msg.flags = MONGOC_MSG_MORE_TO_COME;
}
rpc.msg.n_sections = 1;
section[0].payload_type = 0;
section[0].payload.bson_document = bson_get_data (cmd->command);
rpc.msg.sections[0] = section[0];
if (cmd->payload) {
section[1].payload_type = 1;
section[1].payload.sequence.size = cmd->payload_size +
strlen (cmd->payload_identifier) + 1 +
sizeof (int32_t);
section[1].payload.sequence.identifier = cmd->payload_identifier;
section[1].payload.sequence.bson_documents = cmd->payload;
rpc.msg.sections[1] = section[1];
rpc.msg.n_sections++;
}
_mongoc_rpc_gather (&rpc, &cluster->iov);
_mongoc_rpc_swab_to_le (&rpc);
if (mongoc_cmd_is_compressible (cmd)) {
int32_t compressor_id =
mongoc_server_description_compressor_id (server_stream->sd);
TRACE (
"Function '%s' is compressible: %d", cmd->command_name, compressor_id);
if (compressor_id != -1) {
output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error);
if (output == NULL) {
_mongoc_bson_init_if_set (reply);
_mongoc_buffer_destroy (&buffer);
return false;
}
}
}
ok = _mongoc_stream_writev_full (server_stream->stream,
(mongoc_iovec_t *) cluster->iov.data,
cluster->iov.len,
cluster->sockettimeoutms,
error);
if (!ok) {
/* add info about the command to writev_full's error message */
RUN_CMD_ERR_DECORATE;
- mongoc_cluster_disconnect_node (
- cluster, server_stream->sd->id, true, error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
+ server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
/* If acknowledged, wait for a server response. Otherwise, exit early */
if (cmd->is_acknowledged) {
ok = _mongoc_buffer_append_from_stream (
&buffer, server_stream->stream, 4, cluster->sockettimeoutms, error);
if (!ok) {
RUN_CMD_ERR_DECORATE;
- mongoc_cluster_disconnect_node (
- cluster, server_stream->sd->id, true, error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
+ server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
BSON_ASSERT (buffer.len == 4);
memcpy (&msg_len, buffer.data, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
if ((msg_len < 16) || (msg_len > server_stream->sd->max_msg_size)) {
RUN_CMD_ERR (
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Message size %d is not within expected range 16-%d bytes",
msg_len,
server_stream->sd->max_msg_size);
- mongoc_cluster_disconnect_node (
- cluster, server_stream->sd->id, true, error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
+ server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
ok = _mongoc_buffer_append_from_stream (&buffer,
server_stream->stream,
(size_t) msg_len - 4,
cluster->sockettimeoutms,
error);
if (!ok) {
RUN_CMD_ERR_DECORATE;
- mongoc_cluster_disconnect_node (
- cluster, server_stream->sd->id, true, error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
+ server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
ok = _mongoc_rpc_scatter (&rpc, buffer.data, buffer.len);
if (!ok) {
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Malformed message from server");
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) {
size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
output = bson_realloc (output, len);
if (!_mongoc_rpc_decompress (&rpc, (uint8_t *) output, len)) {
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress message from server");
- mongoc_cluster_disconnect_node (
- cluster, server_stream->sd->id, true, error);
+ _handle_network_error (
+ cluster, server_stream, true /* handshake complete */, error);
+ server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
}
_mongoc_rpc_swab_from_le (&rpc);
memcpy (&msg_len, rpc.msg.sections[0].payload.bson_document, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
bson_init_static (
&reply_local, rpc.msg.sections[0].payload.bson_document, msg_len);
_mongoc_topology_update_cluster_time (cluster->client->topology,
&reply_local);
ok = _mongoc_cmd_check_ok (
&reply_local, cluster->client->error_api_version, error);
if (cmd->session) {
_mongoc_client_session_handle_reply (
cmd->session, cmd->is_acknowledged, &reply_local);
}
if (reply) {
bson_copy_to (&reply_local, reply);
}
} else {
_mongoc_bson_init_if_set (reply);
}
_mongoc_buffer_destroy (&buffer);
bson_free (output);
return ok;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h
index 6c88592d..6982a5ca 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h
@@ -1,145 +1,145 @@
/*
* Copyright 2017 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.
*/
#include "mongoc-prelude.h"
/*
* Internal struct to represent a command we will send to the server - command
* parameters are collected in a mongoc_cmd_parts_t until we know the server's
* wire version and whether it is mongos, then we collect the parts into a
* mongoc_cmd_t, and gather that into a mongoc_rpc_t.
*/
#ifndef MONGOC_CMD_PRIVATE_H
#define MONGOC_CMD_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-server-stream-private.h"
#include "mongoc-read-prefs.h"
#include "mongoc.h"
#include "mongoc-opts-private.h"
BSON_BEGIN_DECLS
#define MONGOC_DEFAULT_RETRYREADS true
/* retryWrites requires sessions, which require crypto */
#ifdef MONGOC_ENABLE_CRYPTO
#define MONGOC_DEFAULT_RETRYWRITES true
#else
#define MONGOC_DEFAULT_RETRYWRITES false
#endif
typedef enum {
MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN,
MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES,
MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_NO
} mongoc_cmd_parts_allow_txn_number_t;
typedef struct _mongoc_cmd_t {
const char *db_name;
mongoc_query_flags_t query_flags;
const bson_t *command;
const char *command_name;
const uint8_t *payload;
int32_t payload_size;
const char *payload_identifier;
- const mongoc_server_stream_t *server_stream;
+ mongoc_server_stream_t *server_stream;
int64_t operation_id;
mongoc_client_session_t *session;
bool is_acknowledged;
bool is_txn_finish;
} mongoc_cmd_t;
typedef struct _mongoc_cmd_parts_t {
mongoc_cmd_t assembled;
mongoc_query_flags_t user_query_flags;
const bson_t *body;
bson_t read_concern_document;
bson_t write_concern_document;
bson_t extra;
const mongoc_read_prefs_t *read_prefs;
bson_t assembled_body;
bool is_read_command;
bool is_write_command;
bool prohibit_lsid;
mongoc_cmd_parts_allow_txn_number_t allow_txn_number;
bool is_retryable_read;
bool is_retryable_write;
bool has_temp_session;
mongoc_client_t *client;
} mongoc_cmd_parts_t;
void
mongoc_cmd_parts_init (mongoc_cmd_parts_t *op,
mongoc_client_t *client,
const char *db_name,
mongoc_query_flags_t user_query_flags,
const bson_t *command_body);
void
mongoc_cmd_parts_set_session (mongoc_cmd_parts_t *parts,
mongoc_client_session_t *cs);
bool
mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts,
bson_iter_t *iter,
int max_wire_version,
bson_error_t *error);
bool
mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts,
const mongoc_read_concern_t *rc,
int max_wire_version,
bson_error_t *error);
bool
mongoc_cmd_parts_set_write_concern (mongoc_cmd_parts_t *parts,
const mongoc_write_concern_t *wc,
int max_wire_version,
bson_error_t *error);
bool
mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts,
mongoc_read_write_opts_t *rw_opts,
int max_wire_version,
bson_error_t *error);
bool
mongoc_cmd_parts_assemble (mongoc_cmd_parts_t *parts,
- const mongoc_server_stream_t *server_stream,
+ mongoc_server_stream_t *server_stream,
bson_error_t *error);
bool
mongoc_cmd_is_compressible (mongoc_cmd_t *cmd);
void
mongoc_cmd_parts_cleanup (mongoc_cmd_parts_t *op);
bool
_is_retryable_read (const mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream);
void
_mongoc_cmd_append_payload_as_array (const mongoc_cmd_t* cmd, bson_t *out);
BSON_END_DECLS
#endif /* MONGOC_CMD_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
index 0acfd771..b05b659f 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
@@ -1,1089 +1,1113 @@
/*
* Copyright 2017 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.
*/
#include "mongoc-cmd-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-client-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-write-concern-private.h"
/* For strcasecmp on Windows */
#include "mongoc-util-private.h"
void
mongoc_cmd_parts_init (mongoc_cmd_parts_t *parts,
mongoc_client_t *client,
const char *db_name,
mongoc_query_flags_t user_query_flags,
const bson_t *command_body)
{
parts->body = command_body;
parts->user_query_flags = user_query_flags;
parts->read_prefs = NULL;
parts->is_read_command = false;
parts->is_write_command = false;
parts->prohibit_lsid = false;
parts->allow_txn_number = MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN;
parts->is_retryable_read = false;
parts->is_retryable_write = false;
parts->has_temp_session = false;
parts->client = client;
bson_init (&parts->read_concern_document);
bson_init (&parts->write_concern_document);
bson_init (&parts->extra);
bson_init (&parts->assembled_body);
parts->assembled.db_name = db_name;
parts->assembled.command = NULL;
parts->assembled.query_flags = MONGOC_QUERY_NONE;
parts->assembled.payload_identifier = NULL;
parts->assembled.payload = NULL;
parts->assembled.session = NULL;
parts->assembled.is_acknowledged = true;
parts->assembled.is_txn_finish = false;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_set_session --
*
* Set the client session field.
*
* Side effects:
* Aborts if the command is assembled or if mongoc_cmd_parts_append_opts
* was called before.
*
*--------------------------------------------------------------------------
*/
void
mongoc_cmd_parts_set_session (mongoc_cmd_parts_t *parts,
mongoc_client_session_t *cs)
{
BSON_ASSERT (parts);
BSON_ASSERT (!parts->assembled.command);
BSON_ASSERT (!parts->assembled.session);
parts->assembled.session = cs;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_append_opts --
*
* Take an iterator over user-supplied options document and append the
* options to @parts->command_extra, taking the selected server's max
* wire version into account.
*
* Return:
* True if the options were successfully applied. If any options are
* invalid, returns false and fills out @error. In that case @parts is
* invalid and must not be used.
*
* Side effects:
* May partly apply options before returning an error.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts,
bson_iter_t *iter,
int max_wire_version,
bson_error_t *error)
{
mongoc_client_session_t *cs = NULL;
mongoc_write_concern_t *wc;
uint32_t len;
const uint8_t *data;
bson_t read_concern;
+ const char *to_append;
ENTRY;
/* not yet assembled */
BSON_ASSERT (!parts->assembled.command);
while (bson_iter_next (iter)) {
if (BSON_ITER_IS_KEY (iter, "collation")) {
if (max_wire_version < WIRE_VERSION_COLLATION) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
RETURN (false);
}
} else if (BSON_ITER_IS_KEY (iter, "writeConcern")) {
wc = _mongoc_write_concern_new_from_iter (iter, error);
if (!wc) {
RETURN (false);
}
if (!mongoc_cmd_parts_set_write_concern (
parts, wc, max_wire_version, error)) {
mongoc_write_concern_destroy (wc);
RETURN (false);
}
mongoc_write_concern_destroy (wc);
continue;
} else if (BSON_ITER_IS_KEY (iter, "readConcern")) {
if (max_wire_version < WIRE_VERSION_READ_CONCERN) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support readConcern");
RETURN (false);
}
if (!BSON_ITER_HOLDS_DOCUMENT (iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Invalid readConcern");
RETURN (false);
}
/* add readConcern later, once we know about causal consistency */
bson_iter_document (iter, &len, &data);
BSON_ASSERT (bson_init_static (&read_concern, data, (size_t) len));
bson_destroy (&parts->read_concern_document);
bson_copy_to (&read_concern, &parts->read_concern_document);
continue;
} else if (BSON_ITER_IS_KEY (iter, "sessionId")) {
BSON_ASSERT (!parts->assembled.session);
if (!_mongoc_client_session_from_iter (
parts->client, iter, &cs, error)) {
RETURN (false);
}
parts->assembled.session = cs;
continue;
} else if (BSON_ITER_IS_KEY (iter, "serverId") ||
BSON_ITER_IS_KEY (iter, "maxAwaitTimeMS")) {
continue;
}
- if (!bson_append_iter (&parts->extra, bson_iter_key (iter), -1, iter)) {
+ to_append = bson_iter_key (iter);
+ if (!bson_append_iter (&parts->extra, to_append, -1, iter)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "Failed to append \"%s\" to create command.",
+ to_append);
RETURN (false);
}
}
RETURN (true);
}
#define OPTS_ERR(_code, ...) \
do { \
bson_set_error ( \
error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_##_code, __VA_ARGS__); \
RETURN (false); \
} while (0)
/* set readConcern if allowed, otherwise error */
bool
mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts,
const mongoc_read_concern_t *rc,
int max_wire_version,
bson_error_t *error)
{
const char *command_name;
ENTRY;
/* In a txn, set read concern in mongoc_cmd_parts_assemble, not here. *
* Transactions Spec: "The readConcern MUST NOT be inherited from the
* collection, database, or client associated with the driver method that
* invokes the first command." */
if (_mongoc_client_session_in_txn (parts->assembled.session)) {
RETURN (true);
}
command_name = _mongoc_get_command_name (parts->body);
if (!command_name) {
OPTS_ERR (COMMAND_INVALID_ARG, "Empty command document");
}
if (mongoc_read_concern_is_default (rc)) {
RETURN (true);
}
if (max_wire_version < WIRE_VERSION_READ_CONCERN) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"\"%s\" command does not support readConcern with "
"wire version %d, wire version %d is required",
command_name,
max_wire_version,
WIRE_VERSION_READ_CONCERN);
RETURN (false);
}
bson_destroy (&parts->read_concern_document);
bson_copy_to (_mongoc_read_concern_get_bson ((mongoc_read_concern_t *) rc),
&parts->read_concern_document);
RETURN (true);
}
/* set writeConcern if allowed, otherwise ignore - unlike set_read_concern, it's
* the caller's responsibility to check if writeConcern is supported */
bool
mongoc_cmd_parts_set_write_concern (mongoc_cmd_parts_t *parts,
const mongoc_write_concern_t *wc,
int max_wire_version,
bson_error_t *error)
{
const char *command_name;
bool is_fam;
bool wc_allowed;
ENTRY;
if (!wc) {
RETURN (true);
}
command_name = _mongoc_get_command_name (parts->body);
if (!command_name) {
OPTS_ERR (COMMAND_INVALID_ARG, "Empty command document");
}
is_fam = !strcasecmp (command_name, "findandmodify");
wc_allowed =
parts->is_write_command ||
(is_fam && max_wire_version >= WIRE_VERSION_FAM_WRITE_CONCERN) ||
(!is_fam && max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN);
if (wc_allowed) {
parts->assembled.is_acknowledged =
mongoc_write_concern_is_acknowledged (wc);
bson_destroy (&parts->write_concern_document);
bson_copy_to (
_mongoc_write_concern_get_bson ((mongoc_write_concern_t *) wc),
&parts->write_concern_document);
}
RETURN (true);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_append_read_write --
*
* Append user-supplied options to @parts->command_extra, taking the
* selected server's max wire version into account.
*
* Return:
* True if the options were successfully applied. If any options are
* invalid, returns false and fills out @error. In that case @parts is
* invalid and must not be used.
*
* Side effects:
* May partly apply options before returning an error.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts,
mongoc_read_write_opts_t *rw_opts,
int max_wire_version,
bson_error_t *error)
{
ENTRY;
/* not yet assembled */
BSON_ASSERT (!parts->assembled.command);
if (!bson_empty (&rw_opts->collation)) {
if (max_wire_version < WIRE_VERSION_COLLATION) {
OPTS_ERR (PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
}
if (!bson_append_document (
&parts->extra, "collation", 9, &rw_opts->collation)) {
OPTS_ERR (COMMAND_INVALID_ARG, "'opts' with 'collation' is too large");
}
}
if (!mongoc_cmd_parts_set_write_concern (
parts, rw_opts->writeConcern, max_wire_version, error)) {
RETURN (false);
}
/* process explicit read concern */
if (!bson_empty (&rw_opts->readConcern)) {
if (max_wire_version < WIRE_VERSION_READ_CONCERN) {
OPTS_ERR (PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support readConcern");
}
/* save readConcern for later, once we know about causal consistency */
bson_destroy (&parts->read_concern_document);
bson_copy_to (&rw_opts->readConcern, &parts->read_concern_document);
}
if (rw_opts->client_session) {
BSON_ASSERT (!parts->assembled.session);
parts->assembled.session = rw_opts->client_session;
}
if (!bson_concat (&parts->extra, &rw_opts->extra)) {
OPTS_ERR (COMMAND_INVALID_ARG, "'opts' with extra fields is too large");
}
RETURN (true);
}
#undef OPTS_ERR
static void
_mongoc_cmd_parts_ensure_copied (mongoc_cmd_parts_t *parts)
{
if (parts->assembled.command == parts->body) {
bson_concat (&parts->assembled_body, parts->body);
bson_concat (&parts->assembled_body, &parts->extra);
parts->assembled.command = &parts->assembled_body;
}
}
static void
_mongoc_cmd_parts_add_write_concern (mongoc_cmd_parts_t *parts)
{
if (!bson_empty (&parts->write_concern_document)) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"writeConcern",
12,
&parts->write_concern_document);
}
}
/* The server type must be mongos, or message must be OP_MSG. */
static void
_mongoc_cmd_parts_add_read_prefs (bson_t *query,
const mongoc_read_prefs_t *prefs)
{
bson_t child;
const char *mode_str;
const bson_t *tags;
int64_t stale;
+ const bson_t *hedge;
mode_str = _mongoc_read_mode_as_str (mongoc_read_prefs_get_mode (prefs));
tags = mongoc_read_prefs_get_tags (prefs);
stale = mongoc_read_prefs_get_max_staleness_seconds (prefs);
+ hedge = mongoc_read_prefs_get_hedge (prefs);
bson_append_document_begin (query, "$readPreference", 15, &child);
bson_append_utf8 (&child, "mode", 4, mode_str, -1);
if (!bson_empty0 (tags)) {
bson_append_array (&child, "tags", 4, tags);
}
if (stale != MONGOC_NO_MAX_STALENESS) {
bson_append_int64 (&child, "maxStalenessSeconds", 19, stale);
}
+ if (!bson_empty0 (hedge)) {
+ bson_append_document (&child, "hedge", 5, hedge);
+ }
+
bson_append_document_end (query, &child);
}
static void
_iter_concat (bson_t *dst, bson_iter_t *iter)
{
uint32_t len;
const uint8_t *data;
bson_t src;
bson_iter_document (iter, &len, &data);
BSON_ASSERT (bson_init_static (&src, data, len));
BSON_ASSERT (bson_concat (dst, &src));
}
/* Update result with the read prefs. Server must be mongos.
*/
static void
_mongoc_cmd_parts_assemble_mongos (mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
mongoc_read_mode_t mode;
const bson_t *tags = NULL;
+ int64_t max_staleness_seconds = MONGOC_NO_MAX_STALENESS;
+ const bson_t *hedge = NULL;
bool add_read_prefs = false;
bson_t query;
bson_iter_t dollar_query;
bool has_dollar_query = false;
bool requires_read_concern;
bool requires_write_concern;
ENTRY;
mode = mongoc_read_prefs_get_mode (parts->read_prefs);
if (parts->read_prefs) {
+ max_staleness_seconds =
+ mongoc_read_prefs_get_max_staleness_seconds (parts->read_prefs);
+
tags = mongoc_read_prefs_get_tags (parts->read_prefs);
+ hedge = mongoc_read_prefs_get_hedge (parts->read_prefs);
}
/* Server Selection Spec says:
*
* For mode 'primary', drivers MUST NOT set the slaveOK wire protocol flag
* and MUST NOT use $readPreference
*
* For mode 'secondary', drivers MUST set the slaveOK wire protocol flag and
* MUST also use $readPreference
*
* For mode 'primaryPreferred', drivers MUST set the slaveOK wire protocol
* flag and MUST also use $readPreference
*
* For mode 'secondaryPreferred', drivers MUST set the slaveOK wire protocol
* flag. If the read preference contains a non-empty tag_sets parameter,
- * drivers MUST use $readPreference; otherwise, drivers MUST NOT use
- * $readPreference
+ * maxStalenessSeconds is a positive integer, or the hedge parameter is
+ * non-empty, drivers MUST use $readPreference; otherwise, drivers MUST NOT
+ * use $readPreference
*
* For mode 'nearest', drivers MUST set the slaveOK wire protocol flag and
* MUST also use $readPreference
*/
switch (mode) {
case MONGOC_READ_PRIMARY:
break;
case MONGOC_READ_SECONDARY_PREFERRED:
- if (!bson_empty0 (tags)) {
+ if (!bson_empty0 (tags) || max_staleness_seconds > 0 ||
+ !bson_empty0 (hedge)) {
add_read_prefs = true;
}
parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK;
break;
case MONGOC_READ_PRIMARY_PREFERRED:
case MONGOC_READ_SECONDARY:
case MONGOC_READ_NEAREST:
default:
parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK;
add_read_prefs = true;
}
requires_read_concern =
!bson_empty (&parts->read_concern_document) &&
strcmp (parts->assembled.command_name, "getMore") != 0;
requires_write_concern = !bson_empty (&parts->write_concern_document);
if (add_read_prefs) {
/* produce {$query: {user query, readConcern}, $readPreference: ... } */
bson_append_document_begin (&parts->assembled_body, "$query", 6, &query);
if (bson_iter_init_find (&dollar_query, parts->body, "$query")) {
/* user provided something like {$query: {key: "x"}} */
has_dollar_query = true;
_iter_concat (&query, &dollar_query);
} else {
bson_concat (&query, parts->body);
}
bson_concat (&query, &parts->extra);
if (requires_read_concern) {
bson_append_document (
&query, "readConcern", 11, &parts->read_concern_document);
}
if (requires_write_concern) {
bson_append_document (
&query, "writeConcern", 12, &parts->write_concern_document);
}
bson_append_document_end (&parts->assembled_body, &query);
_mongoc_cmd_parts_add_read_prefs (&parts->assembled_body,
parts->read_prefs);
if (has_dollar_query) {
/* copy anything that isn't in user's $query */
bson_copy_to_excluding_noinit (
parts->body, &parts->assembled_body, "$query", NULL);
}
parts->assembled.command = &parts->assembled_body;
} else if (bson_iter_init_find (&dollar_query, parts->body, "$query")) {
/* user provided $query, we have no read prefs */
bson_append_document_begin (&parts->assembled_body, "$query", 6, &query);
_iter_concat (&query, &dollar_query);
bson_concat (&query, &parts->extra);
if (requires_read_concern) {
bson_append_document (
&query, "readConcern", 11, &parts->read_concern_document);
}
if (requires_write_concern) {
bson_append_document (
&query, "writeConcern", 12, &parts->write_concern_document);
}
bson_append_document_end (&parts->assembled_body, &query);
/* copy anything that isn't in user's $query */
bson_copy_to_excluding_noinit (
parts->body, &parts->assembled_body, "$query", NULL);
parts->assembled.command = &parts->assembled_body;
} else {
if (requires_read_concern) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"readConcern",
11,
&parts->read_concern_document);
}
_mongoc_cmd_parts_add_write_concern (parts);
}
if (!bson_empty (&parts->extra)) {
/* if none of the above logic has merged "extra", do it now */
_mongoc_cmd_parts_ensure_copied (parts);
}
EXIT;
}
static void
_mongoc_cmd_parts_assemble_mongod (mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
ENTRY;
if (!parts->is_write_command) {
switch (server_stream->topology_type) {
case MONGOC_TOPOLOGY_SINGLE:
/* Server Selection Spec: for topology type single and server types
* besides mongos, "clients MUST always set the slaveOK wire
* protocol flag on reads to ensure that any server type can handle
* the request."
*/
parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK;
break;
case MONGOC_TOPOLOGY_RS_NO_PRIMARY:
case MONGOC_TOPOLOGY_RS_WITH_PRIMARY:
/* Server Selection Spec: for RS topology types, "For all read
* preferences modes except primary, clients MUST set the slaveOK wire
* protocol flag to ensure that any suitable server can handle the
* request. Clients MUST NOT set the slaveOK wire protocol flag if the
* read preference mode is primary.
*/
if (parts->read_prefs &&
parts->read_prefs->mode != MONGOC_READ_PRIMARY) {
parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK;
}
break;
case MONGOC_TOPOLOGY_SHARDED:
case MONGOC_TOPOLOGY_UNKNOWN:
case MONGOC_TOPOLOGY_DESCRIPTION_TYPES:
default:
/* must not call this function w/ sharded or unknown topology type */
BSON_ASSERT (false);
}
} /* if (!parts->is_write_command) */
if (!bson_empty (&parts->extra)) {
_mongoc_cmd_parts_ensure_copied (parts);
}
if (!bson_empty (&parts->read_concern_document) &&
strcmp (parts->assembled.command_name, "getMore") != 0) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"readConcern",
11,
&parts->read_concern_document);
}
_mongoc_cmd_parts_add_write_concern (parts);
EXIT;
}
static const bson_t *
_largest_cluster_time (const bson_t *a, const bson_t *b)
{
if (!a) {
return b;
}
if (!b) {
return a;
}
if (_mongoc_cluster_time_greater (a, b)) {
return a;
}
return b;
}
/* Check if the command should allow a transaction number if that has not
* already been determined.
*
* This should only return true for write commands that are always retryable for
* the server stream's wire version.
*
* The basic write commands (i.e. insert, update, delete) are intentionally
* excluded here. While insert is always retryable, update and delete are only
* retryable if they include no multi-document writes. Since it would be costly
* to inspect the command document here, the bulk operation API explicitly sets
* allow_txn_number for us. This means that insert, update, and delete are not
* retryable if executed via mongoc_client_write_command_with_opts(); however,
* documentation already instructs users not to use that for basic writes.
*/
static bool
_allow_txn_number (const mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
/* There is no reason to call this function if allow_txn_number is set */
BSON_ASSERT (parts->allow_txn_number ==
MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN);
if (!parts->is_write_command) {
return false;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_WRITES) {
return false;
}
if (!parts->assembled.is_acknowledged) {
return false;
}
if (!strcasecmp (parts->assembled.command_name, "findandmodify")) {
return true;
}
return false;
}
/* Check if the write command should support retryable behavior. */
static bool
_is_retryable_write (const mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
if (!parts->assembled.session) {
return false;
}
if (!parts->is_write_command) {
return false;
}
if (parts->allow_txn_number != MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES) {
return false;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_WRITES) {
return false;
}
if (server_stream->sd->type == MONGOC_SERVER_STANDALONE) {
return false;
}
if (_mongoc_client_session_in_txn (parts->assembled.session)) {
return false;
}
if (!mongoc_uri_get_option_as_bool (parts->client->uri,
MONGOC_URI_RETRYWRITES,
MONGOC_DEFAULT_RETRYWRITES)) {
return false;
}
return true;
}
/* Check if the read command should support retryable behavior. */
bool
_is_retryable_read (const mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
if (!parts->is_read_command) {
return false;
}
/* Commands that go through read_write_command helpers are also write
* commands. Prohibit from read retry. */
if (parts->is_write_command) {
return false;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_READS) {
return false;
}
if (_mongoc_client_session_in_txn (parts->assembled.session)) {
return false;
}
if (!mongoc_uri_get_option_as_bool (parts->client->uri,
MONGOC_URI_RETRYREADS,
MONGOC_DEFAULT_RETRYREADS)) {
return false;
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_assemble --
*
* Assemble the command body, options, and read preference into one
* command.
*
* Return:
* True if the options were successfully applied. If any options are
* invalid, returns false and fills out @error. In that case @parts is
* invalid and must not be used.
*
* Side effects:
* May partly assemble before returning an error.
* mongoc_cmd_parts_cleanup should be called in all cases.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cmd_parts_assemble (mongoc_cmd_parts_t *parts,
- const mongoc_server_stream_t *server_stream,
+ mongoc_server_stream_t *server_stream,
bson_error_t *error)
{
mongoc_server_description_type_t server_type;
mongoc_client_session_t *cs;
const bson_t *cluster_time = NULL;
mongoc_read_prefs_t *prefs = NULL;
const char *cmd_name;
bool is_get_more;
const mongoc_read_prefs_t *prefs_ptr;
bool ret = false;
ENTRY;
BSON_ASSERT (parts);
BSON_ASSERT (server_stream);
server_type = server_stream->sd->type;
cs = parts->prohibit_lsid ? NULL : parts->assembled.session;
/* Assembling the command depends on the type of server. If the server has
* been invalidated, error. */
if (server_type == MONGOC_SERVER_UNKNOWN) {
if (error) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot assemble command for invalidated server: %s",
server_stream->sd->error.message);
}
RETURN (false);
}
/* must not be assembled already */
BSON_ASSERT (!parts->assembled.command);
BSON_ASSERT (bson_empty (&parts->assembled_body));
/* begin with raw flags/cmd as assembled flags/cmd, might change below */
parts->assembled.command = parts->body;
/* unused in OP_MSG: */
parts->assembled.query_flags = parts->user_query_flags;
parts->assembled.server_stream = server_stream;
cmd_name = parts->assembled.command_name =
_mongoc_get_command_name (parts->assembled.command);
if (!parts->assembled.command_name) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Empty command document");
GOTO (done);
}
TRACE ("Preparing '%s'", cmd_name);
is_get_more = !strcmp (cmd_name, "getMore");
parts->assembled.is_txn_finish = !strcmp (cmd_name, "commitTransaction") ||
!strcmp (cmd_name, "abortTransaction");
if (!parts->is_write_command && IS_PREF_PRIMARY (parts->read_prefs) &&
server_stream->topology_type == MONGOC_TOPOLOGY_SINGLE &&
server_type != MONGOC_SERVER_MONGOS) {
prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED);
prefs_ptr = prefs;
} else {
prefs_ptr = parts->read_prefs;
}
if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
if (!bson_has_field (parts->body, "$db")) {
BSON_APPEND_UTF8 (&parts->extra, "$db", parts->assembled.db_name);
}
if (cs && _mongoc_client_session_in_txn (cs)) {
if (!IS_PREF_PRIMARY (cs->txn.opts.read_prefs) && !parts->is_write_command) {
bson_set_error (error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Read preference in a transaction must be primary");
GOTO (done);
}
} else if (!IS_PREF_PRIMARY (prefs_ptr) &&
server_type != MONGOC_SERVER_STANDALONE) {
/* "Type Standalone: clients MUST NOT send the read preference to the
* server" */
_mongoc_cmd_parts_add_read_prefs (&parts->extra, prefs_ptr);
}
if (!bson_empty (&parts->extra)) {
_mongoc_cmd_parts_ensure_copied (parts);
}
/* If an explicit session was not provided and lsid is not prohibited,
* attempt to create an implicit session (ignoring any errors). */
if (!cs && !parts->prohibit_lsid && parts->assembled.is_acknowledged) {
cs = mongoc_client_start_session (parts->client, NULL, NULL);
if (cs) {
parts->assembled.session = cs;
parts->has_temp_session = true;
}
}
/* Driver Sessions Spec: "For unacknowledged writes with an explicit
* session, drivers SHOULD raise an error.... Without an explicit
* session, drivers SHOULD NOT use an implicit session." We intentionally
* do not restrict this logic to parts->is_write_command, since
* mongoc_client_command_with_opts() does not identify as a write
* command but may still include a write concern.
*/
if (cs) {
if (!parts->assembled.is_acknowledged) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot use client session with unacknowledged command");
GOTO (done);
}
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"lsid",
4,
mongoc_client_session_get_lsid (cs));
cs->server_session->last_used_usec = bson_get_monotonic_time ();
cluster_time = mongoc_client_session_get_cluster_time (cs);
}
/* Ensure we know if the write command allows a transaction number */
if (!_mongoc_client_session_txn_in_progress (cs) &&
parts->is_write_command &&
parts->allow_txn_number ==
MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN) {
parts->allow_txn_number = _allow_txn_number (parts, server_stream)
? MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES
: MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_NO;
}
/* Determine if the command is retryable. If so, append txnNumber now
* for future use and mark the command as such. */
if (_is_retryable_write (parts, server_stream)) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_int64 (&parts->assembled_body, "txnNumber", 9, 0);
parts->is_retryable_write = true;
}
/* Conversely, check if the command is retryable if it is a read. */
if (_is_retryable_read (parts, server_stream) && !is_get_more) {
parts->is_retryable_read = true;
}
if (!bson_empty (&server_stream->cluster_time)) {
cluster_time =
_largest_cluster_time (&server_stream->cluster_time, cluster_time);
}
if (cluster_time && server_type != MONGOC_SERVER_STANDALONE) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (
&parts->assembled_body, "$clusterTime", 12, cluster_time);
}
if (!is_get_more) {
if (cs) {
+ _mongoc_cmd_parts_ensure_copied (parts);
_mongoc_client_session_append_read_concern (
cs,
&parts->read_concern_document,
parts->is_read_command,
&parts->assembled_body);
} else if (!bson_empty (&parts->read_concern_document)) {
+ _mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"readConcern",
11,
&parts->read_concern_document);
}
}
if (parts->assembled.is_txn_finish ||
!_mongoc_client_session_in_txn (cs)) {
_mongoc_cmd_parts_add_write_concern (parts);
}
+ _mongoc_cmd_parts_ensure_copied (parts);
if (!_mongoc_client_session_append_txn (
cs, &parts->assembled_body, error)) {
GOTO (done);
}
ret = true;
} else if (server_type == MONGOC_SERVER_MONGOS) {
_mongoc_cmd_parts_assemble_mongos (parts, server_stream);
ret = true;
} else {
_mongoc_cmd_parts_assemble_mongod (parts, server_stream);
ret = true;
}
done:
mongoc_read_prefs_destroy (prefs);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_cleanup --
*
* Free memory associated with a stack-allocated mongoc_cmd_parts_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_cmd_parts_cleanup (mongoc_cmd_parts_t *parts)
{
bson_destroy (&parts->read_concern_document);
bson_destroy (&parts->write_concern_document);
bson_destroy (&parts->extra);
bson_destroy (&parts->assembled_body);
if (parts->has_temp_session) {
/* client session returns its server session to server session pool */
mongoc_client_session_destroy (parts->assembled.session);
}
}
bool
mongoc_cmd_is_compressible (mongoc_cmd_t *cmd)
{
BSON_ASSERT (cmd);
BSON_ASSERT (cmd->command_name);
return !!strcasecmp (cmd->command_name, "ismaster") &&
!!strcasecmp (cmd->command_name, "authenticate") &&
!!strcasecmp (cmd->command_name, "getnonce") &&
!!strcasecmp (cmd->command_name, "saslstart") &&
!!strcasecmp (cmd->command_name, "saslcontinue") &&
!!strcasecmp (cmd->command_name, "createuser") &&
!!strcasecmp (cmd->command_name, "updateuser");
}
/*--------------------------------------------------------------------------
*
* _mongoc_cmd_append_payload_as_array --
* Append a write command payload as an array in a BSON document.
* Used by APM and Client-Side Encryption
*
* Arguments:
* cmd The mongoc_cmd_t, which may contain a payload to be appended.
* out A bson_t, which will be appended to if @cmd->payload is set.
*
* Pre-conditions:
* - @out is initialized.
* - cmd has a payload (i.e. is a write command).
*
* Post-conditions:
* - If @cmd->payload is set, then @out is appended to with the payload
* field's name ("documents" if insert, "updates" if update,
* "deletes" if delete) an the payload as a BSON array.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_cmd_append_payload_as_array (const mongoc_cmd_t *cmd, bson_t *out)
{
int32_t doc_len;
bson_t doc;
const uint8_t *pos;
const char *field_name;
bson_t bson;
char str[16];
const char *key;
uint32_t i;
BSON_ASSERT (cmd->payload && cmd->payload_size);
/* make array from outgoing OP_MSG payload type 1 on an "insert",
* "update", or "delete" command. */
field_name = _mongoc_get_documents_field_name (cmd->command_name);
BSON_ASSERT (field_name);
BSON_ASSERT (BSON_APPEND_ARRAY_BEGIN (out, field_name, &bson));
pos = cmd->payload;
i = 0;
while (pos < cmd->payload + cmd->payload_size) {
memcpy (&doc_len, pos, sizeof (doc_len));
doc_len = BSON_UINT32_FROM_LE (doc_len);
BSON_ASSERT (bson_init_static (&doc, pos, (size_t) doc_len));
bson_uint32_to_string (i, &key, str, sizeof (str));
BSON_APPEND_DOCUMENT (&bson, key, &doc);
pos += doc_len;
i++;
}
bson_append_array_end (out, &bson);
-}
\ No newline at end of file
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h
similarity index 81%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h
index f63c1077..44cab670 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h
@@ -1,54 +1,60 @@
/*
* Copyright 2013-2014 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_COLLECTION_PRIVATE_H
#define MONGOC_COLLECTION_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client.h"
BSON_BEGIN_DECLS
struct _mongoc_collection_t {
mongoc_client_t *client;
- char ns[128];
+ char *ns;
uint32_t nslen;
- char db[128];
- char collection[128];
+ char *db;
+ char *collection;
uint32_t collectionlen;
mongoc_read_prefs_t *read_prefs;
mongoc_read_concern_t *read_concern;
mongoc_write_concern_t *write_concern;
bson_t *gle;
};
mongoc_collection_t *
_mongoc_collection_new (mongoc_client_t *client,
const char *db,
const char *collection,
const mongoc_read_prefs_t *read_prefs,
const mongoc_read_concern_t *read_concern,
const mongoc_write_concern_t *write_concern);
+bool
+_mongoc_collection_create_index_if_not_exists (mongoc_collection_t *collection,
+ const bson_t *keys,
+ const bson_t *opts,
+ bson_error_t *error);
+
BSON_END_DECLS
#endif /* MONGOC_COLLECTION_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
similarity index 90%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
index e526f006..076feeda 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
@@ -1,3312 +1,3507 @@
/*
* Copyright 2013 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.
*/
#include <stdio.h>
#include "mongoc-aggregate-private.h"
#include "mongoc-bulk-operation.h"
#include "mongoc-bulk-operation-private.h"
#include "mongoc-change-stream-private.h"
#include "mongoc-client-private.h"
#include "mongoc-find-and-modify-private.h"
#include "mongoc-find-and-modify.h"
#include "mongoc-collection.h"
#include "mongoc-collection-private.h"
#include "mongoc-cursor-private.h"
#include "mongoc-error.h"
#include "mongoc-index.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-command-private.h"
#include "mongoc-opts-private.h"
#include "mongoc-write-command-private.h"
+#include "mongoc-error-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "collection"
static void
_mongoc_collection_write_command_execute (
mongoc_write_command_t *command,
const mongoc_collection_t *collection,
const mongoc_write_concern_t *write_concern,
mongoc_client_session_t *cs,
mongoc_write_result_t *result)
{
mongoc_server_stream_t *server_stream;
ENTRY;
server_stream = mongoc_cluster_stream_for_writes (
&collection->client->cluster, cs, NULL, &result->error);
if (!server_stream) {
/* result->error has been filled out */
EXIT;
}
_mongoc_write_command_execute (command,
collection->client,
server_stream,
collection->db,
collection->collection,
write_concern,
0 /* offset */,
cs,
result);
mongoc_server_stream_cleanup (server_stream);
EXIT;
}
static void
_mongoc_collection_write_command_execute_idl (
mongoc_write_command_t *command,
const mongoc_collection_t *collection,
mongoc_crud_opts_t *crud,
mongoc_write_result_t *result)
{
mongoc_server_stream_t *server_stream;
bson_t reply;
ENTRY;
server_stream =
mongoc_cluster_stream_for_writes (&collection->client->cluster,
crud->client_session,
&reply,
&result->error);
if (!server_stream) {
/* result->error and reply have been filled out */
_mongoc_bson_array_copy_labels_to (&reply, &result->errorLabels);
bson_destroy (&reply);
EXIT;
}
if (_mongoc_client_session_in_txn (crud->client_session) &&
crud->writeConcern) {
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
mongoc_server_stream_cleanup (server_stream);
EXIT;
}
if (!crud->writeConcern &&
!_mongoc_client_session_in_txn (crud->client_session)) {
crud->writeConcern = collection->write_concern;
crud->write_concern_owned = false;
}
_mongoc_write_command_execute_idl (command,
collection->client,
server_stream,
collection->db,
collection->collection,
0 /* offset */,
crud,
result);
mongoc_server_stream_cleanup (server_stream);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_collection_new --
*
* INTERNAL API
*
* Create a new mongoc_collection_t structure for the given client.
*
* @client must remain valid during the lifetime of this structure.
* @db is the db name of the collection.
* @collection is the name of the collection.
* @read_prefs is the default read preferences to apply or NULL.
* @read_concern is the default read concern to apply or NULL.
* @write_concern is the default write concern to apply or NULL.
*
* Returns:
* A newly allocated mongoc_collection_t that should be freed with
* mongoc_collection_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_collection_t *
_mongoc_collection_new (mongoc_client_t *client,
const char *db,
const char *collection,
const mongoc_read_prefs_t *read_prefs,
const mongoc_read_concern_t *read_concern,
const mongoc_write_concern_t *write_concern)
{
mongoc_collection_t *col;
ENTRY;
- BSON_ASSERT (client);
- BSON_ASSERT (db);
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (client);
+ BSON_ASSERT_PARAM (db);
+ BSON_ASSERT_PARAM (collection);
col = (mongoc_collection_t *) bson_malloc0 (sizeof *col);
col->client = client;
col->write_concern = write_concern
? mongoc_write_concern_copy (write_concern)
: mongoc_write_concern_new ();
col->read_concern = read_concern ? mongoc_read_concern_copy (read_concern)
: mongoc_read_concern_new ();
col->read_prefs = read_prefs ? mongoc_read_prefs_copy (read_prefs)
: mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
- bson_snprintf (col->ns, sizeof col->ns, "%s.%s", db, collection);
- bson_snprintf (col->db, sizeof col->db, "%s", db);
- bson_snprintf (col->collection, sizeof col->collection, "%s", collection);
+ col->ns = bson_strdup_printf ("%s.%s", db, collection);
+ col->db = bson_strdup (db);
+ col->collection = bson_strdup (collection);
col->collectionlen = (uint32_t) strlen (col->collection);
col->nslen = (uint32_t) strlen (col->ns);
col->gle = NULL;
RETURN (col);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_destroy --
*
* Release resources associated with @collection and frees the
* structure.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_collection_destroy (mongoc_collection_t *collection) /* IN */
{
ENTRY;
if (!collection) {
EXIT;
}
bson_clear (&collection->gle);
if (collection->read_prefs) {
mongoc_read_prefs_destroy (collection->read_prefs);
collection->read_prefs = NULL;
}
if (collection->read_concern) {
mongoc_read_concern_destroy (collection->read_concern);
collection->read_concern = NULL;
}
if (collection->write_concern) {
mongoc_write_concern_destroy (collection->write_concern);
collection->write_concern = NULL;
}
+ bson_free (collection->collection);
+ bson_free (collection->db);
+ bson_free (collection->ns);
bson_free (collection);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_copy --
*
* Returns a copy of @collection that needs to be freed by calling
* mongoc_collection_destroy.
*
* Returns:
* A copy of this collection.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_collection_t *
mongoc_collection_copy (mongoc_collection_t *collection) /* IN */
{
ENTRY;
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
RETURN (_mongoc_collection_new (collection->client,
collection->db,
collection->collection,
collection->read_prefs,
collection->read_concern,
collection->write_concern));
}
mongoc_cursor_t *
mongoc_collection_aggregate (mongoc_collection_t *collection, /* IN */
mongoc_query_flags_t flags, /* IN */
const bson_t *pipeline, /* IN */
const bson_t *opts, /* IN */
const mongoc_read_prefs_t *read_prefs) /* IN */
{
return _mongoc_aggregate (collection->client,
collection->ns,
flags,
pipeline,
opts,
read_prefs,
collection->read_prefs,
collection->read_concern,
collection->write_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_find --
*
* DEPRECATED: use mongoc_collection_find_with_opts.
*
* Performs a query against the configured MongoDB server. If @read_prefs
* is provided, it will be used to locate a MongoDB node in the cluster
* to deliver the query to.
*
* @flags may be bitwise-or'd flags or MONGOC_QUERY_NONE.
*
* @skip may contain the number of documents to skip before returning the
* matching document.
*
* @limit may contain the maximum number of documents that may be
* returned.
*
* This function will always return a cursor, with the exception of
* invalid API use.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: A bitwise or of mongoc_query_flags_t.
* @skip: The number of documents to skip.
* @limit: The maximum number of items.
* @batch_size: The batch size
* @query: The query to locate matching documents.
* @fields: The fields to return, or NULL for all fields.
* @read_prefs: Read preferences to choose cluster node.
*
* Returns:
* A newly allocated mongoc_cursor_t that should be freed with
* mongoc_cursor_destroy().
*
* The client used by mongoc_collection_t must be valid for the
* lifetime of the resulting mongoc_cursor_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_cursor_t *
mongoc_collection_find (mongoc_collection_t *collection, /* IN */
mongoc_query_flags_t flags, /* IN */
uint32_t skip, /* IN */
uint32_t limit, /* IN */
uint32_t batch_size, /* IN */
const bson_t *query, /* IN */
const bson_t *fields, /* IN */
const mongoc_read_prefs_t *read_prefs) /* IN */
{
bool has_unwrapped;
bson_t unwrapped;
bson_error_t error = {0};
bson_t opts;
bool slave_ok;
mongoc_cursor_t *cursor;
- BSON_ASSERT (collection);
- BSON_ASSERT (query);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (query);
bson_clear (&collection->gle);
bson_init (&opts);
_mongoc_cursor_flags_to_opts (flags, &opts, &slave_ok);
/* check if the query is wrapped in $query */
has_unwrapped = _mongoc_cursor_translate_dollar_query_opts (
query, &opts, &unwrapped, &error);
if (!bson_empty0 (fields)) {
bson_append_document (
&opts, MONGOC_CURSOR_PROJECTION, MONGOC_CURSOR_PROJECTION_LEN, fields);
}
cursor = _mongoc_cursor_find_new (collection->client,
collection->ns,
has_unwrapped ? &unwrapped : query,
&opts,
read_prefs,
collection->read_prefs,
collection->read_concern);
if (skip) {
_mongoc_cursor_set_opt_int64 (cursor, MONGOC_CURSOR_SKIP, skip);
}
if (limit) {
/* limit must be cast to int32_t. Although the argument is a uint32_t,
* callers can specify a negative limit by casting to a signed int32_t
* value to uint32_t. E.g. to set a limit of -4, the caller passes
* UINT32_MAX - 3 */
(void) mongoc_cursor_set_limit (cursor, (int32_t) limit);
}
if (batch_size) {
mongoc_cursor_set_batch_size (cursor, batch_size);
}
bson_destroy (&unwrapped);
bson_destroy (&opts);
if (error.domain) {
memcpy (&cursor->error, &error, sizeof (error));
}
return cursor;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_find_with_opts --
*
* Create a cursor with a query filter. All other options are
* specified in a free-form BSON document.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @filter: The query to locate matching documents.
* @opts: Other options.
* @read_prefs: Optional read preferences to choose cluster node.
*
* Returns:
* A newly allocated mongoc_cursor_t that should be freed with
* mongoc_cursor_destroy().
*
* The client used by mongoc_collection_t must be valid for the
* lifetime of the resulting mongoc_cursor_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_cursor_t *
mongoc_collection_find_with_opts (mongoc_collection_t *collection,
const bson_t *filter,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs)
{
- BSON_ASSERT (collection);
- BSON_ASSERT (filter);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (filter);
bson_clear (&collection->gle);
return _mongoc_cursor_find_new (collection->client,
collection->ns,
filter,
opts,
read_prefs,
collection->read_prefs,
collection->read_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_command --
*
* Executes a command on a cluster node matching @read_prefs. If
* @read_prefs is not provided, it will be run on the primary node.
*
* This function will always return a mongoc_cursor_t.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: Bitwise-or'd flags for command.
* @skip: Number of documents to skip, typically 0.
* @limit : Number of documents to return
* @batch_size : Batch size
* @query: The command to execute.
* @fields: The fields to return, or NULL.
* @read_prefs: Command read preferences or NULL.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_cursor_t *
mongoc_collection_command (mongoc_collection_t *collection,
mongoc_query_flags_t flags,
uint32_t skip,
uint32_t limit,
uint32_t batch_size,
const bson_t *query,
const bson_t *fields,
const mongoc_read_prefs_t *read_prefs)
{
- char ns[MONGOC_NAMESPACE_MAX];
+ char *ns;
mongoc_cursor_t *cursor;
- BSON_ASSERT (collection);
- BSON_ASSERT (query);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (query);
if (!read_prefs) {
read_prefs = collection->read_prefs;
}
bson_clear (&collection->gle);
if (NULL == strstr (collection->collection, "$cmd")) {
- bson_snprintf (ns, sizeof ns, "%s.$cmd", collection->db);
+ ns = bson_strdup_printf ("%s.$cmd", collection->db);
} else {
- bson_snprintf (ns, sizeof ns, "%s", collection->db);
+ ns = bson_strdup (collection->db);
}
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
/* flags, skip, limit, batch_size, fields are unused */
cursor = _mongoc_cursor_cmd_deprecated_new (
collection->client, ns, query, read_prefs);
+ bson_free (ns);
return cursor;
}
bool
mongoc_collection_read_command_with_opts (mongoc_collection_t *collection,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_READ,
opts,
MONGOC_QUERY_NONE,
read_prefs,
collection->read_prefs,
collection->read_concern,
collection->write_concern,
reply,
error);
}
bool
mongoc_collection_write_command_with_opts (mongoc_collection_t *collection,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL,
collection->read_prefs,
collection->read_concern,
collection->write_concern,
reply,
error);
}
bool
mongoc_collection_read_write_command_with_opts (
mongoc_collection_t *collection,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs /* IGNORED */,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_RW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
collection->read_prefs,
collection->read_concern,
collection->write_concern,
reply,
error);
}
bool
mongoc_collection_command_with_opts (mongoc_collection_t *collection,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument." */
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_RAW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
NULL /* default prefs */,
collection->read_concern,
collection->write_concern,
reply,
error);
}
bool
mongoc_collection_command_simple (mongoc_collection_t *collection,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
- BSON_ASSERT (collection);
- BSON_ASSERT (command);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (command);
bson_clear (&collection->gle);
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_RAW,
NULL /* opts */,
MONGOC_QUERY_NONE,
read_prefs,
NULL /* default prefs */,
NULL /* read concern */,
NULL /* write concern */,
reply,
error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_count --
*
* Count the number of documents matching @query.
*
* Parameters:
* @flags: A mongoc_query_flags_t describing the query flags or 0.
* @query: The query to perform or NULL for {}.
* @skip: The $skip to perform within the query or 0.
* @limit: The $limit to perform within the query or 0.
* @read_prefs: desired read preferences or NULL.
* @error: A location for an error or NULL.
*
* Returns:
* -1 on failure; otherwise the number of matching documents.
*
* Side effects:
* @error is set upon failure if non-NULL.
*
*--------------------------------------------------------------------------
*/
int64_t
mongoc_collection_count (mongoc_collection_t *collection, /* IN */
mongoc_query_flags_t flags, /* IN */
const bson_t *query, /* IN */
int64_t skip, /* IN */
int64_t limit, /* IN */
const mongoc_read_prefs_t *read_prefs, /* IN */
bson_error_t *error) /* OUT */
{
int64_t ret;
bson_t opts = BSON_INITIALIZER;
/* Complex types must be parts of `opts`, otherwise we can't
* follow various specs that require validation etc */
if (collection->read_concern->level != NULL) {
const bson_t *read_concern_bson;
read_concern_bson =
_mongoc_read_concern_get_bson (collection->read_concern);
BSON_APPEND_DOCUMENT (&opts, "readConcern", read_concern_bson);
}
/* Server Selection Spec: "may-use-secondary" commands SHOULD take a read
* preference argument and otherwise MUST use the default read preference
* from client, database or collection configuration. */
BEGIN_IGNORE_DEPRECATIONS
ret = mongoc_collection_count_with_opts (
collection, flags, query, skip, limit, &opts, read_prefs, error);
END_IGNORE_DEPRECATIONS
bson_destroy (&opts);
return ret;
}
int64_t
mongoc_collection_count_with_opts (
mongoc_collection_t *collection, /* IN */
mongoc_query_flags_t flags, /* IN */
const bson_t *query, /* IN */
int64_t skip, /* IN */
int64_t limit, /* IN */
const bson_t *opts, /* IN */
const mongoc_read_prefs_t *read_prefs, /* IN */
bson_error_t *error) /* OUT */
{
bson_iter_t iter;
int64_t ret = -1;
bool success;
bson_t reply;
bson_t cmd = BSON_INITIALIZER;
bson_t q;
ENTRY;
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
bson_append_utf8 (
&cmd, "count", 5, collection->collection, collection->collectionlen);
if (query) {
bson_append_document (&cmd, "query", 5, query);
} else {
bson_init (&q);
bson_append_document (&cmd, "query", 5, &q);
bson_destroy (&q);
}
if (limit) {
bson_append_int64 (&cmd, "limit", 5, limit);
}
if (skip) {
bson_append_int64 (&cmd, "skip", 4, skip);
}
success = _mongoc_client_command_with_opts (collection->client,
collection->db,
&cmd,
MONGOC_CMD_READ,
opts,
flags,
read_prefs,
collection->read_prefs,
collection->read_concern,
collection->write_concern,
&reply,
error);
if (success) {
if (bson_iter_init_find (&iter, &reply, "n")) {
ret = bson_iter_as_int64 (&iter);
}
}
bson_destroy (&reply);
bson_destroy (&cmd);
RETURN (ret);
}
int64_t
mongoc_collection_estimated_document_count (
mongoc_collection_t *coll,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
bson_iter_t iter;
int64_t count = -1;
bool ret;
bson_t reply_local;
bson_t *reply_ptr;
bson_t cmd = BSON_INITIALIZER;
ENTRY;
- BSON_ASSERT (coll);
+ BSON_ASSERT_PARAM (coll);
+
+ if (opts && bson_has_field (opts, "sessionId")) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "Collection count must not specify explicit session");
+ GOTO (done);
+ }
reply_ptr = reply ? reply : &reply_local;
bson_append_utf8 (&cmd, "count", 5, coll->collection, coll->collectionlen);
ret = _mongoc_client_command_with_opts (coll->client,
coll->db,
&cmd,
MONGOC_CMD_READ,
opts,
MONGOC_QUERY_NONE,
read_prefs,
coll->read_prefs,
coll->read_concern,
coll->write_concern,
reply_ptr,
error);
if (ret) {
if (bson_iter_init_find (&iter, reply_ptr, "n")) {
count = bson_iter_as_int64 (&iter);
}
}
+done:
if (!reply) {
bson_destroy (&reply_local);
}
bson_destroy (&cmd);
RETURN (count);
}
/* --------------------------------------------------------------------------
*
* _make_aggregate_for_count --
*
* Construct an aggregate pipeline with the following form:
* { pipeline: [
* { $match: {...} },
* { $group: { _id: 1, n: { sum: 1 } } },
* { $skip: ... },
* { $limit: ... }
* ]
* }
*
*--------------------------------------------------------------------------
*/
static void
_make_aggregate_for_count (const mongoc_collection_t *coll,
const bson_t *filter,
const bson_t *opts,
bson_t *out)
{
bson_iter_t iter;
bson_t pipeline;
bson_t match_stage;
bson_t group_stage;
bson_t group_stage_doc;
bson_t sum;
bson_t empty;
const char *keys[] = {"0", "1", "2", "3"};
int key = 0;
bson_init (out);
bson_append_utf8 (
out, "aggregate", 9, coll->collection, coll->collectionlen);
bson_append_document_begin (out, "cursor", 6, &empty);
bson_append_document_end (out, &empty);
bson_append_array_begin (out, "pipeline", 8, &pipeline);
bson_append_document_begin (&pipeline, keys[key++], 1, &match_stage);
bson_append_document (&match_stage, "$match", 6, filter);
bson_append_document_end (&pipeline, &match_stage);
/* if @opts includes "skip", or "count", append $skip and $count stages to
* the aggregate pipeline. */
if (opts && bson_iter_init_find (&iter, opts, "skip")) {
bson_t skip_stage;
bson_append_document_begin (&pipeline, keys[key++], 1, &skip_stage);
bson_append_value (&skip_stage, "$skip", 5, bson_iter_value (&iter));
bson_append_document_end (&pipeline, &skip_stage);
}
if (opts && bson_iter_init_find (&iter, opts, "limit")) {
bson_t limit_stage;
bson_append_document_begin (&pipeline, keys[key++], 1, &limit_stage);
bson_append_value (&limit_stage, "$limit", 6, bson_iter_value (&iter));
bson_append_document_end (&pipeline, &limit_stage);
}
bson_append_document_begin (&pipeline, keys[key], 1, &group_stage);
bson_append_document_begin (&group_stage, "$group", 6, &group_stage_doc);
bson_append_int32 (&group_stage_doc, "_id", 3, 1);
bson_append_document_begin (&group_stage_doc, "n", 1, &sum);
bson_append_int32 (&sum, "$sum", 4, 1);
bson_append_document_end (&group_stage_doc, &sum);
bson_append_document_end (&group_stage, &group_stage_doc);
bson_append_document_end (&pipeline, &group_stage);
bson_append_array_end (out, &pipeline);
}
int64_t
mongoc_collection_count_documents (mongoc_collection_t *coll,
const bson_t *filter,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
bson_t aggregate_cmd;
bson_t aggregate_opts;
bool ret;
const bson_t *result;
mongoc_cursor_t *cursor = NULL;
int64_t count = -1;
bson_t cmd_reply;
bson_iter_t iter;
ENTRY;
- BSON_ASSERT (coll);
- BSON_ASSERT (filter);
+ BSON_ASSERT_PARAM (coll);
+ BSON_ASSERT_PARAM (filter);
_make_aggregate_for_count (coll, filter, opts, &aggregate_cmd);
bson_init (&aggregate_opts);
if (opts) {
bson_copy_to_excluding_noinit (
opts, &aggregate_opts, "skip", "limit", NULL);
}
ret = mongoc_collection_read_command_with_opts (
coll, &aggregate_cmd, read_prefs, &aggregate_opts, &cmd_reply, error);
bson_destroy (&aggregate_cmd);
bson_destroy (&aggregate_opts);
if (reply) {
bson_copy_to (&cmd_reply, reply);
}
if (!ret) {
bson_destroy (&cmd_reply);
GOTO (done);
}
/* steals reply */
cursor = mongoc_cursor_new_from_command_reply_with_opts (
coll->client, &cmd_reply, NULL);
BSON_ASSERT (mongoc_cursor_get_id (cursor) == 0);
ret = mongoc_cursor_next (cursor, &result);
if (!ret) {
if (mongoc_cursor_error (cursor, error)) {
GOTO (done);
} else {
count = 0;
GOTO (done);
}
}
if (bson_iter_init_find (&iter, result, "n") &&
BSON_ITER_HOLDS_INT (&iter)) {
count = bson_iter_as_int64 (&iter);
}
done:
if (cursor) {
mongoc_cursor_destroy (cursor);
}
RETURN (count);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_drop --
*
* Request the MongoDB server drop the collection.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @error is set upon failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_drop (mongoc_collection_t *collection, /* IN */
bson_error_t *error) /* OUT */
{
return mongoc_collection_drop_with_opts (collection, NULL, error);
}
bool
mongoc_collection_drop_with_opts (mongoc_collection_t *collection,
const bson_t *opts,
bson_error_t *error)
{
bool ret;
bson_t cmd;
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
bson_init (&cmd);
bson_append_utf8 (
&cmd, "drop", 4, collection->collection, collection->collectionlen);
ret = _mongoc_client_command_with_opts (collection->client,
collection->db,
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
collection->read_prefs,
collection->read_concern,
collection->write_concern,
NULL, /* reply */
error);
bson_destroy (&cmd);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_drop_index --
*
* Request the MongoDB server drop the named index.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @error is setup upon failure if non-NULL.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_drop_index (mongoc_collection_t *collection, /* IN */
const char *index_name, /* IN */
bson_error_t *error) /* OUT */
{
return mongoc_collection_drop_index_with_opts (
collection, index_name, NULL, error);
}
bool
mongoc_collection_drop_index_with_opts (mongoc_collection_t *collection,
const char *index_name,
const bson_t *opts,
bson_error_t *error)
{
bool ret;
bson_t cmd;
- BSON_ASSERT (collection);
- BSON_ASSERT (index_name);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (index_name);
bson_init (&cmd);
bson_append_utf8 (&cmd,
"dropIndexes",
-1,
collection->collection,
collection->collectionlen);
bson_append_utf8 (&cmd, "index", -1, index_name, -1);
ret = _mongoc_client_command_with_opts (collection->client,
collection->db,
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
collection->read_prefs,
collection->read_concern,
collection->write_concern,
NULL, /* reply */
error);
bson_destroy (&cmd);
return ret;
}
char *
mongoc_collection_keys_to_index_string (const bson_t *keys)
{
bson_string_t *s;
bson_iter_t iter;
bson_type_t type;
int i = 0;
- BSON_ASSERT (keys);
+ BSON_ASSERT_PARAM (keys);
if (!bson_iter_init (&iter, keys)) {
return NULL;
}
s = bson_string_new (NULL);
while (bson_iter_next (&iter)) {
/* Index type can be specified as a string ("2d") or as an integer
* representing direction */
type = bson_iter_type (&iter);
if (type == BSON_TYPE_UTF8) {
bson_string_append_printf (s,
(i++ ? "_%s_%s" : "%s_%s"),
bson_iter_key (&iter),
bson_iter_utf8 (&iter, NULL));
} else if (type == BSON_TYPE_INT32) {
bson_string_append_printf (s,
(i++ ? "_%s_%d" : "%s_%d"),
bson_iter_key (&iter),
bson_iter_int32 (&iter));
} else if (type == BSON_TYPE_INT64) {
bson_string_append_printf (s,
(i++ ? "_%s_%" PRId64 : "%s_%" PRId64),
bson_iter_key (&iter),
bson_iter_int64 (&iter));
} else {
bson_string_free (s, true);
return NULL;
}
}
return bson_string_free (s, false);
}
bool
mongoc_collection_create_index (mongoc_collection_t *collection,
const bson_t *keys,
const mongoc_index_opt_t *opt,
bson_error_t *error)
{
bson_t reply;
bool ret;
BEGIN_IGNORE_DEPRECATIONS
ret = mongoc_collection_create_index_with_opts (
collection, keys, opt, NULL, &reply, error);
END_IGNORE_DEPRECATIONS
bson_destroy (&reply);
return ret;
}
+static bool
+_mongoc_collection_index_keys_equal (const bson_t *expected,
+ const bson_t *actual)
+{
+ bson_iter_t iter_expected;
+ bson_iter_t iter_actual;
+
+ bson_iter_init (&iter_expected, expected);
+ bson_iter_init (&iter_actual, actual);
+
+ while (bson_iter_next (&iter_expected)) {
+ /* If the key document has fewer items than expected, indexes are unequal
+ */
+ if (!bson_iter_next (&iter_actual)) {
+ return false;
+ }
+
+ /* If key order does not match, indexes are unequal */
+ if (strcmp (bson_iter_key (&iter_expected),
+ bson_iter_key (&iter_actual)) != 0) {
+ return false;
+ }
+
+ if (BSON_ITER_HOLDS_NUMBER (&iter_expected) &&
+ BSON_ITER_HOLDS_NUMBER (&iter_actual)) {
+ if (bson_iter_as_int64 (&iter_expected) !=
+ bson_iter_as_int64 (&iter_actual)) {
+ return false;
+ }
+ } else if (BSON_ITER_HOLDS_UTF8 (&iter_expected) &&
+ BSON_ITER_HOLDS_UTF8 (&iter_actual)) {
+ if (strcmp (bson_iter_utf8 (&iter_expected, NULL),
+ bson_iter_utf8 (&iter_actual, NULL)) != 0) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /* If our expected document is exhausted, make sure there are no extra keys
+ * in the actual key document */
+ if (bson_iter_next (&iter_actual)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+_mongoc_collection_create_index_if_not_exists (mongoc_collection_t *collection,
+ const bson_t *keys,
+ const bson_t *opts,
+ bson_error_t *error)
+{
+ mongoc_cursor_t *cursor;
+ bool index_exists;
+ bool r = false;
+ const bson_t *doc;
+ bson_iter_t iter;
+ bson_t inner_doc;
+ uint32_t data_len;
+ const uint8_t *data;
+ bson_t index;
+ bson_t command;
+
+ BSON_ASSERT (collection);
+ BSON_ASSERT (keys);
+
+ cursor = mongoc_collection_find_indexes_with_opts (collection, NULL);
+
+ index_exists = false;
+
+ while (mongoc_cursor_next (cursor, &doc) && !index_exists) {
+ r = bson_iter_init_find (&iter, doc, "key");
+ if (!r) {
+ continue;
+ }
+
+ bson_iter_document (&iter, &data_len, &data);
+ bson_init_static (&inner_doc, data, data_len);
+
+ if (_mongoc_collection_index_keys_equal (keys, &inner_doc)) {
+ index_exists = true;
+ }
+
+ bson_destroy (&inner_doc);
+ }
+
+ if (mongoc_cursor_error (cursor, error)) {
+ mongoc_cursor_destroy (cursor);
+ return false;
+ }
+
+ mongoc_cursor_destroy (cursor);
+
+ if (index_exists) {
+ return true;
+ }
+
+ if (opts) {
+ bson_copy_to (opts, &index);
+ } else {
+ bson_init (&index);
+ }
+
+ BSON_APPEND_DOCUMENT (&index, "key", keys);
+
+ if (!bson_has_field (&index, "name")) {
+ char *alloc_name = mongoc_collection_keys_to_index_string (keys);
+
+ if (!alloc_name) {
+ bson_set_error (
+ error,
+ MONGOC_ERROR_BSON,
+ MONGOC_ERROR_BSON_INVALID,
+ "Cannot generate index name from invalid `keys` argument");
+ GOTO (done);
+ }
+
+ BSON_APPEND_UTF8 (&index, "name", alloc_name);
+
+ bson_free (alloc_name);
+ }
+
+ bson_init (&command);
+ BCON_APPEND (&command,
+ "createIndexes",
+ BCON_UTF8 (mongoc_collection_get_name (collection)),
+ "indexes",
+ "[",
+ BCON_DOCUMENT (&index),
+ "]");
+
+ r = mongoc_collection_write_command_with_opts (
+ collection, &command, NULL, NULL, error);
+
+done:
+ bson_destroy (&index);
+ bson_destroy (&command);
+
+ return r;
+}
+
bool
mongoc_collection_create_index_with_opts (mongoc_collection_t *collection,
const bson_t *keys,
const mongoc_index_opt_t *opt,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_create_index_opts_t parsed;
mongoc_cmd_parts_t parts;
const mongoc_index_opt_t *def_opt;
const mongoc_index_opt_geo_t *def_geo;
const char *name;
bson_t cmd = BSON_INITIALIZER;
bson_t ar;
bson_t doc;
bson_t storage_doc;
bson_t wt_doc;
const mongoc_index_opt_geo_t *geo_opt;
const mongoc_index_opt_storage_t *storage_opt;
const mongoc_index_opt_wt_t *wt_opt;
char *alloc_name = NULL;
bool ret = false;
bool reply_initialized = false;
bool has_collation = false;
mongoc_server_stream_t *server_stream = NULL;
mongoc_cluster_t *cluster;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (keys);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (keys);
def_opt = mongoc_index_opt_get_default ();
opt = opt ? opt : def_opt;
mongoc_cmd_parts_init (
&parts, collection->client, collection->db, MONGOC_QUERY_NONE, &cmd);
parts.is_write_command = true;
if (!_mongoc_create_index_opts_parse (
collection->client, opts, &parsed, error)) {
GOTO (done);
}
if (!parsed.writeConcern) {
parsed.writeConcern = collection->write_concern;
parsed.write_concern_owned = false;
}
/*
* Generate the key name if it was not provided.
*/
name = (opt->name != def_opt->name) ? opt->name : NULL;
if (!name) {
alloc_name = mongoc_collection_keys_to_index_string (keys);
if (alloc_name) {
name = alloc_name;
} else {
bson_set_error (
error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Cannot generate index name from invalid `keys` argument");
GOTO (done);
}
}
/*
* Build our createIndexes command to send to the server.
*/
BSON_ASSERT (
BSON_APPEND_UTF8 (&cmd, "createIndexes", collection->collection));
bson_append_array_begin (&cmd, "indexes", 7, &ar);
bson_append_document_begin (&ar, "0", 1, &doc);
BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "key", keys));
BSON_ASSERT (BSON_APPEND_UTF8 (&doc, "name", name));
if (opt->background) {
BSON_ASSERT (BSON_APPEND_BOOL (&doc, "background", true));
}
if (opt->unique) {
BSON_ASSERT (BSON_APPEND_BOOL (&doc, "unique", true));
}
if (opt->drop_dups) {
BSON_ASSERT (BSON_APPEND_BOOL (&doc, "dropDups", true));
}
if (opt->sparse) {
BSON_ASSERT (BSON_APPEND_BOOL (&doc, "sparse", true));
}
if (opt->expire_after_seconds != def_opt->expire_after_seconds) {
BSON_ASSERT (BSON_APPEND_INT32 (
&doc, "expireAfterSeconds", opt->expire_after_seconds));
}
if (opt->v != def_opt->v) {
BSON_ASSERT (BSON_APPEND_INT32 (&doc, "v", opt->v));
}
if (opt->weights && (opt->weights != def_opt->weights)) {
BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "weights", opt->weights));
}
if (opt->default_language != def_opt->default_language) {
BSON_ASSERT (
BSON_APPEND_UTF8 (&doc, "default_language", opt->default_language));
}
if (opt->language_override != def_opt->language_override) {
BSON_ASSERT (
BSON_APPEND_UTF8 (&doc, "language_override", opt->language_override));
}
if (opt->partial_filter_expression) {
BSON_ASSERT (BSON_APPEND_DOCUMENT (
&doc, "partialFilterExpression", opt->partial_filter_expression));
}
if (opt->collation) {
BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "collation", opt->collation));
has_collation = true;
}
if (opt->geo_options) {
geo_opt = opt->geo_options;
def_geo = mongoc_index_opt_geo_get_default ();
if (geo_opt->twod_sphere_version != def_geo->twod_sphere_version) {
BSON_ASSERT (BSON_APPEND_INT32 (
&doc, "2dsphereIndexVersion", geo_opt->twod_sphere_version));
}
if (geo_opt->twod_bits_precision != def_geo->twod_bits_precision) {
BSON_ASSERT (
BSON_APPEND_INT32 (&doc, "bits", geo_opt->twod_bits_precision));
}
if (geo_opt->twod_location_min != def_geo->twod_location_min) {
BSON_ASSERT (
BSON_APPEND_DOUBLE (&doc, "min", geo_opt->twod_location_min));
}
if (geo_opt->twod_location_max != def_geo->twod_location_max) {
BSON_ASSERT (
BSON_APPEND_DOUBLE (&doc, "max", geo_opt->twod_location_max));
}
if (geo_opt->haystack_bucket_size != def_geo->haystack_bucket_size) {
BSON_ASSERT (BSON_APPEND_DOUBLE (
&doc, "bucketSize", geo_opt->haystack_bucket_size));
}
}
if (opt->storage_options) {
storage_opt = opt->storage_options;
switch (storage_opt->type) {
case MONGOC_INDEX_STORAGE_OPT_WIREDTIGER:
wt_opt = (mongoc_index_opt_wt_t *) storage_opt;
BSON_APPEND_DOCUMENT_BEGIN (&doc, "storageEngine", &storage_doc);
BSON_APPEND_DOCUMENT_BEGIN (&storage_doc, "wiredTiger", &wt_doc);
BSON_ASSERT (
BSON_APPEND_UTF8 (&wt_doc, "configString", wt_opt->config_str));
bson_append_document_end (&storage_doc, &wt_doc);
bson_append_document_end (&doc, &storage_doc);
break;
default:
break;
}
}
bson_append_document_end (&ar, &doc);
bson_append_array_end (&cmd, &ar);
server_stream = mongoc_cluster_stream_for_writes (
&collection->client->cluster, parsed.client_session, reply, error);
if (!server_stream) {
reply_initialized = true;
GOTO (done);
}
if (!mongoc_cmd_parts_set_write_concern (&parts,
parsed.writeConcern,
server_stream->sd->max_wire_version,
error)) {
GOTO (done);
}
if (has_collation &&
server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
GOTO (done);
}
parts.assembled.session = parsed.client_session;
if (!bson_concat (&parts.extra, &parsed.extra)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"'opts' is too large");
GOTO (done);
}
cluster = &collection->client->cluster;
if (mongoc_cmd_parts_assemble (&parts, server_stream, error)) {
ret = mongoc_cluster_run_command_monitored (
cluster, &parts.assembled, reply, error);
} else {
_mongoc_bson_init_if_set (reply);
}
reply_initialized = true;
if (ret) {
if (reply) {
ret = !_mongoc_parse_wc_err (reply, error);
}
}
done:
bson_destroy (&cmd);
bson_free (alloc_name);
_mongoc_create_index_opts_cleanup (&parsed);
mongoc_server_stream_cleanup (server_stream);
mongoc_cmd_parts_cleanup (&parts);
if (!reply_initialized && reply) {
bson_init (reply);
}
RETURN (ret);
}
bool
mongoc_collection_ensure_index (mongoc_collection_t *collection,
const bson_t *keys,
const mongoc_index_opt_t *opt,
bson_error_t *error)
{
BEGIN_IGNORE_DEPRECATIONS
return mongoc_collection_create_index (collection, keys, opt, error);
END_IGNORE_DEPRECATIONS
}
mongoc_cursor_t *
mongoc_collection_find_indexes (mongoc_collection_t *collection,
bson_error_t *error)
{
mongoc_cursor_t *cursor;
cursor = mongoc_collection_find_indexes_with_opts (collection, NULL);
(void) mongoc_cursor_error (cursor, error);
return cursor;
}
mongoc_cursor_t *
mongoc_collection_find_indexes_with_opts (mongoc_collection_t *collection,
const bson_t *opts)
{
mongoc_cursor_t *cursor;
bson_t cmd = BSON_INITIALIZER;
bson_t child;
bson_error_t error;
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
bson_append_utf8 (&cmd,
"listIndexes",
-1,
collection->collection,
collection->collectionlen);
BSON_APPEND_DOCUMENT_BEGIN (&cmd, "cursor", &child);
bson_append_document_end (&cmd, &child);
/* No read preference. Index Enumeration Spec: "run listIndexes on the
* primary node in replicaSet mode". */
cursor = _mongoc_cursor_cmd_new (
collection->client, collection->ns, &cmd, opts, NULL, NULL, NULL);
if (!mongoc_cursor_error (cursor, &error)) {
_mongoc_cursor_prime (cursor);
}
if (mongoc_cursor_error (cursor, &error) &&
error.code == MONGOC_ERROR_COLLECTION_DOES_NOT_EXIST) {
/* collection does not exist. from spec: return no documents but no err:
* https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst#enumeration-getting-index-information
*/
_mongoc_cursor_set_empty (cursor);
}
bson_destroy (&cmd);
return cursor;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_insert_bulk --
*
* Bulk insert documents into a MongoDB collection.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: flags for the insert or 0.
* @documents: The documents to insert.
* @n_documents: The number of documents to insert.
* @write_concern: A write concern or NULL.
* @error: a location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* If the write concern does not dictate checking the result of the
* insert, then true may be returned even though the document was
* not actually inserted on the MongoDB server or cluster.
*
* Side effects:
* @collection->gle is setup, depending on write_concern->w value.
* @error may be set upon failure if non-NULL.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_insert_bulk (mongoc_collection_t *collection,
mongoc_insert_flags_t flags,
const bson_t **documents,
uint32_t n_documents,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
mongoc_write_command_t command;
mongoc_write_result_t result;
mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
uint32_t i;
bool ret;
- BSON_ASSERT (collection);
- BSON_ASSERT (documents);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (documents);
if (!write_concern) {
write_concern = collection->write_concern;
}
if (!(flags & MONGOC_INSERT_NO_VALIDATE)) {
for (i = 0; i < n_documents; i++) {
if (!_mongoc_validate_new_document (
documents[i], _mongoc_default_insert_vflags, error)) {
RETURN (false);
}
}
}
bson_clear (&collection->gle);
_mongoc_write_result_init (&result);
write_flags.ordered = !(flags & MONGOC_INSERT_CONTINUE_ON_ERROR);
_mongoc_write_command_init_insert (
&command,
NULL,
NULL,
write_flags,
++collection->client->cluster.operation_id);
for (i = 0; i < n_documents; i++) {
_mongoc_write_command_insert_append (&command, documents[i]);
}
_mongoc_collection_write_command_execute (
&command, collection, write_concern, NULL, &result);
collection->gle = bson_new ();
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
write_concern,
/* no error domain override */
(mongoc_error_domain_t) 0,
collection->gle,
error);
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
return ret;
}
bool
mongoc_collection_insert (mongoc_collection_t *collection,
mongoc_insert_flags_t flags,
const bson_t *document,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
bson_t opts = BSON_INITIALIZER;
bson_t reply;
bool r;
bson_clear (&collection->gle);
if (flags & MONGOC_INSERT_NO_VALIDATE) {
bson_append_bool (&opts, "validate", 8, false);
}
if (write_concern) {
mongoc_write_concern_append ((mongoc_write_concern_t *) write_concern,
&opts);
}
r =
mongoc_collection_insert_one (collection, document, &opts, &reply, error);
collection->gle = bson_copy (&reply);
bson_destroy (&reply);
bson_destroy (&opts);
return r;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_insert_one --
*
* Insert a document into a MongoDB collection.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @document: The document to insert.
* @opts: Standard command options.
* @reply: Optional. Uninitialized doc to receive the update result.
* @error: A location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* If the write concern does not dictate checking the result of the
* insert, then true may be returned even though the document was
* not actually inserted on the MongoDB server or cluster.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_insert_one (mongoc_collection_t *collection,
const bson_t *document,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_insert_one_opts_t insert_one_opts;
mongoc_write_command_t command;
mongoc_write_result_t result;
bool ret = false;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (document);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (document);
_mongoc_bson_init_if_set (reply);
if (!_mongoc_insert_one_opts_parse (
collection->client, opts, &insert_one_opts, error)) {
GOTO (done);
}
if (!_mongoc_validate_new_document (
document, insert_one_opts.crud.validate, error)) {
GOTO (done);
}
_mongoc_write_result_init (&result);
_mongoc_write_command_init_insert_idl (
&command,
document,
&insert_one_opts.extra,
++collection->client->cluster.operation_id);
command.flags.bypass_document_validation = insert_one_opts.bypass;
_mongoc_collection_write_command_execute_idl (
&command, collection, &insert_one_opts.crud, &result);
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
insert_one_opts.crud.writeConcern,
/* no error domain override */
(mongoc_error_domain_t) 0,
reply,
error,
"insertedCount");
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
done:
_mongoc_insert_one_opts_cleanup (&insert_one_opts);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_insert_many --
*
* Insert documents into a MongoDB collection. Replaces
* mongoc_collection_insert_bulk.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @documents: The documents to insert.
* @n_documents: Length of @documents array.
* @opts: Standard command options.
* @reply: Optional. Uninitialized doc to receive the update result.
* @error: A location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* If the write concern does not dictate checking the result of the
* insert, then true may be returned even though the document was
* not actually inserted on the MongoDB server or cluster.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_insert_many (mongoc_collection_t *collection,
const bson_t **documents,
size_t n_documents,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_insert_many_opts_t insert_many_opts;
mongoc_write_command_t command;
mongoc_write_result_t result;
size_t i;
bool ret;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (documents);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (documents);
_mongoc_bson_init_if_set (reply);
if (!_mongoc_insert_many_opts_parse (
collection->client, opts, &insert_many_opts, error)) {
_mongoc_insert_many_opts_cleanup (&insert_many_opts);
return false;
}
_mongoc_write_result_init (&result);
_mongoc_write_command_init_insert_idl (
&command,
NULL,
&insert_many_opts.extra,
++collection->client->cluster.operation_id);
command.flags.ordered = insert_many_opts.ordered;
command.flags.bypass_document_validation = insert_many_opts.bypass;
for (i = 0; i < n_documents; i++) {
if (!_mongoc_validate_new_document (
documents[i], insert_many_opts.crud.validate, error)) {
ret = false;
GOTO (done);
}
_mongoc_write_command_insert_append (&command, documents[i]);
}
_mongoc_collection_write_command_execute_idl (
&command, collection, &insert_many_opts.crud, &result);
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
insert_many_opts.crud.writeConcern,
/* no error domain override */
(mongoc_error_domain_t) 0,
reply,
error,
"insertedCount");
done:
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
_mongoc_insert_many_opts_cleanup (&insert_many_opts);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_update --
*
* Updates one or more documents matching @selector with @update.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: The flags for the update.
* @selector: A bson_t containing your selector.
* @update: A bson_t containing your update document.
* @write_concern: The write concern or NULL.
* @error: A location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @collection->gle is setup, depending on write_concern->w value.
* @error is setup upon failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_update (mongoc_collection_t *collection,
mongoc_update_flags_t uflags,
const bson_t *selector,
const bson_t *update,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
mongoc_write_command_t command;
mongoc_write_result_t result;
bson_iter_t iter;
bool ret;
int flags = uflags;
bson_t opts;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (selector);
- BSON_ASSERT (update);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (selector);
+ BSON_ASSERT_PARAM (update);
bson_clear (&collection->gle);
if (!write_concern) {
write_concern = collection->write_concern;
}
if (!((uint32_t) flags & MONGOC_UPDATE_NO_VALIDATE) &&
bson_iter_init (&iter, update) && bson_iter_next (&iter)) {
if (bson_iter_key (&iter)[0] == '$') {
/* update document, all keys must be $-operators */
if (!_mongoc_validate_update (
update, _mongoc_default_update_vflags, error)) {
return false;
}
} else {
if (!_mongoc_validate_replace (
update, _mongoc_default_replace_vflags, error)) {
return false;
}
}
}
bson_init (&opts);
BSON_APPEND_BOOL (&opts, "upsert", !!(flags & MONGOC_UPDATE_UPSERT));
BSON_APPEND_BOOL (&opts, "multi", !!(flags & MONGOC_UPDATE_MULTI_UPDATE));
_mongoc_write_result_init (&result);
_mongoc_write_command_init_update (
&command,
selector,
update,
&opts,
write_flags,
++collection->client->cluster.operation_id);
bson_destroy (&opts);
command.flags.has_multi_write = !!(flags & MONGOC_UPDATE_MULTI_UPDATE);
_mongoc_collection_write_command_execute (
&command, collection, write_concern, NULL, &result);
collection->gle = bson_new ();
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
write_concern,
/* no error domain override */
(mongoc_error_domain_t) 0,
collection->gle,
error);
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
RETURN (ret);
}
static bool
_mongoc_collection_update_or_replace (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *update,
mongoc_update_opts_t *update_opts,
bool multi,
bool bypass,
const bson_t *array_filters,
bson_t *extra,
bson_t *reply,
bson_error_t *error)
{
mongoc_write_command_t command;
mongoc_write_result_t result;
mongoc_server_stream_t *server_stream = NULL;
bool reply_initialized = false;
bool ret = false;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (selector);
- BSON_ASSERT (update);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (selector);
+ BSON_ASSERT_PARAM (update);
if (update_opts->upsert) {
bson_append_bool (extra, "upsert", 6, true);
}
if (!bson_empty (&update_opts->collation)) {
bson_append_document (extra, "collation", 9, &update_opts->collation);
}
if (update_opts->hint.value_type) {
bson_append_value (extra, "hint", 4, &update_opts->hint);
}
if (!bson_empty0 (array_filters)) {
bson_append_array (extra, "arrayFilters", 12, array_filters);
}
if (multi) {
bson_append_bool (extra, "multi", 5, true);
}
_mongoc_write_result_init (&result);
_mongoc_write_command_init_update_idl (
&command,
selector,
update,
extra,
++collection->client->cluster.operation_id);
command.flags.has_multi_write = multi;
command.flags.bypass_document_validation = bypass;
if (!bson_empty (&update_opts->collation)) {
command.flags.has_collation = true;
}
if (update_opts->hint.value_type) {
command.flags.has_update_hint = true;
}
server_stream =
mongoc_cluster_stream_for_writes (&collection->client->cluster,
update_opts->crud.client_session,
reply,
error);
if (!server_stream) {
/* mongoc_cluster_stream_for_writes inits reply on error */
reply_initialized = true;
GOTO (done);
}
if (!bson_empty0 (array_filters)) {
if (server_stream->sd->max_wire_version < WIRE_VERSION_ARRAY_FILTERS) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support array filters");
GOTO (done);
}
if (!mongoc_write_concern_is_acknowledged (
update_opts->crud.writeConcern)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Cannot use array filters with unacknowledged writes");
GOTO (done);
}
}
if (_mongoc_client_session_in_txn (update_opts->crud.client_session) &&
update_opts->crud.writeConcern) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
GOTO (done);
}
if (!update_opts->crud.writeConcern &&
!_mongoc_client_session_in_txn (update_opts->crud.client_session)) {
update_opts->crud.writeConcern = collection->write_concern;
update_opts->crud.write_concern_owned = false;
}
_mongoc_write_command_execute_idl (&command,
collection->client,
server_stream,
collection->db,
collection->collection,
0 /* offset */,
&update_opts->crud,
&result);
_mongoc_bson_init_if_set (reply);
reply_initialized = true;
/* set fields described in CRUD spec for the UpdateResult */
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
update_opts->crud.writeConcern,
/* no error domain override */
(mongoc_error_domain_t) 0,
reply,
error,
"modifiedCount",
"matchedCount",
"upsertedCount",
"upsertedId");
done:
_mongoc_write_result_destroy (&result);
mongoc_server_stream_cleanup (server_stream);
_mongoc_write_command_destroy (&command);
if (!reply_initialized) {
_mongoc_bson_init_if_set (reply);
}
RETURN (ret);
}
bool
mongoc_collection_update_one (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *update,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_update_one_opts_t update_one_opts;
bool ret;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (update);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (update);
if (!_mongoc_update_one_opts_parse (
collection->client, opts, &update_one_opts, error)) {
_mongoc_update_one_opts_cleanup (&update_one_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
if (!_mongoc_validate_update (
update, update_one_opts.update.crud.validate, error)) {
_mongoc_update_one_opts_cleanup (&update_one_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
ret = _mongoc_collection_update_or_replace (collection,
selector,
update,
&update_one_opts.update,
false /* multi */,
update_one_opts.update.bypass,
&update_one_opts.arrayFilters,
&update_one_opts.extra,
reply,
error);
_mongoc_update_one_opts_cleanup (&update_one_opts);
RETURN (ret);
}
bool
mongoc_collection_update_many (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *update,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_update_many_opts_t update_many_opts;
bool ret;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (update);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (update);
if (!_mongoc_update_many_opts_parse (
collection->client, opts, &update_many_opts, error)) {
_mongoc_update_many_opts_cleanup (&update_many_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
if (!_mongoc_validate_update (
update, update_many_opts.update.crud.validate, error)) {
_mongoc_update_many_opts_cleanup (&update_many_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
ret = _mongoc_collection_update_or_replace (collection,
selector,
update,
&update_many_opts.update,
true /* multi */,
update_many_opts.update.bypass,
&update_many_opts.arrayFilters,
&update_many_opts.extra,
reply,
error);
_mongoc_update_many_opts_cleanup (&update_many_opts);
RETURN (ret);
}
bool
mongoc_collection_replace_one (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *replacement,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_replace_one_opts_t replace_one_opts;
bool ret;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (replacement);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (replacement);
if (!_mongoc_replace_one_opts_parse (
collection->client, opts, &replace_one_opts, error)) {
_mongoc_replace_one_opts_cleanup (&replace_one_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
if (!_mongoc_validate_replace (
replacement, replace_one_opts.update.crud.validate, error)) {
_mongoc_replace_one_opts_cleanup (&replace_one_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
ret = _mongoc_collection_update_or_replace (collection,
selector,
replacement,
&replace_one_opts.update,
false /* multi */,
replace_one_opts.update.bypass,
NULL,
&replace_one_opts.extra,
reply,
error);
_mongoc_replace_one_opts_cleanup (&replace_one_opts);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_save --
*
* Save @document to @collection.
*
* If the document has an _id field, it will be updated. Otherwise,
* the document will be inserted into the collection.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @error is set upon failure if non-NULL.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_save (mongoc_collection_t *collection,
const bson_t *document,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
bson_iter_t iter;
bool ret;
bson_t selector;
- BSON_ASSERT (collection);
- BSON_ASSERT (document);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (document);
BEGIN_IGNORE_DEPRECATIONS
if (!bson_iter_init_find (&iter, document, "_id")) {
return mongoc_collection_insert (
collection, MONGOC_INSERT_NONE, document, write_concern, error);
}
bson_init (&selector);
if (!bson_append_iter (&selector, NULL, 0, &iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Failed to append bson to create update.");
bson_destroy (&selector);
return false;
}
/* this document will be inserted, validate same as for inserts */
if (!_mongoc_validate_new_document (
document, _mongoc_default_insert_vflags, error)) {
return false;
}
ret = mongoc_collection_update (collection,
MONGOC_UPDATE_UPSERT |
MONGOC_UPDATE_NO_VALIDATE,
&selector,
document,
write_concern,
error);
END_IGNORE_DEPRECATIONS
bson_destroy (&selector);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_remove --
*
* Delete one or more items from a collection. If you want to
* limit to a single delete, provided MONGOC_REMOVE_SINGLE_REMOVE
* for @flags.
*
* Superseded by mongoc_collection_delete_one/many.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: the delete flags or 0.
* @selector: A selector of documents to delete.
* @write_concern: A write concern or NULL. If NULL, the default
* write concern for the collection will be used.
* @error: A location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and error is set.
*
* If the write concern does not dictate checking the result, this
* function may return true even if it failed.
*
* Side effects:
* @collection->gle is setup, depending on write_concern->w value.
* @error is setup upon failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_remove (mongoc_collection_t *collection,
mongoc_remove_flags_t flags,
const bson_t *selector,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
mongoc_write_command_t command;
mongoc_write_result_t result;
bson_t opts;
bool ret;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (selector);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (selector);
bson_clear (&collection->gle);
if (!write_concern) {
write_concern = collection->write_concern;
}
bson_init (&opts);
BSON_APPEND_INT32 (
&opts, "limit", flags & MONGOC_REMOVE_SINGLE_REMOVE ? 1 : 0);
_mongoc_write_result_init (&result);
++collection->client->cluster.operation_id;
_mongoc_write_command_init_delete (&command,
selector,
NULL,
&opts,
write_flags,
collection->client->cluster.operation_id);
bson_destroy (&opts);
command.flags.has_multi_write = !(flags & MONGOC_REMOVE_SINGLE_REMOVE);
_mongoc_collection_write_command_execute (
&command, collection, write_concern, NULL, &result);
collection->gle = bson_new ();
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
write_concern,
0 /* no error domain override */,
collection->gle,
error);
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
RETURN (ret);
}
bool
mongoc_collection_delete (mongoc_collection_t *collection,
mongoc_delete_flags_t flags,
const bson_t *selector,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
return mongoc_collection_remove (collection,
(mongoc_remove_flags_t) flags,
selector,
write_concern,
error);
}
static bool
_mongoc_delete_one_or_many (mongoc_collection_t *collection,
bool multi,
const bson_t *selector,
- mongoc_crud_opts_t *crud,
+ mongoc_delete_opts_t *delete_opts,
const bson_t *cmd_opts,
- const bson_t *collation,
bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_write_command_t command;
mongoc_write_result_t result;
bool ret;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (selector);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (selector);
BSON_ASSERT (bson_empty0 (reply));
_mongoc_write_result_init (&result);
bson_append_int32 (opts, "limit", 5, multi ? 0 : 1);
- if (!bson_empty (collation)) {
- bson_append_document (opts, "collation", 9, collation);
+ if (!bson_empty (&delete_opts->collation)) {
+ bson_append_document (opts, "collation", 9, &delete_opts->collation);
+ }
+
+ if (delete_opts->hint.value_type) {
+ bson_append_value (opts, "hint", 4, &delete_opts->hint);
}
_mongoc_write_command_init_delete_idl (
&command,
selector,
cmd_opts,
opts,
++collection->client->cluster.operation_id);
command.flags.has_multi_write = multi;
- if (!bson_empty (collation)) {
+ if (!bson_empty (&delete_opts->collation)) {
command.flags.has_collation = true;
}
+ if (delete_opts->hint.value_type) {
+ command.flags.has_delete_hint = true;
+ }
_mongoc_collection_write_command_execute_idl (
- &command, collection, crud, &result);
+ &command, collection, &delete_opts->crud, &result);
/* set field described in CRUD spec for the DeleteResult */
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
- crud->writeConcern,
+ delete_opts->crud.writeConcern,
/* no error domain override */
(mongoc_error_domain_t) 0,
reply,
error,
"deletedCount");
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
RETURN (ret);
}
bool
mongoc_collection_delete_one (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_delete_one_opts_t delete_one_opts;
bson_t limit = BSON_INITIALIZER;
bool ret = false;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (selector);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (selector);
_mongoc_bson_init_if_set (reply);
if (!_mongoc_delete_one_opts_parse (
collection->client, opts, &delete_one_opts, error)) {
GOTO (done);
}
ret = _mongoc_delete_one_or_many (collection,
false /* multi */,
selector,
- &delete_one_opts.crud,
+ &delete_one_opts.delete,
&delete_one_opts.extra,
- &delete_one_opts.collation,
&limit,
reply,
error);
done:
_mongoc_delete_one_opts_cleanup (&delete_one_opts);
bson_destroy (&limit);
RETURN (ret);
}
bool
mongoc_collection_delete_many (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_delete_many_opts_t delete_many_opts;
bson_t limit = BSON_INITIALIZER;
bool ret = false;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (selector);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (selector);
_mongoc_bson_init_if_set (reply);
if (!_mongoc_delete_many_opts_parse (
collection->client, opts, &delete_many_opts, error)) {
GOTO (done);
}
ret = _mongoc_delete_one_or_many (collection,
true /* multi */,
selector,
- &delete_many_opts.crud,
+ &delete_many_opts.delete,
&delete_many_opts.extra,
- &delete_many_opts.collation,
&limit,
reply,
error);
done:
_mongoc_delete_many_opts_cleanup (&delete_many_opts);
bson_destroy (&limit);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_read_prefs --
*
* Fetch the default read preferences for the collection.
*
* Returns:
* A mongoc_read_prefs_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_prefs_t *
mongoc_collection_get_read_prefs (const mongoc_collection_t *collection)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
return collection->read_prefs;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_set_read_prefs --
*
* Sets the default read preferences for the collection instance.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_collection_set_read_prefs (mongoc_collection_t *collection,
const mongoc_read_prefs_t *read_prefs)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
if (collection->read_prefs) {
mongoc_read_prefs_destroy (collection->read_prefs);
collection->read_prefs = NULL;
}
if (read_prefs) {
collection->read_prefs = mongoc_read_prefs_copy (read_prefs);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_read_concern --
*
* Fetches the default read concern for the collection instance.
*
* Returns:
* A mongoc_read_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_concern_t *
mongoc_collection_get_read_concern (const mongoc_collection_t *collection)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
return collection->read_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_set_read_concern --
*
* Sets the default read concern for the collection instance.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_collection_set_read_concern (mongoc_collection_t *collection,
const mongoc_read_concern_t *read_concern)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
if (collection->read_concern) {
mongoc_read_concern_destroy (collection->read_concern);
collection->read_concern = NULL;
}
if (read_concern) {
collection->read_concern = mongoc_read_concern_copy (read_concern);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_write_concern --
*
* Fetches the default write concern for the collection instance.
*
* Returns:
* A mongoc_write_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_write_concern_t *
mongoc_collection_get_write_concern (const mongoc_collection_t *collection)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
return collection->write_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_set_write_concern --
*
* Sets the default write concern for the collection instance.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_collection_set_write_concern (
mongoc_collection_t *collection, const mongoc_write_concern_t *write_concern)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
if (collection->write_concern) {
mongoc_write_concern_destroy (collection->write_concern);
collection->write_concern = NULL;
}
if (write_concern) {
collection->write_concern = mongoc_write_concern_copy (write_concern);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_name --
*
* Returns the name of the collection, excluding the database name.
*
* Returns:
* A string which should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const char *
mongoc_collection_get_name (mongoc_collection_t *collection)
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
return collection->collection;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_last_error --
*
* Returns a bulk result.
*
* Returns:
* NULL or a bson_t that should not be modified or freed. This value
* is not guaranteed to be persistent between calls into the
* mongoc_collection_t instance, and therefore must be copied if
* you would like to keep it around.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const bson_t *
mongoc_collection_get_last_error (
const mongoc_collection_t *collection) /* IN */
{
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
return collection->gle;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_validate --
*
* Helper to call the validate command on the MongoDB server to
* validate the collection.
*
* Options may be additional options, or NULL.
* Currently supported options are:
*
* "full": Boolean
*
* If full is true, then perform a more resource intensive
* validation.
*
* The result is stored in reply.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @reply is set if successful.
* @error may be set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_validate (mongoc_collection_t *collection, /* IN */
const bson_t *options, /* IN */
bson_t *reply, /* OUT */
bson_error_t *error) /* IN */
{
bson_iter_t iter;
bson_t cmd = BSON_INITIALIZER;
bool ret = false;
bool reply_initialized = false;
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
if (options && bson_iter_init_find (&iter, options, "full") &&
!BSON_ITER_HOLDS_BOOL (&iter)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"'full' must be a boolean value.");
goto cleanup;
}
bson_append_utf8 (
&cmd, "validate", 8, collection->collection, collection->collectionlen);
if (options) {
bson_concat (&cmd, options);
}
ret =
mongoc_collection_command_simple (collection, &cmd, NULL, reply, error);
reply_initialized = true;
cleanup:
bson_destroy (&cmd);
if (reply && !reply_initialized) {
bson_init (reply);
}
return ret;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_rename --
*
* Rename the collection to @new_name.
*
* If @new_db is NULL, the same db will be used.
*
* If @drop_target_before_rename is true, then a collection named
* @new_name will be dropped before renaming @collection to
* @new_name.
*
* Returns:
* true on success; false on failure and @error is set.
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_rename (mongoc_collection_t *collection,
const char *new_db,
const char *new_name,
bool drop_target_before_rename,
bson_error_t *error)
{
return mongoc_collection_rename_with_opts (
collection, new_db, new_name, drop_target_before_rename, NULL, error);
}
bool
mongoc_collection_rename_with_opts (mongoc_collection_t *collection,
const char *new_db,
const char *new_name,
bool drop_target_before_rename,
const bson_t *opts,
bson_error_t *error)
{
bson_t cmd = BSON_INITIALIZER;
- char newns[MONGOC_NAMESPACE_MAX + 1];
+ char *newns;
bool ret;
- BSON_ASSERT (collection);
- BSON_ASSERT (new_name);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (new_name);
if (strchr (new_name, '$')) {
bson_set_error (error,
MONGOC_ERROR_NAMESPACE,
MONGOC_ERROR_NAMESPACE_INVALID,
"\"%s\" is an invalid collection name.",
new_name);
return false;
}
- bson_snprintf (
- newns, sizeof newns, "%s.%s", new_db ? new_db : collection->db, new_name);
+ newns =
+ bson_strdup_printf ("%s.%s", new_db ? new_db : collection->db, new_name);
BSON_APPEND_UTF8 (&cmd, "renameCollection", collection->ns);
BSON_APPEND_UTF8 (&cmd, "to", newns);
if (drop_target_before_rename) {
BSON_APPEND_BOOL (&cmd, "dropTarget", true);
}
ret = _mongoc_client_command_with_opts (collection->client,
"admin",
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
collection->read_prefs,
collection->read_concern,
collection->write_concern,
NULL, /* reply */
error);
if (ret) {
if (new_db) {
- bson_snprintf (collection->db, sizeof collection->db, "%s", new_db);
+ bson_free (collection->db);
+ collection->db = bson_strdup (new_db);
}
- bson_snprintf (
- collection->collection, sizeof collection->collection, "%s", new_name);
+ bson_free (collection->collection);
+ collection->collection = bson_strdup (new_name);
collection->collectionlen = (int) strlen (collection->collection);
- bson_snprintf (collection->ns,
- sizeof collection->ns,
- "%s.%s",
- collection->db,
- new_name);
+ bson_free (collection->ns);
+ collection->ns = bson_strdup_printf ("%s.%s", collection->db, new_name);
collection->nslen = (int) strlen (collection->ns);
}
+ bson_free (newns);
bson_destroy (&cmd);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_stats --
*
* Fetches statistics about the collection.
*
* The result is stored in @stats, which should NOT be an initialized
* bson_t or a leak will occur.
*
* @stats, @options, and @error are optional.
*
* Returns:
* true on success and @stats is set.
* false on failure and @error is set.
*
* Side effects:
* @stats and @error.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_stats (mongoc_collection_t *collection,
const bson_t *options,
bson_t *stats,
bson_error_t *error)
{
bson_iter_t iter;
bson_t cmd = BSON_INITIALIZER;
bool ret;
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
if (options && bson_iter_init_find (&iter, options, "scale") &&
!BSON_ITER_HOLDS_INT32 (&iter)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"'scale' must be an int32 value.");
return false;
}
BSON_APPEND_UTF8 (&cmd, "collStats", collection->collection);
if (options) {
bson_concat (&cmd, options);
}
/* Server Selection Spec: "may-use-secondary" commands SHOULD take a read
* preference argument and otherwise MUST use the default read preference
* from client, database or collection configuration. */
ret = mongoc_collection_command_simple (
collection, &cmd, collection->read_prefs, stats, error);
bson_destroy (&cmd);
return ret;
}
mongoc_bulk_operation_t *
mongoc_collection_create_bulk_operation (
mongoc_collection_t *collection,
bool ordered,
const mongoc_write_concern_t *write_concern)
{
bson_t opts = BSON_INITIALIZER;
mongoc_bulk_operation_t *bulk;
bool wc_ok = true;
bson_append_bool (&opts, "ordered", 7, ordered);
if (write_concern) {
wc_ok = mongoc_write_concern_append (
(mongoc_write_concern_t *) write_concern, &opts);
}
bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts);
bson_destroy (&opts);
if (!wc_ok) {
bson_set_error (&bulk->result.error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"invalid writeConcern");
}
return bulk;
}
mongoc_bulk_operation_t *
mongoc_collection_create_bulk_operation_with_opts (
mongoc_collection_t *collection, const bson_t *opts)
{
mongoc_bulk_opts_t bulk_opts;
mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
mongoc_write_concern_t *wc = NULL;
mongoc_bulk_operation_t *bulk;
bson_error_t err = {0};
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (collection);
(void) _mongoc_bulk_opts_parse (collection->client, opts, &bulk_opts, &err);
if (!_mongoc_client_session_in_txn (bulk_opts.client_session)) {
wc = COALESCE (bulk_opts.writeConcern, collection->write_concern);
}
write_flags.ordered = bulk_opts.ordered;
bulk = _mongoc_bulk_operation_new (collection->client,
collection->db,
collection->collection,
write_flags,
wc);
bulk->session = bulk_opts.client_session;
if (err.domain) {
/* _mongoc_bulk_opts_parse failed, above */
memcpy (&bulk->result.error, &err, sizeof (bson_error_t));
} else if (_mongoc_client_session_in_txn (bulk_opts.client_session) &&
!mongoc_write_concern_is_default (bulk_opts.writeConcern)) {
bson_set_error (&bulk->result.error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
}
_mongoc_bulk_opts_cleanup (&bulk_opts);
return bulk;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_find_and_modify_with_opts --
*
* Find a document in @collection matching @query, applying @opts.
*
* If @reply is not NULL, then the result document will be placed
* in reply and should be released with bson_destroy().
*
* See http://docs.mongodb.org/manual/reference/command/findAndModify/
* for more information.
*
* Returns:
* true on success; false on failure.
*
* Side effects:
* reply is initialized.
* error is set if false is returned.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_find_and_modify_with_opts (
mongoc_collection_t *collection,
const bson_t *query,
const mongoc_find_and_modify_opts_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_cluster_t *cluster;
- mongoc_client_session_t *cs = NULL;
mongoc_cmd_parts_t parts;
bool is_retryable;
bson_iter_t iter;
bson_iter_t inner;
const char *name;
+ bson_t ss_reply;
bson_t reply_local;
bson_t *reply_ptr;
bool ret = false;
bson_t command = BSON_INITIALIZER;
mongoc_server_stream_t *server_stream = NULL;
mongoc_server_stream_t *retry_server_stream = NULL;
+ mongoc_find_and_modify_appended_opts_t appended_opts;
+ mongoc_write_concern_t *write_concern = NULL;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (query);
- BSON_ASSERT (opts);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (query);
+ BSON_ASSERT_PARAM (opts);
reply_ptr = reply ? reply : &reply_local;
cluster = &collection->client->cluster;
mongoc_cmd_parts_init (
&parts, collection->client, collection->db, MONGOC_QUERY_NONE, &command);
parts.is_read_command = true;
parts.is_write_command = true;
- /* we need a session to fetch a stream to call cmd_parts_append_opts
- * below, which parses the session from opts->extra *again*
- */
- if (bson_iter_init_find (&iter, &opts->extra, "sessionId")) {
- if (!_mongoc_client_session_from_iter (
- collection->client, &iter, &cs, error)) {
- bson_init (reply_ptr);
- GOTO (done);
- }
+ bson_init (reply_ptr);
+
+ if (!_mongoc_find_and_modify_appended_opts_parse (
+ cluster->client, &opts->extra, &appended_opts, error)) {
+ GOTO (done);
}
- server_stream =
- mongoc_cluster_stream_for_writes (cluster, cs, reply_ptr, error);
+ server_stream = mongoc_cluster_stream_for_writes (
+ cluster, appended_opts.client_session, &ss_reply, error);
if (!server_stream) {
+ bson_concat (reply_ptr, &ss_reply);
+ bson_destroy (&ss_reply);
GOTO (done);
}
- bson_init (reply_ptr);
name = mongoc_collection_get_name (collection);
BSON_APPEND_UTF8 (&command, "findAndModify", name);
BSON_APPEND_DOCUMENT (&command, "query", query);
if (opts->sort) {
BSON_APPEND_DOCUMENT (&command, "sort", opts->sort);
}
if (opts->update) {
if (_mongoc_document_is_pipeline (opts->update)) {
BSON_APPEND_ARRAY (&command, "update", opts->update);
} else {
BSON_APPEND_DOCUMENT (&command, "update", opts->update);
}
}
if (opts->fields) {
BSON_APPEND_DOCUMENT (&command, "fields", opts->fields);
}
if (opts->flags & MONGOC_FIND_AND_MODIFY_REMOVE) {
BSON_APPEND_BOOL (&command, "remove", true);
}
if (opts->flags & MONGOC_FIND_AND_MODIFY_UPSERT) {
BSON_APPEND_BOOL (&command, "upsert", true);
}
if (opts->flags & MONGOC_FIND_AND_MODIFY_RETURN_NEW) {
BSON_APPEND_BOOL (&command, "new", true);
}
if (opts->bypass_document_validation) {
BSON_APPEND_BOOL (&command,
"bypassDocumentValidation",
opts->bypass_document_validation);
}
if (opts->max_time_ms > 0) {
BSON_APPEND_INT32 (&command, "maxTimeMS", opts->max_time_ms);
}
- if (bson_iter_init (&iter, &opts->extra)) {
- bool ok = mongoc_cmd_parts_append_opts (
- &parts, &iter, server_stream->sd->max_wire_version, error);
- if (!ok) {
+ /* Some options set via mongoc_find_and_modify_opts_append were parsed. Set
+ * them on the command parts. */
+ if (appended_opts.client_session) {
+ mongoc_cmd_parts_set_session (&parts, appended_opts.client_session);
+ }
+
+ if (appended_opts.writeConcern) {
+ if (_mongoc_client_session_in_txn (parts.assembled.session)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "Cannot set write concern after starting transaction");
GOTO (done);
}
- }
- if (_mongoc_client_session_in_txn (parts.assembled.session) &&
- !bson_empty (&parts.write_concern_document)) {
- bson_set_error (error,
- MONGOC_ERROR_COMMAND,
- MONGOC_ERROR_COMMAND_INVALID_ARG,
- "Cannot set write concern after starting transaction");
- GOTO (done);
+ write_concern = appended_opts.writeConcern;
}
- if (!bson_has_field (&opts->extra, "writeConcern")) {
+ if (!write_concern) {
if (server_stream->sd->max_wire_version >=
- WIRE_VERSION_FAM_WRITE_CONCERN) {
+ WIRE_VERSION_FAM_WRITE_CONCERN &&
+ (mongoc_write_concern_is_acknowledged (collection->write_concern) ||
+ !_mongoc_client_session_in_txn (parts.assembled.session))) {
if (!mongoc_write_concern_is_valid (collection->write_concern)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The write concern is invalid.");
GOTO (done);
}
- if (mongoc_write_concern_is_acknowledged (collection->write_concern)) {
- if (!mongoc_cmd_parts_set_write_concern (
- &parts,
- collection->write_concern,
- server_stream->sd->max_wire_version,
- error)) {
- GOTO (done);
- }
- }
+ write_concern = collection->write_concern;
}
}
+ if (appended_opts.hint.value_type) {
+ int max_wire_version =
+ mongoc_write_concern_is_acknowledged (write_concern)
+ ? WIRE_VERSION_FIND_AND_MODIFY_HINT_SERVER_SIDE_ERROR
+ : WIRE_VERSION_FIND_AND_MODIFY_HINT;
+
+ if (server_stream->sd->max_wire_version < max_wire_version) {
+ bson_set_error (
+ error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
+ "selected server does not support hint on findAndModify");
+ GOTO (done);
+ }
+
+ bson_append_value (&parts.extra, "hint", 4, &appended_opts.hint);
+ }
+
+ /* Append any remaining unparsed options set via
+ * mongoc_find_and_modify_opts_append to the command part. */
+ if (bson_iter_init (&iter, &appended_opts.extra)) {
+ bool ok = mongoc_cmd_parts_append_opts (
+ &parts, &iter, server_stream->sd->max_wire_version, error);
+ if (!ok) {
+ GOTO (done);
+ }
+ }
+
+ /* An empty write concern amounts to a no-op, so there's no need to guard
+ * against it. */
+ if (!mongoc_cmd_parts_set_write_concern (
+ &parts, write_concern, server_stream->sd->max_wire_version, error)) {
+ GOTO (done);
+ }
+
parts.assembled.operation_id = ++cluster->operation_id;
if (!mongoc_cmd_parts_assemble (&parts, server_stream, error)) {
GOTO (done);
}
is_retryable = parts.is_retryable_write;
/* increment the transaction number for the first attempt of each retryable
* write command */
if (is_retryable) {
bson_iter_t txn_number_iter;
BSON_ASSERT (bson_iter_init_find (
&txn_number_iter, parts.assembled.command, "txnNumber"));
bson_iter_overwrite_int64 (
&txn_number_iter,
++parts.assembled.session->server_session->txn_number);
}
retry:
bson_destroy (reply_ptr);
ret = mongoc_cluster_run_command_monitored (
cluster, &parts.assembled, reply_ptr, error);
+ if (parts.is_retryable_write) {
+ _mongoc_write_error_handle_labels (
+ ret, error, reply_ptr, server_stream->sd->max_wire_version);
+ }
+
if (is_retryable) {
_mongoc_write_error_update_if_unsupported_storage_engine (
ret, error, reply_ptr);
}
/* If a retryable error is encountered and the write is retryable, select
* a new writable stream and retry. If server selection fails or the selected
* server does not support retryable writes, fall through and allow the
* original error to be reported. */
if (is_retryable &&
- _mongoc_write_error_get_type (ret, error, reply_ptr) ==
- MONGOC_WRITE_ERR_RETRY) {
+ _mongoc_write_error_get_type (reply_ptr) == MONGOC_WRITE_ERR_RETRY) {
bson_error_t ignored_error;
/* each write command may be retried at most once */
is_retryable = false;
retry_server_stream = mongoc_cluster_stream_for_writes (
cluster, parts.assembled.session, NULL /* reply */, &ignored_error);
if (retry_server_stream &&
retry_server_stream->sd->max_wire_version >=
WIRE_VERSION_RETRY_WRITES) {
parts.assembled.server_stream = retry_server_stream;
GOTO (retry);
}
}
if (bson_iter_init_find (&iter, reply_ptr, "writeConcernError") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
const char *errmsg = NULL;
int32_t code = 0;
BSON_ASSERT (bson_iter_recurse (&iter, &inner));
while (bson_iter_next (&inner)) {
if (BSON_ITER_IS_KEY (&inner, "code")) {
- code = bson_iter_int32 (&inner);
+ code = (uint32_t) bson_iter_as_int64 (&inner);
} else if (BSON_ITER_IS_KEY (&inner, "errmsg")) {
errmsg = bson_iter_utf8 (&inner, NULL);
}
}
bson_set_error (error,
MONGOC_ERROR_WRITE_CONCERN,
code,
"Write Concern error: %s",
errmsg);
ret = false;
}
done:
mongoc_server_stream_cleanup (server_stream);
mongoc_server_stream_cleanup (retry_server_stream);
mongoc_cmd_parts_cleanup (&parts);
bson_destroy (&command);
if (&reply_local == reply_ptr) {
bson_destroy (&reply_local);
}
+ _mongoc_find_and_modify_appended_opts_cleanup (&appended_opts);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_find_and_modify --
*
* Find a document in @collection matching @query and update it with
* the update document @update.
*
* If @reply is not NULL, then the result document will be placed
* in reply and should be released with bson_destroy().
*
* If @remove is true, then the matching documents will be removed.
*
* If @fields is not NULL, it will be used to select the desired
* resulting fields.
*
* If @_new is true, then the new version of the document is returned
* instead of the old document.
*
* See http://docs.mongodb.org/manual/reference/command/findAndModify/
* for more information.
*
* Returns:
* true on success; false on failure.
*
* Side effects:
* reply is initialized.
* error is set if false is returned.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_find_and_modify (mongoc_collection_t *collection,
const bson_t *query,
const bson_t *sort,
const bson_t *update,
const bson_t *fields,
bool _remove,
bool upsert,
bool _new,
bson_t *reply,
bson_error_t *error)
{
mongoc_find_and_modify_opts_t *opts;
int flags = 0;
bool ret;
ENTRY;
- BSON_ASSERT (collection);
- BSON_ASSERT (query);
+ BSON_ASSERT_PARAM (collection);
+ BSON_ASSERT_PARAM (query);
BSON_ASSERT (update || _remove);
if (_remove) {
flags |= MONGOC_FIND_AND_MODIFY_REMOVE;
}
if (upsert) {
flags |= MONGOC_FIND_AND_MODIFY_UPSERT;
}
if (_new) {
flags |= MONGOC_FIND_AND_MODIFY_RETURN_NEW;
}
opts = mongoc_find_and_modify_opts_new ();
mongoc_find_and_modify_opts_set_sort (opts, sort);
mongoc_find_and_modify_opts_set_update (opts, update);
mongoc_find_and_modify_opts_set_fields (opts, fields);
mongoc_find_and_modify_opts_set_flags (opts, flags);
ret = mongoc_collection_find_and_modify_with_opts (
collection, query, opts, reply, error);
mongoc_find_and_modify_opts_destroy (opts);
return ret;
}
mongoc_change_stream_t *
mongoc_collection_watch (const mongoc_collection_t *coll,
const bson_t *pipeline,
const bson_t *opts)
{
return _mongoc_change_stream_new_from_collection (coll, pipeline, opts);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
index a2bf70ae..cc690ec9 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
@@ -1,405 +1,414 @@
/*
* Copyright 2013 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.
*/
#if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION)
#error "Only <mongoc/mongoc.h> can be included directly."
#endif
#ifndef MONGOC_CONFIG_H
#define MONGOC_CONFIG_H
/* MONGOC_USER_SET_CFLAGS is set from config based on what compiler flags were
* used to compile mongoc */
#define MONGOC_USER_SET_CFLAGS ""
#define MONGOC_USER_SET_LDFLAGS ""
/* MONGOC_CC is used to determine what C compiler was used to compile mongoc */
#define MONGOC_CC "cc"
/*
* MONGOC_ENABLE_SSL_SECURE_CHANNEL is set from configure to determine if we are
* compiled with Native SSL support on Windows
*/
#define MONGOC_ENABLE_SSL_SECURE_CHANNEL 0
#if MONGOC_ENABLE_SSL_SECURE_CHANNEL != 1
# undef MONGOC_ENABLE_SSL_SECURE_CHANNEL
#endif
/*
* MONGOC_ENABLE_CRYPTO_CNG is set from configure to determine if we are
* compiled with Native Crypto support on Windows
*/
#define MONGOC_ENABLE_CRYPTO_CNG 0
#if MONGOC_ENABLE_CRYPTO_CNG != 1
# undef MONGOC_ENABLE_CRYPTO_CNG
#endif
/*
* MONGOC_ENABLE_SSL_SECURE_TRANSPORT is set from configure to determine if we are
* compiled with Native SSL support on Darwin
*/
#define MONGOC_ENABLE_SSL_SECURE_TRANSPORT 1
#if MONGOC_ENABLE_SSL_SECURE_TRANSPORT != 1
# undef MONGOC_ENABLE_SSL_SECURE_TRANSPORT
#endif
/*
* MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO is set from configure to determine if we are
* compiled with Native Crypto support on Darwin
*/
#define MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO 1
#if MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO != 1
# undef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO
#endif
/*
* MONGOC_ENABLE_SSL_LIBRESSL is set from configure to determine if we are
* compiled with LibreSSL support.
*/
#define MONGOC_ENABLE_SSL_LIBRESSL 0
#if MONGOC_ENABLE_SSL_LIBRESSL != 1
# undef MONGOC_ENABLE_SSL_LIBRESSL
#endif
/*
* MONGOC_ENABLE_SSL_OPENSSL is set from configure to determine if we are
* compiled with OpenSSL support.
*/
#define MONGOC_ENABLE_SSL_OPENSSL 0
#if MONGOC_ENABLE_SSL_OPENSSL != 1
# undef MONGOC_ENABLE_SSL_OPENSSL
#endif
/*
* MONGOC_ENABLE_CRYPTO_LIBCRYPTO is set from configure to determine if we are
* compiled with OpenSSL support.
*/
#define MONGOC_ENABLE_CRYPTO_LIBCRYPTO 0
#if MONGOC_ENABLE_CRYPTO_LIBCRYPTO != 1
# undef MONGOC_ENABLE_CRYPTO_LIBCRYPTO
#endif
/*
* MONGOC_ENABLE_SSL is set from configure to determine if we are
* compiled with any SSL support.
*/
#define MONGOC_ENABLE_SSL 1
#if MONGOC_ENABLE_SSL != 1
# undef MONGOC_ENABLE_SSL
#endif
/*
* MONGOC_ENABLE_CRYPTO is set from configure to determine if we are
* compiled with any crypto support.
*/
#define MONGOC_ENABLE_CRYPTO 1
#if MONGOC_ENABLE_CRYPTO != 1
# undef MONGOC_ENABLE_CRYPTO
#endif
/*
* Use system crypto profile
*/
#define MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE 0
#if MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE != 1
# undef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE
#endif
/*
* Use ASN1_STRING_get0_data () rather than the deprecated ASN1_STRING_data
*/
#define MONGOC_HAVE_ASN1_STRING_GET0_DATA 0
#if MONGOC_HAVE_ASN1_STRING_GET0_DATA != 1
# undef MONGOC_HAVE_ASN1_STRING_GET0_DATA
#endif
/*
* MONGOC_ENABLE_SASL is set from configure to determine if we are
* compiled with SASL support.
*/
#define MONGOC_ENABLE_SASL 1
#if MONGOC_ENABLE_SASL != 1
# undef MONGOC_ENABLE_SASL
#endif
/*
* MONGOC_ENABLE_SASL_CYRUS is set from configure to determine if we are
* compiled with Cyrus SASL support.
*/
#define MONGOC_ENABLE_SASL_CYRUS 1
#if MONGOC_ENABLE_SASL_CYRUS != 1
# undef MONGOC_ENABLE_SASL_CYRUS
#endif
/*
* MONGOC_ENABLE_SASL_SSPI is set from configure to determine if we are
* compiled with SSPI support.
*/
#define MONGOC_ENABLE_SASL_SSPI 0
#if MONGOC_ENABLE_SASL_SSPI != 1
# undef MONGOC_ENABLE_SASL_SSPI
#endif
/*
* MONGOC_HAVE_SASL_CLIENT_DONE is set from configure to determine if we
* have SASL and its version is new enough to use sasl_client_done (),
* which supersedes sasl_done ().
*/
#define MONGOC_HAVE_SASL_CLIENT_DONE 1
#if MONGOC_HAVE_SASL_CLIENT_DONE != 1
# undef MONGOC_HAVE_SASL_CLIENT_DONE
#endif
/*
* Disable automatic calls to mongoc_init() and mongoc_cleanup()
* before main() is called, and after exit() (respectively).
*/
#define MONGOC_NO_AUTOMATIC_GLOBALS 1
#if MONGOC_NO_AUTOMATIC_GLOBALS != 1
# undef MONGOC_NO_AUTOMATIC_GLOBALS
#endif
/*
* MONGOC_HAVE_SOCKLEN is set from configure to determine if we
* need to emulate the type.
*/
#define MONGOC_HAVE_SOCKLEN 1
#if MONGOC_HAVE_SOCKLEN != 1
# undef MONGOC_HAVE_SOCKLEN
#endif
/*
* MONGOC_HAVE_DNSAPI is set from configure to determine if we should use the
* Windows dnsapi for SRV record lookups.
*/
#define MONGOC_HAVE_DNSAPI 0
#if MONGOC_HAVE_DNSAPI != 1
# undef MONGOC_HAVE_DNSAPI
#endif
/*
* MONGOC_HAVE_RES_NSEARCH is set from configure to determine if we
* have thread-safe res_nsearch().
*/
#define MONGOC_HAVE_RES_NSEARCH 1
#if MONGOC_HAVE_RES_NSEARCH != 1
# undef MONGOC_HAVE_RES_NSEARCH
#endif
/*
* MONGOC_HAVE_RES_NDESTROY is set from configure to determine if we
* have BSD / Darwin's res_ndestroy().
*/
#define MONGOC_HAVE_RES_NDESTROY 1
#if MONGOC_HAVE_RES_NDESTROY != 1
# undef MONGOC_HAVE_RES_NDESTROY
#endif
/*
* MONGOC_HAVE_RES_NCLOSE is set from configure to determine if we
* have Linux's res_nclose().
*/
#define MONGOC_HAVE_RES_NCLOSE 0
#if MONGOC_HAVE_RES_NCLOSE != 1
# undef MONGOC_HAVE_RES_NCLOSE
#endif
/*
* MONGOC_HAVE_RES_SEARCH is set from configure to determine if we
* have thread-unsafe res_search(). It's unset if we have the preferred
* res_nsearch().
*/
#define MONGOC_HAVE_RES_SEARCH 0
#if MONGOC_HAVE_RES_SEARCH != 1
# undef MONGOC_HAVE_RES_SEARCH
#endif
/*
* Set from configure, see
* https://curl.haxx.se/mail/lib-2009-04/0287.html
*/
#define MONGOC_SOCKET_ARG2 struct sockaddr
#define MONGOC_SOCKET_ARG3 socklen_t
/*
* Enable wire protocol compression negotiation
*
*/
#define MONGOC_ENABLE_COMPRESSION 1
#if MONGOC_ENABLE_COMPRESSION != 1
# undef MONGOC_ENABLE_COMPRESSION
#endif
/*
* Set if we have snappy compression support
*
*/
#define MONGOC_ENABLE_COMPRESSION_SNAPPY 0
#if MONGOC_ENABLE_COMPRESSION_SNAPPY != 1
# undef MONGOC_ENABLE_COMPRESSION_SNAPPY
#endif
/*
* Set if we have zlib compression support
*
*/
#define MONGOC_ENABLE_COMPRESSION_ZLIB 1
#if MONGOC_ENABLE_COMPRESSION_ZLIB != 1
# undef MONGOC_ENABLE_COMPRESSION_ZLIB
#endif
/*
* Set if we have zstd compression support
*
*/
-#define MONGOC_ENABLE_COMPRESSION_ZSTD 0
+#define MONGOC_ENABLE_COMPRESSION_ZSTD 1
#if MONGOC_ENABLE_COMPRESSION_ZSTD != 1
# undef MONGOC_ENABLE_COMPRESSION_ZSTD
#endif
/*
* Set if performance counters are available and not disabled.
*
*/
#define MONGOC_ENABLE_SHM_COUNTERS 0
#if MONGOC_ENABLE_SHM_COUNTERS != 1
# undef MONGOC_ENABLE_SHM_COUNTERS
#endif
/*
* Set if we have enabled fast counters on Intel using the RDTSCP instruction
*
*/
#define MONGOC_ENABLE_RDTSCP 0
#if MONGOC_ENABLE_RDTSCP != 1
# undef MONGOC_ENABLE_RDTSCP
#endif
/*
* Set if we have the sched_getcpu() function for use with counters
*
*/
#define MONGOC_HAVE_SCHED_GETCPU 0
#if MONGOC_HAVE_SCHED_GETCPU != 1
# undef MONGOC_HAVE_SCHED_GETCPU
#endif
/*
* Set if tracing is enabled. Logs things like network communication and
* entry/exit of certain functions.
*
*/
#define MONGOC_TRACE 1
#if MONGOC_TRACE != 1
# undef MONGOC_TRACE
#endif
/*
* Set if we have ICU support.
*/
#define MONGOC_ENABLE_ICU 0
#if MONGOC_ENABLE_ICU != 1
# undef MONGOC_ENABLE_ICU
#endif
/*
* Set if we have Client Side Encryption support.
*/
#define MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION 1
#if MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION != 1
# undef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
#endif
/*
* Set if struct sockaddr_storage has __ss_family (instead of ss_family)
*/
#define MONGOC_HAVE_SS_FAMILY 0
#if MONGOC_HAVE_SS_FAMILY != 1
# undef MONGOC_HAVE_SS_FAMILY
#endif
+/*
+ * Set if building with AWS IAM support.
+ */
+#define MONGOC_ENABLE_MONGODB_AWS_AUTH 1
+
+#if MONGOC_ENABLE_MONGODB_AWS_AUTH != 1
+# undef MONGOC_ENABLE_MONGODB_AWS_AUTH
+#endif
+
/*
* NOTICE:
* If you're about to update this file and add a config flag, make sure to
* update:
* o The bitfield in mongoc-handshake-private.h
* o _mongoc_handshake_get_config_hex_string() in mongoc-handshake.c
* o examples/parse_handshake_cfg.py
* o test_handshake_config_string in test-mongoc-handshake.c
*/
#endif /* MONGOC_CONFIG_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in
index 81c1008c..a797c205 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in
@@ -1,405 +1,414 @@
/*
* Copyright 2013 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.
*/
#if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION)
#error "Only <mongoc/mongoc.h> can be included directly."
#endif
#ifndef MONGOC_CONFIG_H
#define MONGOC_CONFIG_H
/* MONGOC_USER_SET_CFLAGS is set from config based on what compiler flags were
* used to compile mongoc */
#define MONGOC_USER_SET_CFLAGS "@MONGOC_USER_SET_CFLAGS@"
#define MONGOC_USER_SET_LDFLAGS "@MONGOC_USER_SET_LDFLAGS@"
/* MONGOC_CC is used to determine what C compiler was used to compile mongoc */
#define MONGOC_CC "@MONGOC_CC@"
/*
* MONGOC_ENABLE_SSL_SECURE_CHANNEL is set from configure to determine if we are
* compiled with Native SSL support on Windows
*/
#define MONGOC_ENABLE_SSL_SECURE_CHANNEL @MONGOC_ENABLE_SSL_SECURE_CHANNEL@
#if MONGOC_ENABLE_SSL_SECURE_CHANNEL != 1
# undef MONGOC_ENABLE_SSL_SECURE_CHANNEL
#endif
/*
* MONGOC_ENABLE_CRYPTO_CNG is set from configure to determine if we are
* compiled with Native Crypto support on Windows
*/
#define MONGOC_ENABLE_CRYPTO_CNG @MONGOC_ENABLE_CRYPTO_CNG@
#if MONGOC_ENABLE_CRYPTO_CNG != 1
# undef MONGOC_ENABLE_CRYPTO_CNG
#endif
/*
* MONGOC_ENABLE_SSL_SECURE_TRANSPORT is set from configure to determine if we are
* compiled with Native SSL support on Darwin
*/
#define MONGOC_ENABLE_SSL_SECURE_TRANSPORT @MONGOC_ENABLE_SSL_SECURE_TRANSPORT@
#if MONGOC_ENABLE_SSL_SECURE_TRANSPORT != 1
# undef MONGOC_ENABLE_SSL_SECURE_TRANSPORT
#endif
/*
* MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO is set from configure to determine if we are
* compiled with Native Crypto support on Darwin
*/
#define MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO @MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO@
#if MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO != 1
# undef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO
#endif
/*
* MONGOC_ENABLE_SSL_LIBRESSL is set from configure to determine if we are
* compiled with LibreSSL support.
*/
#define MONGOC_ENABLE_SSL_LIBRESSL @MONGOC_ENABLE_SSL_LIBRESSL@
#if MONGOC_ENABLE_SSL_LIBRESSL != 1
# undef MONGOC_ENABLE_SSL_LIBRESSL
#endif
/*
* MONGOC_ENABLE_SSL_OPENSSL is set from configure to determine if we are
* compiled with OpenSSL support.
*/
#define MONGOC_ENABLE_SSL_OPENSSL @MONGOC_ENABLE_SSL_OPENSSL@
#if MONGOC_ENABLE_SSL_OPENSSL != 1
# undef MONGOC_ENABLE_SSL_OPENSSL
#endif
/*
* MONGOC_ENABLE_CRYPTO_LIBCRYPTO is set from configure to determine if we are
* compiled with OpenSSL support.
*/
#define MONGOC_ENABLE_CRYPTO_LIBCRYPTO @MONGOC_ENABLE_CRYPTO_LIBCRYPTO@
#if MONGOC_ENABLE_CRYPTO_LIBCRYPTO != 1
# undef MONGOC_ENABLE_CRYPTO_LIBCRYPTO
#endif
/*
* MONGOC_ENABLE_SSL is set from configure to determine if we are
* compiled with any SSL support.
*/
#define MONGOC_ENABLE_SSL @MONGOC_ENABLE_SSL@
#if MONGOC_ENABLE_SSL != 1
# undef MONGOC_ENABLE_SSL
#endif
/*
* MONGOC_ENABLE_CRYPTO is set from configure to determine if we are
* compiled with any crypto support.
*/
#define MONGOC_ENABLE_CRYPTO @MONGOC_ENABLE_CRYPTO@
#if MONGOC_ENABLE_CRYPTO != 1
# undef MONGOC_ENABLE_CRYPTO
#endif
/*
* Use system crypto profile
*/
#define MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE @MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE@
#if MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE != 1
# undef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE
#endif
/*
* Use ASN1_STRING_get0_data () rather than the deprecated ASN1_STRING_data
*/
#define MONGOC_HAVE_ASN1_STRING_GET0_DATA @MONGOC_HAVE_ASN1_STRING_GET0_DATA@
#if MONGOC_HAVE_ASN1_STRING_GET0_DATA != 1
# undef MONGOC_HAVE_ASN1_STRING_GET0_DATA
#endif
/*
* MONGOC_ENABLE_SASL is set from configure to determine if we are
* compiled with SASL support.
*/
#define MONGOC_ENABLE_SASL @MONGOC_ENABLE_SASL@
#if MONGOC_ENABLE_SASL != 1
# undef MONGOC_ENABLE_SASL
#endif
/*
* MONGOC_ENABLE_SASL_CYRUS is set from configure to determine if we are
* compiled with Cyrus SASL support.
*/
#define MONGOC_ENABLE_SASL_CYRUS @MONGOC_ENABLE_SASL_CYRUS@
#if MONGOC_ENABLE_SASL_CYRUS != 1
# undef MONGOC_ENABLE_SASL_CYRUS
#endif
/*
* MONGOC_ENABLE_SASL_SSPI is set from configure to determine if we are
* compiled with SSPI support.
*/
#define MONGOC_ENABLE_SASL_SSPI @MONGOC_ENABLE_SASL_SSPI@
#if MONGOC_ENABLE_SASL_SSPI != 1
# undef MONGOC_ENABLE_SASL_SSPI
#endif
/*
* MONGOC_HAVE_SASL_CLIENT_DONE is set from configure to determine if we
* have SASL and its version is new enough to use sasl_client_done (),
* which supersedes sasl_done ().
*/
#define MONGOC_HAVE_SASL_CLIENT_DONE @MONGOC_HAVE_SASL_CLIENT_DONE@
#if MONGOC_HAVE_SASL_CLIENT_DONE != 1
# undef MONGOC_HAVE_SASL_CLIENT_DONE
#endif
/*
* Disable automatic calls to mongoc_init() and mongoc_cleanup()
* before main() is called, and after exit() (respectively).
*/
#define MONGOC_NO_AUTOMATIC_GLOBALS @MONGOC_NO_AUTOMATIC_GLOBALS@
#if MONGOC_NO_AUTOMATIC_GLOBALS != 1
# undef MONGOC_NO_AUTOMATIC_GLOBALS
#endif
/*
* MONGOC_HAVE_SOCKLEN is set from configure to determine if we
* need to emulate the type.
*/
#define MONGOC_HAVE_SOCKLEN @MONGOC_HAVE_SOCKLEN@
#if MONGOC_HAVE_SOCKLEN != 1
# undef MONGOC_HAVE_SOCKLEN
#endif
/*
* MONGOC_HAVE_DNSAPI is set from configure to determine if we should use the
* Windows dnsapi for SRV record lookups.
*/
#define MONGOC_HAVE_DNSAPI @MONGOC_HAVE_DNSAPI@
#if MONGOC_HAVE_DNSAPI != 1
# undef MONGOC_HAVE_DNSAPI
#endif
/*
* MONGOC_HAVE_RES_NSEARCH is set from configure to determine if we
* have thread-safe res_nsearch().
*/
#define MONGOC_HAVE_RES_NSEARCH @MONGOC_HAVE_RES_NSEARCH@
#if MONGOC_HAVE_RES_NSEARCH != 1
# undef MONGOC_HAVE_RES_NSEARCH
#endif
/*
* MONGOC_HAVE_RES_NDESTROY is set from configure to determine if we
* have BSD / Darwin's res_ndestroy().
*/
#define MONGOC_HAVE_RES_NDESTROY @MONGOC_HAVE_RES_NDESTROY@
#if MONGOC_HAVE_RES_NDESTROY != 1
# undef MONGOC_HAVE_RES_NDESTROY
#endif
/*
* MONGOC_HAVE_RES_NCLOSE is set from configure to determine if we
* have Linux's res_nclose().
*/
#define MONGOC_HAVE_RES_NCLOSE @MONGOC_HAVE_RES_NCLOSE@
#if MONGOC_HAVE_RES_NCLOSE != 1
# undef MONGOC_HAVE_RES_NCLOSE
#endif
/*
* MONGOC_HAVE_RES_SEARCH is set from configure to determine if we
* have thread-unsafe res_search(). It's unset if we have the preferred
* res_nsearch().
*/
#define MONGOC_HAVE_RES_SEARCH @MONGOC_HAVE_RES_SEARCH@
#if MONGOC_HAVE_RES_SEARCH != 1
# undef MONGOC_HAVE_RES_SEARCH
#endif
/*
* Set from configure, see
* https://curl.haxx.se/mail/lib-2009-04/0287.html
*/
#define MONGOC_SOCKET_ARG2 @MONGOC_SOCKET_ARG2@
#define MONGOC_SOCKET_ARG3 @MONGOC_SOCKET_ARG3@
/*
* Enable wire protocol compression negotiation
*
*/
#define MONGOC_ENABLE_COMPRESSION @MONGOC_ENABLE_COMPRESSION@
#if MONGOC_ENABLE_COMPRESSION != 1
# undef MONGOC_ENABLE_COMPRESSION
#endif
/*
* Set if we have snappy compression support
*
*/
#define MONGOC_ENABLE_COMPRESSION_SNAPPY @MONGOC_ENABLE_COMPRESSION_SNAPPY@
#if MONGOC_ENABLE_COMPRESSION_SNAPPY != 1
# undef MONGOC_ENABLE_COMPRESSION_SNAPPY
#endif
/*
* Set if we have zlib compression support
*
*/
#define MONGOC_ENABLE_COMPRESSION_ZLIB @MONGOC_ENABLE_COMPRESSION_ZLIB@
#if MONGOC_ENABLE_COMPRESSION_ZLIB != 1
# undef MONGOC_ENABLE_COMPRESSION_ZLIB
#endif
/*
* Set if we have zstd compression support
*
*/
#define MONGOC_ENABLE_COMPRESSION_ZSTD @MONGOC_ENABLE_COMPRESSION_ZSTD@
#if MONGOC_ENABLE_COMPRESSION_ZSTD != 1
# undef MONGOC_ENABLE_COMPRESSION_ZSTD
#endif
/*
* Set if performance counters are available and not disabled.
*
*/
#define MONGOC_ENABLE_SHM_COUNTERS @MONGOC_ENABLE_SHM_COUNTERS@
#if MONGOC_ENABLE_SHM_COUNTERS != 1
# undef MONGOC_ENABLE_SHM_COUNTERS
#endif
/*
* Set if we have enabled fast counters on Intel using the RDTSCP instruction
*
*/
#define MONGOC_ENABLE_RDTSCP @MONGOC_ENABLE_RDTSCP@
#if MONGOC_ENABLE_RDTSCP != 1
# undef MONGOC_ENABLE_RDTSCP
#endif
/*
* Set if we have the sched_getcpu() function for use with counters
*
*/
#define MONGOC_HAVE_SCHED_GETCPU @MONGOC_HAVE_SCHED_GETCPU@
#if MONGOC_HAVE_SCHED_GETCPU != 1
# undef MONGOC_HAVE_SCHED_GETCPU
#endif
/*
* Set if tracing is enabled. Logs things like network communication and
* entry/exit of certain functions.
*
*/
#define MONGOC_TRACE @MONGOC_TRACE@
#if MONGOC_TRACE != 1
# undef MONGOC_TRACE
#endif
/*
* Set if we have ICU support.
*/
#define MONGOC_ENABLE_ICU @MONGOC_ENABLE_ICU@
#if MONGOC_ENABLE_ICU != 1
# undef MONGOC_ENABLE_ICU
#endif
/*
* Set if we have Client Side Encryption support.
*/
#define MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION @MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION@
#if MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION != 1
# undef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
#endif
/*
* Set if struct sockaddr_storage has __ss_family (instead of ss_family)
*/
#define MONGOC_HAVE_SS_FAMILY @MONGOC_HAVE_SS_FAMILY@
#if MONGOC_HAVE_SS_FAMILY != 1
# undef MONGOC_HAVE_SS_FAMILY
#endif
+/*
+ * Set if building with AWS IAM support.
+ */
+#define MONGOC_ENABLE_MONGODB_AWS_AUTH @MONGOC_ENABLE_MONGODB_AWS_AUTH@
+
+#if MONGOC_ENABLE_MONGODB_AWS_AUTH != 1
+# undef MONGOC_ENABLE_MONGODB_AWS_AUTH
+#endif
+
/*
* NOTICE:
* If you're about to update this file and add a config flag, make sure to
* update:
* o The bitfield in mongoc-handshake-private.h
* o _mongoc_handshake_get_config_hex_string() in mongoc-handshake.c
* o examples/parse_handshake_cfg.py
* o test_handshake_config_string in test-mongoc-handshake.c
*/
#endif /* MONGOC_CONFIG_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
index 646f9d38..50e34322 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
@@ -1,115 +1,115 @@
/*
* Copyright 2019-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
*
* 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CRYPT_PRIVATE_H
#define MONGOC_CRYPT_PRIVATE_H
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
#include "mongoc.h"
/* For interacting with libmongocrypt */
typedef struct __mongoc_crypt_t _mongoc_crypt_t;
/*
Creates a new handle into libmongocrypt.
- schema_map may be NULL.
- may return NULL and set error.
*/
_mongoc_crypt_t *
_mongoc_crypt_new (const bson_t *kms_providers,
const bson_t *schema_map,
bson_error_t *error);
void
_mongoc_crypt_destroy (_mongoc_crypt_t *crypt);
/*
Perform auto encryption.
- cmd_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_auto_encrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *key_vault_coll,
mongoc_client_t *mongocryptd_client,
mongoc_client_t *collinfo_client,
const char *db_name,
const bson_t *cmd_in,
bson_t *cmd_out,
bson_error_t *error);
/*
Perform auto decryption.
- doc_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_auto_decrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *key_vault_coll,
const bson_t *doc_in,
bson_t *doc_out,
bson_error_t *error);
/*
Perform explicit encryption.
- exactly one of keyid or keyaltname must be set, the other NULL, or an error is
returned.
- value_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *key_vault_coll,
const char *algorithm,
const bson_value_t *keyid,
char *keyaltname,
const bson_value_t *value_in,
bson_value_t *value_out,
bson_error_t *error);
/*
Perform explicit decryption.
- value_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_explicit_decrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *key_vault_coll,
const bson_value_t *value_in,
bson_value_t *value_out,
bson_error_t *error);
/*
Create a data key document (does not insert into key vault).
- keyaltnames may be NULL.
- doc_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_create_datakey (_mongoc_crypt_t *crypt,
const char *kms_provider,
const bson_t *masterkey,
char **keyaltnames,
uint32_t keyaltnames_count,
bson_t *doc_out,
bson_error_t *error);
#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
-#endif /* MONGOC_CRYPT_PRIVATE_H */
\ No newline at end of file
+#endif /* MONGOC_CRYPT_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
index 03c36a9a..c26778e4 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
@@ -1,1142 +1,1154 @@
/*
* Copyright 2019-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
*
* 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.
*/
#define MONGOC_LOG_DOMAIN "client-side-encryption"
#include "mongoc-crypt-private.h"
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
#include <mongocrypt/mongocrypt.h>
#include "mongoc-client-private.h"
#include "mongoc-collection-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-stream-private.h"
struct __mongoc_crypt_t {
mongocrypt_t *handle;
};
static void
_log_callback (mongocrypt_log_level_t mongocrypt_log_level,
const char *message,
uint32_t message_len,
void *ctx)
{
mongoc_log_level_t log_level = MONGOC_LOG_LEVEL_ERROR;
switch (mongocrypt_log_level) {
case MONGOCRYPT_LOG_LEVEL_FATAL:
log_level = MONGOC_LOG_LEVEL_CRITICAL;
break;
case MONGOCRYPT_LOG_LEVEL_ERROR:
log_level = MONGOC_LOG_LEVEL_ERROR;
break;
case MONGOCRYPT_LOG_LEVEL_WARNING:
log_level = MONGOC_LOG_LEVEL_WARNING;
break;
case MONGOCRYPT_LOG_LEVEL_INFO:
log_level = MONGOC_LOG_LEVEL_INFO;
break;
case MONGOCRYPT_LOG_LEVEL_TRACE:
log_level = MONGOC_LOG_LEVEL_TRACE;
break;
+ default:
+ log_level = MONGOC_LOG_LEVEL_CRITICAL;
+ break;
}
mongoc_log (log_level, MONGOC_LOG_DOMAIN, "%s", message);
}
static void
_prefix_mongocryptd_error (bson_error_t *error)
{
char buf[sizeof (error->message)];
bson_snprintf (buf, sizeof (buf), "mongocryptd error: %s:", error->message);
memcpy (error->message, buf, sizeof (buf));
}
static void
_prefix_keyvault_error (bson_error_t *error)
{
char buf[sizeof (error->message)];
bson_snprintf (buf, sizeof (buf), "key vault error: %s:", error->message);
memcpy (error->message, buf, sizeof (buf));
}
static void
_status_to_error (mongocrypt_status_t *status, bson_error_t *error)
{
bson_set_error (error,
MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
mongocrypt_status_code (status),
"%s",
mongocrypt_status_message (status, NULL));
}
/* Checks for an error on mongocrypt context.
* If error_expected, then we expect mongocrypt_ctx_status to report a failure
* status (due to a previous failed function call). If it did not, return a
* generic error.
* Returns true if ok, and does not modify @error.
* Returns false if error, and sets @error.
*/
bool
_ctx_check_error (mongocrypt_ctx_t *ctx,
bson_error_t *error,
bool error_expected)
{
mongocrypt_status_t *status;
status = mongocrypt_status_new ();
if (!mongocrypt_ctx_status (ctx, status)) {
_status_to_error (status, error);
mongocrypt_status_destroy (status);
return false;
} else if (error_expected) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"generic error from libmongocrypt operation");
mongocrypt_status_destroy (status);
return false;
}
mongocrypt_status_destroy (status);
return true;
}
bool
_kms_ctx_check_error (mongocrypt_kms_ctx_t *kms_ctx,
bson_error_t *error,
bool error_expected)
{
mongocrypt_status_t *status;
status = mongocrypt_status_new ();
if (!mongocrypt_kms_ctx_status (kms_ctx, status)) {
_status_to_error (status, error);
mongocrypt_status_destroy (status);
return false;
} else if (error_expected) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"generic error from libmongocrypt KMS operation");
mongocrypt_status_destroy (status);
return false;
}
mongocrypt_status_destroy (status);
return true;
}
bool
_crypt_check_error (mongocrypt_t *crypt,
bson_error_t *error,
bool error_expected)
{
mongocrypt_status_t *status;
status = mongocrypt_status_new ();
if (!mongocrypt_status (crypt, status)) {
_status_to_error (status, error);
mongocrypt_status_destroy (status);
return false;
} else if (error_expected) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"generic error from libmongocrypt handle");
mongocrypt_status_destroy (status);
return false;
}
mongocrypt_status_destroy (status);
return true;
}
/* Convert a mongocrypt_binary_t to a static bson_t */
static bool
_bin_to_static_bson (mongocrypt_binary_t *bin, bson_t *out, bson_error_t *error)
{
/* Copy bin into bson_t result. */
if (!bson_init_static (
out, mongocrypt_binary_data (bin), mongocrypt_binary_len (bin))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"invalid returned bson");
return false;
}
return true;
}
typedef struct {
mongocrypt_ctx_t *ctx;
mongoc_collection_t *keyvault_coll;
mongoc_client_t *mongocryptd_client;
mongoc_client_t *collinfo_client;
const char *db_name;
} _state_machine_t;
_state_machine_t *
_state_machine_new (void)
{
return bson_malloc0 (sizeof (_state_machine_t));
}
void
_state_machine_destroy (_state_machine_t *state_machine)
{
mongocrypt_ctx_destroy (state_machine->ctx);
bson_free (state_machine);
}
/* State handler MONGOCRYPT_CTX_NEED_MONGO_COLLINFO */
static bool
_state_need_mongo_collinfo (_state_machine_t *state_machine,
bson_error_t *error)
{
mongoc_database_t *db = NULL;
mongoc_cursor_t *cursor = NULL;
bson_t filter_bson;
const bson_t *collinfo_bson = NULL;
bson_t opts = BSON_INITIALIZER;
mongocrypt_binary_t *filter_bin = NULL;
mongocrypt_binary_t *collinfo_bin = NULL;
bool ret = false;
/* 1. Run listCollections on the encrypted MongoClient with the filter
* provided by mongocrypt_ctx_mongo_op */
filter_bin = mongocrypt_binary_new ();
if (!mongocrypt_ctx_mongo_op (state_machine->ctx, filter_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (!_bin_to_static_bson (filter_bin, &filter_bson, error)) {
goto fail;
}
bson_append_document (&opts, "filter", -1, &filter_bson);
db = mongoc_client_get_database (state_machine->collinfo_client,
state_machine->db_name);
cursor = mongoc_database_find_collections_with_opts (db, &opts);
if (mongoc_cursor_error (cursor, error)) {
goto fail;
}
/* 2. Return the first result (if any) with mongocrypt_ctx_mongo_feed or
* proceed to the next step if nothing was returned. */
if (mongoc_cursor_next (cursor, &collinfo_bson)) {
collinfo_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (collinfo_bson), collinfo_bson->len);
if (!mongocrypt_ctx_mongo_feed (state_machine->ctx, collinfo_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
} else if (mongoc_cursor_error (cursor, error)) {
goto fail;
}
/* 3. Call mongocrypt_ctx_mongo_done */
if (!mongocrypt_ctx_mongo_done (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
ret = true;
fail:
bson_destroy (&opts);
mongocrypt_binary_destroy (filter_bin);
mongocrypt_binary_destroy (collinfo_bin);
mongoc_cursor_destroy (cursor);
mongoc_database_destroy (db);
return ret;
}
static bool
_state_need_mongo_markings (_state_machine_t *state_machine,
bson_error_t *error)
{
bool ret = false;
mongocrypt_binary_t *mongocryptd_cmd_bin = NULL;
mongocrypt_binary_t *mongocryptd_reply_bin = NULL;
bson_t mongocryptd_cmd_bson;
bson_t reply = BSON_INITIALIZER;
mongocryptd_cmd_bin = mongocrypt_binary_new ();
if (!mongocrypt_ctx_mongo_op (state_machine->ctx, mongocryptd_cmd_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (!_bin_to_static_bson (
mongocryptd_cmd_bin, &mongocryptd_cmd_bson, error)) {
goto fail;
}
/* 1. Use db.runCommand to run the command provided by
* mongocrypt_ctx_mongo_op on the MongoClient connected to mongocryptd. */
bson_destroy (&reply);
if (!mongoc_client_command_simple (state_machine->mongocryptd_client,
"admin",
&mongocryptd_cmd_bson,
NULL /* read_prefs */,
&reply,
error)) {
_prefix_mongocryptd_error (error);
goto fail;
}
/* 2. Feed the reply back with mongocrypt_ctx_mongo_feed. */
mongocryptd_reply_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (&reply), reply.len);
if (!mongocrypt_ctx_mongo_feed (state_machine->ctx, mongocryptd_reply_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
/* 3. Call mongocrypt_ctx_mongo_done. */
if (!mongocrypt_ctx_mongo_done (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
ret = true;
fail:
bson_destroy (&reply);
mongocrypt_binary_destroy (mongocryptd_cmd_bin);
mongocrypt_binary_destroy (mongocryptd_reply_bin);
return ret;
}
static bool
_state_need_mongo_keys (_state_machine_t *state_machine, bson_error_t *error)
{
bool ret = false;
mongocrypt_binary_t *filter_bin = NULL;
bson_t filter_bson;
bson_t opts = BSON_INITIALIZER;
mongocrypt_binary_t *key_bin = NULL;
const bson_t *key_bson;
mongoc_cursor_t *cursor = NULL;
mongoc_read_concern_t *rc = NULL;
/* 1. Use MongoCollection.find on the MongoClient connected to the key vault
* client (which may be the same as the encrypted client). Use the filter
* provided by mongocrypt_ctx_mongo_op. */
filter_bin = mongocrypt_binary_new ();
if (!mongocrypt_ctx_mongo_op (state_machine->ctx, filter_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (!_bin_to_static_bson (filter_bin, &filter_bson, error)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
rc = mongoc_read_concern_new ();
mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY);
if (!mongoc_read_concern_append (rc, &opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"%s",
"could not set read concern");
goto fail;
}
cursor = mongoc_collection_find_with_opts (
state_machine->keyvault_coll, &filter_bson, &opts, NULL /* read prefs */);
/* 2. Feed all resulting documents back (if any) with repeated calls to
* mongocrypt_ctx_mongo_feed. */
while (mongoc_cursor_next (cursor, &key_bson)) {
mongocrypt_binary_destroy (key_bin);
key_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (key_bson), key_bson->len);
if (!mongocrypt_ctx_mongo_feed (state_machine->ctx, key_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
if (mongoc_cursor_error (cursor, error)) {
_prefix_keyvault_error (error);
goto fail;
}
/* 3. Call mongocrypt_ctx_mongo_done. */
if (!mongocrypt_ctx_mongo_done (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
ret = true;
fail:
mongocrypt_binary_destroy (filter_bin);
mongoc_cursor_destroy (cursor);
mongoc_read_concern_destroy (rc);
bson_destroy (&opts);
mongocrypt_binary_destroy (key_bin);
return ret;
}
static mongoc_stream_t *
_get_stream (const char *endpoint,
int32_t connecttimeoutms,
bson_error_t *error)
{
mongoc_stream_t *base_stream = NULL;
mongoc_stream_t *tls_stream = NULL;
bool ret = false;
mongoc_ssl_opt_t ssl_opts = {0};
mongoc_host_list_t host;
char *host_and_port = NULL;
if (!strchr (endpoint, ':')) {
host_and_port = bson_strdup_printf ("%s:443", endpoint);
} else {
host_and_port = (char *) endpoint; /* we promise not to modify */
}
if (!_mongoc_host_list_from_string_with_err (&host, host_and_port, error)) {
goto fail;
}
base_stream = mongoc_client_connect_tcp (connecttimeoutms, &host, error);
if (!base_stream) {
goto fail;
}
/* Wrap in a tls_stream. */
memcpy (&ssl_opts, mongoc_ssl_opt_get_default (), sizeof ssl_opts);
tls_stream = mongoc_stream_tls_new_with_hostname (
base_stream, host.host, &ssl_opts, 1 /* client */);
if (!mongoc_stream_tls_handshake_block (
tls_stream, host.host, connecttimeoutms, error)) {
goto fail;
}
ret = true;
fail:
if (host_and_port != endpoint) {
bson_free (host_and_port);
}
if (!ret) {
if (tls_stream) {
/* destroys base_stream too */
mongoc_stream_destroy (tls_stream);
} else if (base_stream) {
mongoc_stream_destroy (base_stream);
}
return NULL;
}
return tls_stream;
}
static bool
_state_need_kms (_state_machine_t *state_machine, bson_error_t *error)
{
mongocrypt_kms_ctx_t *kms_ctx = NULL;
mongoc_stream_t *tls_stream = NULL;
bool ret = false;
mongocrypt_binary_t *http_req = NULL;
mongocrypt_binary_t *http_reply = NULL;
const char *endpoint;
uint32_t sockettimeout;
sockettimeout = MONGOC_DEFAULT_SOCKETTIMEOUTMS;
kms_ctx = mongocrypt_ctx_next_kms_ctx (state_machine->ctx);
while (kms_ctx) {
mongoc_iovec_t iov;
mongocrypt_binary_destroy (http_req);
http_req = mongocrypt_binary_new ();
if (!mongocrypt_kms_ctx_message (kms_ctx, http_req)) {
_kms_ctx_check_error (kms_ctx, error, true);
goto fail;
}
if (!mongocrypt_kms_ctx_endpoint (kms_ctx, &endpoint)) {
_kms_ctx_check_error (kms_ctx, error, true);
goto fail;
}
tls_stream = _get_stream (endpoint, sockettimeout, error);
+#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL
+ /* Retry once with schannel as a workaround for CDRIVER-3566. */
+ if (!tls_stream) {
+ tls_stream = _get_stream (endpoint, sockettimeout, error);
+ }
+#endif
if (!tls_stream) {
goto fail;
}
iov.iov_base = (char *) mongocrypt_binary_data (http_req);
iov.iov_len = mongocrypt_binary_len (http_req);
if (!_mongoc_stream_writev_full (
tls_stream, &iov, 1, sockettimeout, error)) {
goto fail;
}
/* Read and feed reply. */
while (mongocrypt_kms_ctx_bytes_needed (kms_ctx) > 0) {
#define BUFFER_SIZE 1024
uint8_t buf[BUFFER_SIZE];
uint32_t bytes_needed = mongocrypt_kms_ctx_bytes_needed (kms_ctx);
ssize_t read_ret;
/* Cap the bytes requested at the buffer size. */
if (bytes_needed > BUFFER_SIZE) {
bytes_needed = BUFFER_SIZE;
}
read_ret = mongoc_stream_read (
tls_stream, buf, bytes_needed, 1 /* min_bytes. */, sockettimeout);
if (read_ret == -1) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"failed to read from KMS stream: %d",
errno);
goto fail;
}
if (read_ret == 0) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"unexpected EOF from KMS stream");
goto fail;
}
mongocrypt_binary_destroy (http_reply);
http_reply = mongocrypt_binary_new_from_data (buf, read_ret);
if (!mongocrypt_kms_ctx_feed (kms_ctx, http_reply)) {
_kms_ctx_check_error (kms_ctx, error, true);
goto fail;
}
}
kms_ctx = mongocrypt_ctx_next_kms_ctx (state_machine->ctx);
}
/* When NULL is returned by mongocrypt_ctx_next_kms_ctx, this can either be
* an error or end-of-list. */
if (!_ctx_check_error (state_machine->ctx, error, false)) {
goto fail;
}
if (!mongocrypt_ctx_kms_done (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
ret = true;
fail:
mongoc_stream_destroy (tls_stream);
mongocrypt_binary_destroy (http_req);
mongocrypt_binary_destroy (http_reply);
return ret;
#undef BUFFER_SIZE
}
static bool
_state_ready (_state_machine_t *state_machine,
bson_t *result,
bson_error_t *error)
{
mongocrypt_binary_t *result_bin = NULL;
bson_t tmp;
bool ret = false;
bson_init (result);
result_bin = mongocrypt_binary_new ();
if (!mongocrypt_ctx_finalize (state_machine->ctx, result_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (!_bin_to_static_bson (result_bin, &tmp, error)) {
goto fail;
}
bson_destroy (result);
bson_copy_to (&tmp, result);
ret = true;
fail:
mongocrypt_binary_destroy (result_bin);
return ret;
}
/*--------------------------------------------------------------------------
*
* _mongoc_cse_run_state_machine --
* Run the mongocrypt_ctx state machine.
*
* Post-conditions:
* *result may be set to a new bson_t, or NULL otherwise. Caller should
* not assume return value of true means *result is set. If false returned,
* @error is set.
*
* --------------------------------------------------------------------------
*/
bool
_state_machine_run (_state_machine_t *state_machine,
bson_t *result,
bson_error_t *error)
{
bool ret = false;
mongocrypt_binary_t *bin = NULL;
bson_init (result);
while (true) {
switch (mongocrypt_ctx_state (state_machine->ctx)) {
default:
case MONGOCRYPT_CTX_ERROR:
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
if (!_state_need_mongo_collinfo (state_machine, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
if (!_state_need_mongo_markings (state_machine, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
if (!_state_need_mongo_keys (state_machine, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_NEED_KMS:
if (!_state_need_kms (state_machine, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_READY:
bson_destroy (result);
if (!_state_ready (state_machine, result, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_DONE:
goto success;
break;
}
}
success:
ret = true;
fail:
mongocrypt_binary_destroy (bin);
return ret;
}
/* Note, _mongoc_crypt_t only has one member, to the top-level handle of
libmongocrypt, mongocrypt_t.
The purpose of defining _mongoc_crypt_t is to limit all interaction with
libmongocrypt to this one
file.
*/
_mongoc_crypt_t *
_mongoc_crypt_new (const bson_t *kms_providers,
const bson_t *schema_map,
bson_error_t *error)
{
_mongoc_crypt_t *crypt;
mongocrypt_binary_t *local_masterkey_bin = NULL;
mongocrypt_binary_t *schema_map_bin = NULL;
bson_iter_t iter;
bool success = false;
/* Create the handle to libmongocrypt. */
crypt = bson_malloc0 (sizeof (*crypt));
crypt->handle = mongocrypt_new ();
mongocrypt_setopt_log_handler (
crypt->handle, _log_callback, NULL /* context */);
/* Take options from the kms_providers map. */
if (bson_iter_init_find (&iter, kms_providers, "aws")) {
bson_iter_t subiter;
const char *aws_access_key_id = NULL;
uint32_t aws_access_key_id_len = 0;
const char *aws_secret_access_key = NULL;
uint32_t aws_secret_access_key_len = 0;
if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Expected document for KMS provider 'aws'");
goto fail;
}
BSON_ASSERT (bson_iter_recurse (&iter, &subiter));
if (bson_iter_find (&subiter, "accessKeyId")) {
aws_access_key_id = bson_iter_utf8 (&subiter, &aws_access_key_id_len);
}
BSON_ASSERT (bson_iter_recurse (&iter, &subiter));
if (bson_iter_find (&subiter, "secretAccessKey")) {
aws_secret_access_key =
bson_iter_utf8 (&subiter, &aws_secret_access_key_len);
}
/* libmongocrypt returns error if options are NULL. */
if (!mongocrypt_setopt_kms_provider_aws (crypt->handle,
aws_access_key_id,
aws_access_key_id_len,
aws_secret_access_key,
aws_secret_access_key_len)) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
}
if (bson_iter_init_find (&iter, kms_providers, "local")) {
bson_iter_t subiter;
if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Expected document for KMS provider 'local'");
goto fail;
}
bson_iter_recurse (&iter, &subiter);
if (bson_iter_find (&subiter, "key")) {
uint32_t key_len;
const uint8_t *key_data;
bson_iter_binary (&subiter, NULL /* subtype */, &key_len, &key_data);
local_masterkey_bin =
mongocrypt_binary_new_from_data ((uint8_t *) key_data, key_len);
}
/* libmongocrypt returns error if options are NULL. */
if (!mongocrypt_setopt_kms_provider_local (crypt->handle,
local_masterkey_bin)) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
}
if (schema_map) {
schema_map_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (schema_map), schema_map->len);
if (!mongocrypt_setopt_schema_map (crypt->handle, schema_map_bin)) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
}
if (!mongocrypt_init (crypt->handle)) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
success = true;
fail:
mongocrypt_binary_destroy (local_masterkey_bin);
mongocrypt_binary_destroy (schema_map_bin);
if (!success) {
_mongoc_crypt_destroy (crypt);
return NULL;
}
return crypt;
}
void
_mongoc_crypt_destroy (_mongoc_crypt_t *crypt)
{
if (!crypt) {
return;
}
mongocrypt_destroy (crypt->handle);
bson_free (crypt);
}
bool
_mongoc_crypt_auto_encrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *keyvault_coll,
mongoc_client_t *mongocryptd_client,
mongoc_client_t *collinfo_client,
const char *db_name,
const bson_t *cmd_in,
bson_t *cmd_out,
bson_error_t *error)
{
_state_machine_t *state_machine = NULL;
mongocrypt_binary_t *cmd_bin = NULL;
bool ret = false;
bson_init (cmd_out);
state_machine = _state_machine_new ();
state_machine->keyvault_coll = keyvault_coll;
state_machine->mongocryptd_client = mongocryptd_client;
state_machine->collinfo_client = collinfo_client;
state_machine->db_name = db_name;
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
cmd_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (cmd_in), cmd_in->len);
if (!mongocrypt_ctx_encrypt_init (
state_machine->ctx, db_name, -1, cmd_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (cmd_out);
if (!_state_machine_run (state_machine, cmd_out, error)) {
goto fail;
}
ret = true;
fail:
mongocrypt_binary_destroy (cmd_bin);
_state_machine_destroy (state_machine);
return ret;
}
bool
_mongoc_crypt_auto_decrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *keyvault_coll,
const bson_t *doc_in,
bson_t *doc_out,
bson_error_t *error)
{
bool ret = false;
_state_machine_t *state_machine = NULL;
mongocrypt_binary_t *doc_bin = NULL;
bson_init (doc_out);
state_machine = _state_machine_new ();
state_machine->keyvault_coll = keyvault_coll;
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
doc_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (doc_in), doc_in->len);
if (!mongocrypt_ctx_decrypt_init (state_machine->ctx, doc_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (doc_out);
if (!_state_machine_run (state_machine, doc_out, error)) {
goto fail;
}
ret = true;
fail:
mongocrypt_binary_destroy (doc_bin);
_state_machine_destroy (state_machine);
return ret;
}
bool
_mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *keyvault_coll,
const char *algorithm,
const bson_value_t *keyid,
char *keyaltname,
const bson_value_t *value_in,
bson_value_t *value_out,
bson_error_t *error)
{
_state_machine_t *state_machine = NULL;
bson_t *to_encrypt_doc = NULL;
mongocrypt_binary_t *to_encrypt_bin = NULL;
bson_iter_t iter;
bool ret = false;
bson_t result = BSON_INITIALIZER;
value_out->value_type = BSON_TYPE_EOD;
/* Create the context for the operation. */
state_machine = _state_machine_new ();
state_machine->keyvault_coll = keyvault_coll;
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
if (!mongocrypt_ctx_setopt_algorithm (state_machine->ctx, algorithm, -1)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (keyaltname) {
bool keyaltname_ret;
mongocrypt_binary_t *keyaltname_bin;
bson_t *keyaltname_doc;
keyaltname_doc = BCON_NEW ("keyAltName", keyaltname);
keyaltname_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (keyaltname_doc), keyaltname_doc->len);
keyaltname_ret = mongocrypt_ctx_setopt_key_alt_name (state_machine->ctx,
keyaltname_bin);
mongocrypt_binary_destroy (keyaltname_bin);
bson_destroy (keyaltname_doc);
if (!keyaltname_ret) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
if (keyid && keyid->value_type == BSON_TYPE_BINARY) {
mongocrypt_binary_t *keyid_bin;
bool keyid_ret;
if (keyid->value.v_binary.subtype != BSON_SUBTYPE_UUID) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"keyid must be a UUID");
goto fail;
}
keyid_bin = mongocrypt_binary_new_from_data (
keyid->value.v_binary.data, keyid->value.v_binary.data_len);
keyid_ret = mongocrypt_ctx_setopt_key_id (state_machine->ctx, keyid_bin);
mongocrypt_binary_destroy (keyid_bin);
if (!keyid_ret) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
to_encrypt_doc = bson_new ();
BSON_APPEND_VALUE (to_encrypt_doc, "v", value_in);
to_encrypt_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (to_encrypt_doc), to_encrypt_doc->len);
if (!mongocrypt_ctx_explicit_encrypt_init (state_machine->ctx,
to_encrypt_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (&result);
if (!_state_machine_run (state_machine, &result, error)) {
goto fail;
}
/* extract value */
if (!bson_iter_init_find (&iter, &result, "v")) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"encrypted result unexpected");
goto fail;
} else {
const bson_value_t *tmp;
tmp = bson_iter_value (&iter);
bson_value_copy (tmp, value_out);
}
ret = true;
fail:
_state_machine_destroy (state_machine);
mongocrypt_binary_destroy (to_encrypt_bin);
bson_destroy (to_encrypt_doc);
bson_destroy (&result);
return ret;
}
bool
_mongoc_crypt_explicit_decrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *keyvault_coll,
const bson_value_t *value_in,
bson_value_t *value_out,
bson_error_t *error)
{
_state_machine_t *state_machine = NULL;
bson_t *to_decrypt_doc = NULL;
mongocrypt_binary_t *to_decrypt_bin = NULL;
bson_iter_t iter;
bool ret = false;
bson_t result = BSON_INITIALIZER;
state_machine = _state_machine_new ();
state_machine->keyvault_coll = keyvault_coll;
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
to_decrypt_doc = bson_new ();
BSON_APPEND_VALUE (to_decrypt_doc, "v", value_in);
to_decrypt_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (to_decrypt_doc), to_decrypt_doc->len);
if (!mongocrypt_ctx_explicit_decrypt_init (state_machine->ctx,
to_decrypt_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (&result);
if (!_state_machine_run (state_machine, &result, error)) {
goto fail;
}
/* extract value */
if (!bson_iter_init_find (&iter, &result, "v")) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"decrypted result unexpected");
goto fail;
} else {
const bson_value_t *tmp;
tmp = bson_iter_value (&iter);
bson_value_copy (tmp, value_out);
}
ret = true;
fail:
_state_machine_destroy (state_machine);
mongocrypt_binary_destroy (to_decrypt_bin);
bson_destroy (to_decrypt_doc);
bson_destroy (&result);
return ret;
}
bool
_mongoc_crypt_create_datakey (_mongoc_crypt_t *crypt,
const char *kms_provider,
const bson_t *masterkey,
char **keyaltnames,
uint32_t keyaltnames_count,
bson_t *doc_out,
bson_error_t *error)
{
_state_machine_t *state_machine = NULL;
bool ret = false;
bson_init (doc_out);
state_machine = _state_machine_new ();
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
if (0 == strcmp ("aws", kms_provider) && masterkey) {
bson_iter_t iter;
const char *region = NULL;
uint32_t region_len = 0;
const char *key = NULL;
uint32_t key_len = 0;
if (bson_iter_init_find (&iter, masterkey, "region") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
region = bson_iter_utf8 (&iter, &region_len);
}
if (bson_iter_init_find (&iter, masterkey, "key") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
key = bson_iter_utf8 (&iter, &key_len);
}
if (!mongocrypt_ctx_setopt_masterkey_aws (
state_machine->ctx, region, region_len, key, key_len)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
/* Check for optional endpoint */
if (bson_iter_init_find (&iter, masterkey, "endpoint") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
const char *endpoint = NULL;
uint32_t endpoint_len = 0;
endpoint = bson_iter_utf8 (&iter, &endpoint_len);
if (!mongocrypt_ctx_setopt_masterkey_aws_endpoint (
state_machine->ctx, endpoint, endpoint_len)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
}
if (0 == strcmp ("local", kms_provider)) {
if (!mongocrypt_ctx_setopt_masterkey_local (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
if (keyaltnames) {
int i;
for (i = 0; i < keyaltnames_count; i++) {
bool keyaltname_ret;
mongocrypt_binary_t *keyaltname_bin;
bson_t *keyaltname_doc;
keyaltname_doc = BCON_NEW ("keyAltName", keyaltnames[i]);
keyaltname_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (keyaltname_doc), keyaltname_doc->len);
keyaltname_ret = mongocrypt_ctx_setopt_key_alt_name (
state_machine->ctx, keyaltname_bin);
mongocrypt_binary_destroy (keyaltname_bin);
bson_destroy (keyaltname_doc);
if (!keyaltname_ret) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
}
if (!mongocrypt_ctx_datakey_init (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (doc_out);
if (!_state_machine_run (state_machine, doc_out, error)) {
goto fail;
}
ret = true;
fail:
_state_machine_destroy (state_machine);
return ret;
}
-#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
\ No newline at end of file
+#else
+/* ensure the translation unit is not empty */
+extern int no_mongoc_client_side_encryption;
+#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c
similarity index 83%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c
index d094bf1f..4cf82ca4 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c
@@ -1,239 +1,233 @@
/* Copyright 2016 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_CRYPTO_CNG
#include "mongoc-crypto-private.h"
#include "mongoc-crypto-cng-private.h"
#include "mongoc-log.h"
#include "mongoc-thread-private.h"
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#define NT_SUCCESS(Status) (((NTSTATUS) (Status)) >= 0)
#define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L)
static BCRYPT_ALG_HANDLE _sha1_hash_algo;
static BCRYPT_ALG_HANDLE _sha1_hmac_algo;
static BCRYPT_ALG_HANDLE _sha256_hash_algo;
static BCRYPT_ALG_HANDLE _sha256_hmac_algo;
void
mongoc_crypto_cng_init (void)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
_sha1_hash_algo = 0;
status = BCryptOpenAlgorithmProvider (
&_sha1_hash_algo, BCRYPT_SHA1_ALGORITHM, NULL, 0);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA1): %x", status);
+ MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA1): %ld", status);
}
_sha1_hmac_algo = 0;
status = BCryptOpenAlgorithmProvider (&_sha1_hmac_algo,
BCRYPT_SHA1_ALGORITHM,
NULL,
BCRYPT_ALG_HANDLE_HMAC_FLAG);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA1 HMAC): %x", status);
+ MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA1 HMAC): %ld", status);
}
_sha256_hash_algo = 0;
status = BCryptOpenAlgorithmProvider (
&_sha256_hash_algo, BCRYPT_SHA256_ALGORITHM, NULL, 0);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA256): %x", status);
+ MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA256): %ld", status);
}
_sha256_hmac_algo = 0;
status = BCryptOpenAlgorithmProvider (&_sha256_hmac_algo,
BCRYPT_SHA256_ALGORITHM,
NULL,
BCRYPT_ALG_HANDLE_HMAC_FLAG);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA256 HMAC): %x", status);
+ MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA256 HMAC): %ld", status);
}
}
void
mongoc_crypto_cng_cleanup (void)
{
if (_sha1_hash_algo) {
BCryptCloseAlgorithmProvider (&_sha1_hash_algo, 0);
}
if (_sha1_hmac_algo) {
BCryptCloseAlgorithmProvider (&_sha1_hmac_algo, 0);
}
if (_sha256_hash_algo) {
BCryptCloseAlgorithmProvider (&_sha256_hash_algo, 0);
}
if (_sha256_hash_algo) {
BCryptCloseAlgorithmProvider (&_sha256_hash_algo, 0);
}
}
bool
_mongoc_crypto_cng_hmac_or_hash (BCRYPT_ALG_HANDLE algorithm,
- void *key,
+ const void *key,
size_t key_length,
void *data,
size_t data_length,
void *output)
{
- char *hash_object_buffer = 0;
+ unsigned char *hash_object_buffer = 0;
ULONG hash_object_length = 0;
BCRYPT_HASH_HANDLE hash = 0;
ULONG mac_length = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
bool retval = false;
ULONG noop = 0;
status = BCryptGetProperty (algorithm,
BCRYPT_OBJECT_LENGTH,
- (char *) &hash_object_length,
+ (unsigned char *) &hash_object_length,
sizeof hash_object_length,
&noop,
0);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptGetProperty(): OBJECT_LENGTH %x", status);
+ MONGOC_ERROR ("BCryptGetProperty(): OBJECT_LENGTH %ld", status);
return false;
}
status = BCryptGetProperty (algorithm,
BCRYPT_HASH_LENGTH,
- (char *) &mac_length,
+ (unsigned char *) &mac_length,
sizeof mac_length,
&noop,
0);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptGetProperty(): HASH_LENGTH %x", status);
+ MONGOC_ERROR ("BCryptGetProperty(): HASH_LENGTH %ld", status);
return false;
}
hash_object_buffer = bson_malloc (hash_object_length);
status = BCryptCreateHash (algorithm,
&hash,
hash_object_buffer,
hash_object_length,
- key,
+ (PUCHAR) key,
(ULONG) key_length,
0);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptCreateHash(): %x", status);
+ MONGOC_ERROR ("BCryptCreateHash(): %ld", status);
goto cleanup;
}
status = BCryptHashData (hash, data, (ULONG) data_length, 0);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptHashData(): %x", status);
+ MONGOC_ERROR ("BCryptHashData(): %ld", status);
goto cleanup;
}
status = BCryptFinishHash (hash, output, mac_length, 0);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptFinishHash(): %x", status);
+ MONGOC_ERROR ("BCryptFinishHash(): %ld", status);
goto cleanup;
}
retval = true;
cleanup:
if (hash) {
(void) BCryptDestroyHash (hash);
}
bson_free (hash_object_buffer);
return retval;
}
void
mongoc_crypto_cng_hmac_sha1 (mongoc_crypto_t *crypto,
const void *key,
int key_len,
const unsigned char *data,
int data_len,
unsigned char *hmac_out)
{
- NTSTATUS status = STATUS_UNSUCCESSFUL;
-
if (!_sha1_hmac_algo) {
return;
}
_mongoc_crypto_cng_hmac_or_hash (
- _sha1_hmac_algo, key, key_len, data, data_len, hmac_out);
+ _sha1_hmac_algo, key, key_len, (void *) data, data_len, hmac_out);
}
bool
mongoc_crypto_cng_sha1 (mongoc_crypto_t *crypto,
const unsigned char *input,
const size_t input_len,
unsigned char *hash_out)
{
- NTSTATUS status = STATUS_UNSUCCESSFUL;
bool res;
if (!_sha1_hash_algo) {
return false;
}
res = _mongoc_crypto_cng_hmac_or_hash (
- _sha1_hash_algo, NULL, 0, input, input_len, hash_out);
+ _sha1_hash_algo, NULL, 0, (void *) input, input_len, hash_out);
return res;
}
void
mongoc_crypto_cng_hmac_sha256 (mongoc_crypto_t *crypto,
const void *key,
int key_len,
const unsigned char *data,
int data_len,
unsigned char *hmac_out)
{
- NTSTATUS status = STATUS_UNSUCCESSFUL;
-
if (!_sha256_hmac_algo) {
return;
}
_mongoc_crypto_cng_hmac_or_hash (
- _sha256_hmac_algo, key, key_len, data, data_len, hmac_out);
+ _sha256_hmac_algo, key, key_len, (void *) data, data_len, hmac_out);
}
bool
mongoc_crypto_cng_sha256 (mongoc_crypto_t *crypto,
const unsigned char *input,
const size_t input_len,
unsigned char *hash_out)
{
- NTSTATUS status = STATUS_UNSUCCESSFUL;
bool res;
if (!_sha256_hash_algo) {
return false;
}
res = _mongoc_crypto_cng_hmac_or_hash (
- _sha256_hash_algo, NULL, 0, input, input_len, hash_out);
+ _sha256_hash_algo, NULL, 0, (void *) input, input_len, hash_out);
return res;
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
index eefe3ee6..ba59cc18 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
@@ -1,622 +1,624 @@
/*
* Copyright 2018-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
*
* 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.
*/
/* cursor functions for pre-3.2 MongoDB, including:
* - OP_QUERY find (superseded by the find command)
* - OP_GETMORE (superseded by the getMore command)
* - receiving OP_REPLY documents in a stream (instead of batch)
*/
#include "mongoc-cursor.h"
#include "mongoc-cursor-private.h"
#include "mongoc-client-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-error.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-rpc-private.h"
static bool
_mongoc_cursor_monitor_legacy_get_more (mongoc_cursor_t *cursor,
mongoc_server_stream_t *server_stream)
{
bson_t doc;
- char db[MONGOC_NAMESPACE_MAX];
+ char *db;
mongoc_client_t *client;
mongoc_apm_command_started_t event;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.started) {
/* successful */
RETURN (true);
}
_mongoc_cursor_prepare_getmore_command (cursor, &doc);
- bson_strncpy (db, cursor->ns, cursor->dblen + 1);
+ db = bson_strndup (cursor->ns, cursor->dblen);
mongoc_apm_command_started_init (&event,
&doc,
db,
"getMore",
client->cluster.request_id,
cursor->operation_id,
&server_stream->sd->host,
server_stream->sd->id,
client->apm_context);
client->apm_callbacks.started (&event);
mongoc_apm_command_started_cleanup (&event);
bson_destroy (&doc);
+ bson_free (db);
RETURN (true);
}
static bool
_mongoc_cursor_monitor_legacy_query (mongoc_cursor_t *cursor,
const bson_t *filter,
mongoc_server_stream_t *server_stream)
{
bson_t doc;
mongoc_client_t *client;
- char db[MONGOC_NAMESPACE_MAX];
+ char *db;
bool r;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.started) {
/* successful */
RETURN (true);
}
bson_init (&doc);
- bson_strncpy (db, cursor->ns, cursor->dblen + 1);
+ db = bson_strndup (cursor->ns, cursor->dblen);
/* simulate a MongoDB 3.2+ "find" command */
_mongoc_cursor_prepare_find_command (cursor, filter, &doc);
bson_copy_to_excluding_noinit (
&cursor->opts, &doc, "serverId", "maxAwaitTimeMS", "sessionId", NULL);
r = _mongoc_cursor_monitor_command (cursor, server_stream, &doc, "find");
bson_destroy (&doc);
+ bson_free (db);
RETURN (r);
}
void
_mongoc_cursor_op_getmore (mongoc_cursor_t *cursor,
mongoc_cursor_response_legacy_t *response)
{
int64_t started;
mongoc_rpc_t rpc;
uint32_t request_id;
mongoc_cluster_t *cluster;
mongoc_query_flags_t flags;
mongoc_server_stream_t *server_stream;
ENTRY;
started = bson_get_monotonic_time ();
cluster = &cursor->client->cluster;
server_stream = _mongoc_cursor_fetch_stream (cursor);
if (!server_stream) {
return;
}
if (!_mongoc_cursor_opts_to_flags (cursor, server_stream, &flags)) {
GOTO (fail);
}
if (cursor->in_exhaust) {
request_id = (uint32_t) response->rpc.header.request_id;
} else {
request_id = ++cluster->request_id;
rpc.get_more.cursor_id = cursor->cursor_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_GET_MORE;
rpc.get_more.zero = 0;
rpc.get_more.collection = cursor->ns;
if (flags & MONGOC_QUERY_TAILABLE_CURSOR) {
rpc.get_more.n_return = 0;
} else {
rpc.get_more.n_return = _mongoc_n_return (cursor);
}
if (!_mongoc_cursor_monitor_legacy_get_more (cursor, server_stream)) {
GOTO (fail);
}
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
cluster, &rpc, server_stream, &cursor->error)) {
GOTO (fail);
}
}
_mongoc_buffer_clear (&response->buffer, false);
/* reset the last known cursor id. */
cursor->cursor_id = 0;
if (!_mongoc_client_recv (cursor->client,
&response->rpc,
&response->buffer,
server_stream,
&cursor->error)) {
GOTO (fail);
}
if (response->rpc.header.opcode != MONGOC_OPCODE_REPLY) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid opcode. Expected %d, got %d.",
MONGOC_OPCODE_REPLY,
response->rpc.header.opcode);
GOTO (fail);
}
if (response->rpc.header.response_to != request_id) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid response_to for getmore. Expected %d, got %d.",
request_id,
response->rpc.header.response_to);
GOTO (fail);
}
if (!_mongoc_rpc_check_ok (&response->rpc,
cursor->client->error_api_version,
&cursor->error,
&cursor->error_doc)) {
GOTO (fail);
}
if (response->reader) {
bson_reader_destroy (response->reader);
}
cursor->cursor_id = response->rpc.reply.cursor_id;
response->reader =
bson_reader_new_from_data (response->rpc.reply.documents,
(size_t) response->rpc.reply.documents_len);
_mongoc_cursor_monitor_succeeded (cursor,
response,
bson_get_monotonic_time () - started,
false, /* not first batch */
server_stream,
"getMore");
GOTO (done);
fail:
_mongoc_cursor_monitor_failed (
cursor, bson_get_monotonic_time () - started, server_stream, "getMore");
done:
mongoc_server_stream_cleanup (server_stream);
}
#define OPT_CHECK(_type) \
do { \
if (!BSON_ITER_HOLDS_##_type (&iter)) { \
bson_set_error (&cursor->error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
"invalid option %s, should be type %s", \
key, \
#_type); \
return NULL; \
} \
} while (false)
#define OPT_CHECK_INT() \
do { \
if (!BSON_ITER_HOLDS_INT (&iter)) { \
bson_set_error (&cursor->error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
"invalid option %s, should be integer", \
key); \
return NULL; \
} \
} while (false)
#define OPT_ERR(_msg) \
do { \
bson_set_error (&cursor->error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
_msg); \
return NULL; \
} while (false)
#define OPT_BSON_ERR(_msg) \
do { \
bson_set_error ( \
&cursor->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, _msg); \
return NULL; \
} while (false)
#define OPT_FLAG(_flag) \
do { \
OPT_CHECK (BOOL); \
if (bson_iter_as_bool (&iter)) { \
*flags |= _flag; \
} \
} while (false)
#define PUSH_DOLLAR_QUERY() \
do { \
if (!pushed_dollar_query) { \
pushed_dollar_query = true; \
bson_append_document (query, "$query", 6, filter); \
} \
} while (false)
#define OPT_SUBDOCUMENT(_opt_name, _legacy_name) \
do { \
OPT_CHECK (DOCUMENT); \
bson_iter_document (&iter, &len, &data); \
if (!bson_init_static (&subdocument, data, (size_t) len)) { \
OPT_BSON_ERR ("Invalid '" #_opt_name "' subdocument in 'opts'."); \
} \
BSON_APPEND_DOCUMENT (query, "$" #_legacy_name, &subdocument); \
} while (false)
static bson_t *
_mongoc_cursor_parse_opts_for_op_query (mongoc_cursor_t *cursor,
mongoc_server_stream_t *stream,
bson_t *filter,
bson_t *query /* OUT */,
bson_t *fields /* OUT */,
mongoc_query_flags_t *flags /* OUT */,
int32_t *skip /* OUT */)
{
bool pushed_dollar_query;
bson_iter_t iter;
uint32_t len;
const uint8_t *data;
bson_t subdocument;
const char *key;
char *dollar_modifier;
*flags = MONGOC_QUERY_NONE;
*skip = 0;
/* assume we'll send filter straight to server, like "{a: 1}". if we find an
* opt we must add, like "sort", we push the query like "$query: {a: 1}",
* then add a query modifier for the option, in this example "$orderby".
*/
pushed_dollar_query = false;
if (!bson_iter_init (&iter, &cursor->opts)) {
OPT_BSON_ERR ("Invalid 'opts' parameter.");
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
/* most common options first */
if (!strcmp (key, MONGOC_CURSOR_PROJECTION)) {
OPT_CHECK (DOCUMENT);
bson_iter_document (&iter, &len, &data);
if (!bson_init_static (&subdocument, data, (size_t) len)) {
OPT_BSON_ERR ("Invalid 'projection' subdocument in 'opts'.");
}
bson_destroy (fields);
bson_copy_to (&subdocument, fields);
} else if (!strcmp (key, MONGOC_CURSOR_SORT)) {
PUSH_DOLLAR_QUERY ();
OPT_SUBDOCUMENT (sort, orderby);
} else if (!strcmp (key, MONGOC_CURSOR_SKIP)) {
OPT_CHECK_INT ();
*skip = (int32_t) bson_iter_as_int64 (&iter);
}
/* the rest of the options, alphabetically */
else if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) {
OPT_FLAG (MONGOC_QUERY_PARTIAL);
} else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) {
OPT_FLAG (MONGOC_QUERY_AWAIT_DATA);
} else if (!strcmp (key, MONGOC_CURSOR_COMMENT)) {
OPT_CHECK (UTF8);
PUSH_DOLLAR_QUERY ();
BSON_APPEND_UTF8 (query, "$comment", bson_iter_utf8 (&iter, NULL));
} else if (!strcmp (key, MONGOC_CURSOR_HINT)) {
if (BSON_ITER_HOLDS_UTF8 (&iter)) {
PUSH_DOLLAR_QUERY ();
BSON_APPEND_UTF8 (query, "$hint", bson_iter_utf8 (&iter, NULL));
} else if (BSON_ITER_HOLDS_DOCUMENT (&iter)) {
PUSH_DOLLAR_QUERY ();
OPT_SUBDOCUMENT (hint, hint);
} else {
OPT_ERR ("Wrong type for 'hint' field in 'opts'.");
}
} else if (!strcmp (key, MONGOC_CURSOR_MAX)) {
PUSH_DOLLAR_QUERY ();
OPT_SUBDOCUMENT (max, max);
} else if (!strcmp (key, MONGOC_CURSOR_MAX_SCAN)) {
OPT_CHECK_INT ();
PUSH_DOLLAR_QUERY ();
BSON_APPEND_INT64 (query, "$maxScan", bson_iter_as_int64 (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_MAX_TIME_MS)) {
OPT_CHECK_INT ();
PUSH_DOLLAR_QUERY ();
BSON_APPEND_INT64 (query, "$maxTimeMS", bson_iter_as_int64 (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_MIN)) {
PUSH_DOLLAR_QUERY ();
OPT_SUBDOCUMENT (min, min);
} else if (!strcmp (key, MONGOC_CURSOR_READ_CONCERN)) {
OPT_ERR ("Set readConcern on client, database, or collection,"
" not in a query.");
} else if (!strcmp (key, MONGOC_CURSOR_RETURN_KEY)) {
OPT_CHECK (BOOL);
PUSH_DOLLAR_QUERY ();
BSON_APPEND_BOOL (query, "$returnKey", bson_iter_as_bool (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_SHOW_RECORD_ID)) {
OPT_CHECK (BOOL);
PUSH_DOLLAR_QUERY ();
BSON_APPEND_BOOL (query, "$showDiskLoc", bson_iter_as_bool (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_SNAPSHOT)) {
OPT_CHECK (BOOL);
PUSH_DOLLAR_QUERY ();
BSON_APPEND_BOOL (query, "$snapshot", bson_iter_as_bool (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_COLLATION)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
return NULL;
}
/* singleBatch limit and batchSize are handled in _mongoc_n_return,
* exhaust noCursorTimeout oplogReplay tailable in _mongoc_cursor_flags
* maxAwaitTimeMS is handled in _mongoc_cursor_prepare_getmore_command
* sessionId is used to retrieve the mongoc_client_session_t
*/
else if (strcmp (key, MONGOC_CURSOR_SINGLE_BATCH) &&
strcmp (key, MONGOC_CURSOR_LIMIT) &&
strcmp (key, MONGOC_CURSOR_BATCH_SIZE) &&
strcmp (key, MONGOC_CURSOR_EXHAUST) &&
strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT) &&
strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY) &&
strcmp (key, MONGOC_CURSOR_TAILABLE) &&
strcmp (key, MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) {
/* pass unrecognized options to server, prefixed with $ */
PUSH_DOLLAR_QUERY ();
dollar_modifier = bson_strdup_printf ("$%s", key);
if (!bson_append_iter (query, dollar_modifier, -1, &iter)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Error adding \"%s\" to query",
dollar_modifier);
bson_free (dollar_modifier);
return NULL;
}
bson_free (dollar_modifier);
}
}
if (!_mongoc_cursor_opts_to_flags (cursor, stream, flags)) {
/* cursor->error is set */
return NULL;
}
return pushed_dollar_query ? query : filter;
}
#undef OPT_CHECK
#undef OPT_ERR
#undef OPT_BSON_ERR
#undef OPT_FLAG
#undef OPT_SUBDOCUMENT
bool
_mongoc_cursor_op_query_find (mongoc_cursor_t *cursor,
bson_t *filter,
mongoc_cursor_response_legacy_t *response)
{
int64_t started;
uint32_t request_id;
mongoc_rpc_t rpc;
const bson_t *query_ptr;
bson_t query = BSON_INITIALIZER;
bson_t fields = BSON_INITIALIZER;
mongoc_query_flags_t flags;
mongoc_assemble_query_result_t result = ASSEMBLE_QUERY_RESULT_INIT;
bool succeeded = false;
mongoc_server_stream_t *server_stream;
ENTRY;
server_stream = _mongoc_cursor_fetch_stream (cursor);
if (!server_stream) {
return false;
}
started = bson_get_monotonic_time ();
/* When the user explicitly provides a readConcern -- but the server
* doesn't support readConcern, we must error:
* https://github.com/mongodb/specifications/blob/master/source/read-write-concern/read-write-concern.rst#errors-1
*/
if (cursor->read_concern->level != NULL &&
server_stream->sd->max_wire_version < WIRE_VERSION_READ_CONCERN) {
bson_set_error (&cursor->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support readConcern");
GOTO (done);
}
cursor->operation_id = ++cursor->client->cluster.operation_id;
request_id = ++cursor->client->cluster.request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_QUERY;
rpc.query.flags = MONGOC_QUERY_NONE;
rpc.query.collection = cursor->ns;
rpc.query.skip = 0;
rpc.query.n_return = 0;
rpc.query.fields = NULL;
query_ptr = _mongoc_cursor_parse_opts_for_op_query (
cursor, server_stream, filter, &query, &fields, &flags, &rpc.query.skip);
if (!query_ptr) {
/* invalid opts. cursor->error is set */
GOTO (done);
}
assemble_query (
cursor->read_prefs, server_stream, query_ptr, flags, &result);
rpc.query.query = bson_get_data (result.assembled_query);
rpc.query.flags = result.flags;
rpc.query.n_return = _mongoc_n_return (cursor);
if (!bson_empty (&fields)) {
rpc.query.fields = bson_get_data (&fields);
}
/* cursor from mongoc_collection_find[_with_opts] is about to send its
* initial OP_QUERY to pre-3.2 MongoDB */
if (!_mongoc_cursor_monitor_legacy_query (cursor, filter, server_stream)) {
GOTO (done);
}
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
&cursor->client->cluster, &rpc, server_stream, &cursor->error)) {
GOTO (done);
}
_mongoc_buffer_clear (&response->buffer, false);
if (!_mongoc_client_recv (cursor->client,
&response->rpc,
&response->buffer,
server_stream,
&cursor->error)) {
GOTO (done);
}
if (response->rpc.header.opcode != MONGOC_OPCODE_REPLY) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid opcode. Expected %d, got %d.",
MONGOC_OPCODE_REPLY,
response->rpc.header.opcode);
GOTO (done);
}
if (response->rpc.header.response_to != request_id) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid response_to for query. Expected %d, got %d.",
request_id,
response->rpc.header.response_to);
GOTO (done);
}
if (!_mongoc_rpc_check_ok (&response->rpc,
cursor->client->error_api_version,
&cursor->error,
&cursor->error_doc)) {
GOTO (done);
}
if (response->reader) {
bson_reader_destroy (response->reader);
}
cursor->cursor_id = response->rpc.reply.cursor_id;
response->reader =
bson_reader_new_from_data (response->rpc.reply.documents,
(size_t) response->rpc.reply.documents_len);
if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) {
cursor->in_exhaust = true;
cursor->client->in_exhaust = true;
}
_mongoc_cursor_monitor_succeeded (cursor,
response,
bson_get_monotonic_time () - started,
true, /* first_batch */
server_stream,
"find");
succeeded = true;
done:
if (!succeeded) {
_mongoc_cursor_monitor_failed (
cursor, bson_get_monotonic_time () - started, server_stream, "find");
}
mongoc_server_stream_cleanup (server_stream);
assemble_query_result_cleanup (&result);
bson_destroy (&query);
bson_destroy (&fields);
return succeeded;
}
void
_mongoc_cursor_response_legacy_init (mongoc_cursor_response_legacy_t *response)
{
_mongoc_buffer_init (&response->buffer, NULL, 0, NULL, NULL);
}
void
_mongoc_cursor_response_legacy_destroy (
mongoc_cursor_response_legacy_t *response)
{
if (response->reader) {
bson_reader_destroy (response->reader);
response->reader = NULL;
}
_mongoc_buffer_destroy (&response->buffer);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h
index 54d4339d..fbc4daa4 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h
@@ -1,326 +1,326 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CURSOR_PRIVATE_H
#define MONGOC_CURSOR_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-buffer-private.h"
#include "mongoc-rpc-private.h"
#include "mongoc-server-stream-private.h"
BSON_BEGIN_DECLS
#define MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS "allowPartialResults"
#define MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS_LEN 19
#define MONGOC_CURSOR_AWAIT_DATA "awaitData"
#define MONGOC_CURSOR_AWAIT_DATA_LEN 9
#define MONGOC_CURSOR_BATCH_SIZE "batchSize"
#define MONGOC_CURSOR_BATCH_SIZE_LEN 9
#define MONGOC_CURSOR_COLLATION "collation"
#define MONGOC_CURSOR_COLLATION_LEN 9
#define MONGOC_CURSOR_COMMENT "comment"
#define MONGOC_CURSOR_COMMENT_LEN 7
#define MONGOC_CURSOR_EXHAUST "exhaust"
#define MONGOC_CURSOR_EXHAUST_LEN 7
#define MONGOC_CURSOR_FILTER "filter"
#define MONGOC_CURSOR_FILTER_LEN 6
#define MONGOC_CURSOR_FIND "find"
#define MONGOC_CURSOR_FIND_LEN 4
#define MONGOC_CURSOR_HINT "hint"
#define MONGOC_CURSOR_HINT_LEN 4
#define MONGOC_CURSOR_LIMIT "limit"
#define MONGOC_CURSOR_LIMIT_LEN 5
#define MONGOC_CURSOR_MAX "max"
#define MONGOC_CURSOR_MAX_LEN 3
#define MONGOC_CURSOR_MAX_AWAIT_TIME_MS "maxAwaitTimeMS"
#define MONGOC_CURSOR_MAX_AWAIT_TIME_MS_LEN 14
#define MONGOC_CURSOR_MAX_SCAN "maxScan"
#define MONGOC_CURSOR_MAX_SCAN_LEN 7
#define MONGOC_CURSOR_MAX_TIME_MS "maxTimeMS"
#define MONGOC_CURSOR_MAX_TIME_MS_LEN 9
#define MONGOC_CURSOR_MIN "min"
#define MONGOC_CURSOR_MIN_LEN 3
#define MONGOC_CURSOR_NO_CURSOR_TIMEOUT "noCursorTimeout"
#define MONGOC_CURSOR_NO_CURSOR_TIMEOUT_LEN 15
#define MONGOC_CURSOR_OPLOG_REPLAY "oplogReplay"
#define MONGOC_CURSOR_OPLOG_REPLAY_LEN 11
#define MONGOC_CURSOR_ORDERBY "orderby"
#define MONGOC_CURSOR_ORDERBY_LEN 7
#define MONGOC_CURSOR_PROJECTION "projection"
#define MONGOC_CURSOR_PROJECTION_LEN 10
#define MONGOC_CURSOR_QUERY "query"
#define MONGOC_CURSOR_QUERY_LEN 5
#define MONGOC_CURSOR_READ_CONCERN "readConcern"
#define MONGOC_CURSOR_READ_CONCERN_LEN 11
#define MONGOC_CURSOR_RETURN_KEY "returnKey"
#define MONGOC_CURSOR_RETURN_KEY_LEN 9
#define MONGOC_CURSOR_SHOW_DISK_LOC "showDiskLoc"
#define MONGOC_CURSOR_SHOW_DISK_LOC_LEN 11
#define MONGOC_CURSOR_SHOW_RECORD_ID "showRecordId"
#define MONGOC_CURSOR_SHOW_RECORD_ID_LEN 12
#define MONGOC_CURSOR_SINGLE_BATCH "singleBatch"
#define MONGOC_CURSOR_SINGLE_BATCH_LEN 11
#define MONGOC_CURSOR_SKIP "skip"
#define MONGOC_CURSOR_SKIP_LEN 4
#define MONGOC_CURSOR_SNAPSHOT "snapshot"
#define MONGOC_CURSOR_SNAPSHOT_LEN 8
#define MONGOC_CURSOR_SORT "sort"
#define MONGOC_CURSOR_SORT_LEN 4
#define MONGOC_CURSOR_TAILABLE "tailable"
#define MONGOC_CURSOR_TAILABLE_LEN 8
typedef struct _mongoc_cursor_impl_t mongoc_cursor_impl_t;
typedef enum { UNPRIMED, IN_BATCH, END_OF_BATCH, DONE } mongoc_cursor_state_t;
typedef mongoc_cursor_state_t (*_mongoc_cursor_impl_transition_t) (
mongoc_cursor_t *cursor);
struct _mongoc_cursor_impl_t {
void (*clone) (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src);
void (*destroy) (mongoc_cursor_impl_t *ctx);
_mongoc_cursor_impl_transition_t prime;
_mongoc_cursor_impl_transition_t pop_from_batch;
_mongoc_cursor_impl_transition_t get_next_batch;
void *data;
};
/* pre-3.2 and exhaust cursor responses -- read documents from stream. */
typedef struct _mongoc_cursor_response_legacy {
mongoc_rpc_t rpc;
mongoc_buffer_t buffer;
bson_reader_t *reader;
} mongoc_cursor_response_legacy_t;
/* 3.2+ responses -- read batch docs like {cursor:{id: 123, firstBatch: []}} */
typedef struct _mongoc_cursor_response_t {
bson_t reply; /* the entire command reply */
bson_iter_t batch_iter; /* iterates over the batch array */
bson_t current_doc; /* the current doc inside the batch array */
} mongoc_cursor_response_t;
struct _mongoc_cursor_t {
mongoc_client_t *client;
uint32_t client_generation;
uint32_t server_id;
bool slave_ok;
mongoc_cursor_state_t state;
bool in_exhaust;
bson_t opts;
mongoc_read_concern_t *read_concern;
mongoc_read_prefs_t *read_prefs;
mongoc_write_concern_t *write_concern;
bool explicit_session;
mongoc_client_session_t *client_session;
uint32_t count;
- char ns[140];
+ char *ns;
uint32_t nslen;
uint32_t dblen;
bson_error_t error;
bson_t error_doc; /* always initialized, and set with server errors. */
const bson_t *current;
mongoc_cursor_impl_t impl;
int64_t operation_id;
int64_t cursor_id;
};
int32_t
_mongoc_n_return (mongoc_cursor_t *cursor);
void
_mongoc_set_cursor_ns (mongoc_cursor_t *cursor, const char *ns, uint32_t nslen);
bool
_mongoc_cursor_get_opt_bool (const mongoc_cursor_t *cursor, const char *option);
void
_mongoc_cursor_flags_to_opts (mongoc_query_flags_t qflags,
bson_t *opts,
bool *slave_ok);
bool
_mongoc_cursor_translate_dollar_query_opts (const bson_t *query,
bson_t *opts,
bson_t *unwrapped,
bson_error_t *error);
mongoc_server_stream_t *
_mongoc_cursor_fetch_stream (mongoc_cursor_t *cursor);
void
_mongoc_cursor_collection (const mongoc_cursor_t *cursor,
const char **collection,
int *collection_len);
bool
_mongoc_cursor_run_command (mongoc_cursor_t *cursor,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bool retry_prohibited);
bool
_mongoc_cursor_more (mongoc_cursor_t *cursor);
bool
_mongoc_cursor_set_opt_int64 (mongoc_cursor_t *cursor,
const char *option,
int64_t value);
void
_mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor,
int64_t duration,
mongoc_server_stream_t *stream,
const char *cmd_name);
bool
_mongoc_cursor_monitor_command (mongoc_cursor_t *cursor,
mongoc_server_stream_t *server_stream,
const bson_t *cmd,
const char *cmd_name);
void
_mongoc_cursor_prepare_find_command (mongoc_cursor_t *cursor,
const bson_t *filter,
bson_t *command);
const bson_t *
_mongoc_cursor_initial_query (mongoc_cursor_t *cursor);
const bson_t *
_mongoc_cursor_get_more (mongoc_cursor_t *cursor);
bool
_mongoc_cursor_opts_to_flags (mongoc_cursor_t *cursor,
mongoc_server_stream_t *stream,
mongoc_query_flags_t *flags /* OUT */);
void
_mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor,
mongoc_cursor_response_legacy_t *response,
int64_t duration,
bool first_batch,
mongoc_server_stream_t *stream,
const char *cmd_name);
/* start iterating a reply like
* {cursor: {id: 1234, ns: "db.collection", firstBatch: [...]}} or
* {cursor: {id: 1234, ns: "db.collection", nextBatch: [...]}} */
void
_mongoc_cursor_response_refresh (mongoc_cursor_t *cursor,
const bson_t *command,
const bson_t *opts,
mongoc_cursor_response_t *response);
bool
_mongoc_cursor_start_reading_response (mongoc_cursor_t *cursor,
mongoc_cursor_response_t *response);
void
_mongoc_cursor_response_read (mongoc_cursor_t *cursor,
mongoc_cursor_response_t *response,
const bson_t **bson);
void
_mongoc_cursor_prepare_getmore_command (mongoc_cursor_t *cursor,
bson_t *command);
void
_mongoc_cursor_set_empty (mongoc_cursor_t *cursor);
bool
_mongoc_cursor_check_and_copy_to (mongoc_cursor_t *cursor,
const char *err_prefix,
const bson_t *src,
bson_t *dst);
void
_mongoc_cursor_prime (mongoc_cursor_t *cursor);
/* legacy functions defined in mongoc-cursor-legacy.c */
bool
_mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson);
bool
_mongoc_cursor_op_query_find (mongoc_cursor_t *cursor,
bson_t *filter,
mongoc_cursor_response_legacy_t *response);
void
_mongoc_cursor_op_getmore (mongoc_cursor_t *cursor,
mongoc_cursor_response_legacy_t *response);
mongoc_cursor_t *
_mongoc_cursor_new_with_opts (mongoc_client_t *client,
const char *db_and_collection,
const bson_t *opts,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
const mongoc_read_concern_t *read_concern);
void
_mongoc_cursor_response_legacy_init (mongoc_cursor_response_legacy_t *response);
void
_mongoc_cursor_response_legacy_destroy (
mongoc_cursor_response_legacy_t *response);
/* cursor constructors. */
mongoc_cursor_t *
_mongoc_cursor_find_new (mongoc_client_t *client,
const char *db_and_coll,
const bson_t *filter,
const bson_t *opts,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
const mongoc_read_concern_t *read_concern);
mongoc_cursor_t *
_mongoc_cursor_cmd_new (mongoc_client_t *client,
const char *db_and_coll,
const bson_t *cmd,
const bson_t *opts,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
const mongoc_read_concern_t *read_concern);
mongoc_cursor_t *
_mongoc_cursor_cmd_new_from_reply (mongoc_client_t *client,
const bson_t *cmd,
const bson_t *opts,
bson_t *reply);
mongoc_cursor_t *
_mongoc_cursor_cmd_deprecated_new (mongoc_client_t *client,
const char *db_and_coll,
const bson_t *cmd,
const mongoc_read_prefs_t *read_prefs);
mongoc_cursor_t *
_mongoc_cursor_array_new (mongoc_client_t *client,
const char *db_and_coll,
const bson_t *cmd,
const bson_t *opts,
const char *field_name);
mongoc_cursor_t *
_mongoc_cursor_change_stream_new (mongoc_client_t *client,
bson_t *reply,
const bson_t *opts);
bool
_mongoc_cursor_change_stream_end_of_batch (mongoc_cursor_t *cursor);
const bson_t *
_mongoc_cursor_change_stream_get_post_batch_resume_token (
mongoc_cursor_t *cursor);
bool
_mongoc_cursor_change_stream_has_post_batch_resume_token (
mongoc_cursor_t *cursor);
const bson_t *
_mongoc_cursor_change_stream_get_reply (mongoc_cursor_t *cursor);
BSON_END_DECLS
#endif /* MONGOC_CURSOR_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
index ff053871..cd9a4bd8 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
@@ -1,1746 +1,1751 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-cursor.h"
#include "mongoc-cursor-private.h"
#include "mongoc-client-private.h"
#include "mongoc-client-session-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-error.h"
#include "mongoc-error-private.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-aggregate-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "cursor"
#define CURSOR_FAILED(cursor_) ((cursor_)->error.domain != 0)
static bool
_translate_query_opt (const char *query_field,
const char **cmd_field,
int *len);
bool
_mongoc_cursor_set_opt_int64 (mongoc_cursor_t *cursor,
const char *option,
int64_t value)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, &cursor->opts, option)) {
if (!BSON_ITER_HOLDS_INT64 (&iter)) {
return false;
}
bson_iter_overwrite_int64 (&iter, value);
return true;
}
return BSON_APPEND_INT64 (&cursor->opts, option, value);
}
static int64_t
_mongoc_cursor_get_opt_int64 (const mongoc_cursor_t *cursor,
const char *option,
int64_t default_value)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, &cursor->opts, option)) {
return bson_iter_as_int64 (&iter);
}
return default_value;
}
static bool
_mongoc_cursor_set_opt_bool (mongoc_cursor_t *cursor,
const char *option,
bool value)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, &cursor->opts, option)) {
if (!BSON_ITER_HOLDS_BOOL (&iter)) {
return false;
}
bson_iter_overwrite_bool (&iter, value);
return true;
}
return BSON_APPEND_BOOL (&cursor->opts, option, value);
}
bool
_mongoc_cursor_get_opt_bool (const mongoc_cursor_t *cursor, const char *option)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, &cursor->opts, option)) {
return bson_iter_as_bool (&iter);
}
return false;
}
int32_t
_mongoc_n_return (mongoc_cursor_t *cursor)
{
int64_t limit;
int64_t batch_size;
int64_t n_return;
/* calculate numberToReturn according to:
* https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#combining-limit-and-batch-size-for-the-wire-protocol
*/
limit = mongoc_cursor_get_limit (cursor);
batch_size = mongoc_cursor_get_batch_size (cursor);
if (limit < 0) {
n_return = limit;
} else if (limit == 0) {
n_return = batch_size;
} else if (batch_size == 0) {
n_return = limit;
} else if (limit < batch_size) {
n_return = limit;
} else {
n_return = batch_size;
}
/* if a specified limit exists, account for documents already returned. */
if (limit > 0 && cursor->count) {
int64_t remaining = limit - cursor->count;
/* remaining can be 0 if we have retrieved "limit" documents, but still
* have a cursor id: SERVER-21086. use nonzero batchSize to fetch final
* empty batch and trigger server to close cursor. */
if (remaining <= 0) {
return 1;
}
n_return = BSON_MIN (n_return, remaining);
}
/* check boundary conditions */
if (n_return < INT32_MIN) {
return INT32_MIN;
} else if (n_return > INT32_MAX) {
return INT32_MAX;
} else {
return (int32_t) n_return;
}
}
void
_mongoc_set_cursor_ns (mongoc_cursor_t *cursor, const char *ns, uint32_t nslen)
{
const char *dot;
- bson_strncpy (cursor->ns, ns, sizeof cursor->ns);
- cursor->nslen = BSON_MIN (nslen, sizeof cursor->ns);
+ bson_free (cursor->ns);
+ cursor->ns = bson_strndup (ns, nslen);
+ cursor->nslen = nslen;
dot = strstr (cursor->ns, ".");
if (dot) {
cursor->dblen = (uint32_t) (dot - cursor->ns);
} else {
/* a database name with no collection name */
cursor->dblen = cursor->nslen;
}
}
/* return first key beginning with $, or NULL. precondition: bson is valid. */
static const char *
_first_dollar_field (const bson_t *bson)
{
bson_iter_t iter;
const char *key;
BSON_ASSERT (bson_iter_init (&iter, bson));
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (key[0] == '$') {
return key;
}
}
return NULL;
}
/* if src is non-NULL, it is validated and copied to dst. returns false and
* sets the cursor error if validation fails. */
bool
_mongoc_cursor_check_and_copy_to (mongoc_cursor_t *cursor,
const char *err_prefix,
const bson_t *src,
bson_t *dst)
{
bson_error_t validate_err;
bson_init (dst);
if (src) {
if (!bson_validate_with_error (
src, BSON_VALIDATE_EMPTY_KEYS, &validate_err)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Invalid %s: %s",
err_prefix,
validate_err.message);
return false;
}
bson_destroy (dst);
bson_copy_to (src, dst);
}
return true;
}
mongoc_cursor_t *
_mongoc_cursor_new_with_opts (mongoc_client_t *client,
const char *db_and_collection,
const bson_t *opts,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
const mongoc_read_concern_t *read_concern)
{
mongoc_cursor_t *cursor;
mongoc_topology_description_type_t td_type;
uint32_t server_id;
mongoc_read_concern_t *read_concern_local = NULL;
bson_error_t validate_err;
const char *dollar_field;
bson_iter_t iter;
ENTRY;
BSON_ASSERT (client);
cursor = (mongoc_cursor_t *) bson_malloc0 (sizeof *cursor);
cursor->client = client;
cursor->state = UNPRIMED;
cursor->client_generation = client->generation;
bson_init (&cursor->opts);
bson_init (&cursor->error_doc);
if (opts) {
if (!bson_validate_with_error (
opts, BSON_VALIDATE_EMPTY_KEYS, &validate_err)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Invalid opts: %s",
validate_err.message);
GOTO (finish);
}
dollar_field = _first_dollar_field (opts);
if (dollar_field) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot use $-modifiers in opts: \"%s\"",
dollar_field);
GOTO (finish);
}
if (bson_iter_init_find (&iter, opts, "sessionId")) {
if (!_mongoc_client_session_from_iter (
client, &iter, &cursor->client_session, &cursor->error)) {
GOTO (finish);
}
cursor->explicit_session = true;
}
if (bson_iter_init_find (&iter, opts, "readConcern")) {
read_concern_local =
_mongoc_read_concern_new_from_iter (&iter, &cursor->error);
if (!read_concern_local) {
/* invalid read concern */
GOTO (finish);
}
read_concern = read_concern_local;
}
/* true if there's a valid serverId or no serverId, false on err */
if (!_mongoc_get_server_id_from_opts (opts,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
&server_id,
&cursor->error)) {
GOTO (finish);
}
if (server_id) {
(void) mongoc_cursor_set_hint (cursor, server_id);
}
bson_copy_to_excluding_noinit (opts,
&cursor->opts,
"serverId",
"sessionId",
"bypassDocumentValidation",
NULL);
/* only include bypassDocumentValidation if it's true */
if (bson_iter_init_find (&iter, opts, "bypassDocumentValidation") &&
bson_iter_as_bool (&iter)) {
BSON_APPEND_BOOL (&cursor->opts, "bypassDocumentValidation", true);
}
}
if (_mongoc_client_session_in_txn (cursor->client_session)) {
if (!IS_PREF_PRIMARY (user_prefs)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Read preference in a transaction must be primary");
GOTO (finish);
}
cursor->read_prefs =
mongoc_read_prefs_copy (cursor->client_session->txn.opts.read_prefs);
if (bson_has_field (opts, "readConcern")) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot set read concern after starting transaction");
GOTO (finish);
}
} else if (user_prefs) {
cursor->read_prefs = mongoc_read_prefs_copy (user_prefs);
} else if (default_prefs) {
cursor->read_prefs = mongoc_read_prefs_copy (default_prefs);
} else {
cursor->read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
}
cursor->read_concern = read_concern ? mongoc_read_concern_copy (read_concern)
: mongoc_read_concern_new ();
if (db_and_collection) {
_mongoc_set_cursor_ns (
cursor, db_and_collection, (uint32_t) strlen (db_and_collection));
}
if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) {
if (_mongoc_cursor_get_opt_int64 (cursor, MONGOC_CURSOR_LIMIT, 0)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot specify both 'exhaust' and 'limit'.");
GOTO (finish);
}
td_type = _mongoc_topology_get_type (client->topology);
if (td_type == MONGOC_TOPOLOGY_SHARDED) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot use exhaust cursor with sharded cluster.");
GOTO (finish);
}
}
(void) _mongoc_read_prefs_validate (cursor->read_prefs, &cursor->error);
finish:
mongoc_read_concern_destroy (read_concern_local);
mongoc_counter_cursors_active_inc ();
RETURN (cursor);
}
static bool
_translate_query_opt (const char *query_field, const char **cmd_field, int *len)
{
if (query_field[0] != '$') {
*cmd_field = query_field;
*len = -1;
return true;
}
/* strip the leading '$' */
query_field++;
if (!strcmp (MONGOC_CURSOR_ORDERBY, query_field)) {
*cmd_field = MONGOC_CURSOR_SORT;
*len = MONGOC_CURSOR_SORT_LEN;
} else if (!strcmp (MONGOC_CURSOR_SHOW_DISK_LOC,
query_field)) { /* <= MongoDb 3.0 */
*cmd_field = MONGOC_CURSOR_SHOW_RECORD_ID;
*len = MONGOC_CURSOR_SHOW_RECORD_ID_LEN;
} else if (!strcmp (MONGOC_CURSOR_HINT, query_field)) {
*cmd_field = MONGOC_CURSOR_HINT;
*len = MONGOC_CURSOR_HINT_LEN;
} else if (!strcmp (MONGOC_CURSOR_COMMENT, query_field)) {
*cmd_field = MONGOC_CURSOR_COMMENT;
*len = MONGOC_CURSOR_COMMENT_LEN;
} else if (!strcmp (MONGOC_CURSOR_MAX_SCAN, query_field)) {
*cmd_field = MONGOC_CURSOR_MAX_SCAN;
*len = MONGOC_CURSOR_MAX_SCAN_LEN;
} else if (!strcmp (MONGOC_CURSOR_MAX_TIME_MS, query_field)) {
*cmd_field = MONGOC_CURSOR_MAX_TIME_MS;
*len = MONGOC_CURSOR_MAX_TIME_MS_LEN;
} else if (!strcmp (MONGOC_CURSOR_MAX, query_field)) {
*cmd_field = MONGOC_CURSOR_MAX;
*len = MONGOC_CURSOR_MAX_LEN;
} else if (!strcmp (MONGOC_CURSOR_MIN, query_field)) {
*cmd_field = MONGOC_CURSOR_MIN;
*len = MONGOC_CURSOR_MIN_LEN;
} else if (!strcmp (MONGOC_CURSOR_RETURN_KEY, query_field)) {
*cmd_field = MONGOC_CURSOR_RETURN_KEY;
*len = MONGOC_CURSOR_RETURN_KEY_LEN;
} else if (!strcmp (MONGOC_CURSOR_SNAPSHOT, query_field)) {
*cmd_field = MONGOC_CURSOR_SNAPSHOT;
*len = MONGOC_CURSOR_SNAPSHOT_LEN;
} else {
/* not a special command field, must be a query operator like $or */
return false;
}
return true;
}
/* set up a new opt bson from older ways of specifying options.
* slave_ok may be NULL.
* error may be NULL.
*/
void
_mongoc_cursor_flags_to_opts (mongoc_query_flags_t qflags,
bson_t *opts, /* IN/OUT */
bool *slave_ok /* OUT */)
{
ENTRY;
BSON_ASSERT (opts);
if (slave_ok) {
*slave_ok = !!(qflags & MONGOC_QUERY_SLAVE_OK);
}
if (qflags & MONGOC_QUERY_TAILABLE_CURSOR) {
bson_append_bool (
opts, MONGOC_CURSOR_TAILABLE, MONGOC_CURSOR_TAILABLE_LEN, true);
}
if (qflags & MONGOC_QUERY_OPLOG_REPLAY) {
bson_append_bool (opts,
MONGOC_CURSOR_OPLOG_REPLAY,
MONGOC_CURSOR_OPLOG_REPLAY_LEN,
true);
}
if (qflags & MONGOC_QUERY_NO_CURSOR_TIMEOUT) {
bson_append_bool (opts,
MONGOC_CURSOR_NO_CURSOR_TIMEOUT,
MONGOC_CURSOR_NO_CURSOR_TIMEOUT_LEN,
true);
}
if (qflags & MONGOC_QUERY_AWAIT_DATA) {
bson_append_bool (
opts, MONGOC_CURSOR_AWAIT_DATA, MONGOC_CURSOR_AWAIT_DATA_LEN, true);
}
if (qflags & MONGOC_QUERY_EXHAUST) {
bson_append_bool (
opts, MONGOC_CURSOR_EXHAUST, MONGOC_CURSOR_EXHAUST_LEN, true);
}
if (qflags & MONGOC_QUERY_PARTIAL) {
bson_append_bool (opts,
MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS,
MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS_LEN,
true);
}
}
/* Checks if the passed query was wrapped in a $query, and if so, parses the
* query modifiers:
* https://docs.mongodb.com/manual/reference/operator/query-modifier/
* and translates them to find command options:
* https://docs.mongodb.com/manual/reference/command/find/
* opts must be initialized, and may already have options set.
* unwrapped must be uninitialized, and will be initialized at return.
* Returns true if query was unwrapped. */
bool
_mongoc_cursor_translate_dollar_query_opts (const bson_t *query,
bson_t *opts,
bson_t *unwrapped,
bson_error_t *error)
{
bool has_filter = false;
const char *key;
bson_iter_t iter;
const char *opt_key;
int len;
uint32_t data_len;
const uint8_t *data;
bson_error_t error_local = {0};
ENTRY;
BSON_ASSERT (query);
BSON_ASSERT (opts);
/* If the query is explicitly specified wrapped in $query, unwrap it and
* translate the options to new options. */
if (bson_has_field (query, "$query")) {
/* like "{$query: {a: 1}, $orderby: {b: 1}, $otherModifier: true}" */
if (!bson_iter_init (&iter, query)) {
bson_set_error (&error_local,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid BSON in query document");
GOTO (done);
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (key[0] != '$') {
bson_set_error (&error_local,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot mix $query with non-dollar field '%s'",
key);
GOTO (done);
}
if (!strcmp (key, "$query")) {
/* set "filter" to the incoming document's "$query" */
bson_iter_document (&iter, &data_len, &data);
if (!bson_init_static (unwrapped, data, (size_t) data_len)) {
bson_set_error (&error_local,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid BSON in $query subdocument");
GOTO (done);
}
has_filter = true;
} else if (_translate_query_opt (key, &opt_key, &len)) {
/* "$orderby" becomes "sort", etc., "$unknown" -> "unknown" */
if (!bson_append_iter (opts, opt_key, len, &iter)) {
bson_set_error (&error_local,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Error adding \"%s\" to query",
opt_key);
}
} else {
/* strip leading "$" */
if (!bson_append_iter (opts, key + 1, -1, &iter)) {
bson_set_error (&error_local,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Error adding \"%s\" to query",
key);
}
}
}
}
done:
if (error) {
memcpy (error, &error_local, sizeof (bson_error_t));
}
if (!has_filter) {
bson_init (unwrapped);
}
RETURN (has_filter);
}
void
mongoc_cursor_destroy (mongoc_cursor_t *cursor)
{
- char db[MONGOC_NAMESPACE_MAX];
+ char *db;
ENTRY;
if (!cursor) {
EXIT;
}
if (cursor->impl.destroy) {
cursor->impl.destroy (&cursor->impl);
}
/* Always close the socket for an exhaust cursor, even if the client was
* reset with mongoc_client_reset. That prevents further use of that socket.
*/
if (cursor->in_exhaust) {
cursor->client->in_exhaust = false;
if (cursor->state != DONE) {
/* The only way to stop an exhaust cursor is to kill the connection
*/
- mongoc_cluster_disconnect_node (
- &cursor->client->cluster, cursor->server_id, false, NULL);
+ mongoc_cluster_disconnect_node (&cursor->client->cluster,
+ cursor->server_id);
}
} else if (cursor->client_generation == cursor->client->generation) {
if (cursor->cursor_id) {
- bson_strncpy (db, cursor->ns, cursor->dblen + 1);
+ db = bson_strndup (cursor->ns, cursor->dblen);
_mongoc_client_kill_cursor (cursor->client,
cursor->server_id,
cursor->cursor_id,
cursor->operation_id,
db,
cursor->ns + cursor->dblen + 1,
cursor->client_session);
+ bson_free (db);
}
}
if (cursor->client_session && !cursor->explicit_session) {
mongoc_client_session_destroy (cursor->client_session);
}
mongoc_read_prefs_destroy (cursor->read_prefs);
mongoc_read_concern_destroy (cursor->read_concern);
mongoc_write_concern_destroy (cursor->write_concern);
bson_destroy (&cursor->opts);
bson_destroy (&cursor->error_doc);
+ bson_free (cursor->ns);
bson_free (cursor);
mongoc_counter_cursors_active_dec ();
mongoc_counter_cursors_disposed_inc ();
EXIT;
}
mongoc_server_stream_t *
_mongoc_cursor_fetch_stream (mongoc_cursor_t *cursor)
{
mongoc_server_stream_t *server_stream;
bson_t reply;
ENTRY;
if (cursor->server_id) {
server_stream =
mongoc_cluster_stream_for_server (&cursor->client->cluster,
cursor->server_id,
true /* reconnect_ok */,
cursor->client_session,
&reply,
&cursor->error);
} else {
server_stream = mongoc_cluster_stream_for_reads (&cursor->client->cluster,
cursor->read_prefs,
cursor->client_session,
&reply,
&cursor->error);
if (server_stream) {
cursor->server_id = server_stream->sd->id;
}
}
if (!server_stream) {
bson_destroy (&cursor->error_doc);
bson_copy_to (&reply, &cursor->error_doc);
bson_destroy (&reply);
}
RETURN (server_stream);
}
bool
_mongoc_cursor_monitor_command (mongoc_cursor_t *cursor,
mongoc_server_stream_t *server_stream,
const bson_t *cmd,
const char *cmd_name)
{
mongoc_client_t *client;
mongoc_apm_command_started_t event;
- char db[MONGOC_NAMESPACE_MAX];
+ char *db;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.started) {
/* successful */
RETURN (true);
}
- bson_strncpy (db, cursor->ns, cursor->dblen + 1);
+ db = bson_strndup (cursor->ns, cursor->dblen);
mongoc_apm_command_started_init (&event,
cmd,
db,
cmd_name,
client->cluster.request_id,
cursor->operation_id,
&server_stream->sd->host,
server_stream->sd->id,
client->apm_context);
client->apm_callbacks.started (&event);
mongoc_apm_command_started_cleanup (&event);
+ bson_free (db);
RETURN (true);
}
/* append array of docs from current cursor batch */
static void
_mongoc_cursor_append_docs_array (mongoc_cursor_t *cursor,
bson_t *docs,
mongoc_cursor_response_legacy_t *response)
{
bool eof = false;
char str[16];
const char *key;
uint32_t i = 0;
size_t keylen;
const bson_t *doc;
while ((doc = bson_reader_read (response->reader, &eof))) {
keylen = bson_uint32_to_string (i, &key, str, sizeof str);
bson_append_document (docs, key, (int) keylen, doc);
}
bson_reader_reset (response->reader);
}
void
_mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor,
mongoc_cursor_response_legacy_t *response,
int64_t duration,
bool first_batch,
mongoc_server_stream_t *stream,
const char *cmd_name)
{
bson_t docs_array;
mongoc_apm_command_succeeded_t event;
mongoc_client_t *client;
bson_t reply;
bson_t reply_cursor;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.succeeded) {
EXIT;
}
/* we sent OP_QUERY/OP_GETMORE, fake a reply to find/getMore command:
* {ok: 1, cursor: {id: 17, ns: "...", first/nextBatch: [ ... docs ... ]}}
*/
bson_init (&docs_array);
_mongoc_cursor_append_docs_array (cursor, &docs_array, response);
bson_init (&reply);
bson_append_int32 (&reply, "ok", 2, 1);
bson_append_document_begin (&reply, "cursor", 6, &reply_cursor);
bson_append_int64 (&reply_cursor, "id", 2, mongoc_cursor_get_id (cursor));
bson_append_utf8 (&reply_cursor, "ns", 2, cursor->ns, cursor->nslen);
bson_append_array (&reply_cursor,
first_batch ? "firstBatch" : "nextBatch",
first_batch ? 10 : 9,
&docs_array);
bson_append_document_end (&reply, &reply_cursor);
bson_destroy (&docs_array);
mongoc_apm_command_succeeded_init (&event,
duration,
&reply,
cmd_name,
client->cluster.request_id,
cursor->operation_id,
&stream->sd->host,
stream->sd->id,
client->apm_context);
client->apm_callbacks.succeeded (&event);
mongoc_apm_command_succeeded_cleanup (&event);
bson_destroy (&reply);
EXIT;
}
void
_mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor,
int64_t duration,
mongoc_server_stream_t *stream,
const char *cmd_name)
{
mongoc_apm_command_failed_t event;
mongoc_client_t *client;
bson_t reply;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.failed) {
EXIT;
}
/* we sent OP_QUERY/OP_GETMORE, fake a reply to find/getMore command:
* {ok: 0}
*/
bson_init (&reply);
bson_append_int32 (&reply, "ok", 2, 0);
mongoc_apm_command_failed_init (&event,
duration,
cmd_name,
&cursor->error,
&reply,
client->cluster.request_id,
cursor->operation_id,
&stream->sd->host,
stream->sd->id,
client->apm_context);
client->apm_callbacks.failed (&event);
mongoc_apm_command_failed_cleanup (&event);
bson_destroy (&reply);
EXIT;
}
#define ADD_FLAG(_flags, _value) \
do { \
if (!BSON_ITER_HOLDS_BOOL (&iter)) { \
bson_set_error (&cursor->error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
"invalid option %s, should be type bool", \
key); \
return false; \
} \
if (bson_iter_as_bool (&iter)) { \
*_flags |= _value; \
} \
} while (false);
bool
_mongoc_cursor_opts_to_flags (mongoc_cursor_t *cursor,
mongoc_server_stream_t *stream,
mongoc_query_flags_t *flags /* OUT */)
{
bson_iter_t iter;
const char *key;
*flags = MONGOC_QUERY_NONE;
if (!bson_iter_init (&iter, &cursor->opts)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) {
ADD_FLAG (flags, MONGOC_QUERY_PARTIAL);
} else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) {
ADD_FLAG (flags, MONGOC_QUERY_AWAIT_DATA);
} else if (!strcmp (key, MONGOC_CURSOR_EXHAUST)) {
ADD_FLAG (flags, MONGOC_QUERY_EXHAUST);
} else if (!strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT)) {
ADD_FLAG (flags, MONGOC_QUERY_NO_CURSOR_TIMEOUT);
} else if (!strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY)) {
ADD_FLAG (flags, MONGOC_QUERY_OPLOG_REPLAY);
} else if (!strcmp (key, MONGOC_CURSOR_TAILABLE)) {
ADD_FLAG (flags, MONGOC_QUERY_TAILABLE_CURSOR);
}
}
if (cursor->slave_ok) {
*flags |= MONGOC_QUERY_SLAVE_OK;
} else if (cursor->server_id &&
(stream->topology_type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY ||
stream->topology_type == MONGOC_TOPOLOGY_RS_NO_PRIMARY) &&
stream->sd->type != MONGOC_SERVER_RS_PRIMARY) {
*flags |= MONGOC_QUERY_SLAVE_OK;
}
return true;
}
bool
_mongoc_cursor_run_command (mongoc_cursor_t *cursor,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bool retry_prohibited)
{
mongoc_server_stream_t *server_stream;
bson_iter_t iter;
mongoc_cmd_parts_t parts;
const char *cmd_name;
bool is_primary;
mongoc_read_prefs_t *prefs = NULL;
- char db[MONGOC_NAMESPACE_MAX];
+ char *db = NULL;
mongoc_session_opt_t *session_opts;
bool ret = false;
bool is_retryable = true;
ENTRY;
mongoc_cmd_parts_init (
&parts, cursor->client, db, MONGOC_QUERY_NONE, command);
parts.is_read_command = true;
parts.read_prefs = cursor->read_prefs;
parts.assembled.operation_id = cursor->operation_id;
server_stream = _mongoc_cursor_fetch_stream (cursor);
if (!server_stream) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
if (opts) {
if (!bson_iter_init (&iter, opts)) {
_mongoc_bson_init_if_set (reply);
bson_set_error (&cursor->error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid BSON in opts document");
GOTO (done);
}
if (!mongoc_cmd_parts_append_opts (&parts,
&iter,
server_stream->sd->max_wire_version,
&cursor->error)) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
}
if (parts.assembled.session) {
/* initial query/aggregate/etc, and opts contains "sessionId" */
BSON_ASSERT (!cursor->client_session);
BSON_ASSERT (!cursor->explicit_session);
cursor->client_session = parts.assembled.session;
cursor->explicit_session = true;
} else if (cursor->client_session) {
/* a getMore with implicit or explicit session already acquired */
mongoc_cmd_parts_set_session (&parts, cursor->client_session);
} else {
/* try to create an implicit session. not causally consistent. we keep
* the session but leave cursor->explicit_session as 0, so we use the
* same lsid for getMores but destroy the session when the cursor dies.
*/
session_opts = mongoc_session_opts_new ();
mongoc_session_opts_set_causal_consistency (session_opts, false);
/* returns NULL if sessions aren't supported. ignore errors. */
cursor->client_session =
mongoc_client_start_session (cursor->client, session_opts, NULL);
mongoc_cmd_parts_set_session (&parts, cursor->client_session);
mongoc_session_opts_destroy (session_opts);
}
if (!mongoc_cmd_parts_set_read_concern (&parts,
cursor->read_concern,
server_stream->sd->max_wire_version,
&cursor->error)) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
- bson_strncpy (db, cursor->ns, cursor->dblen + 1);
+ db = bson_strndup (cursor->ns, cursor->dblen);
parts.assembled.db_name = db;
if (!_mongoc_cursor_opts_to_flags (
cursor, server_stream, &parts.user_query_flags)) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
/* we might use mongoc_cursor_set_hint to target a secondary but have no
* read preference, so the secondary rejects the read. same if we have a
* direct connection to a secondary (topology type "single"). with
* OP_QUERY we handle this by setting slaveOk. here we use $readPreference.
*/
cmd_name = _mongoc_get_command_name (command);
is_primary =
!cursor->read_prefs || cursor->read_prefs->mode == MONGOC_READ_PRIMARY;
if (strcmp (cmd_name, "getMore") != 0 &&
server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG &&
is_primary && parts.user_query_flags & MONGOC_QUERY_SLAVE_OK) {
parts.read_prefs = prefs =
mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED);
} else {
parts.read_prefs = cursor->read_prefs;
}
is_retryable = _is_retryable_read (&parts, server_stream);
if (!strcmp (cmd_name, "getMore")) {
is_retryable = false;
}
if (!strcmp (cmd_name, "aggregate")) {
bson_iter_t pipeline_iter;
if (bson_iter_init_find (&pipeline_iter, command, "pipeline") &&
BSON_ITER_HOLDS_ARRAY (&pipeline_iter) &&
bson_iter_recurse (&pipeline_iter, &pipeline_iter)) {
if (_has_write_key (&pipeline_iter)) {
is_retryable = false;
}
}
}
if (is_retryable && retry_prohibited) {
is_retryable = false;
}
if (cursor->write_concern &&
!mongoc_write_concern_is_default (cursor->write_concern) &&
server_stream->sd->max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN) {
parts.assembled.is_acknowledged =
mongoc_write_concern_is_acknowledged (cursor->write_concern);
mongoc_write_concern_append (cursor->write_concern, &parts.extra);
}
if (!mongoc_cmd_parts_assemble (&parts, server_stream, &cursor->error)) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
retry:
ret = mongoc_cluster_run_command_monitored (
&cursor->client->cluster, &parts.assembled, reply, &cursor->error);
if (ret) {
memset (&cursor->error, 0, sizeof (bson_error_t));
}
if (is_retryable &&
_mongoc_read_error_get_type (ret, &cursor->error, reply) ==
MONGOC_READ_ERR_RETRY) {
is_retryable = false;
mongoc_server_stream_cleanup (server_stream);
server_stream = mongoc_cluster_stream_for_reads (&cursor->client->cluster,
cursor->read_prefs,
cursor->client_session,
reply,
&cursor->error);
if (server_stream &&
server_stream->sd->max_wire_version >= WIRE_VERSION_RETRY_READS) {
cursor->server_id = server_stream->sd->id;
parts.assembled.server_stream = server_stream;
bson_destroy (reply);
GOTO (retry);
}
}
if (cursor->error.domain) {
bson_destroy (&cursor->error_doc);
bson_copy_to (reply, &cursor->error_doc);
}
/* Read and Write Concern Spec: "Drivers SHOULD parse server replies for a
* "writeConcernError" field and report the error only in command-specific
* helper methods that take a separate write concern parameter or an options
* parameter that may contain a write concern option.
*
* Only command helpers with names like "_with_write_concern" can create
* cursors with a non-NULL write_concern field.
*/
if (ret && cursor->write_concern) {
ret = !_mongoc_parse_wc_err (reply, &cursor->error);
}
done:
mongoc_server_stream_cleanup (server_stream);
mongoc_cmd_parts_cleanup (&parts);
mongoc_read_prefs_destroy (prefs);
+ bson_free (db);
return ret;
}
void
_mongoc_cursor_collection (const mongoc_cursor_t *cursor,
const char **collection,
int *collection_len)
{
/* ns is like "db.collection". Collection name is located past the ".". */
*collection = cursor->ns + (cursor->dblen + 1);
/* Collection name's length is ns length, minus length of db name and ".". */
*collection_len = cursor->nslen - cursor->dblen - 1;
BSON_ASSERT (*collection_len > 0);
}
void
_mongoc_cursor_prepare_find_command (mongoc_cursor_t *cursor,
const bson_t *filter,
bson_t *command)
{
const char *collection;
int collection_len;
_mongoc_cursor_collection (cursor, &collection, &collection_len);
bson_append_utf8 (command,
MONGOC_CURSOR_FIND,
MONGOC_CURSOR_FIND_LEN,
collection,
collection_len);
bson_append_document (
command, MONGOC_CURSOR_FILTER, MONGOC_CURSOR_FILTER_LEN, filter);
}
bool
mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error)
{
ENTRY;
RETURN (mongoc_cursor_error_document (cursor, error, NULL));
}
bool
mongoc_cursor_error_document (mongoc_cursor_t *cursor,
bson_error_t *error,
const bson_t **doc)
{
ENTRY;
BSON_ASSERT (cursor);
if (BSON_UNLIKELY (CURSOR_FAILED (cursor))) {
bson_set_error (error,
cursor->error.domain,
cursor->error.code,
"%s",
cursor->error.message);
if (doc) {
*doc = &cursor->error_doc;
}
RETURN (true);
}
if (doc) {
*doc = NULL;
}
RETURN (false);
}
static mongoc_cursor_state_t
_call_transition (mongoc_cursor_t *cursor)
{
mongoc_cursor_state_t state = cursor->state;
_mongoc_cursor_impl_transition_t fn = NULL;
switch (state) {
case UNPRIMED:
fn = cursor->impl.prime;
break;
case IN_BATCH:
fn = cursor->impl.pop_from_batch;
break;
case END_OF_BATCH:
fn = cursor->impl.get_next_batch;
break;
case DONE:
default:
fn = NULL;
break;
}
if (!fn) {
return DONE;
}
state = fn (cursor);
if (cursor->error.domain) {
state = DONE;
}
return state;
}
bool
mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson)
{
bool ret = false;
bool attempted_refresh = false;
ENTRY;
BSON_ASSERT (cursor);
BSON_ASSERT (bson);
TRACE ("cursor_id(%" PRId64 ")", cursor->cursor_id);
if (cursor->client_generation != cursor->client->generation) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot advance cursor after client reset");
RETURN (false);
}
if (bson) {
*bson = NULL;
}
if (CURSOR_FAILED (cursor)) {
RETURN (false);
}
if (cursor->state == DONE) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot advance a completed or failed cursor.");
RETURN (false);
}
/*
* We cannot proceed if another cursor is receiving results in exhaust mode.
*/
if (cursor->client->in_exhaust && !cursor->in_exhaust) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_IN_EXHAUST,
"Another cursor derived from this client is in exhaust.");
RETURN (false);
}
cursor->current = NULL;
/* if an error was set on this cursor before calling next, transition to DONE
* immediately. */
if (cursor->error.domain) {
cursor->state = DONE;
GOTO (done);
}
while (cursor->state != DONE) {
/* even when there is no data to return, some cursors remain open and
* continue sending empty batches (e.g. a tailable or change stream
* cursor). in that case, do not attempt to get another batch. */
if (cursor->state == END_OF_BATCH) {
if (attempted_refresh) {
RETURN (false);
}
attempted_refresh = true;
}
cursor->state = _call_transition (cursor);
/* check if we received a document. */
if (cursor->current) {
*bson = cursor->current;
ret = true;
GOTO (done);
}
if (cursor->state == DONE) {
GOTO (done);
}
}
done:
cursor->count++;
RETURN (ret);
}
bool
mongoc_cursor_more (mongoc_cursor_t *cursor)
{
ENTRY;
BSON_ASSERT (cursor);
if (CURSOR_FAILED (cursor)) {
RETURN (false);
}
RETURN (cursor->state != DONE);
}
void
mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host)
{
mongoc_server_description_t *description;
BSON_ASSERT (cursor);
BSON_ASSERT (host);
memset (host, 0, sizeof *host);
if (!cursor->server_id) {
MONGOC_WARNING ("%s(): Must send query before fetching peer.", BSON_FUNC);
return;
}
description = mongoc_topology_server_by_id (
cursor->client->topology, cursor->server_id, &cursor->error);
if (!description) {
return;
}
*host = description->host;
mongoc_server_description_destroy (description);
EXIT;
}
mongoc_cursor_t *
mongoc_cursor_clone (const mongoc_cursor_t *cursor)
{
mongoc_cursor_t *_clone;
BSON_ASSERT (cursor);
_clone = (mongoc_cursor_t *) bson_malloc0 (sizeof *_clone);
_clone->client = cursor->client;
_clone->nslen = cursor->nslen;
_clone->dblen = cursor->dblen;
_clone->explicit_session = cursor->explicit_session;
if (cursor->read_prefs) {
_clone->read_prefs = mongoc_read_prefs_copy (cursor->read_prefs);
}
if (cursor->read_concern) {
_clone->read_concern = mongoc_read_concern_copy (cursor->read_concern);
}
if (cursor->write_concern) {
_clone->write_concern = mongoc_write_concern_copy (cursor->write_concern);
}
if (cursor->explicit_session) {
_clone->client_session = cursor->client_session;
}
bson_copy_to (&cursor->opts, &_clone->opts);
bson_init (&_clone->error_doc);
- bson_strncpy (_clone->ns, cursor->ns, sizeof _clone->ns);
+ _clone->ns = bson_strdup (cursor->ns);
/* copy the context functions by default. */
memcpy (&_clone->impl, &cursor->impl, sizeof (cursor->impl));
if (cursor->impl.clone) {
cursor->impl.clone (&_clone->impl, &cursor->impl);
}
mongoc_counter_cursors_active_inc ();
RETURN (_clone);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cursor_is_alive --
*
* Deprecated for mongoc_cursor_more.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cursor_is_alive (const mongoc_cursor_t *cursor) /* IN */
{
return mongoc_cursor_more ((mongoc_cursor_t *) cursor);
}
const bson_t *
mongoc_cursor_current (const mongoc_cursor_t *cursor) /* IN */
{
BSON_ASSERT (cursor);
return cursor->current;
}
void
mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size)
{
BSON_ASSERT (cursor);
_mongoc_cursor_set_opt_int64 (
cursor, MONGOC_CURSOR_BATCH_SIZE, (int64_t) batch_size);
}
uint32_t
mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor)
{
BSON_ASSERT (cursor);
return (uint32_t) _mongoc_cursor_get_opt_int64 (
cursor, MONGOC_CURSOR_BATCH_SIZE, 0);
}
bool
mongoc_cursor_set_limit (mongoc_cursor_t *cursor, int64_t limit)
{
BSON_ASSERT (cursor);
if (cursor->state == UNPRIMED) {
if (limit < 0) {
return _mongoc_cursor_set_opt_int64 (
cursor, MONGOC_CURSOR_LIMIT, -limit) &&
_mongoc_cursor_set_opt_bool (
cursor, MONGOC_CURSOR_SINGLE_BATCH, true);
} else {
return _mongoc_cursor_set_opt_int64 (
cursor, MONGOC_CURSOR_LIMIT, limit);
}
} else {
return false;
}
}
int64_t
mongoc_cursor_get_limit (const mongoc_cursor_t *cursor)
{
int64_t limit;
bool single_batch;
BSON_ASSERT (cursor);
limit = _mongoc_cursor_get_opt_int64 (cursor, MONGOC_CURSOR_LIMIT, 0);
single_batch =
_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_SINGLE_BATCH);
if (limit > 0 && single_batch) {
limit = -limit;
}
return limit;
}
bool
mongoc_cursor_set_hint (mongoc_cursor_t *cursor, uint32_t server_id)
{
BSON_ASSERT (cursor);
if (cursor->server_id) {
MONGOC_ERROR ("mongoc_cursor_set_hint: server_id already set");
return false;
}
if (!server_id) {
MONGOC_ERROR ("mongoc_cursor_set_hint: cannot set server_id to 0");
return false;
}
cursor->server_id = server_id;
return true;
}
uint32_t
mongoc_cursor_get_hint (const mongoc_cursor_t *cursor)
{
BSON_ASSERT (cursor);
return cursor->server_id;
}
int64_t
mongoc_cursor_get_id (const mongoc_cursor_t *cursor)
{
BSON_ASSERT (cursor);
return cursor->cursor_id;
}
void
mongoc_cursor_set_max_await_time_ms (mongoc_cursor_t *cursor,
uint32_t max_await_time_ms)
{
BSON_ASSERT (cursor);
if (cursor->state == UNPRIMED) {
_mongoc_cursor_set_opt_int64 (
cursor, MONGOC_CURSOR_MAX_AWAIT_TIME_MS, (int64_t) max_await_time_ms);
}
}
uint32_t
mongoc_cursor_get_max_await_time_ms (const mongoc_cursor_t *cursor)
{
bson_iter_t iter;
BSON_ASSERT (cursor);
if (bson_iter_init_find (
&iter, &cursor->opts, MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) {
return (uint32_t) bson_iter_as_int64 (&iter);
}
return 0;
}
/* deprecated for mongoc_cursor_new_from_command_reply_with_opts */
mongoc_cursor_t *
mongoc_cursor_new_from_command_reply (mongoc_client_t *client,
bson_t *reply,
uint32_t server_id)
{
mongoc_cursor_t *cursor;
bson_t cmd = BSON_INITIALIZER;
bson_t opts = BSON_INITIALIZER;
BSON_ASSERT (client);
BSON_ASSERT (reply);
/* options are passed through by adding them to reply. */
bson_copy_to_excluding_noinit (reply,
&opts,
"cursor",
"ok",
"operationTime",
"$clusterTime",
"$gleStats",
NULL);
if (server_id) {
bson_append_int64 (&opts, "serverId", 8, server_id);
}
cursor = _mongoc_cursor_cmd_new_from_reply (client, &cmd, &opts, reply);
bson_destroy (&cmd);
bson_destroy (&opts);
return cursor;
}
mongoc_cursor_t *
mongoc_cursor_new_from_command_reply_with_opts (mongoc_client_t *client,
bson_t *reply,
const bson_t *opts)
{
mongoc_cursor_t *cursor;
bson_t cmd = BSON_INITIALIZER;
BSON_ASSERT (client);
BSON_ASSERT (reply);
cursor = _mongoc_cursor_cmd_new_from_reply (client, &cmd, opts, reply);
bson_destroy (&cmd);
return cursor;
}
bool
_mongoc_cursor_start_reading_response (mongoc_cursor_t *cursor,
mongoc_cursor_response_t *response)
{
bson_iter_t iter;
bson_iter_t child;
const char *ns;
uint32_t nslen;
bool in_batch = false;
if (bson_iter_init_find (&iter, &response->reply, "cursor") &&
BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child)) {
while (bson_iter_next (&child)) {
if (BSON_ITER_IS_KEY (&child, "id")) {
cursor->cursor_id = bson_iter_as_int64 (&child);
} else if (BSON_ITER_IS_KEY (&child, "ns")) {
ns = bson_iter_utf8 (&child, &nslen);
_mongoc_set_cursor_ns (cursor, ns, nslen);
} else if (BSON_ITER_IS_KEY (&child, "firstBatch") ||
BSON_ITER_IS_KEY (&child, "nextBatch")) {
if (BSON_ITER_HOLDS_ARRAY (&child) &&
bson_iter_recurse (&child, &response->batch_iter)) {
in_batch = true;
}
}
}
}
/* Driver Sessions Spec: "When an implicit session is associated with a
* cursor for use with getMore operations, the session MUST be returned to
* the pool immediately following a getMore operation that indicates that the
* cursor has been exhausted." */
if (cursor->cursor_id == 0 && cursor->client_session &&
!cursor->explicit_session) {
mongoc_client_session_destroy (cursor->client_session);
cursor->client_session = NULL;
}
return in_batch;
}
void
_mongoc_cursor_response_read (mongoc_cursor_t *cursor,
mongoc_cursor_response_t *response,
const bson_t **bson)
{
const uint8_t *data = NULL;
uint32_t data_len = 0;
ENTRY;
if (bson_iter_next (&response->batch_iter) &&
BSON_ITER_HOLDS_DOCUMENT (&response->batch_iter)) {
bson_iter_document (&response->batch_iter, &data_len, &data);
/* bson_iter_next guarantees valid BSON, so this must succeed */
BSON_ASSERT (bson_init_static (&response->current_doc, data, data_len));
*bson = &response->current_doc;
}
}
/* sets cursor error if could not get the next batch. */
void
_mongoc_cursor_response_refresh (mongoc_cursor_t *cursor,
const bson_t *command,
const bson_t *opts,
mongoc_cursor_response_t *response)
{
ENTRY;
bson_destroy (&response->reply);
/* server replies to find / aggregate with {cursor: {id: N, firstBatch: []}},
* to getMore command with {cursor: {id: N, nextBatch: []}}. */
if (_mongoc_cursor_run_command (
cursor, command, opts, &response->reply, false) &&
_mongoc_cursor_start_reading_response (cursor, response)) {
return;
}
if (!cursor->error.domain) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply to %s command.",
_mongoc_get_command_name (command));
}
}
void
_mongoc_cursor_prepare_getmore_command (mongoc_cursor_t *cursor,
bson_t *command)
{
const char *collection;
int collection_len;
int64_t batch_size;
bool await_data;
int64_t max_await_time_ms;
ENTRY;
_mongoc_cursor_collection (cursor, &collection, &collection_len);
bson_init (command);
bson_append_int64 (command, "getMore", 7, mongoc_cursor_get_id (cursor));
bson_append_utf8 (command, "collection", 10, collection, collection_len);
batch_size = mongoc_cursor_get_batch_size (cursor);
/* See find, getMore, and killCursors Spec for batchSize rules */
if (batch_size) {
bson_append_int64 (command,
MONGOC_CURSOR_BATCH_SIZE,
MONGOC_CURSOR_BATCH_SIZE_LEN,
abs (_mongoc_n_return (cursor)));
}
/* Find, getMore And killCursors Commands Spec: "In the case of a tailable
cursor with awaitData == true the driver MUST provide a Cursor level
option named maxAwaitTimeMS (See CRUD specification for details). The
maxTimeMS option on the getMore command MUST be set to the value of the
option maxAwaitTimeMS. If no maxAwaitTimeMS is specified, the driver
SHOULD not set maxTimeMS on the getMore command."
*/
await_data = _mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_TAILABLE) &&
_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_AWAIT_DATA);
if (await_data) {
max_await_time_ms = _mongoc_cursor_get_opt_int64 (
cursor, MONGOC_CURSOR_MAX_AWAIT_TIME_MS, 0);
if (max_await_time_ms) {
bson_append_int64 (command,
MONGOC_CURSOR_MAX_TIME_MS,
MONGOC_CURSOR_MAX_TIME_MS_LEN,
max_await_time_ms);
}
}
}
/* sets the cursor to be empty so it returns NULL on the first call to
* cursor_next but does not return an error. */
void
_mongoc_cursor_set_empty (mongoc_cursor_t *cursor)
{
memset (&cursor->error, 0, sizeof (bson_error_t));
bson_reinit (&cursor->error_doc);
cursor->state = IN_BATCH;
}
void
_mongoc_cursor_prime (mongoc_cursor_t *cursor)
{
cursor->state = cursor->impl.prime (cursor);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h
similarity index 94%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h
index ed364fbf..2fcb33a9 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h
@@ -1,75 +1,73 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CYRUS_PRIVATE_H
#define MONGOC_CYRUS_PRIVATE_H
#include "mongoc-uri.h"
#include "mongoc-cluster-private.h"
#include "mongoc-sasl-private.h"
#include <bson/bson.h>
#include <sasl/sasl.h>
-#include <sasl/saslutil.h>
BSON_BEGIN_DECLS
typedef struct _mongoc_cyrus_t mongoc_cyrus_t;
struct _mongoc_cyrus_t {
mongoc_sasl_t credentials;
sasl_callback_t callbacks[6];
sasl_conn_t *conn;
bool done;
int step;
sasl_interact_t *interact;
};
#ifndef SASL_CALLBACK_FN
#define SASL_CALLBACK_FN(_f) ((int (*) (void)) (_f))
#endif
void
_mongoc_cyrus_init (mongoc_cyrus_t *sasl);
bool
_mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl,
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
const char *hostname,
bson_error_t *error);
int
_mongoc_cyrus_log (mongoc_cyrus_t *sasl, int level, const char *message);
void
_mongoc_cyrus_destroy (mongoc_cyrus_t *sasl);
bool
_mongoc_cyrus_step (mongoc_cyrus_t *sasl,
const uint8_t *inbuf,
uint32_t inbuflen,
- uint8_t *outbuf,
- uint32_t outbufmax,
+ uint8_t **outbuf,
uint32_t *outbuflen,
bson_error_t *error);
BSON_END_DECLS
#endif /* MONGOC_CYRUS_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
similarity index 82%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
index 8699b61c..dba953d0 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
@@ -1,418 +1,468 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SASL_CYRUS
#include <string.h>
#include "mongoc-error.h"
#include "mongoc-cyrus-private.h"
#include "mongoc-util-private.h"
#include "mongoc-trace-private.h"
+#include "common-b64-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "CYRUS-SASL"
bool
_mongoc_cyrus_set_mechanism (mongoc_cyrus_t *sasl,
const char *mechanism,
bson_error_t *error)
{
bson_string_t *str = bson_string_new ("");
const char **mechs = sasl_global_listmech ();
int i = 0;
bool ok = false;
BSON_ASSERT (sasl);
for (i = 0; mechs[i]; i++) {
if (!strcmp (mechs[i], mechanism)) {
ok = true;
break;
}
bson_string_append (str, mechs[i]);
if (mechs[i + 1]) {
bson_string_append (str, ",");
}
}
if (ok) {
bson_free (sasl->credentials.mechanism);
sasl->credentials.mechanism = mechanism ? bson_strdup (mechanism) : NULL;
} else {
bson_set_error (error,
MONGOC_ERROR_SASL,
SASL_NOMECH,
"SASL Failure: Unsupported mechanism by client: %s. "
"Available mechanisms: %s",
mechanism,
str->str);
}
bson_string_free (str, true);
return ok;
}
static int
_mongoc_cyrus_get_pass (mongoc_cyrus_t *sasl,
int param_id,
const char **result,
unsigned *result_len)
{
BSON_ASSERT (sasl);
BSON_ASSERT (param_id == SASL_CB_PASS);
if (result) {
*result = sasl->credentials.pass;
}
if (result_len) {
*result_len = sasl->credentials.pass
? (unsigned) strlen (sasl->credentials.pass)
: 0;
}
return (sasl->credentials.pass != NULL) ? SASL_OK : SASL_FAIL;
}
static int
_mongoc_cyrus_canon_user (sasl_conn_t *conn,
mongoc_cyrus_t *sasl,
const char *in,
unsigned inlen,
unsigned flags,
const char *user_realm,
char *out,
unsigned out_max,
unsigned *out_len)
{
TRACE ("Canonicalizing %s (%" PRIu32 ")\n", in, inlen);
strcpy (out, in);
*out_len = inlen;
return SASL_OK;
}
static int
_mongoc_cyrus_get_user (mongoc_cyrus_t *sasl,
int param_id,
const char **result,
unsigned *result_len)
{
BSON_ASSERT (sasl);
BSON_ASSERT ((param_id == SASL_CB_USER) || (param_id == SASL_CB_AUTHNAME));
if (result) {
*result = sasl->credentials.user;
}
if (result_len) {
*result_len = sasl->credentials.user
? (unsigned) strlen (sasl->credentials.user)
: 0;
}
return (sasl->credentials.user != NULL) ? SASL_OK : SASL_FAIL;
}
void
_mongoc_cyrus_init (mongoc_cyrus_t *sasl)
{
sasl_callback_t callbacks[] = {
{SASL_CB_AUTHNAME, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl},
{SASL_CB_USER, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl},
{SASL_CB_PASS, SASL_CALLBACK_FN (_mongoc_cyrus_get_pass), sasl},
{SASL_CB_CANON_USER, SASL_CALLBACK_FN (_mongoc_cyrus_canon_user), sasl},
{SASL_CB_LIST_END}};
BSON_ASSERT (sasl);
memset (sasl, 0, sizeof *sasl);
memcpy (&sasl->callbacks, callbacks, sizeof callbacks);
sasl->done = false;
sasl->step = 0;
sasl->conn = NULL;
sasl->interact = NULL;
sasl->credentials.mechanism = NULL;
sasl->credentials.user = NULL;
sasl->credentials.pass = NULL;
sasl->credentials.service_name = NULL;
sasl->credentials.service_host = NULL;
}
bool
_mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl,
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
const char *hostname,
bson_error_t *error)
{
const char *mechanism;
char real_name[BSON_HOST_NAME_MAX + 1];
_mongoc_cyrus_init (sasl);
mechanism = mongoc_uri_get_auth_mechanism (cluster->uri);
if (!mechanism) {
mechanism = "GSSAPI";
}
if (!_mongoc_cyrus_set_mechanism (sasl, mechanism, error)) {
_mongoc_cyrus_destroy (sasl);
return false;
}
_mongoc_sasl_set_pass ((mongoc_sasl_t *) sasl,
mongoc_uri_get_password (cluster->uri));
_mongoc_sasl_set_user ((mongoc_sasl_t *) sasl,
mongoc_uri_get_username (cluster->uri));
_mongoc_sasl_set_properties ((mongoc_sasl_t *) sasl, cluster->uri);
/*
* If the URI requested canonicalizeHostname, we need to resolve the real
* hostname for the IP Address and pass that to the SASL layer. Some
* underlying GSSAPI layers will do this for us, but can be disabled in
* their config (krb.conf).
*
* This allows the consumer to specify canonicalizeHostname=true in the URI
* and have us do that for them.
*
* See CDRIVER-323 for more information.
*/
if (sasl->credentials.canonicalize_host_name &&
_mongoc_sasl_get_canonicalized_name (
stream, real_name, sizeof real_name)) {
_mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, real_name);
} else {
_mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, hostname);
}
return true;
}
void
_mongoc_cyrus_destroy (mongoc_cyrus_t *sasl)
{
BSON_ASSERT (sasl);
if (sasl->conn) {
sasl_dispose (&sasl->conn);
}
bson_free (sasl->credentials.user);
bson_free (sasl->credentials.pass);
bson_free (sasl->credentials.mechanism);
bson_free (sasl->credentials.service_name);
bson_free (sasl->credentials.service_host);
}
static bool
_mongoc_cyrus_is_failure (int status, bson_error_t *error)
{
bool ret = (status < 0);
TRACE ("Got status: %d ok is %d, continue=%d interact=%d\n",
status,
SASL_OK,
SASL_CONTINUE,
SASL_INTERACT);
if (ret) {
switch (status) {
case SASL_NOMEM:
bson_set_error (error,
MONGOC_ERROR_SASL,
status,
"SASL Failure: insufficient memory.");
break;
case SASL_NOMECH: {
bson_string_t *str = bson_string_new ("available mechanisms: ");
const char **mechs = sasl_global_listmech ();
int i = 0;
for (i = 0; mechs[i]; i++) {
bson_string_append (str, mechs[i]);
if (mechs[i + 1]) {
bson_string_append (str, ",");
}
}
bson_set_error (error,
MONGOC_ERROR_SASL,
status,
"SASL Failure: failure to negotiate mechanism (%s)",
str->str);
bson_string_free (str, 0);
} break;
case SASL_BADPARAM:
bson_set_error (error,
MONGOC_ERROR_SASL,
status,
"Bad parameter supplied. Please file a bug "
"with mongo-c-driver.");
break;
default:
bson_set_error (error,
MONGOC_ERROR_SASL,
status,
"SASL Failure: (%d): %s",
status,
sasl_errstring (status, NULL, NULL));
break;
}
}
return ret;
}
static bool
_mongoc_cyrus_start (mongoc_cyrus_t *sasl,
- uint8_t *outbuf,
- uint32_t outbufmax,
+ uint8_t **outbuf,
uint32_t *outbuflen,
bson_error_t *error)
{
const char *service_name = "mongodb";
const char *service_host = "";
const char *mechanism = NULL;
const char *raw = NULL;
unsigned raw_len = 0;
int status;
+ int b64_ret;
+ int outbuf_capacity;
BSON_ASSERT (sasl);
BSON_ASSERT (outbuf);
- BSON_ASSERT (outbufmax);
BSON_ASSERT (outbuflen);
if (sasl->credentials.service_name) {
service_name = sasl->credentials.service_name;
}
if (sasl->credentials.service_host) {
service_host = sasl->credentials.service_host;
}
status = sasl_client_new (
service_name, service_host, NULL, NULL, sasl->callbacks, 0, &sasl->conn);
TRACE ("Created new sasl client %s",
status == SASL_OK ? "successfully" : "UNSUCCESSFULLY");
if (_mongoc_cyrus_is_failure (status, error)) {
return false;
}
status = sasl_client_start (sasl->conn,
sasl->credentials.mechanism,
&sasl->interact,
&raw,
&raw_len,
&mechanism);
TRACE ("Started the sasl client %s",
status == SASL_CONTINUE ? "successfully" : "UNSUCCESSFULLY");
if (_mongoc_cyrus_is_failure (status, error)) {
return false;
}
if ((0 != strcasecmp (mechanism, "GSSAPI")) &&
(0 != strcasecmp (mechanism, "PLAIN"))) {
bson_set_error (error,
MONGOC_ERROR_SASL,
SASL_NOMECH,
"SASL Failure: invalid mechanism \"%s\"",
mechanism);
return false;
}
+ *outbuflen = 0;
+ outbuf_capacity =
+ COMMON_PREFIX (bson_b64_ntop_calculate_target_size (raw_len));
+ *outbuf = bson_malloc (outbuf_capacity);
- status = sasl_encode64 (raw, raw_len, (char *) outbuf, outbufmax, outbuflen);
- if (_mongoc_cyrus_is_failure (status, error)) {
+ b64_ret = COMMON_PREFIX (bson_b64_ntop) (
+ (uint8_t *) raw, raw_len, (char *) *outbuf, outbuf_capacity);
+ if (b64_ret == -1) {
+ bson_set_error (error,
+ MONGOC_ERROR_SASL,
+ MONGOC_ERROR_CLIENT_AUTHENTICATE,
+ "Unable to base64 encode client SASL message");
return false;
+ } else {
+ *outbuflen = b64_ret;
}
return true;
}
bool
_mongoc_cyrus_step (mongoc_cyrus_t *sasl,
const uint8_t *inbuf,
uint32_t inbuflen,
- uint8_t *outbuf,
- uint32_t outbufmax,
+ uint8_t **outbuf,
uint32_t *outbuflen,
bson_error_t *error)
{
const char *raw = NULL;
unsigned rawlen = 0;
int status;
+ char *decoded; /* post base64 decoded data */
+ uint32_t decoded_len;
+ uint32_t decoded_capacity;
+ uint32_t outbuf_capacity;
+ int b64_ret;
BSON_ASSERT (sasl);
- BSON_ASSERT (inbuf);
+ if (sasl->step > 1) {
+ BSON_ASSERT (inbuf);
+ }
BSON_ASSERT (outbuf);
BSON_ASSERT (outbuflen);
TRACE ("Running %d, inbuflen: %" PRIu32, sasl->step, inbuflen);
sasl->step++;
if (sasl->step == 1) {
- return _mongoc_cyrus_start (sasl, outbuf, outbufmax, outbuflen, error);
+ return _mongoc_cyrus_start (sasl, outbuf, outbuflen, error);
} else if (sasl->step >= 10) {
bson_set_error (error,
MONGOC_ERROR_SASL,
SASL_NOTDONE,
"SASL Failure: maximum steps detected");
return false;
}
TRACE ("Running %d, inbuflen: %" PRIu32, sasl->step, inbuflen);
if (!inbuflen) {
bson_set_error (error,
MONGOC_ERROR_SASL,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"SASL Failure: no payload provided from server: %s",
sasl_errdetail (sasl->conn));
return false;
}
- status = sasl_decode64 (
- (char *) inbuf, inbuflen, (char *) outbuf, outbufmax, outbuflen);
- if (_mongoc_cyrus_is_failure (status, error)) {
+ decoded_len = 0;
+ decoded_capacity =
+ COMMON_PREFIX (bson_b64_pton_calculate_target_size) (inbuflen);
+ decoded = bson_malloc (decoded_capacity);
+ b64_ret = COMMON_PREFIX (bson_b64_pton) (
+ (char *) inbuf, (uint8_t *) decoded, decoded_capacity);
+ if (b64_ret == -1) {
+ bson_set_error (error,
+ MONGOC_ERROR_SASL,
+ MONGOC_ERROR_CLIENT_AUTHENTICATE,
+ "Unable to base64 decode client SASL message");
+ bson_free (decoded);
+ bson_free (*outbuf);
+ *outbuf = NULL;
return false;
+ } else {
+ /* Set the output length to the number of bytes actually decoded to
+ * excluding the NULL. */
+ decoded_len = b64_ret;
}
TRACE ("%s", "Running client_step");
status = sasl_client_step (
- sasl->conn, (char *) outbuf, *outbuflen, &sasl->interact, &raw, &rawlen);
+ sasl->conn, decoded, decoded_len, &sasl->interact, &raw, &rawlen);
TRACE ("%s sent a client step",
status == SASL_OK ? "Successfully" : "UNSUCCESSFULLY");
if (_mongoc_cyrus_is_failure (status, error)) {
+ bson_free (decoded);
return false;
}
- status = sasl_encode64 (raw, rawlen, (char *) outbuf, outbufmax, outbuflen);
- if (_mongoc_cyrus_is_failure (status, error)) {
+ *outbuflen = 0;
+ outbuf_capacity = COMMON_PREFIX (bson_b64_ntop_calculate_target_size (rawlen));
+ *outbuf = bson_malloc0 (outbuf_capacity);
+ b64_ret = COMMON_PREFIX (bson_b64_ntop) (
+ (const uint8_t *) raw, rawlen, (char *) *outbuf, outbuf_capacity);
+ if (b64_ret == -1) {
+ bson_set_error (error,
+ MONGOC_ERROR_SASL,
+ MONGOC_ERROR_CLIENT_AUTHENTICATE,
+ "Unable to base64 encode client SASL message");
+ bson_free (decoded);
+ bson_free (*outbuf);
+ *outbuf = NULL;
return false;
+ } else {
+ /* Set the output length to the number of characters written excluding the
+ * NULL. */
+ *outbuflen = b64_ret;
}
+ bson_free (decoded);
return true;
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
index 8597b070..c19cf8cf 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
@@ -1,51 +1,51 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_DATABASE_PRIVATE_H
#define MONGOC_DATABASE_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-read-prefs.h"
#include "mongoc-read-concern.h"
#include "mongoc-write-concern.h"
BSON_BEGIN_DECLS
struct _mongoc_database_t {
mongoc_client_t *client;
- char name[128];
+ char *name;
mongoc_read_prefs_t *read_prefs;
mongoc_read_concern_t *read_concern;
mongoc_write_concern_t *write_concern;
};
mongoc_database_t *
_mongoc_database_new (mongoc_client_t *client,
const char *name,
const mongoc_read_prefs_t *read_prefs,
const mongoc_read_concern_t *read_concern,
const mongoc_write_concern_t *write_concern);
BSON_END_DECLS
#endif /* MONGOC_DATABASE_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
index f0aa1c40..17829b1a 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
@@ -1,1027 +1,1031 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-aggregate-private.h"
#include "mongoc-client-private.h"
#include "mongoc-collection.h"
#include "mongoc-collection-private.h"
#include "mongoc-cursor.h"
#include "mongoc-cursor-private.h"
#include "mongoc-database.h"
#include "mongoc-database-private.h"
#include "mongoc-error.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-change-stream-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "database"
/*
*--------------------------------------------------------------------------
*
* _mongoc_database_new --
*
* Create a new instance of mongoc_database_t for @client.
*
* @client must stay valid for the life of the resulting
* database structure.
*
* Returns:
* A newly allocated mongoc_database_t that should be freed with
* mongoc_database_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_database_t *
_mongoc_database_new (mongoc_client_t *client,
const char *name,
const mongoc_read_prefs_t *read_prefs,
const mongoc_read_concern_t *read_concern,
const mongoc_write_concern_t *write_concern)
{
mongoc_database_t *db;
ENTRY;
- BSON_ASSERT (client);
- BSON_ASSERT (name);
+ BSON_ASSERT_PARAM (client);
+ BSON_ASSERT_PARAM (name);
db = (mongoc_database_t *) bson_malloc0 (sizeof *db);
db->client = client;
db->write_concern = write_concern ? mongoc_write_concern_copy (write_concern)
: mongoc_write_concern_new ();
db->read_concern = read_concern ? mongoc_read_concern_copy (read_concern)
: mongoc_read_concern_new ();
db->read_prefs = read_prefs ? mongoc_read_prefs_copy (read_prefs)
: mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
- bson_strncpy (db->name, name, sizeof db->name);
+ db->name = bson_strdup (name);
RETURN (db);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_destroy --
*
* Releases resources associated with @database.
*
* Returns:
* None.
*
* Side effects:
* Everything.
*
*--------------------------------------------------------------------------
*/
void
mongoc_database_destroy (mongoc_database_t *database)
{
ENTRY;
if (!database) {
EXIT;
}
if (database->read_prefs) {
mongoc_read_prefs_destroy (database->read_prefs);
database->read_prefs = NULL;
}
if (database->read_concern) {
mongoc_read_concern_destroy (database->read_concern);
database->read_concern = NULL;
}
if (database->write_concern) {
mongoc_write_concern_destroy (database->write_concern);
database->write_concern = NULL;
}
+ bson_free (database->name);
bson_free (database);
EXIT;
}
mongoc_cursor_t *
mongoc_database_aggregate (mongoc_database_t *db, /* IN */
const bson_t *pipeline, /* IN */
const bson_t *opts, /* IN */
const mongoc_read_prefs_t *read_prefs) /* IN */
{
return _mongoc_aggregate (db->client,
db->name,
MONGOC_QUERY_NONE,
pipeline,
opts,
read_prefs,
db->read_prefs,
db->read_concern,
db->write_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_copy --
*
* Returns a copy of @database that needs to be freed by calling
* mongoc_database_destroy.
*
* Returns:
* A copy of this database.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_database_t *
mongoc_database_copy (mongoc_database_t *database)
{
ENTRY;
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
RETURN (_mongoc_database_new (database->client,
database->name,
database->read_prefs,
database->read_concern,
database->write_concern));
}
mongoc_cursor_t *
mongoc_database_command (mongoc_database_t *database,
mongoc_query_flags_t flags,
uint32_t skip,
uint32_t limit,
uint32_t batch_size,
const bson_t *command,
const bson_t *fields,
const mongoc_read_prefs_t *read_prefs)
{
- char ns[MONGOC_NAMESPACE_MAX];
+ char *ns;
+ mongoc_cursor_t *cursor;
- BSON_ASSERT (database);
- BSON_ASSERT (command);
+ BSON_ASSERT_PARAM (database);
+ BSON_ASSERT_PARAM (command);
- bson_snprintf (ns, sizeof ns, "%s.$cmd", database->name);
+ ns = bson_strdup_printf ("%s.$cmd", database->name);
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
/* flags, skip, limit, batch_size, fields are unused */
- return _mongoc_cursor_cmd_deprecated_new (
+ cursor = _mongoc_cursor_cmd_deprecated_new (
database->client, ns, command, read_prefs);
+ bson_free (ns);
+ return cursor;
}
bool
mongoc_database_command_simple (mongoc_database_t *database,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
- BSON_ASSERT (database);
- BSON_ASSERT (command);
+ BSON_ASSERT_PARAM (database);
+ BSON_ASSERT_PARAM (command);
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_RAW,
NULL /* opts */,
MONGOC_QUERY_NONE,
read_prefs,
NULL, /* user prefs */
NULL /* read concern */,
NULL /* write concern */,
reply,
error);
}
bool
mongoc_database_read_command_with_opts (mongoc_database_t *database,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_READ,
opts,
MONGOC_QUERY_NONE,
read_prefs,
database->read_prefs,
database->read_concern,
database->write_concern,
reply,
error);
}
bool
mongoc_database_write_command_with_opts (mongoc_database_t *database,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
database->read_prefs,
database->read_concern,
database->write_concern,
reply,
error);
}
bool
mongoc_database_read_write_command_with_opts (
mongoc_database_t *database,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs /* IGNORED */,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_RW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
database->read_prefs,
database->read_concern,
database->write_concern,
reply,
error);
}
bool
mongoc_database_command_with_opts (mongoc_database_t *database,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_RAW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
NULL, /* default prefs */
database->read_concern,
database->write_concern,
reply,
error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_drop --
*
* Requests that the MongoDB server drops @database, including all
* collections and indexes associated with @database.
*
* Make sure this is really what you want!
*
* Returns:
* true if @database was dropped.
*
* Side effects:
* @error may be set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_database_drop (mongoc_database_t *database, bson_error_t *error)
{
return mongoc_database_drop_with_opts (database, NULL, error);
}
bool
mongoc_database_drop_with_opts (mongoc_database_t *database,
const bson_t *opts,
bson_error_t *error)
{
bool ret;
bson_t cmd;
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
bson_init (&cmd);
bson_append_int32 (&cmd, "dropDatabase", 12, 1);
ret = _mongoc_client_command_with_opts (database->client,
database->name,
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
database->read_prefs,
database->read_concern,
database->write_concern,
NULL, /* reply */
error);
bson_destroy (&cmd);
return ret;
}
bool
mongoc_database_remove_user (mongoc_database_t *database,
const char *username,
bson_error_t *error)
{
bson_t cmd;
bool ret;
ENTRY;
- BSON_ASSERT (database);
- BSON_ASSERT (username);
+ BSON_ASSERT_PARAM (database);
+ BSON_ASSERT_PARAM (username);
bson_init (&cmd);
BSON_APPEND_UTF8 (&cmd, "dropUser", username);
ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error);
bson_destroy (&cmd);
RETURN (ret);
}
bool
mongoc_database_remove_all_users (mongoc_database_t *database,
bson_error_t *error)
{
bson_t cmd;
bool ret;
ENTRY;
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
bson_init (&cmd);
BSON_APPEND_INT32 (&cmd, "dropAllUsersFromDatabase", 1);
ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error);
bson_destroy (&cmd);
RETURN (ret);
}
/**
* mongoc_database_add_user:
* @database: A #mongoc_database_t.
* @username: A string containing the username.
* @password: (allow-none): A string containing password, or NULL.
* @roles: (allow-none): An optional bson_t of roles.
* @custom_data: (allow-none): An optional bson_t of data to store.
* @error: (out) (allow-none): A location for a bson_error_t or %NULL.
*
* Creates a new user with access to @database.
*
* Returns: None.
* Side effects: None.
*/
bool
mongoc_database_add_user (mongoc_database_t *database,
const char *username,
const char *password,
const bson_t *roles,
const bson_t *custom_data,
bson_error_t *error)
{
bson_t cmd;
bson_t ar;
bool ret = false;
ENTRY;
- BSON_ASSERT (database);
- BSON_ASSERT (username);
+ BSON_ASSERT_PARAM (database);
+ BSON_ASSERT_PARAM (username);
bson_init (&cmd);
BSON_APPEND_UTF8 (&cmd, "createUser", username);
BSON_APPEND_UTF8 (&cmd, "pwd", password);
if (custom_data) {
BSON_APPEND_DOCUMENT (&cmd, "customData", custom_data);
}
if (roles) {
BSON_APPEND_ARRAY (&cmd, "roles", roles);
} else {
bson_append_array_begin (&cmd, "roles", 5, &ar);
bson_append_array_end (&cmd, &ar);
}
ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error);
bson_destroy (&cmd);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_get_read_prefs --
*
* Fetch the read preferences for @database.
*
* Returns:
* A mongoc_read_prefs_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_prefs_t *
mongoc_database_get_read_prefs (const mongoc_database_t *database) /* IN */
{
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
return database->read_prefs;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_set_read_prefs --
*
* Sets the default read preferences for @database.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_database_set_read_prefs (mongoc_database_t *database,
const mongoc_read_prefs_t *read_prefs)
{
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
if (database->read_prefs) {
mongoc_read_prefs_destroy (database->read_prefs);
database->read_prefs = NULL;
}
if (read_prefs) {
database->read_prefs = mongoc_read_prefs_copy (read_prefs);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_get_read_concern --
*
* Fetches the read concern for @database.
*
* Returns:
* A mongoc_read_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_concern_t *
mongoc_database_get_read_concern (const mongoc_database_t *database)
{
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
return database->read_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_set_read_concern --
*
* Set the default read concern for @database.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_database_set_read_concern (mongoc_database_t *database,
const mongoc_read_concern_t *read_concern)
{
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
if (database->read_concern) {
mongoc_read_concern_destroy (database->read_concern);
database->read_concern = NULL;
}
if (read_concern) {
database->read_concern = mongoc_read_concern_copy (read_concern);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_get_write_concern --
*
* Fetches the write concern for @database.
*
* Returns:
* A mongoc_write_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_write_concern_t *
mongoc_database_get_write_concern (const mongoc_database_t *database)
{
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
return database->write_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_set_write_concern --
*
* Set the default write concern for @database.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_database_set_write_concern (mongoc_database_t *database,
const mongoc_write_concern_t *write_concern)
{
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
if (database->write_concern) {
mongoc_write_concern_destroy (database->write_concern);
database->write_concern = NULL;
}
if (write_concern) {
database->write_concern = mongoc_write_concern_copy (write_concern);
}
}
/**
* mongoc_database_has_collection:
* @database: (in): A #mongoc_database_t.
* @name: (in): The name of the collection to check for.
* @error: (out) (allow-none): A location for a #bson_error_t, or %NULL.
*
* Checks to see if a collection exists within the database on the MongoDB
* server.
*
* This will return %false if their was an error communicating with the
* server, or if the collection does not exist.
*
* If @error is provided, it will first be zeroed. Upon error, error.domain
* will be set.
*
* Returns: %true if @name exists, otherwise %false. @error may be set.
*/
bool
mongoc_database_has_collection (mongoc_database_t *database,
const char *name,
bson_error_t *error)
{
bson_iter_t col_iter;
bool ret = false;
const char *cur_name;
bson_t opts = BSON_INITIALIZER;
bson_t filter;
mongoc_cursor_t *cursor;
const bson_t *doc;
ENTRY;
- BSON_ASSERT (database);
- BSON_ASSERT (name);
+ BSON_ASSERT_PARAM (database);
+ BSON_ASSERT_PARAM (name);
if (error) {
memset (error, 0, sizeof *error);
}
BSON_APPEND_DOCUMENT_BEGIN (&opts, "filter", &filter);
BSON_APPEND_UTF8 (&filter, "name", name);
bson_append_document_end (&opts, &filter);
cursor = mongoc_database_find_collections_with_opts (database, &opts);
while (mongoc_cursor_next (cursor, &doc)) {
if (bson_iter_init (&col_iter, doc) &&
bson_iter_find (&col_iter, "name") &&
BSON_ITER_HOLDS_UTF8 (&col_iter) &&
(cur_name = bson_iter_utf8 (&col_iter, NULL))) {
if (!strcmp (cur_name, name)) {
ret = true;
GOTO (cleanup);
}
}
}
(void) mongoc_cursor_error (cursor, error);
cleanup:
mongoc_cursor_destroy (cursor);
bson_destroy (&opts);
RETURN (ret);
}
mongoc_cursor_t *
mongoc_database_find_collections (mongoc_database_t *database,
const bson_t *filter,
bson_error_t *error)
{
bson_t opts = BSON_INITIALIZER;
mongoc_cursor_t *cursor;
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
if (filter) {
if (!BSON_APPEND_DOCUMENT (&opts, "filter", filter)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'filter' parameter.");
bson_destroy (&opts);
return NULL;
}
}
cursor = mongoc_database_find_collections_with_opts (database, &opts);
bson_destroy (&opts);
/* this deprecated API returns NULL on error */
if (mongoc_cursor_error (cursor, error)) {
mongoc_cursor_destroy (cursor);
return NULL;
}
return cursor;
}
mongoc_cursor_t *
mongoc_database_find_collections_with_opts (mongoc_database_t *database,
const bson_t *opts)
{
mongoc_cursor_t *cursor;
bson_t cmd = BSON_INITIALIZER;
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
BSON_APPEND_INT32 (&cmd, "listCollections", 1);
/* Enumerate Collections Spec: "run listCollections on the primary node in
* replicaset mode" */
cursor = _mongoc_cursor_cmd_new (
database->client, database->name, &cmd, opts, NULL, NULL, NULL);
if (cursor->error.domain == 0) {
_mongoc_cursor_prime (cursor);
}
bson_destroy (&cmd);
return cursor;
}
char **
mongoc_database_get_collection_names (mongoc_database_t *database,
bson_error_t *error)
{
return mongoc_database_get_collection_names_with_opts (
database, NULL, error);
}
char **
mongoc_database_get_collection_names_with_opts (mongoc_database_t *database,
const bson_t *opts,
bson_error_t *error)
{
bson_t opts_copy;
bson_iter_t col;
const char *name;
char *namecopy;
mongoc_array_t strv_buf;
mongoc_cursor_t *cursor;
const bson_t *doc;
char **ret;
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
if (opts) {
bson_copy_to (opts, &opts_copy);
} else {
bson_init (&opts_copy);
}
/* nameOnly option is faster in MongoDB 4+, ignored by older versions,
* see Enumerating Collections Spec */
if (!bson_has_field (&opts_copy, "nameOnly")) {
bson_append_bool (&opts_copy, "nameOnly", 8, true);
}
cursor = mongoc_database_find_collections_with_opts (database, &opts_copy);
_mongoc_array_init (&strv_buf, sizeof (char *));
while (mongoc_cursor_next (cursor, &doc)) {
if (bson_iter_init (&col, doc) && bson_iter_find (&col, "name") &&
BSON_ITER_HOLDS_UTF8 (&col) && (name = bson_iter_utf8 (&col, NULL))) {
namecopy = bson_strdup (name);
_mongoc_array_append_val (&strv_buf, namecopy);
}
}
/* append a null pointer for the last value. also handles the case
* of no values. */
namecopy = NULL;
_mongoc_array_append_val (&strv_buf, namecopy);
if (mongoc_cursor_error (cursor, error)) {
_mongoc_array_destroy (&strv_buf);
ret = NULL;
} else {
ret = (char **) strv_buf.data;
}
mongoc_cursor_destroy (cursor);
bson_destroy (&opts_copy);
return ret;
}
mongoc_collection_t *
mongoc_database_create_collection (mongoc_database_t *database,
const char *name,
const bson_t *opts,
bson_error_t *error)
{
mongoc_collection_t *collection = NULL;
bson_iter_t iter;
bson_t cmd;
bool capped = false;
- BSON_ASSERT (database);
- BSON_ASSERT (name);
+ BSON_ASSERT_PARAM (database);
+ BSON_ASSERT_PARAM (name);
if (strchr (name, '$')) {
bson_set_error (error,
MONGOC_ERROR_NAMESPACE,
MONGOC_ERROR_NAMESPACE_INVALID,
"The namespace \"%s\" is invalid.",
name);
return NULL;
}
if (opts) {
if (bson_iter_init_find (&iter, opts, "capped")) {
if (!BSON_ITER_HOLDS_BOOL (&iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The argument \"capped\" must be a boolean.");
return NULL;
}
capped = bson_iter_bool (&iter);
}
if (bson_iter_init_find (&iter, opts, "size")) {
if (!BSON_ITER_HOLDS_INT (&iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The argument \"size\" must be an integer.");
return NULL;
}
if (!capped) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"size\" parameter requires {\"capped\": true}");
return NULL;
}
}
if (bson_iter_init_find (&iter, opts, "max")) {
if (!BSON_ITER_HOLDS_INT (&iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The argument \"max\" must be an integer.");
return NULL;
}
if (!capped) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"max\" parameter requires {\"capped\": true}");
return NULL;
}
}
if (bson_iter_init_find (&iter, opts, "storageEngine")) {
if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"storageEngine\" parameter must be a document");
return NULL;
}
if (bson_iter_find (&iter, "wiredTiger")) {
if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"wiredTiger\" option must take a document "
"argument with a \"configString\" field");
return NULL;
}
if (bson_iter_find (&iter, "configString")) {
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"configString\" parameter must be a string");
return NULL;
}
} else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"wiredTiger\" option must take a document "
"argument with a \"configString\" field");
return NULL;
}
}
}
}
bson_init (&cmd);
BSON_APPEND_UTF8 (&cmd, "create", name);
if (_mongoc_client_command_with_opts (database->client,
database->name,
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
database->read_prefs,
database->read_concern,
database->write_concern,
NULL, /* reply */
error)) {
collection = _mongoc_collection_new (database->client,
database->name,
name,
database->read_prefs,
database->read_concern,
database->write_concern);
}
bson_destroy (&cmd);
return collection;
}
mongoc_collection_t *
mongoc_database_get_collection (mongoc_database_t *database,
const char *collection)
{
- BSON_ASSERT (database);
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (database);
+ BSON_ASSERT_PARAM (collection);
return _mongoc_collection_new (database->client,
database->name,
collection,
database->read_prefs,
database->read_concern,
database->write_concern);
}
const char *
mongoc_database_get_name (mongoc_database_t *database)
{
- BSON_ASSERT (database);
+ BSON_ASSERT_PARAM (database);
return database->name;
}
mongoc_change_stream_t *
mongoc_database_watch (const mongoc_database_t *db,
const bson_t *pipeline,
const bson_t *opts)
{
return _mongoc_change_stream_new_from_database (db, pipeline, opts);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
new file mode 100644
index 00000000..3e2a8172
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#include "mongoc-prelude.h"
+
+#include <bson/bson.h>
+#include <stddef.h>
+
+BSON_BEGIN_DECLS
+
+typedef enum {
+ MONGOC_READ_ERR_NONE,
+ MONGOC_READ_ERR_OTHER,
+ MONGOC_READ_ERR_RETRY
+} mongoc_read_err_type_t;
+
+/* Server error codes libmongoc cares about. Compare with:
+ * https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.yml
+ */
+typedef enum {
+ MONGOC_SERVER_ERR_HOSTUNREACHABLE = 6,
+ MONGOC_SERVER_ERR_HOSTNOTFOUND = 7,
+ MONGOC_SERVER_ERR_CURSOR_NOT_FOUND = 43,
+ MONGOC_SERVER_ERR_STALESHARDVERSION = 63,
+ MONGOC_SERVER_ERR_NETWORKTIMEOUT = 89,
+ MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS = 91,
+ MONGOC_SERVER_ERR_FAILEDTOSATISFYREADPREFERENCE = 133,
+ MONGOC_SERVER_ERR_STALEEPOCH = 150,
+ MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN = 189,
+ MONGOC_SERVER_ERR_ELECTIONINPROGRESS = 216,
+ MONGOC_SERVER_ERR_RETRYCHANGESTREAM = 234,
+ MONGOC_SERVER_ERR_EXCEEDEDTIMELIMIT = 262,
+ MONGOC_SERVER_ERR_SOCKETEXCEPTION = 9001,
+ MONGOC_SERVER_ERR_NOTMASTER = 10107,
+ MONGOC_SERVER_ERR_INTERRUPTEDATSHUTDOWN = 11600,
+ MONGOC_SERVER_ERR_INTERRUPTEDDUETOREPLSTATECHANGE = 11602,
+ MONGOC_SERVER_ERR_STALECONFIG = 13388,
+ MONGOC_SERVER_ERR_NOTMASTERNOSLAVEOK = 13435,
+ MONGOC_SERVER_ERR_NOTMASTERORSECONDARY = 13436
+} mongoc_server_err_t;
+
+mongoc_read_err_type_t
+_mongoc_read_error_get_type (bool cmd_ret,
+ const bson_error_t *cmd_err,
+ const bson_t *reply);
+
+void
+_mongoc_error_copy_labels_and_upsert (const bson_t *src,
+ bson_t *dst,
+ char *label);
+
+void
+_mongoc_write_error_handle_labels (bool cmd_ret,
+ const bson_error_t *cmd_err,
+ bson_t *reply,
+ int32_t server_max_wire_version);
+
+bool
+_mongoc_error_is_shutdown (bson_error_t *error);
+
+bool
+_mongoc_error_is_recovering (bson_error_t *error);
+
+bool
+_mongoc_error_is_not_master (bson_error_t *error);
+
+bool
+_mongoc_error_is_state_change (bson_error_t *error);
+
+bool
+_mongoc_error_is_network (const bson_error_t *error);
+
+BSON_END_DECLS
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c
new file mode 100644
index 00000000..411067aa
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2018-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
+ *
+ * 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.
+ */
+
+#include <bson/bson.h>
+
+#include "mongoc-error.h"
+#include "mongoc-error-private.h"
+#include "mongoc-rpc-private.h"
+#include "mongoc-client-private.h"
+
+bool
+mongoc_error_has_label (const bson_t *reply, const char *label)
+{
+ bson_iter_t iter;
+ bson_iter_t error_labels;
+
+ BSON_ASSERT (reply);
+ BSON_ASSERT (label);
+
+ if (bson_iter_init_find (&iter, reply, "errorLabels") &&
+ bson_iter_recurse (&iter, &error_labels)) {
+ while (bson_iter_next (&error_labels)) {
+ if (BSON_ITER_HOLDS_UTF8 (&error_labels) &&
+ !strcmp (bson_iter_utf8 (&error_labels, NULL), label)) {
+ return true;
+ }
+ }
+ }
+
+ if (!bson_iter_init_find (&iter, reply, "writeConcernError")) {
+ return false;
+ }
+
+ BSON_ASSERT (bson_iter_recurse (&iter, &iter));
+
+ if (bson_iter_find (&iter, "errorLabels") &&
+ bson_iter_recurse (&iter, &error_labels)) {
+ while (bson_iter_next (&error_labels)) {
+ if (BSON_ITER_HOLDS_UTF8 (&error_labels) &&
+ !strcmp (bson_iter_utf8 (&error_labels, NULL), label)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool
+_mongoc_error_is_server (bson_error_t *error)
+{
+ if (!error) {
+ return false;
+ }
+
+ return error->domain == MONGOC_ERROR_SERVER ||
+ error->domain == MONGOC_ERROR_WRITE_CONCERN;
+}
+
+static bool
+_mongoc_write_error_is_retryable (bson_error_t *error)
+{
+ if (!_mongoc_error_is_server (error)) {
+ return false;
+ }
+
+ switch (error->code) {
+ case MONGOC_SERVER_ERR_HOSTUNREACHABLE:
+ case MONGOC_SERVER_ERR_HOSTNOTFOUND:
+ case MONGOC_SERVER_ERR_NETWORKTIMEOUT:
+ case MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS:
+ case MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN:
+ case MONGOC_SERVER_ERR_EXCEEDEDTIMELIMIT:
+ case MONGOC_SERVER_ERR_SOCKETEXCEPTION:
+ case MONGOC_SERVER_ERR_NOTMASTER:
+ case MONGOC_SERVER_ERR_INTERRUPTEDATSHUTDOWN:
+ case MONGOC_SERVER_ERR_INTERRUPTEDDUETOREPLSTATECHANGE:
+ case MONGOC_SERVER_ERR_NOTMASTERNOSLAVEOK:
+ case MONGOC_SERVER_ERR_NOTMASTERORSECONDARY:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void
+_mongoc_write_error_append_retryable_label (bson_t *reply)
+{
+ bson_t reply_local = BSON_INITIALIZER;
+
+ if (!reply) {
+ bson_destroy (&reply_local);
+ return;
+ }
+
+ bson_copy_to_excluding_noinit (reply, &reply_local, "errorLabels", NULL);
+ _mongoc_error_copy_labels_and_upsert (
+ reply, &reply_local, RETRYABLE_WRITE_ERROR);
+
+ bson_destroy (reply);
+ bson_steal (reply, &reply_local);
+}
+
+void
+_mongoc_write_error_handle_labels (bool cmd_ret,
+ const bson_error_t *cmd_err,
+ bson_t *reply,
+ int32_t server_max_wire_version)
+{
+ bson_error_t error;
+
+ /* check for a client error. */
+ if (!cmd_ret && _mongoc_error_is_network (cmd_err)) {
+ /* Retryable writes spec: When the driver encounters a network error
+ * communicating with any server version that supports retryable
+ * writes, it MUST add a RetryableWriteError label to that error. */
+ _mongoc_write_error_append_retryable_label (reply);
+ return;
+ }
+
+ if (server_max_wire_version >= WIRE_VERSION_RETRYABLE_WRITE_ERROR_LABEL) {
+ return;
+ }
+
+ /* check for a server error. */
+ if (_mongoc_cmd_check_ok_no_wce (
+ reply, MONGOC_ERROR_API_VERSION_2, &error)) {
+ return;
+ }
+
+ if (_mongoc_write_error_is_retryable (&error)) {
+ _mongoc_write_error_append_retryable_label (reply);
+ }
+}
+
+
+/*--------------------------------------------------------------------------
+ *
+ * _mongoc_read_error_get_type --
+ *
+ * Checks if the error or reply from a read command is considered
+ * retryable according to the retryable reads spec. Checks both
+ * for a client error (a network exception) and a server error in
+ * the reply. @cmd_ret and @cmd_err come from the result of a
+ * read_command function.
+ *
+ *
+ * Return:
+ * A mongoc_read_error_type_t indicating the type of error (if any).
+ *
+ *--------------------------------------------------------------------------
+ */
+mongoc_read_err_type_t
+_mongoc_read_error_get_type (bool cmd_ret,
+ const bson_error_t *cmd_err,
+ const bson_t *reply)
+{
+ bson_error_t error;
+
+ /* check for a client error. */
+ if (!cmd_ret && cmd_err && _mongoc_error_is_network (cmd_err)) {
+ /* Retryable reads spec: "considered retryable if [...] any network
+ * exception (e.g. socket timeout or error) */
+ return MONGOC_READ_ERR_RETRY;
+ }
+
+ /* check for a server error. */
+ if (_mongoc_cmd_check_ok_no_wce (
+ reply, MONGOC_ERROR_API_VERSION_2, &error)) {
+ return MONGOC_READ_ERR_NONE;
+ }
+
+ switch (error.code) {
+ case MONGOC_SERVER_ERR_INTERRUPTEDATSHUTDOWN:
+ case MONGOC_SERVER_ERR_INTERRUPTEDDUETOREPLSTATECHANGE:
+ case MONGOC_SERVER_ERR_NOTMASTER:
+ case MONGOC_SERVER_ERR_NOTMASTERNOSLAVEOK:
+ case MONGOC_SERVER_ERR_NOTMASTERORSECONDARY:
+ case MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN:
+ case MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS:
+ case MONGOC_SERVER_ERR_HOSTNOTFOUND:
+ case MONGOC_SERVER_ERR_HOSTUNREACHABLE:
+ case MONGOC_SERVER_ERR_NETWORKTIMEOUT:
+ case MONGOC_SERVER_ERR_SOCKETEXCEPTION:
+ return MONGOC_READ_ERR_RETRY;
+ default:
+ if (strstr (error.message, "not master") ||
+ strstr (error.message, "node is recovering")) {
+ return MONGOC_READ_ERR_RETRY;
+ }
+ return MONGOC_READ_ERR_OTHER;
+ }
+}
+
+void
+_mongoc_error_copy_labels_and_upsert (const bson_t *src,
+ bson_t *dst,
+ char *label)
+{
+ bson_iter_t iter;
+ bson_iter_t src_label;
+ bson_t dst_labels;
+ char str[16];
+ uint32_t i = 0;
+ const char *key;
+
+ BSON_APPEND_ARRAY_BEGIN (dst, "errorLabels", &dst_labels);
+ BSON_APPEND_UTF8 (&dst_labels, "0", label);
+
+ /* append any other errorLabels already in "src" */
+ if (bson_iter_init_find (&iter, src, "errorLabels") &&
+ bson_iter_recurse (&iter, &src_label)) {
+ while (bson_iter_next (&src_label) && BSON_ITER_HOLDS_UTF8 (&src_label)) {
+ if (strcmp (bson_iter_utf8 (&src_label, NULL), label) != 0) {
+ i++;
+ bson_uint32_to_string (i, &key, str, sizeof str);
+ BSON_APPEND_UTF8 (
+ &dst_labels, key, bson_iter_utf8 (&src_label, NULL));
+ }
+ }
+ }
+
+ bson_append_array_end (dst, &dst_labels);
+}
+
+/* Defined in SDAM spec under "Application Errors".
+ * @error should have been obtained from a command reply, e.g. with
+ * _mongoc_cmd_check_ok.
+ */
+bool
+_mongoc_error_is_shutdown (bson_error_t *error)
+{
+ if (!_mongoc_error_is_server (error)) {
+ return false;
+ }
+ switch (error->code) {
+ case 11600: /* InterruptedAtShutdown */
+ case 91: /* ShutdownInProgress */
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool
+_mongoc_error_is_not_master (bson_error_t *error)
+{
+ if (!_mongoc_error_is_server (error)) {
+ return false;
+ }
+
+ if (_mongoc_error_is_recovering (error)) {
+ return false;
+ }
+ switch (error->code) {
+ case MONGOC_SERVER_ERR_NOTMASTER:
+ case MONGOC_SERVER_ERR_NOTMASTERNOSLAVEOK:
+ return true;
+ default:
+ return NULL != strstr (error->message, "not master");
+ }
+}
+
+bool
+_mongoc_error_is_recovering (bson_error_t *error)
+{
+ if (!_mongoc_error_is_server (error)) {
+ return false;
+ }
+ switch (error->code) {
+ case MONGOC_SERVER_ERR_INTERRUPTEDATSHUTDOWN:
+ case MONGOC_SERVER_ERR_INTERRUPTEDDUETOREPLSTATECHANGE:
+ case MONGOC_SERVER_ERR_NOTMASTERORSECONDARY:
+ case MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN:
+ case MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS:
+ return true;
+ default:
+ return NULL != strstr (error->message, "not master or secondary") ||
+ NULL != strstr (error->message, "node is recovering");
+ }
+}
+
+/* Assumes @error was parsed as an API V2 error. */
+bool
+_mongoc_error_is_state_change (bson_error_t *error)
+{
+ return _mongoc_error_is_recovering (error) ||
+ _mongoc_error_is_not_master (error);
+}
+
+bool
+_mongoc_error_is_network (const bson_error_t *error)
+{
+ if (!error) {
+ return false;
+ }
+ if (error->domain == MONGOC_ERROR_STREAM) {
+ return true;
+ }
+
+ if (error->domain == MONGOC_ERROR_PROTOCOL &&
+ error->code == MONGOC_ERROR_PROTOCOL_INVALID_REPLY) {
+ return true;
+ }
+
+ return false;
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c
index b7f90fac..25067d2b 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c
@@ -1,226 +1,229 @@
/*
* Copyright 2015 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.
*/
#include "mongoc-write-concern.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-find-and-modify.h"
#include "mongoc-find-and-modify-private.h"
#include "mongoc-util-private.h"
/**
* mongoc_find_and_modify_new:
*
* Create a new mongoc_find_and_modify_t.
*
* Returns: A newly allocated mongoc_find_and_modify_t. This should be freed
* with mongoc_find_and_modify_destroy().
*/
mongoc_find_and_modify_opts_t *
mongoc_find_and_modify_opts_new (void)
{
mongoc_find_and_modify_opts_t *opts = NULL;
opts = (mongoc_find_and_modify_opts_t *) bson_malloc0 (sizeof *opts);
bson_init (&opts->extra);
opts->bypass_document_validation = false;
return opts;
}
bool
mongoc_find_and_modify_opts_set_sort (mongoc_find_and_modify_opts_t *opts,
const bson_t *sort)
{
BSON_ASSERT (opts);
if (sort) {
bson_destroy (opts->sort);
opts->sort = bson_copy (sort);
return true;
}
return false;
}
void
mongoc_find_and_modify_opts_get_sort (const mongoc_find_and_modify_opts_t *opts,
bson_t *sort)
{
BSON_ASSERT (opts);
BSON_ASSERT (sort);
if (opts->sort) {
bson_copy_to (opts->sort, sort);
} else {
bson_init (sort);
}
}
bool
mongoc_find_and_modify_opts_set_update (mongoc_find_and_modify_opts_t *opts,
const bson_t *update)
{
BSON_ASSERT (opts);
if (update) {
bson_destroy (opts->update);
opts->update = bson_copy (update);
return true;
}
return false;
}
void
mongoc_find_and_modify_opts_get_update (
const mongoc_find_and_modify_opts_t *opts, bson_t *update)
{
BSON_ASSERT (opts);
BSON_ASSERT (update);
if (opts->update) {
bson_copy_to (opts->update, update);
} else {
bson_init (update);
}
}
bool
mongoc_find_and_modify_opts_set_fields (mongoc_find_and_modify_opts_t *opts,
const bson_t *fields)
{
BSON_ASSERT (opts);
if (fields) {
bson_destroy (opts->fields);
opts->fields = bson_copy (fields);
return true;
}
return false;
}
void
mongoc_find_and_modify_opts_get_fields (
const mongoc_find_and_modify_opts_t *opts, bson_t *fields)
{
BSON_ASSERT (opts);
BSON_ASSERT (fields);
if (opts->fields) {
bson_copy_to (opts->fields, fields);
} else {
bson_init (fields);
}
}
bool
mongoc_find_and_modify_opts_set_flags (
mongoc_find_and_modify_opts_t *opts,
const mongoc_find_and_modify_flags_t flags)
{
BSON_ASSERT (opts);
opts->flags = flags;
return true;
}
mongoc_find_and_modify_flags_t
mongoc_find_and_modify_opts_get_flags (
const mongoc_find_and_modify_opts_t *opts)
{
BSON_ASSERT (opts);
return opts->flags;
}
bool
mongoc_find_and_modify_opts_set_bypass_document_validation (
mongoc_find_and_modify_opts_t *opts, bool bypass)
{
BSON_ASSERT (opts);
opts->bypass_document_validation = bypass;
return true;
}
bool
mongoc_find_and_modify_opts_get_bypass_document_validation (
const mongoc_find_and_modify_opts_t *opts)
{
BSON_ASSERT (opts);
return opts->bypass_document_validation;
}
bool
mongoc_find_and_modify_opts_set_max_time_ms (
mongoc_find_and_modify_opts_t *opts, uint32_t max_time_ms)
{
BSON_ASSERT (opts);
opts->max_time_ms = max_time_ms;
return true;
}
uint32_t
mongoc_find_and_modify_opts_get_max_time_ms (
const mongoc_find_and_modify_opts_t *opts)
{
BSON_ASSERT (opts);
return opts->max_time_ms;
}
bool
mongoc_find_and_modify_opts_append (mongoc_find_and_modify_opts_t *opts,
const bson_t *extra)
{
BSON_ASSERT (opts);
- BSON_ASSERT (extra);
+
+ if (!extra) {
+ return true;
+ }
return bson_concat (&opts->extra, extra);
}
void
mongoc_find_and_modify_opts_get_extra (
const mongoc_find_and_modify_opts_t *opts, bson_t *extra)
{
BSON_ASSERT (opts);
BSON_ASSERT (extra);
bson_copy_to (&opts->extra, extra);
}
/**
* mongoc_find_and_modify_opts_destroy:
* @opts: A mongoc_find_and_modify_opts_t.
*
* Releases a mongoc_find_and_modify_opts_t and all associated memory.
*/
void
mongoc_find_and_modify_opts_destroy (mongoc_find_and_modify_opts_t *opts)
{
if (opts) {
bson_destroy (opts->sort);
bson_destroy (opts->update);
bson_destroy (opts->fields);
bson_destroy (&opts->extra);
bson_free (opts);
}
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h
similarity index 50%
copy from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h
copy to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h
index 3616a748..f60598bc 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h
@@ -1,44 +1,46 @@
/*
- * Copyright 2013 MongoDB, Inc.
+ * Copyright 2020-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
*
* 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.
*/
#include "mongoc-prelude.h"
-#ifndef MONGOC_OPCODE_H
-#define MONGOC_OPCODE_H
+#ifndef MONGOC_FLAGS_PRIVATE_H
+#define MONGOC_FLAGS_PRIVATE_H
#include <bson/bson.h>
-
BSON_BEGIN_DECLS
-
+/**
+ * mongoc_op_msg_flags_t:
+ * @MONGOC_MSG_CHECKSUM_PRESENT: The message ends with 4 bytes containing a
+ * CRC-32C checksum.
+ * @MONGOC_MSG_MORE_TO_COME: If set to 0, wait for a server response. If set to
+ * 1, do not expect a server response.
+ * @MONGOC_MSG_EXHAUST_ALLOWED: If set, allows multiple replies to this request
+ * using the moreToCome bit.
+ */
typedef enum {
- MONGOC_OPCODE_REPLY = 1,
- MONGOC_OPCODE_UPDATE = 2001,
- MONGOC_OPCODE_INSERT = 2002,
- MONGOC_OPCODE_QUERY = 2004,
- MONGOC_OPCODE_GET_MORE = 2005,
- MONGOC_OPCODE_DELETE = 2006,
- MONGOC_OPCODE_KILL_CURSORS = 2007,
- MONGOC_OPCODE_COMPRESSED = 2012,
- MONGOC_OPCODE_MSG = 2013,
-} mongoc_opcode_t;
+ MONGOC_MSG_NONE = 0,
+ MONGOC_MSG_CHECKSUM_PRESENT = 1 << 0,
+ MONGOC_MSG_MORE_TO_COME = 1 << 1,
+ MONGOC_MSG_EXHAUST_ALLOWED = 1 << 16,
+} mongoc_op_msg_flags_t;
BSON_END_DECLS
-#endif /* MONGOC_OPCODE_H */
+#endif /* MONGOC_FLAGS_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h
index 465bc0fb..6d597bfc 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h
@@ -1,149 +1,148 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_FLAGS_H
#define MONGOC_FLAGS_H
#include <bson/bson.h>
BSON_BEGIN_DECLS
/**
* mongoc_delete_flags_t:
* @MONGOC_DELETE_NONE: Specify no delete flags.
* @MONGOC_DELETE_SINGLE_REMOVE: Only remove the first document matching the
* document selector.
*
* This type is only for use with deprecated functions and should not be
* used in new code. Use mongoc_remove_flags_t instead.
*
* #mongoc_delete_flags_t are used when performing a delete operation.
*/
typedef enum {
MONGOC_DELETE_NONE = 0,
MONGOC_DELETE_SINGLE_REMOVE = 1 << 0,
} mongoc_delete_flags_t;
/**
* mongoc_remove_flags_t:
* @MONGOC_REMOVE_NONE: Specify no delete flags.
* @MONGOC_REMOVE_SINGLE_REMOVE: Only remove the first document matching the
* document selector.
*
* #mongoc_remove_flags_t are used when performing a remove operation.
*/
typedef enum {
MONGOC_REMOVE_NONE = 0,
MONGOC_REMOVE_SINGLE_REMOVE = 1 << 0,
} mongoc_remove_flags_t;
/**
* mongoc_insert_flags_t:
* @MONGOC_INSERT_NONE: Specify no insert flags.
* @MONGOC_INSERT_CONTINUE_ON_ERROR: Continue inserting documents from
* the insertion set even if one fails.
*
* #mongoc_insert_flags_t are used when performing an insert operation.
*/
typedef enum {
MONGOC_INSERT_NONE = 0,
MONGOC_INSERT_CONTINUE_ON_ERROR = 1 << 0,
} mongoc_insert_flags_t;
#define MONGOC_INSERT_NO_VALIDATE (1U << 31)
/**
* mongoc_query_flags_t:
* @MONGOC_QUERY_NONE: No query flags supplied.
* @MONGOC_QUERY_TAILABLE_CURSOR: Cursor will not be closed when the last
* data is retrieved. You can resume this cursor later.
* @MONGOC_QUERY_SLAVE_OK: Allow query of replica slave.
* @MONGOC_QUERY_OPLOG_REPLAY: Used internally by Mongo.
* @MONGOC_QUERY_NO_CURSOR_TIMEOUT: The server normally times out idle
* cursors after an inactivity period (10 minutes). This prevents that.
* @MONGOC_QUERY_AWAIT_DATA: Use with %MONGOC_QUERY_TAILABLE_CURSOR. Block
* rather than returning no data. After a period, time out.
* @MONGOC_QUERY_EXHAUST: Stream the data down full blast in multiple
* "more" packages. Faster when you are pulling a lot of data and
* know you want to pull it all down.
* @MONGOC_QUERY_PARTIAL: Get partial results from mongos if some shards
* are down (instead of throwing an error).
*
* #mongoc_query_flags_t is used for querying a Mongo instance.
*/
typedef enum {
MONGOC_QUERY_NONE = 0,
MONGOC_QUERY_TAILABLE_CURSOR = 1 << 1,
MONGOC_QUERY_SLAVE_OK = 1 << 2,
MONGOC_QUERY_OPLOG_REPLAY = 1 << 3,
MONGOC_QUERY_NO_CURSOR_TIMEOUT = 1 << 4,
MONGOC_QUERY_AWAIT_DATA = 1 << 5,
MONGOC_QUERY_EXHAUST = 1 << 6,
MONGOC_QUERY_PARTIAL = 1 << 7,
} mongoc_query_flags_t;
/**
* mongoc_reply_flags_t:
* @MONGOC_REPLY_NONE: No flags set.
* @MONGOC_REPLY_CURSOR_NOT_FOUND: Cursor was not found.
* @MONGOC_REPLY_QUERY_FAILURE: Query failed, error document provided.
* @MONGOC_REPLY_SHARD_CONFIG_STALE: Shard configuration is stale.
* @MONGOC_REPLY_AWAIT_CAPABLE: Wait for data to be returned until timeout
* has passed. Used with %MONGOC_QUERY_TAILABLE_CURSOR.
*
* #mongoc_reply_flags_t contains flags supplied by the Mongo server in reply
* to a request.
*/
typedef enum {
MONGOC_REPLY_NONE = 0,
MONGOC_REPLY_CURSOR_NOT_FOUND = 1 << 0,
MONGOC_REPLY_QUERY_FAILURE = 1 << 1,
MONGOC_REPLY_SHARD_CONFIG_STALE = 1 << 2,
MONGOC_REPLY_AWAIT_CAPABLE = 1 << 3,
} mongoc_reply_flags_t;
/**
* mongoc_update_flags_t:
* @MONGOC_UPDATE_NONE: No update flags specified.
* @MONGOC_UPDATE_UPSERT: Perform an upsert.
* @MONGOC_UPDATE_MULTI_UPDATE: Continue updating after first match.
*
* #mongoc_update_flags_t is used when updating documents found in Mongo.
*/
typedef enum {
MONGOC_UPDATE_NONE = 0,
MONGOC_UPDATE_UPSERT = 1 << 0,
MONGOC_UPDATE_MULTI_UPDATE = 1 << 1,
} mongoc_update_flags_t;
#define MONGOC_UPDATE_NO_VALIDATE (1U << 31)
-
BSON_END_DECLS
#endif /* MONGOC_FLAGS_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c
similarity index 84%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c
index 78b12825..7be74dc0 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c
@@ -1,587 +1,519 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "mongoc.h"
#include "mongoc-gridfs-bucket-file-private.h"
#include "mongoc-gridfs-bucket-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-stream-gridfs-download-private.h"
#include "mongoc-stream-gridfs-upload-private.h"
+#include "mongoc-collection-private.h"
/* Returns the minimum of two numbers */
static size_t
_mongoc_min (const size_t a, const size_t b)
{
return a < b ? a : b;
}
-/*--------------------------------------------------------------------------
- *
- * _mongoc_create_index_if_not_present --
- *
- * Creates an index in the given collection if it doesn't exist.
- *
- * Return:
- * True if the index was already present or was successfully created.
- * False if an error occurred while trying to create the index.
- *
- *--------------------------------------------------------------------------
- */
-static bool
-_mongoc_create_index_if_not_present (mongoc_collection_t *col,
- const bson_t *index,
- bool unique,
- bson_error_t *error)
-{
- mongoc_cursor_t *cursor;
- bool index_exists;
- bool r;
- const bson_t *doc;
- bson_iter_t iter;
- bson_t inner_doc;
- char *index_name;
- bson_t index_command;
- uint32_t data_len;
- const uint8_t *data;
-
- BSON_ASSERT (col);
- BSON_ASSERT (index);
-
- cursor = mongoc_collection_find_indexes_with_opts (col, NULL);
-
- index_exists = false;
-
- while (mongoc_cursor_next (cursor, &doc)) {
- r = bson_iter_init_find (&iter, doc, "key");
- if (!r) {
- continue;
- }
- bson_iter_document (&iter, &data_len, &data);
- bson_init_static (&inner_doc, data, data_len);
- if (bson_compare (&inner_doc, index) == 0) {
- index_exists = true;
- }
- bson_destroy (&inner_doc);
- }
-
- mongoc_cursor_destroy (cursor);
-
- if (index_exists) {
- return true;
- }
-
- index_name = mongoc_collection_keys_to_index_string (index);
- bson_init (&index_command);
- BCON_APPEND (&index_command,
- "createIndexes",
- BCON_UTF8 (mongoc_collection_get_name (col)),
- "indexes",
- "[",
- "{",
- "key",
- BCON_DOCUMENT (index),
- "name",
- BCON_UTF8 (index_name),
- "unique",
- BCON_BOOL (unique),
- "}",
- "]");
-
- r = mongoc_collection_write_command_with_opts (
- col, &index_command, NULL, NULL, error);
- bson_destroy (&index_command);
- bson_free (index_name);
- if (!r) {
- return false;
- }
-
-
- return true;
-}
-
/*--------------------------------------------------------------------------
*
* _mongoc_gridfs_bucket_create_indexes --
*
* Creates the indexes needed for GridFS on the 'files' and 'chunks'
* collections.
*
* Return:
* True if creating the indexes was successful, otherwise returns
* false.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_gridfs_bucket_create_indexes (mongoc_gridfs_bucket_t *bucket,
bson_error_t *error)
{
mongoc_read_prefs_t *prefs;
bson_t filter;
bson_t opts;
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t files_index;
bson_t chunks_index;
bool r;
/* Check to see if there already exists a document in the files collection */
bson_init (&filter);
bson_append_int32 (&filter, "_id", 3, 1);
bson_init (&opts);
bson_append_bool (&opts, "singleBatch", 11, true);
bson_append_int32 (&opts, "limit", 5, 1);
prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
cursor =
mongoc_collection_find_with_opts (bucket->files, &filter, &opts, prefs);
bson_destroy (&filter);
bson_destroy (&opts);
r = mongoc_cursor_next (cursor, &doc);
mongoc_read_prefs_destroy (prefs);
if (r) {
/* Files exist */
mongoc_cursor_destroy (cursor);
return true;
} else if (mongoc_cursor_error (cursor, error)) {
mongoc_cursor_destroy (cursor);
return false;
}
mongoc_cursor_destroy (cursor);
/* Create files index */
bson_init (&files_index);
BSON_APPEND_INT32 (&files_index, "filename", 1);
BSON_APPEND_INT32 (&files_index, "uploadDate", 1);
- r = _mongoc_create_index_if_not_present (
- bucket->files, &files_index, false, error);
+
+ r = _mongoc_collection_create_index_if_not_exists (
+ bucket->files, &files_index, NULL, error);
bson_destroy (&files_index);
if (!r) {
return false;
}
/* Create unique chunks index */
+ bson_init (&opts);
+ BSON_APPEND_BOOL (&opts, "unique", true);
+ BSON_APPEND_UTF8 (&opts, "name", "files_id_1_n_1");
+
bson_init (&chunks_index);
BSON_APPEND_INT32 (&chunks_index, "files_id", 1);
BSON_APPEND_INT32 (&chunks_index, "n", 1);
- r = _mongoc_create_index_if_not_present (
- bucket->chunks, &chunks_index, true, error);
+
+ r = _mongoc_collection_create_index_if_not_exists (
+ bucket->chunks, &chunks_index, &opts, error);
+ bson_destroy (&opts);
bson_destroy (&chunks_index);
+
if (!r) {
return false;
}
return true;
}
/*--------------------------------------------------------------------------
*
* _mongoc_gridfs_bucket_write_chunk --
*
* Writes a chunk from the buffer into the chunks collection.
*
* Return:
* Returns true if the chunk was successfully written. Otherwise,
* returns false and sets an error on the bucket file.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_gridfs_bucket_write_chunk (mongoc_gridfs_bucket_file_t *file)
{
bson_t chunk;
bool r;
BSON_ASSERT (file);
bson_init (&chunk);
BSON_APPEND_INT32 (&chunk, "n", file->curr_chunk);
BSON_APPEND_VALUE (&chunk, "files_id", file->file_id);
BSON_APPEND_BINARY (&chunk,
"data",
BSON_SUBTYPE_BINARY,
file->buffer,
(uint32_t) file->in_buffer);
r = mongoc_collection_insert_one (file->bucket->chunks,
&chunk,
NULL /* opts */,
NULL /* reply */,
&file->err);
bson_destroy (&chunk);
if (!r) {
return false;
}
file->curr_chunk++;
file->in_buffer = 0;
return true;
}
/*--------------------------------------------------------------------------
*
* _mongoc_gridfs_bucket_init_cursor --
*
* Initializes the cursor at file->cursor for the given file.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_gridfs_bucket_init_cursor (mongoc_gridfs_bucket_file_t *file)
{
bson_t filter;
bson_t opts;
bson_t sort;
BSON_ASSERT (file);
bson_init (&filter);
bson_init (&opts);
bson_init (&sort);
BSON_APPEND_VALUE (&filter, "files_id", file->file_id);
BSON_APPEND_INT32 (&sort, "n", 1);
BSON_APPEND_DOCUMENT (&opts, "sort", &sort);
file->cursor = mongoc_collection_find_with_opts (
file->bucket->chunks, &filter, &opts, NULL);
bson_destroy (&filter);
bson_destroy (&opts);
bson_destroy (&sort);
}
/*--------------------------------------------------------------------------
*
* _mongoc_gridfs_bucket_read_chunk --
*
* Reads a chunk from the server and places it into the file's buffer
*
* Return:
* True if the buffer has been filled with any available data.
* Otherwise, false and sets the error on the bucket file.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_gridfs_bucket_read_chunk (mongoc_gridfs_bucket_file_t *file)
{
const bson_t *next;
bool r;
bson_iter_t iter;
int32_t n;
const uint8_t *data;
uint32_t data_len;
int64_t total_chunks;
int64_t expected_size;
BSON_ASSERT (file);
if (file->length == 0) {
/* This file has zero length */
file->in_buffer = 0;
file->finished = true;
return true;
}
/* Calculate the total number of chunks for this file */
total_chunks = (file->length / file->chunk_size);
if (file->length % file->chunk_size != 0) {
total_chunks++;
}
if (file->curr_chunk == total_chunks) {
/* All chunks have been read! */
file->in_buffer = 0;
file->finished = true;
return true;
}
if (file->cursor == NULL) {
_mongoc_gridfs_bucket_init_cursor (file);
}
r = mongoc_cursor_next (file->cursor, &next);
if (mongoc_cursor_error (file->cursor, &file->err)) {
return false;
}
if (!r) {
bson_set_error (&file->err,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_CHUNK_MISSING,
"Missing chunk %d.",
file->curr_chunk);
return false;
}
r = bson_iter_init_find (&iter, next, "n");
if (!r) {
bson_set_error (&file->err,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_CORRUPT,
"Chunk %d missing a required field 'n'.",
file->curr_chunk);
return false;
}
n = bson_iter_int32 (&iter);
if (n != file->curr_chunk) {
bson_set_error (&file->err,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_CHUNK_MISSING,
"Missing chunk %d.",
file->curr_chunk);
return false;
}
r = bson_iter_init_find (&iter, next, "data");
if (!r) {
bson_set_error (&file->err,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_CORRUPT,
"Chunk %d missing a required field 'data'.",
file->curr_chunk);
return false;
}
bson_iter_binary (&iter, NULL, &data_len, &data);
/* Assert that the data is the correct length */
if (file->curr_chunk != total_chunks - 1) {
expected_size = file->chunk_size;
} else {
expected_size = file->length - ((total_chunks - 1) * file->chunk_size);
}
if (data_len != expected_size) {
bson_set_error (&file->err,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_CORRUPT,
"Chunk %d expected to have size %" PRId64
" but is size %d.",
file->curr_chunk,
expected_size,
data_len);
return false;
}
memcpy (file->buffer, data, data_len);
file->in_buffer = data_len;
file->bytes_read = 0;
file->curr_chunk++;
return true;
}
ssize_t
_mongoc_gridfs_bucket_file_writev (mongoc_gridfs_bucket_file_t *file,
const mongoc_iovec_t *iov,
size_t iovcnt)
{
uint32_t total;
size_t bytes_available;
size_t space_available;
int32_t written_this_iov;
size_t to_write;
size_t i;
bool r;
BSON_ASSERT (file);
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
total = 0;
if (file->err.code) {
return -1;
}
if (file->saved) {
bson_set_error (&file->err,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_PROTOCOL_ERROR,
"Cannot write after saving/aborting on a GridFS file.");
return -1;
}
if (!file->bucket->indexed) {
r = _mongoc_gridfs_bucket_create_indexes (file->bucket, &file->err);
if (!r) {
/* Error is set on file. */
return -1;
} else {
file->bucket->indexed = true;
}
}
for (i = 0; i < iovcnt; i++) {
written_this_iov = 0;
while (written_this_iov < iov[i].iov_len) {
bytes_available = iov[i].iov_len - written_this_iov;
space_available = file->chunk_size - file->in_buffer;
to_write = _mongoc_min (bytes_available, space_available);
memcpy (file->buffer + file->in_buffer,
+#ifndef _WIN32
+ (char *)
+#endif
iov[i].iov_base + written_this_iov,
to_write);
file->in_buffer += to_write;
written_this_iov += to_write;
total += to_write;
if (file->in_buffer == file->chunk_size) {
/* Buffer is filled, write the chunk */
_mongoc_gridfs_bucket_write_chunk (file);
}
}
}
return total;
}
ssize_t
_mongoc_gridfs_bucket_file_readv (mongoc_gridfs_bucket_file_t *file,
mongoc_iovec_t *iov,
size_t iovcnt)
{
uint32_t total;
size_t bytes_available;
size_t space_available;
int32_t read_this_iov;
size_t to_read;
bool r;
size_t i;
BSON_ASSERT (file);
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
total = 0;
if (file->err.code) {
return -1;
}
if (file->finished) {
return 0;
}
for (i = 0; i < iovcnt; i++) {
read_this_iov = 0;
while (read_this_iov < iov[i].iov_len) {
bytes_available = file->in_buffer - file->bytes_read;
space_available = iov[i].iov_len - read_this_iov;
to_read = _mongoc_min (bytes_available, space_available);
- memcpy (iov[i].iov_base + read_this_iov,
+ memcpy (
+#ifndef _WIN32
+ (char *)
+#endif
+ iov[i].iov_base + read_this_iov,
file->buffer + file->bytes_read,
to_read);
file->bytes_read += to_read;
read_this_iov += to_read;
total += to_read;
if (file->bytes_read == file->in_buffer) {
/* Everything in the current chunk has been read, so read a new
* chunk */
r = _mongoc_gridfs_bucket_read_chunk (file);
if (!r) {
/* an error occured while reading the chunk */
return -1;
}
if (file->finished) {
/* There's nothing left to read */
RETURN (total);
}
}
}
}
RETURN (total);
}
/*--------------------------------------------------------------------------
*
* _mongoc_gridfs_bucket_file_save --
*
* Saves the file to the files collection in gridFS. This locks the
* file into GridFS, and no more chunks are allowed to be written.
*
* Return:
* True if saved or no-op. False otherwise, and sets the file error.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_gridfs_bucket_file_save (mongoc_gridfs_bucket_file_t *file)
{
bson_t new_doc;
int64_t length;
bool r;
BSON_ASSERT (file);
if (file->saved) {
/* Already saved, or aborted. */
return true;
}
if (file->err.code) {
return false;
}
length = ((int64_t) file->curr_chunk) * file->chunk_size;
if (file->in_buffer != 0) {
length += file->in_buffer;
_mongoc_gridfs_bucket_write_chunk (file);
}
file->length = length;
bson_init (&new_doc);
BSON_APPEND_VALUE (&new_doc, "_id", file->file_id);
BSON_APPEND_INT64 (&new_doc, "length", file->length);
BSON_APPEND_INT32 (&new_doc, "chunkSize", file->chunk_size);
BSON_APPEND_DATE_TIME (&new_doc, "uploadDate", bson_get_monotonic_time ());
BSON_APPEND_UTF8 (&new_doc, "filename", file->filename);
if (file->metadata) {
BSON_APPEND_DOCUMENT (&new_doc, "metadata", file->metadata);
}
r = mongoc_collection_insert_one (
file->bucket->files, &new_doc, NULL, NULL, &file->err);
bson_destroy (&new_doc);
file->saved = r;
return (file->err.code) ? false : true;
}
void
_mongoc_gridfs_bucket_file_destroy (mongoc_gridfs_bucket_file_t *file)
{
if (file) {
bson_value_destroy (file->file_id);
bson_free (file->file_id);
bson_destroy (file->metadata);
mongoc_cursor_destroy (file->cursor);
bson_free (file->buffer);
bson_free (file->filename);
bson_free (file);
}
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c
index cd655509..d8fa1d6a 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c
@@ -1,538 +1,538 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "bson/bson.h"
#include "mongoc.h"
#include "mongoc-cursor-private.h"
#include "mongoc-database-private.h"
#include "mongoc-gridfs-bucket-private.h"
#include "mongoc-gridfs-bucket-file-private.h"
#include "mongoc-opts-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-stream-gridfs-download-private.h"
#include "mongoc-stream-gridfs-upload-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-write-concern-private.h"
/*--------------------------------------------------------------------------
*
* _mongoc_gridfs_find_file_with_id --
*
* Attempts to find the file corresponding to the given file_id in
* GridFS.
*
* Return:
* True on success and initializes file. Otherwise, returns false
* and sets error.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_gridfs_find_file_with_id (mongoc_gridfs_bucket_t *bucket,
const bson_value_t *file_id,
bson_t *file,
bson_error_t *error)
{
mongoc_cursor_t *cursor;
bson_t filter;
const bson_t *doc;
bool r;
BSON_ASSERT (bucket);
BSON_ASSERT (file_id);
bson_init (&filter);
BSON_APPEND_VALUE (&filter, "_id", file_id);
cursor =
mongoc_collection_find_with_opts (bucket->files, &filter, NULL, NULL);
bson_destroy (&filter);
r = mongoc_cursor_next (cursor, &doc);
if (!r) {
if (!mongoc_cursor_error (cursor, error)) {
bson_set_error (error,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_BUCKET_FILE_NOT_FOUND,
"No file with given id exists");
}
} else {
if (file) {
bson_copy_to (doc, file);
}
}
mongoc_cursor_destroy (cursor);
return r;
}
mongoc_gridfs_bucket_t *
mongoc_gridfs_bucket_new (mongoc_database_t *db,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error)
{
mongoc_gridfs_bucket_t *bucket;
char buf[128];
mongoc_gridfs_bucket_opts_t gridfs_opts;
BSON_ASSERT (db);
if (!_mongoc_gridfs_bucket_opts_parse (
db->client, opts, &gridfs_opts, error)) {
_mongoc_gridfs_bucket_opts_cleanup (&gridfs_opts);
return NULL;
}
/* Initialize the bucket fields */
if (strlen (gridfs_opts.bucketName) + strlen (".chunks") + 1 >
sizeof (buf)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"bucketName \"%s\" must have fewer than %d characters",
gridfs_opts.bucketName,
(int) (sizeof (buf) - (strlen (".chunks") + 1)));
}
bucket = (mongoc_gridfs_bucket_t *) bson_malloc0 (sizeof *bucket);
bson_snprintf (buf, sizeof (buf), "%s.chunks", gridfs_opts.bucketName);
bucket->chunks = mongoc_database_get_collection (db, buf);
bson_snprintf (buf, sizeof (buf), "%s.files", gridfs_opts.bucketName);
bucket->files = mongoc_database_get_collection (db, buf);
if (gridfs_opts.writeConcern) {
mongoc_collection_set_write_concern (bucket->chunks,
gridfs_opts.writeConcern);
mongoc_collection_set_write_concern (bucket->files,
gridfs_opts.writeConcern);
}
if (gridfs_opts.readConcern) {
mongoc_collection_set_read_concern (bucket->chunks,
gridfs_opts.readConcern);
mongoc_collection_set_read_concern (bucket->files,
gridfs_opts.readConcern);
}
if (read_prefs) {
mongoc_collection_set_read_prefs (bucket->chunks, read_prefs);
mongoc_collection_set_read_prefs (bucket->files, read_prefs);
}
bucket->chunk_size = gridfs_opts.chunkSizeBytes;
bucket->bucket_name = bson_strdup (gridfs_opts.bucketName);
_mongoc_gridfs_bucket_opts_cleanup (&gridfs_opts);
return bucket;
}
mongoc_stream_t *
mongoc_gridfs_bucket_open_upload_stream_with_id (mongoc_gridfs_bucket_t *bucket,
const bson_value_t *file_id,
const char *filename,
const bson_t *opts,
bson_error_t *error)
{
mongoc_gridfs_bucket_file_t *file;
size_t len;
mongoc_gridfs_bucket_upload_opts_t gridfs_opts;
BSON_ASSERT (bucket);
BSON_ASSERT (file_id);
BSON_ASSERT (filename);
if (!_mongoc_gridfs_bucket_upload_opts_parse (
NULL /* not needed. */, opts, &gridfs_opts, error)) {
_mongoc_gridfs_bucket_upload_opts_cleanup (&gridfs_opts);
return NULL;
}
/* default to bucket's chunk size. */
if (!gridfs_opts.chunkSizeBytes) {
gridfs_opts.chunkSizeBytes = bucket->chunk_size;
}
/* Initialize the file's fields */
len = strlen (filename);
file = (mongoc_gridfs_bucket_file_t *) bson_malloc0 (sizeof *file);
file->filename = bson_malloc0 (len + 1);
bson_strncpy (file->filename, filename, len + 1);
file->file_id = (bson_value_t *) bson_malloc0 (sizeof *(file->file_id));
bson_value_copy (file_id, file->file_id);
file->bucket = bucket;
file->chunk_size = gridfs_opts.chunkSizeBytes;
file->metadata = bson_copy (&gridfs_opts.metadata);
file->buffer = bson_malloc ((size_t) gridfs_opts.chunkSizeBytes);
file->in_buffer = 0;
_mongoc_gridfs_bucket_upload_opts_cleanup (&gridfs_opts);
return _mongoc_upload_stream_gridfs_new (file);
}
mongoc_stream_t *
mongoc_gridfs_bucket_open_upload_stream (mongoc_gridfs_bucket_t *bucket,
const char *filename,
const bson_t *opts,
bson_value_t *file_id /* OUT */,
bson_error_t *error)
{
mongoc_stream_t *stream;
bson_oid_t object_id;
bson_value_t val;
BSON_ASSERT (bucket);
BSON_ASSERT (filename);
/* Create an objectId to use as the file's id */
bson_oid_init (&object_id, NULL);
val.value_type = BSON_TYPE_OID;
val.value.v_oid = object_id;
stream = mongoc_gridfs_bucket_open_upload_stream_with_id (
bucket, &val, filename, opts, error);
if (!stream) {
return NULL;
}
if (file_id) {
bson_value_copy (&val, file_id);
}
return stream;
}
bool
mongoc_gridfs_bucket_upload_from_stream_with_id (mongoc_gridfs_bucket_t *bucket,
const bson_value_t *file_id,
const char *filename,
mongoc_stream_t *source,
const bson_t *opts,
bson_error_t *error)
{
mongoc_stream_t *upload_stream;
ssize_t bytes_read;
ssize_t bytes_written;
char buf[512];
BSON_ASSERT (bucket);
BSON_ASSERT (file_id);
BSON_ASSERT (filename);
BSON_ASSERT (source);
upload_stream = mongoc_gridfs_bucket_open_upload_stream_with_id (
bucket, file_id, filename, opts, error);
if (!upload_stream) {
return false;
}
while ((bytes_read = mongoc_stream_read (source, buf, 512, 1, 0)) > 0) {
bytes_written = mongoc_stream_write (upload_stream, buf, bytes_read, 0);
if (bytes_written < 0) {
BSON_ASSERT (mongoc_gridfs_bucket_stream_error (upload_stream, error));
mongoc_gridfs_bucket_abort_upload (upload_stream);
mongoc_stream_destroy (upload_stream);
return false;
}
}
if (bytes_read < 0) {
mongoc_gridfs_bucket_abort_upload (upload_stream);
bson_set_error (error,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_BUCKET_STREAM,
"Error occurred on the provided stream.");
mongoc_stream_destroy (upload_stream);
return false;
} else {
mongoc_stream_destroy (upload_stream);
return true;
}
}
bool
mongoc_gridfs_bucket_upload_from_stream (mongoc_gridfs_bucket_t *bucket,
const char *filename,
mongoc_stream_t *source,
const bson_t *opts,
bson_value_t *file_id /* OUT */,
bson_error_t *error)
{
bool r;
bson_oid_t object_id;
bson_value_t val;
BSON_ASSERT (bucket);
BSON_ASSERT (filename);
BSON_ASSERT (source);
/* Create an objectId to use as the file's id */
bson_oid_init (&object_id, bson_context_get_default ());
val.value_type = BSON_TYPE_OID;
val.value.v_oid = object_id;
r = mongoc_gridfs_bucket_upload_from_stream_with_id (
bucket, &val, filename, source, opts, error);
if (!r) {
return false;
}
if (file_id) {
bson_value_copy (&val, file_id);
}
return true;
}
mongoc_stream_t *
mongoc_gridfs_bucket_open_download_stream (mongoc_gridfs_bucket_t *bucket,
const bson_value_t *file_id,
bson_error_t *error)
{
mongoc_gridfs_bucket_file_t *file;
bson_t file_doc;
const char *key;
bson_iter_t iter;
uint32_t data_len;
const uint8_t *data;
bool r;
BSON_ASSERT (bucket);
BSON_ASSERT (file_id);
r = _mongoc_gridfs_find_file_with_id (bucket, file_id, &file_doc, error);
if (!r) {
/* Error should already be set. */
return NULL;
}
if (!bson_iter_init (&iter, &file_doc)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"File document malformed");
return NULL;
}
file = (mongoc_gridfs_bucket_file_t *) bson_malloc0 (sizeof *file);
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (strcmp (key, "length") == 0) {
file->length = bson_iter_as_int64 (&iter);
} else if (strcmp (key, "chunkSize") == 0) {
file->chunk_size = bson_iter_int32 (&iter);
} else if (strcmp (key, "filename") == 0) {
file->filename = bson_strdup (bson_iter_utf8 (&iter, NULL));
} else if (strcmp (key, "metadata") == 0) {
bson_iter_document (&iter, &data_len, &data);
file->metadata = bson_new_from_data (data, data_len);
}
}
bson_destroy (&file_doc);
file->file_id = (bson_value_t *) bson_malloc0 (sizeof *(file->file_id));
bson_value_copy (file_id, file->file_id);
file->bucket = bucket;
file->buffer = bson_malloc0 ((size_t) file->chunk_size);
BSON_ASSERT (file->file_id);
return _mongoc_download_stream_gridfs_new (file);
}
bool
mongoc_gridfs_bucket_download_to_stream (mongoc_gridfs_bucket_t *bucket,
const bson_value_t *file_id,
mongoc_stream_t *destination,
bson_error_t *error)
{
mongoc_stream_t *download_stream;
ssize_t bytes_read;
ssize_t bytes_written;
char buf[512];
BSON_ASSERT (bucket);
BSON_ASSERT (file_id);
BSON_ASSERT (destination);
/* Make the download stream */
download_stream =
mongoc_gridfs_bucket_open_download_stream (bucket, file_id, error);
while ((bytes_read = mongoc_stream_read (download_stream, buf, 256, 1, 0)) >
0) {
bytes_written = mongoc_stream_write (destination, buf, bytes_read, 0);
if (bytes_written < 0) {
bson_set_error (error,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_BUCKET_STREAM,
"Error occurred on the provided stream.");
mongoc_stream_destroy (download_stream);
return false;
}
}
mongoc_stream_destroy (download_stream);
return bytes_read != -1;
}
bool
mongoc_gridfs_bucket_delete_by_id (mongoc_gridfs_bucket_t *bucket,
const bson_value_t *file_id,
bson_error_t *error)
{
bson_t files_selector;
bson_t chunks_selector;
bson_t reply;
bson_iter_t iter;
bool r;
BSON_ASSERT (bucket);
BSON_ASSERT (file_id);
bson_init (&files_selector);
BSON_APPEND_VALUE (&files_selector, "_id", file_id);
r = mongoc_collection_delete_one (
bucket->files, &files_selector, NULL, &reply, error);
bson_destroy (&files_selector);
if (!r) {
bson_destroy (&reply);
return false;
}
BSON_ASSERT (bson_iter_init_find (&iter, &reply, "deletedCount"));
if (bson_iter_as_int64 (&iter) != 1) {
bson_set_error (error,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_BUCKET_FILE_NOT_FOUND,
"File not found");
bson_destroy (&reply);
return false;
}
bson_destroy (&reply);
bson_init (&chunks_selector);
BSON_APPEND_VALUE (&chunks_selector, "files_id", file_id);
r = mongoc_collection_delete_many (
bucket->chunks, &chunks_selector, NULL, NULL, error);
bson_destroy (&chunks_selector);
if (!r) {
return false;
}
return true;
}
mongoc_cursor_t *
mongoc_gridfs_bucket_find (mongoc_gridfs_bucket_t *bucket,
const bson_t *filter,
const bson_t *opts)
{
mongoc_cursor_t *cursor;
BSON_ASSERT (bucket);
BSON_ASSERT (filter);
cursor =
mongoc_collection_find_with_opts (bucket->files, filter, NULL, NULL);
if (!cursor->error.code && bson_has_field (opts, "sessionId")) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot pass sessionId as an option");
}
return cursor;
}
bool
mongoc_gridfs_bucket_stream_error (mongoc_stream_t *stream, bson_error_t *error)
{
bson_error_t *stream_err;
BSON_ASSERT (stream);
BSON_ASSERT (error);
if (stream->type == MONGOC_STREAM_GRIDFS_UPLOAD) {
stream_err = &((mongoc_gridfs_upload_stream_t *) stream)->file->err;
} else if (stream->type == MONGOC_STREAM_GRIDFS_DOWNLOAD) {
stream_err = &((mongoc_gridfs_download_stream_t *) stream)->file->err;
} else {
return false;
}
if (stream_err->code) {
memcpy (error, stream_err, sizeof (*stream_err));
return true;
} else {
return false;
}
}
void
mongoc_gridfs_bucket_destroy (mongoc_gridfs_bucket_t *bucket)
{
if (bucket) {
mongoc_collection_destroy (bucket->chunks);
mongoc_collection_destroy (bucket->files);
bson_free (bucket->bucket_name);
bson_free (bucket);
}
}
bool
mongoc_gridfs_bucket_abort_upload (mongoc_stream_t *stream)
{
mongoc_gridfs_bucket_file_t *file;
bson_t chunks_selector;
bool r;
BSON_ASSERT (stream);
BSON_ASSERT (stream->type == MONGOC_STREAM_GRIDFS_UPLOAD);
file = ((mongoc_gridfs_upload_stream_t *) stream)->file;
/* Pretend we've already saved. This way we won't add an entry to the files
* collection when the stream is closed */
file->saved = true;
bson_init (&chunks_selector);
BSON_APPEND_VALUE (&chunks_selector, "files_id", file->file_id);
r = mongoc_collection_delete_many (
file->bucket->chunks, &chunks_selector, NULL, NULL, &file->err);
bson_destroy (&chunks_selector);
return r;
-}
\ No newline at end of file
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c
similarity index 95%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c
index a3665058..6b485e7e 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c
@@ -1,492 +1,491 @@
/*
* Copyright 2013 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.
*/
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "gridfs"
#include "mongoc-bulk-operation.h"
#include "mongoc-client-private.h"
#include "mongoc-collection.h"
#include "mongoc-collection-private.h"
#include "mongoc-error.h"
#include "mongoc-index.h"
#include "mongoc-gridfs.h"
#include "mongoc-gridfs-private.h"
#include "mongoc-gridfs-file.h"
#include "mongoc-gridfs-file-private.h"
#include "mongoc-gridfs-file-list.h"
#include "mongoc-gridfs-file-list-private.h"
#include "mongoc-client.h"
#include "mongoc-trace-private.h"
#include "mongoc-cursor-private.h"
#include "mongoc-util-private.h"
#define MONGOC_GRIDFS_STREAM_CHUNK 4096
/**
* _mongoc_gridfs_ensure_index:
*
* ensure gridfs indexes
*
* Ensure fast searches for chunks via [ files_id, n ]
* Ensure fast searches for files via [ filename ]
*/
static bool
_mongoc_gridfs_ensure_index (mongoc_gridfs_t *gridfs, bson_error_t *error)
{
bson_t keys;
- mongoc_index_opt_t opt;
+ bson_t opts;
bool r;
ENTRY;
- bson_init (&keys);
+ bson_init (&opts);
+ BSON_APPEND_BOOL (&opts, "unique", true);
- bson_append_int32 (&keys, "files_id", -1, 1);
- bson_append_int32 (&keys, "n", -1, 1);
+ bson_init (&keys);
- mongoc_index_opt_init (&opt);
- opt.unique = 1;
+ BSON_APPEND_INT32 (&keys, "files_id", 1);
+ BSON_APPEND_INT32 (&keys, "n", 1);
- BEGIN_IGNORE_DEPRECATIONS
- r = mongoc_collection_create_index (gridfs->chunks, &keys, &opt, error);
- END_IGNORE_DEPRECATIONS
+ r = _mongoc_collection_create_index_if_not_exists (
+ gridfs->chunks, &keys, &opts, error);
+ bson_destroy (&opts);
bson_destroy (&keys);
if (!r) {
RETURN (r);
}
bson_init (&keys);
- bson_append_int32 (&keys, "filename", -1, 1);
- bson_append_int32 (&keys, "uploadDate", -1, 1);
- opt.unique = 0;
+ BSON_APPEND_INT32 (&keys, "filename", 1);
+ BSON_APPEND_INT32 (&keys, "uploadDate", 1);
+
+ r = _mongoc_collection_create_index_if_not_exists (
+ gridfs->files, &keys, NULL, error);
- BEGIN_IGNORE_DEPRECATIONS
- r = mongoc_collection_create_index (gridfs->files, &keys, &opt, error);
- END_IGNORE_DEPRECATIONS
bson_destroy (&keys);
if (!r) {
RETURN (r);
}
RETURN (1);
}
mongoc_gridfs_t *
_mongoc_gridfs_new (mongoc_client_t *client,
const char *db,
const char *prefix,
bson_error_t *error)
{
mongoc_gridfs_t *gridfs;
char buf[128];
bool r;
uint32_t prefix_len;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (db);
if (!prefix) {
prefix = "fs";
}
/* make sure prefix is short enough to bucket the chunks and files
* collections
*/
prefix_len = (uint32_t) strlen (prefix);
BSON_ASSERT (prefix_len + sizeof (".chunks") < sizeof (buf));
gridfs = (mongoc_gridfs_t *) bson_malloc0 (sizeof *gridfs);
gridfs->client = client;
bson_snprintf (buf, sizeof (buf), "%s.chunks", prefix);
gridfs->chunks = mongoc_client_get_collection (client, db, buf);
bson_snprintf (buf, sizeof (buf), "%s.files", prefix);
gridfs->files = mongoc_client_get_collection (client, db, buf);
r = _mongoc_gridfs_ensure_index (gridfs, error);
if (!r) {
mongoc_gridfs_destroy (gridfs);
RETURN (NULL);
}
RETURN (gridfs);
}
bool
mongoc_gridfs_drop (mongoc_gridfs_t *gridfs, bson_error_t *error)
{
bool r;
ENTRY;
r = mongoc_collection_drop (gridfs->files, error);
if (!r) {
RETURN (0);
}
r = mongoc_collection_drop (gridfs->chunks, error);
if (!r) {
RETURN (0);
}
RETURN (1);
}
void
mongoc_gridfs_destroy (mongoc_gridfs_t *gridfs)
{
ENTRY;
if (!gridfs) {
EXIT;
}
mongoc_collection_destroy (gridfs->files);
mongoc_collection_destroy (gridfs->chunks);
bson_free (gridfs);
EXIT;
}
/** find all matching gridfs files */
mongoc_gridfs_file_list_t *
mongoc_gridfs_find (mongoc_gridfs_t *gridfs, const bson_t *query)
{
return _mongoc_gridfs_file_list_new (gridfs, query, 0);
}
/** find a single gridfs file */
mongoc_gridfs_file_t *
mongoc_gridfs_find_one (mongoc_gridfs_t *gridfs,
const bson_t *query,
bson_error_t *error)
{
mongoc_gridfs_file_list_t *list;
mongoc_gridfs_file_t *file;
ENTRY;
list = _mongoc_gridfs_file_list_new (gridfs, query, 1);
file = mongoc_gridfs_file_list_next (list);
if (!mongoc_gridfs_file_list_error (list, error) && error) {
/* no error, but an error out-pointer was provided - clear it */
memset (error, 0, sizeof (*error));
}
mongoc_gridfs_file_list_destroy (list);
RETURN (file);
}
/** find all matching gridfs files */
mongoc_gridfs_file_list_t *
mongoc_gridfs_find_with_opts (mongoc_gridfs_t *gridfs,
const bson_t *filter,
const bson_t *opts)
{
return _mongoc_gridfs_file_list_new_with_opts (gridfs, filter, opts);
}
/** find a single gridfs file */
mongoc_gridfs_file_t *
mongoc_gridfs_find_one_with_opts (mongoc_gridfs_t *gridfs,
const bson_t *filter,
const bson_t *opts,
bson_error_t *error)
{
mongoc_gridfs_file_list_t *list;
mongoc_gridfs_file_t *file;
bson_t new_opts;
ENTRY;
bson_init (&new_opts);
if (opts) {
bson_copy_to_excluding_noinit (opts, &new_opts, "limit", (char *) NULL);
}
BSON_APPEND_INT32 (&new_opts, "limit", 1);
list = _mongoc_gridfs_file_list_new_with_opts (gridfs, filter, &new_opts);
file = mongoc_gridfs_file_list_next (list);
if (!mongoc_gridfs_file_list_error (list, error) && error) {
/* no error, but an error out-pointer was provided - clear it */
memset (error, 0, sizeof (*error));
}
mongoc_gridfs_file_list_destroy (list);
bson_destroy (&new_opts);
RETURN (file);
}
/** find a single gridfs file by filename */
mongoc_gridfs_file_t *
mongoc_gridfs_find_one_by_filename (mongoc_gridfs_t *gridfs,
const char *filename,
bson_error_t *error)
{
mongoc_gridfs_file_t *file;
bson_t filter;
bson_init (&filter);
bson_append_utf8 (&filter, "filename", -1, filename, -1);
file = mongoc_gridfs_find_one_with_opts (gridfs, &filter, NULL, error);
bson_destroy (&filter);
return file;
}
/** create a gridfs file from a stream
*
* The stream is fully consumed in creating the file
*/
mongoc_gridfs_file_t *
mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t *gridfs,
mongoc_stream_t *stream,
mongoc_gridfs_file_opt_t *opt)
{
mongoc_gridfs_file_t *file;
ssize_t r;
uint8_t buf[MONGOC_GRIDFS_STREAM_CHUNK];
mongoc_iovec_t iov;
int timeout;
ENTRY;
BSON_ASSERT (gridfs);
BSON_ASSERT (stream);
iov.iov_base = (void *) buf;
iov.iov_len = 0;
file = _mongoc_gridfs_file_new (gridfs, opt);
timeout = gridfs->client->cluster.sockettimeoutms;
for (;;) {
r = mongoc_stream_read (
stream, iov.iov_base, MONGOC_GRIDFS_STREAM_CHUNK, 0, timeout);
if (r > 0) {
iov.iov_len = r;
if (mongoc_gridfs_file_writev (file, &iov, 1, timeout) < 0) {
MONGOC_ERROR ("%s", file->error.message);
mongoc_gridfs_file_destroy (file);
RETURN (NULL);
}
} else if (r == 0) {
break;
} else {
MONGOC_ERROR ("Error reading from GridFS file source stream");
mongoc_gridfs_file_destroy (file);
RETURN (NULL);
}
}
mongoc_stream_failed (stream);
if (-1 == mongoc_gridfs_file_seek (file, 0, SEEK_SET)) {
MONGOC_ERROR ("%s", file->error.message);
mongoc_gridfs_file_destroy (file);
RETURN (NULL);
}
RETURN (file);
}
/** create an empty gridfs file */
mongoc_gridfs_file_t *
mongoc_gridfs_create_file (mongoc_gridfs_t *gridfs,
mongoc_gridfs_file_opt_t *opt)
{
mongoc_gridfs_file_t *file;
ENTRY;
BSON_ASSERT (gridfs);
file = _mongoc_gridfs_file_new (gridfs, opt);
RETURN (file);
}
/** accessor functions for collections */
mongoc_collection_t *
mongoc_gridfs_get_files (mongoc_gridfs_t *gridfs)
{
BSON_ASSERT (gridfs);
return gridfs->files;
}
mongoc_collection_t *
mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs)
{
BSON_ASSERT (gridfs);
return gridfs->chunks;
}
bool
mongoc_gridfs_remove_by_filename (mongoc_gridfs_t *gridfs,
const char *filename,
bson_error_t *error)
{
mongoc_bulk_operation_t *bulk_files = NULL;
mongoc_bulk_operation_t *bulk_chunks = NULL;
mongoc_cursor_t *cursor = NULL;
bson_error_t files_error;
bson_error_t chunks_error;
const bson_t *doc;
const char *key;
char keybuf[16];
int count = 0;
bool chunks_ret;
bool files_ret;
bool ret = false;
bson_iter_t iter;
bson_t *files_q = NULL;
bson_t *chunks_q = NULL;
bson_t find_filter = BSON_INITIALIZER;
bson_t find_opts = BSON_INITIALIZER;
bson_t find_opts_project;
bson_t ar = BSON_INITIALIZER;
bson_t opts = BSON_INITIALIZER;
BSON_ASSERT (gridfs);
if (!filename) {
bson_set_error (error,
MONGOC_ERROR_GRIDFS,
MONGOC_ERROR_GRIDFS_INVALID_FILENAME,
"A non-NULL filename must be specified.");
return false;
}
/*
* Find all files matching this filename. Hopefully just one, but not
* strictly required!
*/
BSON_APPEND_UTF8 (&find_filter, "filename", filename);
BSON_APPEND_DOCUMENT_BEGIN (&find_opts, "projection", &find_opts_project);
BSON_APPEND_INT32 (&find_opts_project, "_id", 1);
bson_append_document_end (&find_opts, &find_opts_project);
cursor = _mongoc_cursor_find_new (gridfs->client,
gridfs->files->ns,
&find_filter,
&find_opts,
NULL /* user_prefs */,
NULL /* default_prefs */,
NULL /* read_concern */);
BSON_ASSERT (cursor);
while (mongoc_cursor_next (cursor, &doc)) {
if (bson_iter_init_find (&iter, doc, "_id")) {
const bson_value_t *value = bson_iter_value (&iter);
bson_uint32_to_string (count, &key, keybuf, sizeof keybuf);
BSON_APPEND_VALUE (&ar, key, value);
}
}
if (mongoc_cursor_error (cursor, error)) {
goto failure;
}
bson_append_bool (&opts, "ordered", 7, false);
bulk_files =
mongoc_collection_create_bulk_operation_with_opts (gridfs->files, &opts);
bulk_chunks =
mongoc_collection_create_bulk_operation_with_opts (gridfs->chunks, &opts);
bson_destroy (&opts);
files_q = BCON_NEW ("_id", "{", "$in", BCON_ARRAY (&ar), "}");
chunks_q = BCON_NEW ("files_id", "{", "$in", BCON_ARRAY (&ar), "}");
mongoc_bulk_operation_remove (bulk_files, files_q);
mongoc_bulk_operation_remove (bulk_chunks, chunks_q);
files_ret = mongoc_bulk_operation_execute (bulk_files, NULL, &files_error);
chunks_ret =
mongoc_bulk_operation_execute (bulk_chunks, NULL, &chunks_error);
if (error) {
if (!files_ret) {
memcpy (error, &files_error, sizeof *error);
} else if (!chunks_ret) {
memcpy (error, &chunks_error, sizeof *error);
}
}
ret = (files_ret && chunks_ret);
failure:
if (cursor) {
mongoc_cursor_destroy (cursor);
}
if (bulk_files) {
mongoc_bulk_operation_destroy (bulk_files);
}
if (bulk_chunks) {
mongoc_bulk_operation_destroy (bulk_chunks);
}
bson_destroy (&find_filter);
bson_destroy (&find_opts);
bson_destroy (&ar);
if (files_q) {
bson_destroy (files_q);
}
if (chunks_q) {
bson_destroy (chunks_q);
}
return ret;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
index f314ff40..800905aa 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
@@ -1,132 +1,133 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_HANDSHAKE_PRIVATE_H
#define MONGOC_HANDSHAKE_PRIVATE_H
#include "mongoc.h"
BSON_BEGIN_DECLS
#define HANDSHAKE_FIELD "client"
#define HANDSHAKE_PLATFORM_FIELD "platform"
#define HANDSHAKE_MAX_SIZE 512
#define HANDSHAKE_OS_TYPE_MAX 32
#define HANDSHAKE_OS_NAME_MAX 32
#define HANDSHAKE_OS_VERSION_MAX 32
#define HANDSHAKE_OS_ARCHITECTURE_MAX 32
#define HANDSHAKE_DRIVER_NAME_MAX 64
#define HANDSHAKE_DRIVER_VERSION_MAX 32
/* platform has no fixed max size. It can just occupy the remaining
* available space in the document. */
/* When adding a new field to mongoc-config.h.in, update this! */
typedef enum {
/* The bit position (from the RHS) of each config flag. Do not reorder. */
MONGOC_MD_FLAG_ENABLE_CRYPTO = 0,
MONGOC_MD_FLAG_ENABLE_CRYPTO_CNG,
MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO,
MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO,
MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE,
MONGOC_MD_FLAG_ENABLE_SASL,
MONGOC_MD_FLAG_ENABLE_SSL,
MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL,
MONGOC_MD_FLAG_ENABLE_SSL_SECURE_CHANNEL,
MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT,
MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES,
MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE,
MONGOC_MD_FLAG_HAVE_WEAK_SYMBOLS,
MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS,
MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL,
MONGOC_MD_FLAG_ENABLE_SASL_CYRUS,
MONGOC_MD_FLAG_ENABLE_SASL_SSPI,
MONGOC_MD_FLAG_HAVE_SOCKLEN,
MONGOC_MD_FLAG_ENABLE_COMPRESSION,
MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY,
MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB,
MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI_UNUSED, /* CDRIVER-2654 removed this . */
MONGOC_MD_FLAG_ENABLE_RES_NSEARCH,
MONGOC_MD_FLAG_ENABLE_RES_NDESTROY,
MONGOC_MD_FLAG_ENABLE_RES_NCLOSE,
MONGOC_MD_FLAG_ENABLE_RES_SEARCH,
MONGOC_MD_FLAG_ENABLE_DNSAPI,
MONGOC_MD_FLAG_ENABLE_RDTSCP,
MONGOC_MD_FLAG_HAVE_SCHED_GETCPU,
MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS,
MONGOC_MD_FLAG_TRACE,
MONGOC_MD_FLAG_ENABLE_ICU,
MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION,
+ MONGOC_MD_FLAG_ENABLE_MONGODB_AWS_AUTH,
/* Add additional config flags here, above LAST_MONGOC_MD_FLAG. */
LAST_MONGOC_MD_FLAG
} mongoc_handshake_config_flag_bit_t;
typedef struct _mongoc_handshake_t {
char *os_type;
char *os_name;
char *os_version;
char *os_architecture;
char *driver_name;
char *driver_version;
char *platform;
char *compiler_info;
char *flags;
bool frozen;
} mongoc_handshake_t;
void
_mongoc_handshake_init (void);
void
_mongoc_handshake_cleanup (void);
bool
_mongoc_handshake_build_doc_with_application (bson_t *doc,
const char *application);
void
_mongoc_handshake_freeze (void);
mongoc_handshake_t *
_mongoc_handshake_get (void);
bool
_mongoc_handshake_appname_is_valid (const char *appname);
typedef struct {
bool scram_sha_256;
bool scram_sha_1;
} mongoc_handshake_sasl_supported_mechs_t;
void
_mongoc_handshake_append_sasl_supported_mechs (const mongoc_uri_t *uri,
bson_t *ismaster);
void
_mongoc_handshake_parse_sasl_supported_mechs (
const bson_t *ismaster,
mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs);
BSON_END_DECLS
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c
index 8374af2e..5378015b 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c
@@ -1,704 +1,708 @@
/*
* Copyright 2016 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.
*/
#include <bson/bson.h>
#ifdef _POSIX_VERSION
#include <sys/utsname.h>
#endif
#ifdef _WIN32
#include <windows.h>
#endif
#include "mongoc-linux-distro-scanner-private.h"
#include "mongoc-handshake.h"
#include "mongoc-handshake-compiler-private.h"
#include "mongoc-handshake-os-private.h"
#include "mongoc-handshake-private.h"
#include "mongoc-client.h"
#include "mongoc-client-private.h"
#include "mongoc-error.h"
#include "mongoc-log.h"
#include "mongoc-version.h"
#include "mongoc-util-private.h"
/*
* Global handshake data instance. Initialized at startup from mongoc_init
*
* Can be modified by calls to mongoc_handshake_data_append
*/
static mongoc_handshake_t gMongocHandshake;
/*
* Used for thread-safety in mongoc_handshake_data_append
*/
static bson_mutex_t gHandshakeLock;
static void
_set_bit (uint8_t *bf, uint32_t byte_count, uint32_t bit)
{
uint32_t byte = bit / 8;
uint32_t bit_of_byte = (bit) % 8;
/* byte 0 is the last location in bf. */
bf[(byte_count - 1) - byte] |= 1u << bit_of_byte;
}
/* returns a hex string for all config flag bits, which must be freed. */
char *
_mongoc_handshake_get_config_hex_string (void)
{
uint32_t byte_count;
uint8_t *bf;
bson_string_t *str;
int i;
byte_count = (LAST_MONGOC_MD_FLAG + 7) / 8; /* ceil (num_bits / 8) */
/* allocate enough bytes to fit all config bits. */
bf = (uint8_t *) bson_malloc0 (byte_count);
#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL
_set_bit (bf, byte_count, MONGOC_ENABLE_SSL_SECURE_CHANNEL);
#endif
#ifdef MONGOC_ENABLE_CRYPTO_CNG
_set_bit (bf, byte_count, MONGOC_ENABLE_CRYPTO_CNG);
#endif
#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT);
#endif
#ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO);
#endif
#ifdef MONGOC_ENABLE_SSL_OPENSSL
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL);
#endif
#ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO);
#endif
#ifdef MONGOC_ENABLE_SSL
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SSL);
#endif
#ifdef MONGOC_ENABLE_CRYPTO
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CRYPTO);
#endif
#ifdef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE);
#endif
#ifdef MONGOC_ENABLE_SASL
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SASL);
#endif
#ifdef MONGOC_HAVE_SASL_CLIENT_DONE
_set_bit (bf, byte_count, MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE);
#endif
#ifdef MONGOC_NO_AUTOMATIC_GLOBALS
_set_bit (bf, byte_count, MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS);
#endif
#ifdef MONGOC_EXPERIMENTAL_FEATURES
_set_bit (bf, byte_count, MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES);
#endif
#ifdef MONGOC_ENABLE_SSL_LIBRESSL
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL);
#endif
#ifdef MONGOC_ENABLE_SASL_CYRUS
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SASL_CYRUS);
#endif
#ifdef MONGOC_ENABLE_SASL_SSPI
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SASL_SSPI);
#endif
#ifdef MONGOC_HAVE_SOCKLEN
_set_bit (bf, byte_count, MONGOC_MD_FLAG_HAVE_SOCKLEN);
#endif
#ifdef MONGOC_ENABLE_COMPRESSION
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_COMPRESSION);
#endif
#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY);
#endif
#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB);
#endif
#ifdef MONGOC_HAVE_RES_NSEARCH
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RES_NSEARCH);
#endif
#ifdef MONGOC_HAVE_RES_NDESTROY
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RES_NDESTROY);
#endif
#ifdef MONGOC_HAVE_RES_NCLOSE
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RES_NCLOSE);
#endif
#ifdef MONGOC_HAVE_RES_SEARCH
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RES_SEARCH);
#endif
#ifdef MONGOC_HAVE_DNSAPI
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_DNSAPI);
#endif
#ifdef MONGOC_HAVE_RDTSCP
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RDTSCP);
#endif
#ifdef MONGOC_HAVE_SCHED_GETCPU
_set_bit (bf, byte_count, MONGOC_MD_FLAG_HAVE_SCHED_GETCPU);
#endif
#ifdef MONGOC_ENABLE_SHM_COUNTERS
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS);
#endif
#ifdef MONGOC_TRACE
_set_bit (bf, byte_count, MONGOC_MD_FLAG_TRACE);
#endif
#ifdef MONGOC_ENABLE_ICU
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_ICU);
#endif
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
_set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION);
#endif
+#ifdef MONGOC_ENABLE_MONGODB_AWS_AUTH
+ _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_MONGODB_AWS_AUTH);
+#endif
+
str = bson_string_new ("0x");
for (i = 0; i < byte_count; i++) {
bson_string_append_printf (str, "%02x", bf[i]);
}
bson_free (bf);
/* free the bson_string_t, but keep the underlying char* alive. */
return bson_string_free (str, false);
}
static char *
_get_os_type (void)
{
#ifdef MONGOC_OS_TYPE
return bson_strndup (MONGOC_OS_TYPE, HANDSHAKE_OS_TYPE_MAX);
#else
return bson_strndup ("unknown", HANDSHAKE_OS_TYPE_MAX);
#endif
}
static char *
_get_os_architecture (void)
{
const char *ret = NULL;
#ifdef _WIN32
SYSTEM_INFO system_info;
DWORD arch;
GetSystemInfo (&system_info);
arch = system_info.wProcessorArchitecture;
switch (arch) {
case PROCESSOR_ARCHITECTURE_AMD64:
ret = "x86_64";
break;
case PROCESSOR_ARCHITECTURE_ARM:
ret = "ARM";
break;
case PROCESSOR_ARCHITECTURE_IA64:
ret = "IA64";
break;
case PROCESSOR_ARCHITECTURE_INTEL:
ret = "x86";
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
ret = "Unknown";
break;
default:
ret = "Other";
break;
}
#elif defined(_POSIX_VERSION)
struct utsname system_info;
if (uname (&system_info) >= 0) {
ret = system_info.machine;
}
#endif
if (ret) {
return bson_strndup (ret, HANDSHAKE_OS_ARCHITECTURE_MAX);
}
return NULL;
}
#ifndef MONGOC_OS_IS_LINUX
static char *
_get_os_name (void)
{
#ifdef MONGOC_OS_NAME
return bson_strndup (MONGOC_OS_NAME, HANDSHAKE_OS_NAME_MAX);
#elif defined(_POSIX_VERSION)
struct utsname system_info;
if (uname (&system_info) >= 0) {
return bson_strndup (system_info.sysname, HANDSHAKE_OS_NAME_MAX);
}
#endif
return NULL;
}
static char *
_get_os_version (void)
{
char *ret = bson_malloc (HANDSHAKE_OS_VERSION_MAX);
bool found = false;
#ifdef _WIN32
OSVERSIONINFO osvi;
ZeroMemory (&osvi, sizeof (OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (GetVersionEx (&osvi)) {
bson_snprintf (ret,
HANDSHAKE_OS_VERSION_MAX,
"%lu.%lu (%lu)",
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.dwBuildNumber);
found = true;
} else {
MONGOC_WARNING ("Error with GetVersionEx(): %lu", GetLastError ());
}
#elif defined(_POSIX_VERSION)
struct utsname system_info;
if (uname (&system_info) >= 0) {
bson_strncpy (ret, system_info.release, HANDSHAKE_OS_VERSION_MAX);
found = true;
} else {
MONGOC_WARNING ("Error with uname(): %d", errno);
}
#endif
if (!found) {
bson_free (ret);
ret = NULL;
}
return ret;
}
#endif
static void
_get_system_info (mongoc_handshake_t *handshake)
{
handshake->os_type = _get_os_type ();
#ifdef MONGOC_OS_IS_LINUX
_mongoc_linux_distro_scanner_get_distro (&handshake->os_name,
&handshake->os_version);
#else
handshake->os_name = _get_os_name ();
handshake->os_version = _get_os_version ();
#endif
handshake->os_architecture = _get_os_architecture ();
}
static void
_free_system_info (mongoc_handshake_t *handshake)
{
bson_free (handshake->os_type);
bson_free (handshake->os_name);
bson_free (handshake->os_version);
bson_free (handshake->os_architecture);
}
static void
_get_driver_info (mongoc_handshake_t *handshake)
{
handshake->driver_name = bson_strndup ("mongoc", HANDSHAKE_DRIVER_NAME_MAX);
handshake->driver_version =
bson_strndup (MONGOC_VERSION_S, HANDSHAKE_DRIVER_VERSION_MAX);
}
static void
_free_driver_info (mongoc_handshake_t *handshake)
{
bson_free (handshake->driver_name);
bson_free (handshake->driver_version);
}
static void
_set_platform_string (mongoc_handshake_t *handshake)
{
bson_string_t *str;
str = bson_string_new ("");
handshake->platform = bson_string_free (str, false);
}
static void
_set_compiler_info (mongoc_handshake_t *handshake)
{
bson_string_t *str;
char *config_str;
str = bson_string_new ("");
config_str = _mongoc_handshake_get_config_hex_string ();
bson_string_append_printf (str, "cfg=%s", config_str);
bson_free (config_str);
#ifdef _POSIX_VERSION
bson_string_append_printf (str, " posix=%ld", _POSIX_VERSION);
#endif
#ifdef __STDC_VERSION__
bson_string_append_printf (str, " stdc=%ld", __STDC_VERSION__);
#endif
bson_string_append_printf (str, " CC=%s", MONGOC_COMPILER);
#ifdef MONGOC_COMPILER_VERSION
bson_string_append_printf (str, " %s", MONGOC_COMPILER_VERSION);
#endif
handshake->compiler_info = bson_string_free (str, false);
}
static void
_set_flags (mongoc_handshake_t *handshake)
{
bson_string_t *str;
str = bson_string_new ("");
if (strlen (MONGOC_EVALUATE_STR (MONGOC_USER_SET_CFLAGS)) > 0) {
bson_string_append_printf (
str, " CFLAGS=%s", MONGOC_EVALUATE_STR (MONGOC_USER_SET_CFLAGS));
}
if (strlen (MONGOC_EVALUATE_STR (MONGOC_USER_SET_LDFLAGS)) > 0) {
bson_string_append_printf (
str, " LDFLAGS=%s", MONGOC_EVALUATE_STR (MONGOC_USER_SET_LDFLAGS));
}
handshake->flags = bson_string_free (str, false);
}
static void
_free_platform_string (mongoc_handshake_t *handshake)
{
bson_free (handshake->platform);
bson_free (handshake->compiler_info);
bson_free (handshake->flags);
}
void
_mongoc_handshake_init (void)
{
_get_system_info (_mongoc_handshake_get ());
_get_driver_info (_mongoc_handshake_get ());
_set_platform_string (_mongoc_handshake_get ());
_set_compiler_info (_mongoc_handshake_get ());
_set_flags (_mongoc_handshake_get ());
_mongoc_handshake_get ()->frozen = false;
bson_mutex_init (&gHandshakeLock);
}
void
_mongoc_handshake_cleanup (void)
{
_free_system_info (_mongoc_handshake_get ());
_free_driver_info (_mongoc_handshake_get ());
_free_platform_string (_mongoc_handshake_get ());
bson_mutex_destroy (&gHandshakeLock);
}
static void
_append_platform_field (bson_t *doc, const char *platform)
{
int max_platform_str_size;
char *compiler_info = _mongoc_handshake_get ()->compiler_info;
char *flags = _mongoc_handshake_get ()->flags;
bson_string_t *combined_platform = bson_string_new (platform);
/* Compute space left for platform field */
max_platform_str_size =
HANDSHAKE_MAX_SIZE - ((int) doc->len +
/* 1 byte for utf8 tag */
1 +
/* key size */
(int) strlen (HANDSHAKE_PLATFORM_FIELD) +
1 +
/* 4 bytes for length of string */
4);
if (max_platform_str_size <= 0) {
return;
}
/* We opt to drop compiler info and flags if they can't fit, while the
* platform information is truncated
* Try to drop flags first, and if there is still not enough space also drop
* compiler info */
if (max_platform_str_size >
combined_platform->len + strlen (compiler_info) + 1) {
bson_string_append (combined_platform, compiler_info);
}
if (max_platform_str_size > combined_platform->len + strlen (flags) + 1) {
bson_string_append (combined_platform, flags);
}
/* We use the flags_index field to check if the CLAGS/LDFLAGS need to be
* truncated, and if so we drop them altogether */
bson_append_utf8 (
doc,
HANDSHAKE_PLATFORM_FIELD,
-1,
combined_platform->str,
BSON_MIN (max_platform_str_size - 1, combined_platform->len));
bson_string_free (combined_platform, true);
BSON_ASSERT (doc->len <= HANDSHAKE_MAX_SIZE);
}
/*
* Return true if we build the document, and it's not too big
* false if there's no way to prevent the doc from being too big. In this
* case, the caller shouldn't include it with isMaster
*/
bool
_mongoc_handshake_build_doc_with_application (bson_t *doc, const char *appname)
{
const mongoc_handshake_t *md = _mongoc_handshake_get ();
bson_t child;
if (appname) {
BSON_APPEND_DOCUMENT_BEGIN (doc, "application", &child);
BSON_APPEND_UTF8 (&child, "name", appname);
bson_append_document_end (doc, &child);
}
BSON_APPEND_DOCUMENT_BEGIN (doc, "driver", &child);
BSON_APPEND_UTF8 (&child, "name", md->driver_name);
BSON_APPEND_UTF8 (&child, "version", md->driver_version);
bson_append_document_end (doc, &child);
BSON_APPEND_DOCUMENT_BEGIN (doc, "os", &child);
BSON_ASSERT (md->os_type);
BSON_APPEND_UTF8 (&child, "type", md->os_type);
if (md->os_name) {
BSON_APPEND_UTF8 (&child, "name", md->os_name);
}
if (md->os_version) {
BSON_APPEND_UTF8 (&child, "version", md->os_version);
}
if (md->os_architecture) {
BSON_APPEND_UTF8 (&child, "architecture", md->os_architecture);
}
bson_append_document_end (doc, &child);
if (doc->len > HANDSHAKE_MAX_SIZE) {
/* We've done all we can possibly do to ensure the current
* document is below the maxsize, so if it overflows there is
* nothing else we can do, so we fail */
return false;
}
if (md->platform) {
_append_platform_field (doc, md->platform);
}
return true;
}
void
_mongoc_handshake_freeze (void)
{
_mongoc_handshake_get ()->frozen = true;
}
/*
* free (*s) and make *s point to *s concated with suffix.
* If *s is NULL it's treated like it's an empty string.
* If suffix is NULL, nothing happens.
*/
static void
_append_and_truncate (char **s, const char *suffix, int max_len)
{
char *old_str = *s;
char *prefix;
const int delim_len = (int) strlen (" / ");
int space_for_suffix;
BSON_ASSERT (s);
prefix = old_str ? old_str : "";
if (!suffix) {
return;
}
space_for_suffix = max_len - (int) strlen (prefix) - delim_len;
if (space_for_suffix <= 0) {
/* the old string already takes the whole allotted space */
return;
}
*s = bson_strdup_printf ("%s / %.*s", prefix, space_for_suffix, suffix);
BSON_ASSERT (strlen (*s) <= max_len);
bson_free (old_str);
}
/*
* Set some values in our global handshake struct. These values will be sent
* to the server as part of the initial connection handshake (isMaster).
* If this function is called more than once, or after we've connected to a
* mongod, then it will do nothing and return false. It will return true if it
* successfully sets the values.
*
* All arguments are optional.
*/
bool
mongoc_handshake_data_append (const char *driver_name,
const char *driver_version,
const char *platform)
{
int platform_space;
bson_mutex_lock (&gHandshakeLock);
if (_mongoc_handshake_get ()->frozen) {
bson_mutex_unlock (&gHandshakeLock);
return false;
}
/* allow practically any size for "platform", we'll trim it down in
* _mongoc_handshake_build_doc_with_application */
platform_space =
HANDSHAKE_MAX_SIZE - (int) strlen (_mongoc_handshake_get ()->platform);
/* we check for an empty string as a special case to avoid an unnecessary
* delimiter being added in front of the string by _append_and_truncate */
if (strcmp (_mongoc_handshake_get ()->platform, "") == 0) {
bson_free (_mongoc_handshake_get ()->platform);
_mongoc_handshake_get ()->platform =
bson_strdup_printf ("%.*s", platform_space, platform);
} else {
_append_and_truncate (
&_mongoc_handshake_get ()->platform, platform, HANDSHAKE_MAX_SIZE);
}
_append_and_truncate (&_mongoc_handshake_get ()->driver_name,
driver_name,
HANDSHAKE_DRIVER_NAME_MAX);
_append_and_truncate (&_mongoc_handshake_get ()->driver_version,
driver_version,
HANDSHAKE_DRIVER_VERSION_MAX);
_mongoc_handshake_freeze ();
bson_mutex_unlock (&gHandshakeLock);
return true;
}
mongoc_handshake_t *
_mongoc_handshake_get (void)
{
return &gMongocHandshake;
}
bool
_mongoc_handshake_appname_is_valid (const char *appname)
{
return strlen (appname) <= MONGOC_HANDSHAKE_APPNAME_MAX;
}
void
_mongoc_handshake_append_sasl_supported_mechs (const mongoc_uri_t *uri,
bson_t *cmd)
{
const char *username;
char *db_user;
username = mongoc_uri_get_username (uri);
db_user =
bson_strdup_printf ("%s.%s", mongoc_uri_get_auth_source (uri), username);
bson_append_utf8 (cmd, "saslSupportedMechs", 18, db_user, -1);
bson_free (db_user);
}
void
_mongoc_handshake_parse_sasl_supported_mechs (
const bson_t *ismaster,
mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs)
{
bson_iter_t iter;
memset (sasl_supported_mechs, 0, sizeof (*sasl_supported_mechs));
if (bson_iter_init_find (&iter, ismaster, "saslSupportedMechs")) {
bson_iter_t array_iter;
if (BSON_ITER_HOLDS_ARRAY (&iter) &&
bson_iter_recurse (&iter, &array_iter)) {
while (bson_iter_next (&array_iter)) {
if (BSON_ITER_HOLDS_UTF8 (&array_iter)) {
const char *mechanism_name = bson_iter_utf8 (&array_iter, NULL);
if (0 == strcmp (mechanism_name, "SCRAM-SHA-256")) {
sasl_supported_mechs->scram_sha_256 = true;
} else if (0 == strcmp (mechanism_name, "SCRAM-SHA-1")) {
sasl_supported_mechs->scram_sha_1 = true;
}
}
}
}
}
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h
similarity index 83%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h
index b36e8f16..b830a7e5 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h
@@ -1,74 +1,77 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_HOST_LIST_PRIVATE_H
#define MONGOC_HOST_LIST_PRIVATE_H
#include "mongoc-host-list.h"
BSON_BEGIN_DECLS
mongoc_host_list_t *
_mongoc_host_list_push (const char *host,
uint16_t port,
int family,
mongoc_host_list_t *next);
void
_mongoc_host_list_upsert (mongoc_host_list_t **list,
- mongoc_host_list_t *new_host);
+ const mongoc_host_list_t *new_host);
mongoc_host_list_t *
-_mongoc_host_list_copy (const mongoc_host_list_t *src,
- mongoc_host_list_t *next);
+_mongoc_host_list_copy_all (const mongoc_host_list_t *src);
bool
_mongoc_host_list_from_string (mongoc_host_list_t *host_list,
const char *host_and_port);
bool
_mongoc_host_list_from_string_with_err (mongoc_host_list_t *host_list,
const char *host_and_port,
bson_error_t *error);
bool
_mongoc_host_list_from_hostport_with_err (mongoc_host_list_t *host_list,
const char *host,
uint16_t port,
bson_error_t *error);
int
_mongoc_host_list_length (mongoc_host_list_t *list);
bool
-_mongoc_host_list_equal (const mongoc_host_list_t *host_a,
- const mongoc_host_list_t *host_b);
+_mongoc_host_list_compare_one (const mongoc_host_list_t *host_a,
+ const mongoc_host_list_t *host_b);
void
_mongoc_host_list_remove_host (mongoc_host_list_t **phosts,
const char *host,
uint16_t port);
void
_mongoc_host_list_destroy_all (mongoc_host_list_t *host);
+bool
+_mongoc_host_list_contains_one (mongoc_host_list_t *host_list,
+ mongoc_host_list_t *host);
+
BSON_END_DECLS
#endif /* MONGOC_HOST_LIST_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c
similarity index 78%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c
index f6d0236f..2d17f846 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c
@@ -1,366 +1,397 @@
/*
* Copyright 2015 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.
*/
#include "mongoc-host-list-private.h"
/* strcasecmp on windows */
#include "mongoc-util-private.h"
#include "utlist.h"
/*
*--------------------------------------------------------------------------
*
* _mongoc_host_list_push --
*
* Add a host to the front of the list and return it.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_host_list_t *
_mongoc_host_list_push (const char *host,
uint16_t port,
int family,
mongoc_host_list_t *next)
{
mongoc_host_list_t *h;
BSON_ASSERT (host);
h = bson_malloc0 (sizeof (mongoc_host_list_t));
bson_strncpy (h->host, host, sizeof h->host);
h->port = port;
bson_snprintf (
h->host_and_port, sizeof h->host_and_port, "%s:%hu", host, port);
h->family = family;
h->next = next;
return h;
}
static mongoc_host_list_t *
_mongoc_host_list_find_host_and_port (mongoc_host_list_t *hosts,
const char *host_and_port)
{
mongoc_host_list_t *iter;
LL_FOREACH (hosts, iter)
{
BSON_ASSERT (iter);
- if (strcmp (iter->host_and_port, host_and_port) == 0) {
+ if (strcasecmp (iter->host_and_port, host_and_port) == 0) {
return iter;
}
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_host_list_upsert --
*
- * If new_host is not already in list, add it to the end of list.
+ * If new_host is not already in list, copy and add it to the end of list.
+ * If *list == NULL, then it will be set to a new host.
*
* Returns:
* Nothing.
*
- * Side effects:
- * Modifies new_host->next when inserting.
- *
*--------------------------------------------------------------------------
*/
void
_mongoc_host_list_upsert (mongoc_host_list_t **list,
- mongoc_host_list_t *new_host)
+ const mongoc_host_list_t *new_host)
{
mongoc_host_list_t *link = NULL;
+ mongoc_host_list_t *next_link = NULL;
BSON_ASSERT (list);
if (!new_host) {
return;
}
link = _mongoc_host_list_find_host_and_port (*list, new_host->host_and_port);
if (!link) {
link = bson_malloc0 (sizeof (mongoc_host_list_t));
LL_APPEND (*list, link);
} else {
/* Make sure linking is preserved when copying data into final. */
- new_host->next = link->next;
+ next_link = link->next;
}
memcpy (link, new_host, sizeof (mongoc_host_list_t));
+ link->next = next_link;
}
-/* Duplicates the elements of {src}, creating a new chain,
- * optionally prepended to an existing chain {next}.
- *
- * Note that as a side-effect of the implementation,
- * this reverses the order of src's copy in the destination.
+/* Duplicates a host list.
*/
mongoc_host_list_t *
-_mongoc_host_list_copy (const mongoc_host_list_t *src, mongoc_host_list_t *next)
+_mongoc_host_list_copy_all (const mongoc_host_list_t *src)
{
- mongoc_host_list_t *h = NULL;
+ mongoc_host_list_t *tail = NULL;
const mongoc_host_list_t *src_iter;
+ mongoc_host_list_t *head = NULL;
LL_FOREACH (src, src_iter)
{
- h = bson_malloc0 (sizeof (mongoc_host_list_t));
- memcpy (h, src_iter, sizeof (mongoc_host_list_t));
+ tail = bson_malloc0 (sizeof (mongoc_host_list_t));
+ memcpy (tail, src_iter, sizeof (mongoc_host_list_t));
- LL_PREPEND (next, h);
+ LL_PREPEND (head, tail);
}
- return h;
+ return head;
}
int
_mongoc_host_list_length (mongoc_host_list_t *list)
{
mongoc_host_list_t *tmp;
int counter = 0;
tmp = list;
while (tmp) {
tmp = tmp->next;
counter++;
}
return counter;
}
/*
*--------------------------------------------------------------------------
*
- * _mongoc_host_list_equal --
+ * _mongoc_host_list_compare_one --
*
* Check two hosts have the same domain (case-insensitive), port,
* and address family.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
-_mongoc_host_list_equal (const mongoc_host_list_t *host_a,
- const mongoc_host_list_t *host_b)
+_mongoc_host_list_compare_one (const mongoc_host_list_t *host_a,
+ const mongoc_host_list_t *host_b)
{
- return (!strcasecmp (host_a->host_and_port, host_b->host_and_port) &&
+ return (0 == strcasecmp (host_a->host_and_port, host_b->host_and_port) &&
host_a->family == host_b->family);
}
+bool
+_mongoc_host_list_contains_one (mongoc_host_list_t *host_list,
+ mongoc_host_list_t *host)
+{
+ return NULL !=
+ _mongoc_host_list_find_host_and_port (host_list, host->host_and_port);
+}
+
/*
*--------------------------------------------------------------------------
*
* _mongoc_host_list_destroy_all --
*
* Destroy whole linked list of hosts.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_host_list_destroy_all (mongoc_host_list_t *host)
{
mongoc_host_list_t *tmp;
while (host) {
tmp = host->next;
bson_free (host);
host = tmp;
}
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_host_list_from_string --
*
* Populate a mongoc_host_list_t from a fully qualified address
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_host_list_from_string (mongoc_host_list_t *link_, const char *address)
{
bson_error_t error = {0};
bool r = _mongoc_host_list_from_string_with_err (link_, address, &error);
if (!r) {
MONGOC_ERROR ("Could not parse address %s: %s", address, error.message);
return false;
}
return true;
}
bool
_mongoc_host_list_from_string_with_err (mongoc_host_list_t *link_,
const char *address,
bson_error_t *error)
{
char *close_bracket;
char *sport;
uint16_t port;
char *host;
bool ret;
bool ipv6 = false;
close_bracket = strchr (address, ']');
/* if this is an ipv6 address. */
if (close_bracket) {
/* if present, the port should immediately follow after ] */
sport = strchr (close_bracket, ':');
if (sport > close_bracket + 1) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "If present, port should immediately follow the \"]\""
+ "in an IPv6 address"
+ );
return false;
}
/* otherwise ] should be the last char. */
if (!sport && *(close_bracket + 1) != '\0') {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "If port is not supplied, \"[\" should be the last"
+ "character");
return false;
}
if (*address != '[') {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "Missing matching bracket \"[\""
+ );
return false;
}
ipv6 = true;
}
/* otherwise, just find the first : */
else {
sport = strchr (address, ':');
}
/* like "example.com:27019" or "[fe80::1]:27019", but not "[fe80::1]" */
if (sport) {
if (sport == address) {
/* bad address like ":27017" */
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "Bad address, \":\" should not be first character"
+ );
return false;
}
if (!mongoc_parse_port (&port, sport + 1)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "Port could not be parsed"
+ );
return false;
}
/* if this is an ipv6 address, strip the [ and ] */
if (ipv6) {
host = bson_strndup (address + 1, close_bracket - address - 1);
} else {
host = bson_strndup (address, sport - address);
}
} else {
/* if this is an ipv6 address, strip the [ and ] */
if (ipv6) {
host = bson_strndup (address + 1, close_bracket - address - 1);
} else {
host = bson_strdup (address);
}
port = MONGOC_DEFAULT_PORT;
}
ret = _mongoc_host_list_from_hostport_with_err (link_, host, port, error);
bson_free (host);
return ret;
}
bool
_mongoc_host_list_from_hostport_with_err (mongoc_host_list_t *link_,
const char *host,
uint16_t port,
bson_error_t *error)
{
size_t host_len = strlen (host);
link_->port = port;
if (host_len == 0) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"Empty hostname in URI");
return false;
}
if (host_len > BSON_HOST_NAME_MAX) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"Hostname provided in URI is too long, max is %d chars",
BSON_HOST_NAME_MAX);
return false;
}
bson_strncpy (link_->host, host, host_len + 1);
/* like "fe80::1" or "::1" */
if (strchr (host, ':')) {
link_->family = AF_INET6;
mongoc_lowercase (link_->host, link_->host);
bson_snprintf (link_->host_and_port,
sizeof link_->host_and_port,
"[%s]:%hu",
link_->host,
link_->port);
} else if (strchr (host, '/') && strstr (host, ".sock")) {
link_->family = AF_UNIX;
bson_strncpy (link_->host_and_port, link_->host, host_len + 1);
} else {
/* This is either an IPv4 or hostname. */
link_->family = AF_UNSPEC;
mongoc_lowercase (link_->host, link_->host);
bson_snprintf (link_->host_and_port,
sizeof link_->host_and_port,
"%s:%hu",
link_->host,
link_->port);
}
link_->next = NULL;
return true;
}
void
_mongoc_host_list_remove_host (mongoc_host_list_t **hosts,
const char *host,
uint16_t port)
{
mongoc_host_list_t *current;
mongoc_host_list_t *prev = NULL;
for (current = *hosts; current; prev = current, current = current->next) {
if ((current->port == port) && (strcmp (current->host, host) == 0)) {
/* Node found, unlink. */
if (prev) {
prev->next = current->next;
} else {
/* No previous, unlinking at head. */
*hosts = current->next;
}
bson_free (current);
break;
}
}
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h
new file mode 100644
index 00000000..c5bc0532
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "mongoc.h"
+#include "mongoc-ssl.h"
+
+#include "mongoc-prelude.h"
+
+#ifndef MONGOC_HTTP_PRIVATE_H
+#define MONGOC_HTTP_PRIVATE_H
+
+typedef struct {
+ const char *host;
+ int port;
+ const char *method;
+ const char *path;
+ const char *extra_headers;
+ const char *body;
+ int body_len;
+} mongoc_http_request_t;
+
+typedef struct {
+ int status;
+ char *headers;
+ int headers_len;
+ char *body;
+ int body_len;
+} mongoc_http_response_t;
+
+void
+_mongoc_http_request_init (mongoc_http_request_t *request);
+
+void
+_mongoc_http_response_init (mongoc_http_response_t *response);
+
+void
+_mongoc_http_response_cleanup (mongoc_http_response_t *response);
+
+/*
+ * Send an HTTP request and get a response.
+ * On success, returns true.
+ * On failure, returns false and sets error.
+ * If use_tls is true, then ssl_opts must be set.
+ * Caller must call _mongoc_http_response_cleanup on res.
+ */
+bool
+_mongoc_http_send (mongoc_http_request_t *req,
+ int timeout_ms,
+ bool use_tls,
+ mongoc_ssl_opt_t *ssl_opts,
+ mongoc_http_response_t *res,
+ bson_error_t *error);
+
+#endif /* MONGOC_HTTP_PRIVATE */
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c
new file mode 100644
index 00000000..d1d813df
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "mongoc-http-private.h"
+
+#include "mongoc-client-private.h"
+#include "mongoc-host-list-private.h"
+#include "mongoc-stream-tls.h"
+#include "mongoc-stream-private.h"
+#include "mongoc-buffer-private.h"
+
+void
+_mongoc_http_request_init (mongoc_http_request_t *request)
+{
+ memset (request, 0, sizeof (*request));
+}
+
+void
+_mongoc_http_response_init (mongoc_http_response_t *response)
+{
+ memset (response, 0, sizeof (*response));
+}
+
+void
+_mongoc_http_response_cleanup (mongoc_http_response_t *response)
+{
+ if (!response) {
+ return;
+ }
+ bson_free (response->headers);
+ bson_free (response->body);
+}
+
+bool
+_mongoc_http_send (mongoc_http_request_t *req,
+ int timeout_ms,
+ bool use_tls,
+ mongoc_ssl_opt_t *ssl_opts,
+ mongoc_http_response_t *res,
+ bson_error_t *error)
+{
+ mongoc_stream_t *stream = NULL;
+ mongoc_host_list_t host_list;
+ bool ret = false;
+ mongoc_iovec_t iovec;
+ ssize_t bytes_read;
+ char *path = NULL;
+ bson_string_t *http_request = NULL;
+ mongoc_buffer_t http_response_buf;
+ char *http_response_str;
+ char *ptr;
+ const char *header_delimiter = "\r\n\r\n";
+
+ memset (res, 0, sizeof (*res));
+ _mongoc_buffer_init (&http_response_buf, NULL, 0, NULL, NULL);
+
+ if (!_mongoc_host_list_from_hostport_with_err (
+ &host_list, req->host, (uint16_t) req->port, error)) {
+ goto fail;
+ }
+
+ stream = mongoc_client_connect_tcp (timeout_ms, &host_list, error);
+ if (!stream) {
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "Failed to connect to: %s",
+ req->host);
+ goto fail;
+ }
+
+#ifndef MONGOC_ENABLE_SSL
+ if (use_tls) {
+ bson_set_error (
+ error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "Failed to connect to %s: libmongoc not built with TLS support",
+ req->host);
+ goto fail;
+ }
+#else
+ if (use_tls) {
+ mongoc_stream_t *tls_stream;
+
+ BSON_ASSERT (ssl_opts);
+ tls_stream = mongoc_stream_tls_new_with_hostname (
+ stream, req->host, ssl_opts, true);
+ if (!tls_stream) {
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "Failed create TLS stream to: %s",
+ req->host);
+ goto fail;
+ }
+
+ stream = tls_stream;
+ if (!mongoc_stream_tls_handshake_block (
+ stream, req->host, timeout_ms, error)) {
+ goto fail;
+ }
+ }
+#endif
+
+ if (!req->path) {
+ path = bson_strdup ("/");
+ } else if (req->path[0] != '/') {
+ path = bson_strdup_printf ("/%s", req->path);
+ } else {
+ path = bson_strdup (req->path);
+ }
+
+ http_request = bson_string_new ("");
+ bson_string_append_printf (
+ http_request, "%s %s HTTP/1.0\r\n", req->method, path);
+ /* Always add Host header. */
+ bson_string_append_printf (http_request, "Host: %s\r\n", req->host);
+ /* Always add Connection: close header to ensure server closes connection. */
+ bson_string_append_printf (http_request, "Connection: close\r\n");
+ /* Add Content-Length if body included. */
+ if (req->body_len) {
+ bson_string_append_printf (
+ http_request, "Content-Length: %d\r\n", req->body_len);
+ }
+ if (req->extra_headers) {
+ bson_string_append (http_request, req->extra_headers);
+ }
+ bson_string_append (http_request, "\r\n");
+
+ iovec.iov_base = http_request->str;
+ iovec.iov_len = http_request->len;
+
+ if (!_mongoc_stream_writev_full (stream, &iovec, 1, timeout_ms, error)) {
+ goto fail;
+ }
+
+ if (req->body) {
+ iovec.iov_base = (void *) req->body;
+ iovec.iov_len = req->body_len;
+ if (!_mongoc_stream_writev_full (stream, &iovec, 1, timeout_ms, error)) {
+ goto fail;
+ }
+ }
+
+ /* Read until connection close. */
+ do {
+ bytes_read = _mongoc_buffer_try_append_from_stream (
+ &http_response_buf, stream, 512, timeout_ms);
+ } while (bytes_read > 0 || mongoc_stream_should_retry (stream));
+
+ if (bytes_read < 0 && mongoc_stream_timed_out (stream)) {
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "Timeout reading from stream");
+ goto fail;
+ }
+
+ if (http_response_buf.len == 0) {
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "No response received");
+ goto fail;
+ }
+
+ http_response_str = (char *) http_response_buf.data;
+
+ /* Find the end of the headers. */
+ ptr = strstr (http_response_str, header_delimiter);
+ if (NULL == ptr) {
+ bson_set_error (
+ error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "Error occurred reading response: end of headers not found");
+ goto fail;
+ }
+
+ res->headers_len = ptr - http_response_str;
+ res->headers = bson_strndup (http_response_str, res->headers_len);
+ res->body_len =
+ http_response_buf.len - res->headers_len - strlen (header_delimiter);
+ /* Add a NULL character in case caller assumes NULL terminated. */
+ res->body = bson_malloc0 (res->body_len + 1);
+ memcpy (res->body, ptr + strlen (header_delimiter), res->body_len);
+ ret = true;
+
+fail:
+ mongoc_stream_destroy (stream);
+ if (http_request) {
+ bson_string_free (http_request, true);
+ }
+ _mongoc_buffer_destroy (&http_response_buf);
+ bson_free (path);
+ return ret;
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c
similarity index 89%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c
index 8f3daea4..2e662b83 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c
@@ -1,202 +1,226 @@
/*
* Copyright 2013 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.
*/
#include <bson/bson.h>
#include "mongoc-config.h"
#include "mongoc-counters-private.h"
#include "mongoc-init.h"
#include "mongoc-handshake-private.h"
#ifdef MONGOC_ENABLE_SSL_OPENSSL
#include "mongoc-openssl-private.h"
#elif defined(MONGOC_ENABLE_SSL_LIBRESSL)
#include "tls.h"
#endif
#include "mongoc-thread-private.h"
#include "common-b64-private.h"
#if defined(MONGOC_ENABLE_CRYPTO_CNG)
#include "mongoc-crypto-private.h"
#include "mongoc-crypto-cng-private.h"
#endif
+#ifdef MONGOC_ENABLE_MONGODB_AWS_AUTH
+#include "kms_message/kms_message.h"
+#endif
+
+#ifdef MONGOC_ENABLE_OCSP_OPENSSL
+#include "mongoc-ocsp-cache-private.h"
+#endif
+
#ifndef MONGOC_NO_AUTOMATIC_GLOBALS
#pragma message( \
"Configure the driver with ENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF.\
Automatic cleanup is deprecated and will be removed in version 2.0.")
#endif
#ifdef MONGOC_ENABLE_SASL_CYRUS
#include <sasl/sasl.h>
static void *
mongoc_cyrus_mutex_alloc (void)
{
bson_mutex_t *mutex;
mutex = (bson_mutex_t *) bson_malloc0 (sizeof (bson_mutex_t));
bson_mutex_init (mutex);
return (void *) mutex;
}
static int
mongoc_cyrus_mutex_lock (void *mutex)
{
bson_mutex_lock ((bson_mutex_t *) mutex);
return SASL_OK;
}
static int
mongoc_cyrus_mutex_unlock (void *mutex)
{
bson_mutex_unlock ((bson_mutex_t *) mutex);
return SASL_OK;
}
static void
mongoc_cyrus_mutex_free (void *mutex)
{
bson_mutex_destroy ((bson_mutex_t *) mutex);
bson_free (mutex);
}
#endif /* MONGOC_ENABLE_SASL_CYRUS */
static BSON_ONCE_FUN (_mongoc_do_init)
{
#ifdef MONGOC_ENABLE_SASL_CYRUS
int status;
#endif
#ifdef MONGOC_ENABLE_SSL_OPENSSL
_mongoc_openssl_init ();
#elif defined(MONGOC_ENABLE_SSL_LIBRESSL)
tls_init ();
#endif
#ifdef MONGOC_ENABLE_SASL_CYRUS
/* The following functions should not use tracing, as they may be invoked
* before mongoc_log_set_handler() can complete. */
sasl_set_mutex (mongoc_cyrus_mutex_alloc,
mongoc_cyrus_mutex_lock,
mongoc_cyrus_mutex_unlock,
mongoc_cyrus_mutex_free);
status = sasl_client_init (NULL);
BSON_ASSERT (status == SASL_OK);
#endif
_mongoc_counters_init ();
#ifdef _WIN32
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD (2, 2);
err = WSAStartup (wVersionRequested, &wsaData);
/* check the version perhaps? */
BSON_ASSERT (err == 0);
}
#endif
#if defined(MONGOC_ENABLE_CRYPTO_CNG)
mongoc_crypto_cng_init ();
#endif
_mongoc_handshake_init ();
+#if defined(MONGOC_ENABLE_MONGODB_AWS_AUTH)
+ kms_message_init ();
+#endif
+
+#if defined(MONGOC_ENABLE_OCSP_OPENSSL)
+ _mongoc_ocsp_cache_init ();
+#endif
+
BSON_ONCE_RETURN;
}
void
mongoc_init (void)
{
static bson_once_t once = BSON_ONCE_INIT;
bson_once (&once, _mongoc_do_init);
}
static BSON_ONCE_FUN (_mongoc_do_cleanup)
{
#ifdef MONGOC_ENABLE_SSL_OPENSSL
_mongoc_openssl_cleanup ();
#endif
#ifdef MONGOC_ENABLE_SASL_CYRUS
#ifdef MONGOC_HAVE_SASL_CLIENT_DONE
sasl_client_done ();
#else
/* fall back to deprecated function */
sasl_done ();
#endif
#endif
#ifdef _WIN32
WSACleanup ();
#endif
#if defined(MONGOC_ENABLE_CRYPTO_CNG)
mongoc_crypto_cng_cleanup ();
#endif
_mongoc_counters_cleanup ();
_mongoc_handshake_cleanup ();
+#if defined(MONGOC_ENABLE_MONGODB_AWS_AUTH)
+ kms_message_cleanup ();
+#endif
+
+#if defined(MONGOC_ENABLE_OCSP_OPENSSL)
+ _mongoc_ocsp_cache_cleanup ();
+#endif
+
BSON_ONCE_RETURN;
}
void
mongoc_cleanup (void)
{
static bson_once_t once = BSON_ONCE_INIT;
bson_once (&once, _mongoc_do_cleanup);
}
/*
* On GCC, just use __attribute__((constructor)) to perform initialization
* automatically for the application.
*/
#if defined(__GNUC__) && !defined(MONGOC_NO_AUTOMATIC_GLOBALS)
static void
_mongoc_init_ctor (void) __attribute__ ((constructor));
static void
_mongoc_init_ctor (void)
{
mongoc_init ();
}
static void
_mongoc_init_dtor (void) __attribute__ ((destructor));
static void
_mongoc_init_dtor (void)
{
bson_mem_restore_vtable ();
mongoc_cleanup ();
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h
new file mode 100644
index 00000000..e764fdd8
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "mongoc-prelude.h"
+
+#ifndef MONGOC_STREAM_INTERRUPTIBLE_PRIVATE_H
+#define MONGOC_STREAM_INTERRUPTIBLE_PRIVATE_H
+
+#include "mongoc-stream.h"
+
+/* Creates a stream to use to interrupt calls to mongoc_stream_poll.
+ *
+ * The expected use is to cancel in-progress ismaster commands (especially for
+ * awaitable ismaster). An ismaster command may not respond for a long time, so
+ * reading the reply may block on mongoc_stream_poll until data is readable. To
+ * interrupt mongoc_stream_poll, a stream retrieved by
+ * _mongoc_interrupt_get_stream can be added to the call of poll. Any other
+ * thread can call _mongoc_interrupt_interrupt to write to that stream.
+ */
+typedef struct _mongoc_interrupt_t mongoc_interrupt_t;
+
+mongoc_interrupt_t *
+_mongoc_interrupt_new (uint32_t timeout_ms);
+
+/* Interrupt the stream. An in progress poll for POLLIN should return. */
+bool
+_mongoc_interrupt_interrupt (mongoc_interrupt_t *interrupt);
+
+/* Returns a socket stream, that can be polled alongside other
+ * socket streams. */
+mongoc_stream_t *
+_mongoc_interrupt_get_stream (mongoc_interrupt_t *interrupt);
+
+/* Flushes queued data on an interrupt.
+ *
+ * This is not guaranteed to flush all data, but it does not block.
+ */
+bool
+_mongoc_interrupt_flush (mongoc_interrupt_t *interrupt);
+
+void
+_mongoc_interrupt_destroy (mongoc_interrupt_t *interrupt);
+
+#endif /* MONGOC_STREAM_INTERRUPTIBLE_PRIVATE_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c
new file mode 100644
index 00000000..577bcc2c
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "mongoc/mongoc-errno-private.h"
+#include "mongoc/mongoc-interrupt-private.h"
+#include "mongoc/mongoc-log.h"
+#include "mongoc/mongoc-socket-private.h"
+#include "mongoc/mongoc-stream-socket.h"
+#include "mongoc/mongoc-trace-private.h"
+#include "common-thread-private.h"
+
+/* The interrupt stream is implemented in two ways.
+ * On POSIX, this uses the self-pipe trick.
+ * On Windows, this uses a pair of TCP sockets.
+ */
+struct _mongoc_interrupt_t {
+ bson_mutex_t mutex;
+
+ union {
+ /* For POSIX. pipe_fds[0] is the read end and pipe_fds[1] is the write
+ * end. */
+ int pipe_fds[2];
+
+ /* For Windows */
+ struct {
+ mongoc_socket_t *read;
+ mongoc_socket_t *write;
+ } socket_pair;
+ } impl;
+
+ mongoc_stream_t *stream;
+};
+
+mongoc_stream_t *
+_mongoc_interrupt_get_stream (mongoc_interrupt_t *interrupt)
+{
+ return interrupt->stream;
+}
+
+static void
+_log_errno (char *prefix, int _errno)
+{
+ char buf[128] = {0};
+
+ bson_strerror_r (_errno, buf, sizeof (buf));
+ MONGOC_ERROR ("%s: (%d) %s", prefix, _errno, buf);
+}
+
+#ifdef _WIN32
+/* TCP socket pair implementation. */
+mongoc_interrupt_t *
+_mongoc_interrupt_new (uint32_t timeout_ms)
+{
+ mongoc_interrupt_t *interrupt;
+ mongoc_socket_t *listen_socket = NULL;
+ mongoc_socket_t *interrupt_socket = NULL;
+ struct sockaddr_storage server_addr;
+ mongoc_socklen_t sock_len;
+ int ret;
+ bool success = false;
+ struct sockaddr_in server_addr_in = {0};
+
+ ENTRY;
+
+ interrupt = (mongoc_interrupt_t *) bson_malloc0 (sizeof *interrupt);
+ bson_mutex_init (&interrupt->mutex);
+
+ /* Inspired by cpython's implementation of socketpair. */
+ listen_socket = mongoc_socket_new (AF_INET, SOCK_STREAM, 0);
+ if (!listen_socket) {
+ MONGOC_ERROR ("socket creation failed");
+ GOTO (fail);
+ }
+
+ memset (&server_addr_in, 0, sizeof (server_addr_in));
+ server_addr_in.sin_family = AF_INET;
+ server_addr_in.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ ret = mongoc_socket_bind (listen_socket,
+ (struct sockaddr *) &server_addr_in,
+ sizeof (server_addr_in));
+ if (ret == -1) {
+ _log_errno ("bind failed", mongoc_socket_errno (listen_socket));
+ GOTO (fail);
+ }
+
+ ret = mongoc_socket_listen (listen_socket, 1);
+ if (ret == -1) {
+ _log_errno ("listen failed", mongoc_socket_errno (listen_socket));
+ GOTO (fail);
+ }
+
+ sock_len = sizeof (server_addr);
+ ret = mongoc_socket_getsockname (
+ listen_socket, (struct sockaddr *) &server_addr, &sock_len);
+ if (-1 == ret) {
+ _log_errno ("getsockname failed", mongoc_socket_errno (listen_socket));
+ GOTO (fail);
+ }
+
+ interrupt->impl.socket_pair.read =
+ mongoc_socket_new (server_addr.ss_family, SOCK_STREAM, 0);
+ if (!interrupt->impl.socket_pair.read) {
+ MONGOC_ERROR ("socket creation failed");
+ GOTO (fail);
+ }
+
+ /* Begin non-blocking connect. */
+ ret = mongoc_socket_connect (interrupt->impl.socket_pair.read,
+ (struct sockaddr *) &server_addr,
+ sock_len,
+ 0);
+ if (ret == -1 &&
+ !MONGOC_ERRNO_IS_AGAIN (
+ mongoc_socket_errno (interrupt->impl.socket_pair.read))) {
+ _log_errno ("connect failed",
+ mongoc_socket_errno (interrupt->impl.socket_pair.read));
+ GOTO (fail);
+ }
+
+ interrupt->impl.socket_pair.write = mongoc_socket_accept (
+ listen_socket, bson_get_monotonic_time () + timeout_ms * 1000);
+ if (!interrupt->impl.socket_pair.write) {
+ _log_errno ("accept failed", mongoc_socket_errno (listen_socket));
+ GOTO (fail);
+ }
+
+ /* Create an unowned socket. interrupt_socket has 0 for the pid, so it will
+ * be considered unowned. */
+ interrupt_socket = bson_malloc0 (sizeof (mongoc_socket_t));
+ interrupt_socket->sd = interrupt->impl.socket_pair.read->sd;
+ /* Creating the stream takes ownership of the mongoc_socket_t. */
+ interrupt->stream = mongoc_stream_socket_new (interrupt_socket);
+ success = true;
+fail:
+ mongoc_socket_destroy (listen_socket);
+ if (!success) {
+ _mongoc_interrupt_destroy (interrupt);
+ interrupt = NULL;
+ }
+ RETURN (interrupt);
+}
+
+void
+_mongoc_interrupt_destroy (mongoc_interrupt_t *interrupt)
+{
+ if (!interrupt) {
+ return;
+ }
+
+ bson_mutex_destroy (&interrupt->mutex);
+ mongoc_socket_destroy (interrupt->impl.socket_pair.read);
+ mongoc_socket_destroy (interrupt->impl.socket_pair.write);
+ mongoc_stream_destroy (interrupt->stream);
+ bson_free (interrupt);
+}
+
+bool
+_mongoc_interrupt_flush (mongoc_interrupt_t *interrupt)
+{
+ uint8_t buf[1];
+ while (true) {
+ if (-1 == mongoc_socket_recv (
+ interrupt->impl.socket_pair.read, buf, sizeof (buf), 0, 0)) {
+ if (MONGOC_ERRNO_IS_AGAIN (errno)) {
+ /* Nothing left to read. */
+ return true;
+ } else {
+ /* Unexpected error. */
+ _log_errno ("interrupt recv failed",
+ mongoc_socket_errno (interrupt->impl.socket_pair.read));
+ return false;
+ }
+ }
+ }
+ /* Should never be reached. */
+ BSON_ASSERT (false);
+}
+
+bool
+_mongoc_interrupt_interrupt (mongoc_interrupt_t *interrupt)
+{
+ bson_mutex_lock (&interrupt->mutex);
+ if (mongoc_socket_send (interrupt->impl.socket_pair.write, "!", 1, 0) ==
+ -1 &&
+ !MONGOC_ERRNO_IS_AGAIN (errno)) {
+ _log_errno ("interrupt send failed",
+ mongoc_socket_errno (interrupt->impl.socket_pair.write));
+ bson_mutex_unlock (&interrupt->mutex);
+ return false;
+ }
+ bson_mutex_unlock (&interrupt->mutex);
+ return true;
+}
+
+#else
+/* Pipe implementation. */
+
+/* Set non-blocking and close on exec. */
+static bool
+_set_pipe_flags (int pipe_fd)
+{
+ int flags;
+
+ flags = fcntl (pipe_fd, F_GETFL);
+
+ if (-1 == fcntl (pipe_fd, F_SETFL, (flags | O_NONBLOCK))) {
+ return false;
+ }
+
+#ifdef FD_CLOEXEC
+ flags = fcntl (pipe_fd, F_GETFD);
+ if (-1 == fcntl (pipe_fd, F_SETFD, (flags | FD_CLOEXEC))) {
+ return false;
+ }
+#endif
+ return true;
+}
+
+mongoc_interrupt_t *
+_mongoc_interrupt_new (uint32_t timeout_ms)
+{
+ mongoc_interrupt_t *interrupt;
+ mongoc_socket_t *interrupt_socket = NULL;
+ bool success = false;
+
+ ENTRY;
+
+ interrupt = (mongoc_interrupt_t *) bson_malloc0 (sizeof *interrupt);
+ bson_mutex_init (&interrupt->mutex);
+
+ if (0 != pipe (interrupt->impl.pipe_fds)) {
+ _log_errno ("pipe creation failed", errno);
+ GOTO (fail);
+ }
+
+ /* Make the pipe non-blocking and close-on-exec. */
+ if (!_set_pipe_flags (interrupt->impl.pipe_fds[0]) ||
+ !_set_pipe_flags (interrupt->impl.pipe_fds[1])) {
+ _log_errno ("unable to configure pipes", errno);
+ }
+
+ /* Create an unowned socket. interrupt_socket has 0 for the pid, so it will
+ * be considered unowned. */
+ interrupt_socket = bson_malloc0 (sizeof (mongoc_socket_t));
+ interrupt_socket->sd = interrupt->impl.pipe_fds[0];
+ /* Creating the stream takes ownership of the mongoc_socket_t. */
+ interrupt->stream = mongoc_stream_socket_new (interrupt_socket);
+
+ success = true;
+fail:
+ if (!success) {
+ _mongoc_interrupt_destroy (interrupt);
+ interrupt = NULL;
+ }
+ RETURN (interrupt);
+}
+
+bool
+_mongoc_interrupt_flush (mongoc_interrupt_t *interrupt)
+{
+ char c;
+ while (true) {
+ if (read (interrupt->impl.pipe_fds[0], &c, 1) == -1) {
+ if (MONGOC_ERRNO_IS_AGAIN (errno)) {
+ /* Nothing left to read. */
+ return true;
+ } else {
+ /* Unexpected error. */
+ MONGOC_ERROR ("failed to read from pipe: %d", errno);
+ return false;
+ }
+ }
+ }
+ /* Should never be reached. */
+ BSON_ASSERT (false);
+}
+
+bool
+_mongoc_interrupt_interrupt (mongoc_interrupt_t *interrupt)
+{
+ bson_mutex_lock (&interrupt->mutex);
+ if (write (interrupt->impl.pipe_fds[1], "!", 1) == -1 &&
+ !MONGOC_ERRNO_IS_AGAIN (errno)) {
+ MONGOC_ERROR ("failed to write to pipe: %d", errno);
+ bson_mutex_unlock (&interrupt->mutex);
+ return false;
+ }
+ bson_mutex_unlock (&interrupt->mutex);
+ return true;
+}
+
+void
+_mongoc_interrupt_destroy (mongoc_interrupt_t *interrupt)
+{
+ if (!interrupt) {
+ return;
+ }
+ bson_mutex_destroy (&interrupt->mutex);
+ if (interrupt->impl.pipe_fds[0]) {
+ close (interrupt->impl.pipe_fds[0]);
+ }
+ if (interrupt->impl.pipe_fds[1]) {
+ close (interrupt->impl.pipe_fds[1]);
+ }
+ mongoc_stream_destroy (interrupt->stream);
+ bson_free (interrupt);
+}
+#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c
index 849e1347..dc9538c7 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c
@@ -1,438 +1,441 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-handshake-os-private.h"
#ifdef MONGOC_OS_IS_LINUX
#include <stdio.h>
#include <sys/utsname.h>
#include "mongoc-error.h"
#include "mongoc-linux-distro-scanner-private.h"
#include "mongoc-log.h"
#include "mongoc-handshake-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#include "mongoc-version.h"
#define LINE_BUFFER_SIZE 1024
/*
* fgets() wrapper which removes '\n' at the end of the string
* Return 0 on failure or EOF.
*/
static size_t
_fgets_wrapper (char *buffer, size_t buffer_size, FILE *f)
{
char *fgets_res;
size_t len;
fgets_res = fgets (buffer, buffer_size, f);
if (!fgets_res) {
/* Didn't read anything. Empty file or error. */
if (ferror (f)) {
TRACE ("fgets() failed with error %d", errno);
}
return 0;
}
/* Chop off trailing \n */
len = strlen (buffer);
if (len > 0 && buffer[len - 1] == '\n') {
buffer[len - 1] = '\0';
len--;
} else if (len == buffer_size - 1) {
/* We read buffer_size bytes without hitting a newline
* therefore the line is super long, so we say this file is invalid.
* This is important since if we are in this situation, the NEXT call to
* fgets() will keep reading where we left off.
*
* This protects us from files like:
* aaaaa...DISTRIB_ID=nasal demons
*/
TRACE ("Found line of length %ld, bailing out", len);
return 0;
}
return len;
}
static void
_process_line (const char *name_key,
size_t name_key_len,
char **name,
const char *version_key,
size_t version_key_len,
char **version,
const char *line,
size_t line_len)
{
size_t key_len;
const char *equal_sign;
const char *value;
const char *needle = "=";
size_t value_len = 0;
ENTRY;
/* Figure out where = is. Everything before is the key,
* and everything after is the value */
equal_sign = strstr (line, needle);
if (equal_sign == NULL) {
TRACE ("Encountered malformed line: %s", line);
/* This line is malformed/incomplete, so skip it */
EXIT;
}
/* Should never happen since we null terminated this line */
BSON_ASSERT (equal_sign < line + line_len);
key_len = equal_sign - line;
value = equal_sign + strlen (needle);
value_len = strlen (value);
if (value_len > 2 && value[0] == '"' && value[value_len - 1] == '"') {
value_len -= 2;
value++;
}
/* If we find two copies of either key, the *name == NULL check will fail
* so we will just keep the first value encountered. */
if (name_key_len == key_len && strncmp (line, name_key, key_len) == 0 &&
!(*name)) {
*name = bson_strndup (value, value_len);
TRACE ("Found name: %s", *name);
} else if (version_key_len == key_len &&
strncmp (line, version_key, key_len) == 0 && !(*version)) {
*version = bson_strndup (value, value_len);
TRACE ("Found version: %s", *version);
}
EXIT;
}
/*
* Parse a file of the form:
* KEY=VALUE
* Looking for name_key and version_key, and storing
* their values into *name and *version.
* The values in *name and *version must be freed with bson_free.
*/
void
_mongoc_linux_distro_scanner_read_key_value_file (const char *path,
const char *name_key,
ssize_t name_key_len,
char **name,
const char *version_key,
ssize_t version_key_len,
char **version)
{
const int max_lines = 100;
int lines_read = 0;
char buffer[LINE_BUFFER_SIZE];
size_t buflen;
FILE *f;
ENTRY;
*name = NULL;
*version = NULL;
if (name_key_len < 0) {
name_key_len = strlen (name_key);
}
if (version_key_len < 0) {
version_key_len = strlen (version_key);
}
if (access (path, R_OK)) {
TRACE ("No permission to read from %s: errno: %d", path, errno);
EXIT;
}
f = fopen (path, "r");
if (!f) {
TRACE ("fopen failed on %s: %d", path, errno);
EXIT;
}
while (lines_read < max_lines) {
buflen = _fgets_wrapper (buffer, sizeof (buffer), f);
if (buflen == 0) {
/* Error or eof */
break;
}
_process_line (name_key,
name_key_len,
name,
version_key,
version_key_len,
version,
buffer,
buflen);
if (*version && *name) {
/* No point in reading any more */
break;
}
lines_read++;
}
fclose (f);
EXIT;
}
/*
* Find the first string in a list which is a valid file. Assumes
* passed in list is NULL terminated!
*/
const char *
_get_first_existing (const char **paths)
{
const char **p = &paths[0];
ENTRY;
for (; *p != NULL; p++) {
if (access (*p, F_OK)) {
/* Just doesn't exist */
continue;
}
if (access (*p, R_OK)) {
TRACE ("file %s exists, but cannot be read: error %d", *p, errno);
continue;
}
RETURN (*p);
}
RETURN (NULL);
}
/*
* Given a line of text, split it by the word "release." For example:
* Ubuntu release 14.04 =>
* *name = Ubuntu
* *version = 14.04
* If the word "release" isn't found then we put the whole string into *name
* (even if the string is empty).
*/
void
_mongoc_linux_distro_scanner_split_line_by_release (const char *line,
ssize_t line_len,
char **name,
char **version)
{
const char *needle_loc;
const char *const needle = " release ";
const char *version_string;
*name = NULL;
*version = NULL;
if (line_len < 0) {
line_len = strlen (line);
}
needle_loc = strstr (line, needle);
if (!needle_loc) {
*name = bson_strdup (line);
return;
} else if (needle_loc == line) {
/* The file starts with the word " release "
* This file is weird enough we will just abandon it. */
return;
}
*name = bson_strndup (line, needle_loc - line);
version_string = needle_loc + strlen (needle);
if (version_string == line + line_len) {
/* Weird. The file just ended with "release " */
return;
}
*version = bson_strdup (version_string);
}
/*
* Search for a *-release file, and read its contents.
*/
void
_mongoc_linux_distro_scanner_read_generic_release_file (const char **paths,
char **name,
char **version)
{
const char *path;
size_t buflen;
char buffer[LINE_BUFFER_SIZE];
FILE *f;
ENTRY;
*name = NULL;
*version = NULL;
path = _get_first_existing (paths);
if (!path) {
EXIT;
}
f = fopen (path, "r");
if (!f) {
TRACE ("Found %s exists and readable but couldn't open: %d", path, errno);
EXIT;
}
/* Read the first line of the file, look for the word "release" */
buflen = _fgets_wrapper (buffer, sizeof (buffer), f);
if (buflen > 0) {
TRACE ("Trying to split buffer with contents %s", buffer);
/* Try splitting the string. If we can't it'll store everything in
* *name. */
_mongoc_linux_distro_scanner_split_line_by_release (
buffer, buflen, name, version);
}
fclose (f);
EXIT;
}
static void
_get_kernel_version_from_uname (char **version)
{
struct utsname system_info;
if (uname (&system_info) >= 0) {
*version = bson_strdup_printf ("kernel %s", system_info.release);
} else {
*version = NULL;
}
}
/*
* Some boilerplate logic that tries to set *name and *version to new_name
* and new_version if it's not already set. Values of new_name and new_version
* should not be used after this call.
*/
static bool
_set_name_and_version_if_needed (char **name,
char **version,
char *new_name,
char *new_version)
{
if (new_name && !(*name)) {
*name = new_name;
} else {
bson_free (new_name);
}
if (new_version && !(*version)) {
*version = new_version;
} else {
bson_free (new_version);
}
return (*name) && (*version);
}
bool
_mongoc_linux_distro_scanner_get_distro (char **name, char **version)
{
/* In case we decide to try looking up name/version again */
char *new_name;
char *new_version;
const char *generic_release_paths[] = {
"/etc/redhat-release",
"/etc/novell-release",
"/etc/gentoo-release",
"/etc/SuSE-release",
"/etc/SUSE-release",
"/etc/sles-release",
"/etc/debian_release",
"/etc/slackware-version",
"/etc/centos-release",
NULL,
};
ENTRY;
*name = NULL;
*version = NULL;
_mongoc_linux_distro_scanner_read_key_value_file (
"/etc/os-release", "NAME", -1, name, "VERSION_ID", -1, version);
if (*name && *version) {
RETURN (true);
}
_mongoc_linux_distro_scanner_read_key_value_file ("/etc/lsb-release",
"DISTRIB_ID",
-1,
&new_name,
"DISTRIB_RELEASE",
-1,
&new_version);
if (_set_name_and_version_if_needed (name, version, new_name, new_version)) {
RETURN (true);
}
/* Try to read from a generic release file */
_mongoc_linux_distro_scanner_read_generic_release_file (
generic_release_paths, &new_name, &new_version);
if (_set_name_and_version_if_needed (name, version, new_name, new_version)) {
RETURN (true);
}
if (*version == NULL) {
_get_kernel_version_from_uname (version);
}
if (*name && *version) {
RETURN (true);
}
bson_free (*name);
bson_free (*version);
*name = NULL;
*version = NULL;
RETURN (false);
}
+#else
+/* ensure the translation unit is not empty */
+extern int mongoc_os_is_not_linux;
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h
new file mode 100644
index 00000000..7b93de11
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+#include "mongoc-prelude.h"
+
+#ifndef MONGOC_OCSP_CACHE_PRIVATE_H
+#define MONGOC_OCSP_CACHE_PRIVATE_H
+
+#include "mongoc-config.h"
+
+#ifdef MONGOC_ENABLE_SSL_OPENSSL
+#include "mongoc-openssl-private.h"
+
+#ifdef MONGOC_ENABLE_OCSP_OPENSSL
+#include <openssl/ocsp.h>
+
+void
+_mongoc_ocsp_cache_init (void);
+
+void
+_mongoc_ocsp_cache_set_resp (OCSP_CERTID *id,
+ int cert_status,
+ int reason,
+ ASN1_GENERALIZEDTIME *this_update,
+ ASN1_GENERALIZEDTIME *next_update);
+
+int
+_mongoc_ocsp_cache_length (void);
+
+bool
+_mongoc_ocsp_cache_get_status (OCSP_CERTID *id,
+ int *cert_status,
+ int *reason,
+ ASN1_GENERALIZEDTIME **this_update,
+ ASN1_GENERALIZEDTIME **next_update);
+
+void
+_mongoc_ocsp_cache_cleanup (void);
+
+#endif /* MONGOC_ENABLE_OCSP_OPENSSL */
+#endif /* MONGOC_ENABLE_SSL_OPENSSL */
+
+/* ensure the translation unit is not empty */
+extern int no_mongoc_ocsp_cache;
+#endif /* MONGO_C_DRIVER_MONGOC_OCSP_CACHE_PRIVATE_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c
new file mode 100644
index 00000000..3f30c2e1
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+
+#include "mongoc-ocsp-cache-private.h"
+#ifdef MONGOC_ENABLE_OCSP_OPENSSL
+
+#include "utlist.h"
+#include "mongoc-trace-private.h"
+#include <bson/bson.h>
+#include <common-thread-private.h>
+
+typedef struct _cache_entry_list_t {
+ struct _cache_entry_list_t *next;
+ OCSP_CERTID *id;
+ int cert_status, reason;
+ ASN1_GENERALIZEDTIME *this_update, *next_update;
+} cache_entry_list_t;
+
+static cache_entry_list_t *cache;
+static bson_mutex_t ocsp_cache_mutex;
+
+void
+_mongoc_ocsp_cache_init ()
+{
+ bson_mutex_init (&ocsp_cache_mutex);
+}
+
+static int
+cache_cmp (cache_entry_list_t *out, OCSP_CERTID *id)
+{
+ ENTRY;
+ if (!out || !out->id || !id)
+ RETURN (1);
+ RETURN (OCSP_id_cmp (out->id, id));
+}
+
+static cache_entry_list_t *
+get_cache_entry (OCSP_CERTID *id)
+{
+ cache_entry_list_t *iter = NULL;
+ ENTRY;
+
+ LL_SEARCH (cache, iter, id, cache_cmp);
+ RETURN (iter);
+}
+
+#define REPLACE_ASN1_TIME(_old, _new) \
+ do { \
+ if ((_new)) { \
+ if ((_old)) \
+ ASN1_GENERALIZEDTIME_free ((_old)); \
+ (_old) = ASN1_item_dup (ASN1_ITEM_rptr (ASN1_TIME), (_new)); \
+ } \
+ } while (0)
+
+static void
+update_entry (cache_entry_list_t *entry,
+ int cert_status,
+ int reason,
+ ASN1_GENERALIZEDTIME *this_update,
+ ASN1_GENERALIZEDTIME *next_update)
+{
+ ENTRY;
+ REPLACE_ASN1_TIME (entry->next_update, next_update);
+ REPLACE_ASN1_TIME (entry->this_update, this_update);
+ entry->cert_status = cert_status;
+ entry->reason = reason;
+}
+
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+static int
+_cmp_time (ASN1_TIME *a, ASN1_TIME *b)
+{
+ return ASN1_TIME_compare (a, b);
+}
+#else
+static int
+_cmp_time (ASN1_TIME *a, ASN1_TIME *b)
+{
+ /* For older OpenSSL, always report that "a" is before "b". I.e. do not
+ * replace the entry.
+ * If a driver would accept a stapled OCSP response and that response has a
+ * later nextUpdate than the response already in the cache, drivers SHOULD
+ * replace the older entry in the cache with the fresher response. */
+ return -1;
+}
+#endif
+
+void
+_mongoc_ocsp_cache_set_resp (OCSP_CERTID *id,
+ int cert_status,
+ int reason,
+ ASN1_GENERALIZEDTIME *this_update,
+ ASN1_GENERALIZEDTIME *next_update)
+{
+ cache_entry_list_t *entry = NULL;
+ ENTRY;
+
+ bson_mutex_lock (&ocsp_cache_mutex);
+ if (!(entry = get_cache_entry (id))) {
+ entry = bson_malloc0 (sizeof (cache_entry_list_t));
+ entry->id = OCSP_CERTID_dup (id);
+ LL_APPEND (cache, entry);
+ update_entry (entry, cert_status, reason, this_update, next_update);
+ } else if (next_update && _cmp_time (next_update, entry->next_update) == 1) {
+ update_entry (entry, cert_status, reason, this_update, next_update);
+ } else {
+ /* Do nothing; our next_update is at a later date */
+ }
+ bson_mutex_unlock (&ocsp_cache_mutex);
+}
+
+int
+_mongoc_ocsp_cache_length ()
+{
+ cache_entry_list_t *iter;
+ int counter;
+
+ bson_mutex_lock (&ocsp_cache_mutex);
+ LL_COUNT (cache, iter, counter);
+ bson_mutex_unlock (&ocsp_cache_mutex);
+ RETURN (counter);
+}
+
+static void
+cache_entry_destroy (cache_entry_list_t *entry)
+{
+ OCSP_CERTID_free (entry->id);
+ ASN1_GENERALIZEDTIME_free (entry->this_update);
+ ASN1_GENERALIZEDTIME_free (entry->next_update);
+ bson_free (entry);
+}
+bool
+_mongoc_ocsp_cache_get_status (OCSP_CERTID *id,
+ int *cert_status,
+ int *reason,
+ ASN1_GENERALIZEDTIME **this_update,
+ ASN1_GENERALIZEDTIME **next_update)
+{
+ cache_entry_list_t *entry = NULL;
+ bool ret = false;
+ ENTRY;
+
+ bson_mutex_lock (&ocsp_cache_mutex);
+ if (!(entry = get_cache_entry (id))) {
+ GOTO (done);
+ }
+
+ if (entry->this_update && entry->next_update &&
+ !OCSP_check_validity (entry->this_update, entry->next_update, 0L, -1L)) {
+ LL_DELETE (cache, entry);
+ cache_entry_destroy (entry);
+ GOTO (done);
+ }
+
+ BSON_ASSERT_PARAM (cert_status);
+ BSON_ASSERT_PARAM (reason);
+ BSON_ASSERT_PARAM (this_update);
+ BSON_ASSERT_PARAM (next_update);
+
+ *cert_status = entry->cert_status;
+ *reason = entry->reason;
+ *this_update = entry->this_update;
+ *next_update = entry->next_update;
+
+ ret = true;
+done:
+ bson_mutex_unlock (&ocsp_cache_mutex);
+ RETURN (ret);
+}
+
+void
+_mongoc_ocsp_cache_cleanup ()
+{
+ cache_entry_list_t *iter = NULL;
+ cache_entry_list_t *next = NULL;
+ ENTRY;
+
+ bson_mutex_lock (&ocsp_cache_mutex);
+ for (iter = cache; iter != NULL; iter = next) {
+ next = iter->next;
+ cache_entry_destroy (iter);
+ }
+
+ cache = NULL;
+ bson_mutex_unlock (&ocsp_cache_mutex);
+ bson_mutex_destroy (&ocsp_cache_mutex);
+}
+
+#endif /* MONGOC_ENABLE_OCSP_OPENSSL */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h
similarity index 66%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h
index 9ccec85c..b276622f 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h
@@ -1,50 +1,62 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_OPENSSL_PRIVATE_H
#define MONGOC_OPENSSL_PRIVATE_H
#include <bson/bson.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "mongoc-ssl.h"
+#include "mongoc-stream-tls-openssl-private.h"
+#if (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_OCSP) && \
+ !defined(LIBRESSL_VERSION_NUMBER)
+#define MONGOC_ENABLE_OCSP_OPENSSL
+#endif
-BSON_BEGIN_DECLS
+BSON_BEGIN_DECLS
bool
-_mongoc_openssl_check_cert (SSL *ssl,
- const char *host,
- bool allow_invalid_hostname);
+_mongoc_openssl_check_peer_hostname (SSL *ssl,
+ const char *host,
+ bool allow_invalid_hostname);
SSL_CTX *
_mongoc_openssl_ctx_new (mongoc_ssl_opt_t *opt);
char *
_mongoc_openssl_extract_subject (const char *filename, const char *passphrase);
void
_mongoc_openssl_init (void);
void
_mongoc_openssl_cleanup (void);
+#ifdef MONGOC_ENABLE_OCSP_OPENSSL
+int
+_mongoc_ocsp_tlsext_status (SSL *ssl, mongoc_openssl_ocsp_opt_t *opts);
+#endif
+
+bool
+_mongoc_tlsfeature_has_status_request (const uint8_t *data, int length);
BSON_END_DECLS
#endif /* MONGOC_OPENSSL_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
similarity index 53%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
index 0dcfe4cf..d6c1fef9 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
@@ -1,679 +1,1187 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_OPENSSL
#include <bson/bson.h>
#include <limits.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
+#include <openssl/ocsp.h>
#include <openssl/x509v3.h>
#include <openssl/crypto.h>
#include <string.h>
+#include "mongoc-http-private.h"
#include "mongoc-init.h"
+#include "mongoc-openssl-private.h"
#include "mongoc-socket.h"
#include "mongoc-ssl.h"
-#include "mongoc-openssl-private.h"
-#include "mongoc-trace-private.h"
+#include "mongoc-stream-tls-openssl-private.h"
#include "mongoc-thread-private.h"
+#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
+#ifdef MONGOC_ENABLE_OCSP_OPENSSL
+#include "mongoc-ocsp-cache-private.h"
+#endif
+
#ifdef _WIN32
#include <wincrypt.h>
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static bson_mutex_t *gMongocOpenSslThreadLocks;
static void
_mongoc_openssl_thread_startup (void);
static void
_mongoc_openssl_thread_cleanup (void);
#endif
#ifndef MONGOC_HAVE_ASN1_STRING_GET0_DATA
#define ASN1_STRING_get0_data ASN1_STRING_data
#endif
+static int tlsfeature_nid;
+
/**
* _mongoc_openssl_init:
*
* initialization function for SSL
*
* This needs to get called early on and is not threadsafe. Called by
* mongoc_init.
*/
void
_mongoc_openssl_init (void)
{
SSL_CTX *ctx;
SSL_library_init ();
SSL_load_error_strings ();
ERR_load_BIO_strings ();
OpenSSL_add_all_algorithms ();
#if OPENSSL_VERSION_NUMBER < 0x10100000L
_mongoc_openssl_thread_startup ();
#endif
ctx = SSL_CTX_new (SSLv23_method ());
if (!ctx) {
MONGOC_ERROR ("Failed to initialize OpenSSL.");
}
+#ifdef NID_tlsfeature
+ tlsfeature_nid = NID_tlsfeature;
+#else
+ /* TLS versions before 1.1.0 did not define the TLS Feature extension. */
+ tlsfeature_nid =
+ OBJ_create ("1.3.6.1.5.5.7.1.24", "tlsfeature", "TLS Feature");
+#endif
+
SSL_CTX_free (ctx);
}
void
_mongoc_openssl_cleanup (void)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
_mongoc_openssl_thread_cleanup ();
#endif
}
static int
_mongoc_openssl_password_cb (char *buf, int num, int rwflag, void *user_data)
{
char *pass = (char *) user_data;
int pass_len = (int) strlen (pass);
if (num < pass_len + 1) {
return 0;
}
bson_strncpy (buf, pass, num);
return pass_len;
}
#ifdef _WIN32
bool
_mongoc_openssl_import_cert_store (LPWSTR store_name,
DWORD dwFlags,
X509_STORE *openssl_store)
{
PCCERT_CONTEXT cert = NULL;
HCERTSTORE cert_store;
cert_store = CertOpenStore (
CERT_STORE_PROV_SYSTEM, /* provider */
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */
0, /* unused */
dwFlags, /* dwFlags */
store_name); /* system store name. "My" or "Root" */
if (cert_store == NULL) {
LPTSTR msg = NULL;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError (),
LANG_NEUTRAL,
(LPTSTR) &msg,
0,
NULL);
MONGOC_ERROR ("Can't open CA store: 0x%.8X: '%s'", GetLastError (), msg);
LocalFree (msg);
return false;
}
while ((cert = CertEnumCertificatesInStore (cert_store, cert)) != NULL) {
X509 *x509Obj = d2i_X509 (NULL,
(const unsigned char **) &cert->pbCertEncoded,
cert->cbCertEncoded);
if (x509Obj == NULL) {
MONGOC_WARNING (
"Error parsing X509 object from Windows certificate store");
continue;
}
X509_STORE_add_cert (openssl_store, x509Obj);
X509_free (x509Obj);
}
CertCloseStore (cert_store, 0);
return true;
}
bool
_mongoc_openssl_import_cert_stores (SSL_CTX *context)
{
bool retval;
X509_STORE *store = SSL_CTX_get_cert_store (context);
if (!store) {
MONGOC_WARNING ("no X509 store found for SSL context while loading "
"system certificates");
return false;
}
retval = _mongoc_openssl_import_cert_store (L"root",
CERT_SYSTEM_STORE_CURRENT_USER |
CERT_STORE_READONLY_FLAG,
store);
retval &= _mongoc_openssl_import_cert_store (
L"CA", CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, store);
return retval;
}
#endif
+#if OPENSSL_VERSION_NUMBER > 0x10002000L
+bool
+_mongoc_openssl_check_peer_hostname (SSL *ssl,
+ const char *host,
+ bool allow_invalid_hostname)
+{
+ X509 *peer = NULL;
+
+ if (allow_invalid_hostname) {
+ return true;
+ }
+
+ peer = SSL_get_peer_certificate (ssl);
+ if (peer && (X509_check_host (peer, host, 0, 0, NULL) == 1 ||
+ X509_check_ip_asc (peer, host, 0) == 1)) {
+ X509_free (peer);
+ return true;
+ }
+
+ if (peer) {
+ X509_free (peer);
+ }
+ return false;
+}
+#else
/** mongoc_openssl_hostcheck
*
* rfc 6125 match a given hostname against a given pattern
*
* Patterns come from DNS common names or subjectAltNames.
*
* This code is meant to implement RFC 6125 6.4.[1-3]
*
*/
static bool
_mongoc_openssl_hostcheck (const char *pattern, const char *hostname)
{
const char *pattern_label_end;
const char *pattern_wildcard;
const char *hostname_label_end;
size_t prefixlen;
size_t suffixlen;
TRACE ("Comparing '%s' == '%s'", pattern, hostname);
pattern_wildcard = strchr (pattern, '*');
if (pattern_wildcard == NULL) {
return strcasecmp (pattern, hostname) == 0;
}
pattern_label_end = strchr (pattern, '.');
/* Bail out on wildcarding in a couple of situations:
* o we don't have 2 dots - we're not going to wildcard root tlds
* o the wildcard isn't in the left most group (separated by dots)
* o the pattern is embedded in an A-label or U-label
*/
if (pattern_label_end == NULL ||
strchr (pattern_label_end + 1, '.') == NULL ||
pattern_wildcard > pattern_label_end ||
strncasecmp (pattern, "xn--", 4) == 0) {
return strcasecmp (pattern, hostname) == 0;
}
hostname_label_end = strchr (hostname, '.');
/* we know we have a dot in the pattern, we need one in the hostname */
if (hostname_label_end == NULL ||
strcasecmp (pattern_label_end, hostname_label_end)) {
return 0;
}
/* The wildcard must match at least one character, so the left part of the
* hostname is at least as large as the left part of the pattern. */
if ((hostname_label_end - hostname) < (pattern_label_end - pattern)) {
return 0;
}
/* If the left prefix group before the star matches and right of the star
* matches... we have a wildcard match */
prefixlen = pattern_wildcard - pattern;
suffixlen = pattern_label_end - (pattern_wildcard + 1);
return strncasecmp (pattern, hostname, prefixlen) == 0 &&
strncasecmp (pattern_wildcard + 1,
hostname_label_end - suffixlen,
suffixlen) == 0;
}
/** check if a provided cert matches a passed hostname
*/
bool
-_mongoc_openssl_check_cert (SSL *ssl,
- const char *host,
- bool allow_invalid_hostname)
+_mongoc_openssl_check_peer_hostname (SSL *ssl,
+ const char *host,
+ bool allow_invalid_hostname)
{
X509 *peer;
X509_NAME *subject_name;
X509_NAME_ENTRY *entry;
ASN1_STRING *entry_data;
int length;
int idx;
int r = 0;
long verify_status;
size_t addrlen = 0;
unsigned char addr4[sizeof (struct in_addr)];
unsigned char addr6[sizeof (struct in6_addr)];
int i;
int n_sans = -1;
int target = GEN_DNS;
STACK_OF (GENERAL_NAME) *sans = NULL;
ENTRY;
BSON_ASSERT (ssl);
BSON_ASSERT (host);
if (allow_invalid_hostname) {
RETURN (true);
}
/** if the host looks like an IP address, match that, otherwise we assume we
* have a DNS name */
if (inet_pton (AF_INET, host, &addr4)) {
target = GEN_IPADD;
addrlen = sizeof addr4;
} else if (inet_pton (AF_INET6, host, &addr6)) {
target = GEN_IPADD;
addrlen = sizeof addr6;
}
peer = SSL_get_peer_certificate (ssl);
if (!peer) {
MONGOC_WARNING ("SSL Certification verification failed: %s",
ERR_error_string (ERR_get_error (), NULL));
RETURN (false);
}
verify_status = SSL_get_verify_result (ssl);
if (verify_status == X509_V_OK) {
/* gets a stack of alt names that we can iterate through */
sans = (STACK_OF (GENERAL_NAME) *) X509_get_ext_d2i (
(X509 *) peer, NID_subject_alt_name, NULL, NULL);
if (sans) {
n_sans = sk_GENERAL_NAME_num (sans);
/* loop through the stack, or until we find a match */
for (i = 0; i < n_sans && !r; i++) {
const GENERAL_NAME *name = sk_GENERAL_NAME_value (sans, i);
/* skip entries that can't apply, I.e. IP entries if we've got a
* DNS host */
if (name->type == target) {
const char *check;
check = (const char *) ASN1_STRING_get0_data (name->d.ia5);
length = ASN1_STRING_length (name->d.ia5);
switch (target) {
case GEN_DNS:
/* check that we don't have an embedded null byte */
if ((length == bson_strnlen (check, length)) &&
_mongoc_openssl_hostcheck (check, host)) {
r = 1;
}
break;
case GEN_IPADD:
if (length == addrlen) {
if (length == sizeof addr6 &&
!memcmp (check, &addr6, length)) {
r = 1;
} else if (length == sizeof addr4 &&
!memcmp (check, &addr4, length)) {
r = 1;
}
}
break;
default:
BSON_ASSERT (0);
break;
}
}
}
GENERAL_NAMES_free (sans);
} else {
subject_name = X509_get_subject_name (peer);
if (subject_name) {
i = -1;
/* skip to the last common name */
while ((idx = X509_NAME_get_index_by_NID (
subject_name, NID_commonName, i)) >= 0) {
i = idx;
}
if (i >= 0) {
entry = X509_NAME_get_entry (subject_name, i);
entry_data = X509_NAME_ENTRY_get_data (entry);
if (entry_data) {
char *check;
/* TODO: I've heard tell that old versions of SSL crap out
* when calling ASN1_STRING_to_UTF8 on already utf8 data.
* Check up on that */
length = ASN1_STRING_to_UTF8 ((unsigned char **) &check,
entry_data);
if (length >= 0) {
/* check for embedded nulls */
if ((length == bson_strnlen (check, length)) &&
_mongoc_openssl_hostcheck (check, host)) {
r = 1;
}
OPENSSL_free (check);
}
}
}
}
}
}
X509_free (peer);
RETURN (r);
}
+#endif /* OPENSSL_VERSION_NUMBER */
static bool
_mongoc_openssl_setup_ca (SSL_CTX *ctx, const char *cert, const char *cert_dir)
{
BSON_ASSERT (ctx);
BSON_ASSERT (cert || cert_dir);
if (!SSL_CTX_load_verify_locations (ctx, cert, cert_dir)) {
MONGOC_ERROR ("Cannot load Certificate Authorities from '%s' and '%s'",
cert,
cert_dir);
return 0;
}
return 1;
}
static bool
_mongoc_openssl_setup_crl (SSL_CTX *ctx, const char *crlfile)
{
X509_STORE *store;
X509_LOOKUP *lookup;
int status;
store = SSL_CTX_get_cert_store (ctx);
X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK);
lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ());
status = X509_load_crl_file (lookup, crlfile, X509_FILETYPE_PEM);
return status != 0;
}
static bool
_mongoc_openssl_setup_pem_file (SSL_CTX *ctx,
const char *pem_file,
const char *password)
{
if (!SSL_CTX_use_certificate_chain_file (ctx, pem_file)) {
MONGOC_ERROR ("Cannot find certificate in '%s'", pem_file);
return 0;
}
if (password) {
SSL_CTX_set_default_passwd_cb_userdata (ctx, (void *) password);
SSL_CTX_set_default_passwd_cb (ctx, _mongoc_openssl_password_cb);
}
if (!(SSL_CTX_use_PrivateKey_file (ctx, pem_file, SSL_FILETYPE_PEM))) {
MONGOC_ERROR ("Cannot find private key in: '%s'", pem_file);
return 0;
}
if (!(SSL_CTX_check_private_key (ctx))) {
MONGOC_ERROR ("Cannot load private key: '%s'", pem_file);
return 0;
}
return 1;
}
+#ifdef MONGOC_ENABLE_OCSP_OPENSSL
+
+static X509 *
+_get_issuer (X509 *cert, STACK_OF (X509) * chain)
+{
+ X509 *issuer = NULL, *candidate = NULL;
+ X509_NAME *issuer_name = NULL, *candidate_name = NULL;
+ int i;
+
+ issuer_name = X509_get_issuer_name (cert);
+ for (i = 0; i < sk_X509_num (chain) && issuer == NULL; i++) {
+ candidate = sk_X509_value (chain, i);
+ candidate_name = X509_get_subject_name (candidate);
+ if (0 == X509_NAME_cmp (candidate_name, issuer_name)) {
+ issuer = candidate;
+ }
+ }
+ RETURN (issuer);
+}
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+/* OpenSSL 1.1.0+ has conveniences that we polyfill in older OpenSSL versions.
+ */
+
+STACK_OF (X509) * _get_verified_chain (SSL *ssl)
+{
+ return SSL_get0_verified_chain (ssl);
+}
+
+void _free_verified_chain (STACK_OF (X509) * verified_chain)
+{
+ /* _get_verified_chain does not return a copy. Do nothing. */
+ return;
+}
+
+const STACK_OF (X509_EXTENSION) * _get_extensions (const X509 *cert)
+{
+ return X509_get0_extensions (cert);
+}
+
+#else
+/* Polyfill functionality for pre 1.1.0 OpenSSL */
+
+STACK_OF (X509) * _get_verified_chain (SSL *ssl)
+{
+ X509_STORE *store = NULL;
+ X509 *peer = NULL;
+ STACK_OF (X509) *peer_chain = NULL;
+ X509_STORE_CTX *store_ctx = NULL;
+ STACK_OF (X509) *verified_chain = NULL;
+
+ /* Get the certificate the server presented. */
+ peer = SSL_get_peer_certificate (ssl);
+ /* Get the chain of certificates the server presented. This is not a verified
+ * chain. */
+ peer_chain = SSL_get_peer_cert_chain (ssl);
+ store = SSL_CTX_get_cert_store (SSL_get_SSL_CTX (ssl));
+ store_ctx = X509_STORE_CTX_new ();
+ if (!X509_STORE_CTX_init (store_ctx, store, peer, peer_chain)) {
+ MONGOC_ERROR ("failed to initialize X509 store");
+ goto fail;
+ }
+
+ if (X509_verify_cert (store_ctx) <= 0) {
+ MONGOC_ERROR ("failed to obtain verified chain");
+ goto fail;
+ }
+
+ verified_chain = X509_STORE_CTX_get1_chain (store_ctx);
+
+fail:
+ X509_free (peer);
+ X509_STORE_CTX_free (store_ctx);
+ return verified_chain;
+}
+
+/* On OpenSSL < 1.1.0, this chain isn't attached to the SSL session, so we need
+ * it to dispose of itself. */
+void _free_verified_chain (STACK_OF (X509) * verified_chain)
+{
+ if (!verified_chain) {
+ return;
+ }
+ sk_X509_pop_free (verified_chain, X509_free);
+}
+
+const STACK_OF (X509_EXTENSION) * _get_extensions (const X509 *cert)
+{
+ return cert->cert_info->extensions;
+}
+#endif /* OPENSSL_VERSION_NUMBER */
+
+
+#define TLSFEATURE_STATUS_REQUEST 5
+
+/* Check a tlsfeature extension contents for a status_request.
+ *
+ * Parse just enough of a DER encoded data to check if a SEQUENCE of INTEGER
+ * contains the status_request extension (5). There are only five tlsfeature
+ * extension types, so this only handles the case that the sequence's length is
+ * representable in one byte, and that each integer is representable in one
+ * byte. */
+bool
+_mongoc_tlsfeature_has_status_request (const uint8_t *data, int length)
+{
+ int i;
+
+ /* Expect a sequence type, with a sequence length representable in one byte.
+ */
+ if (length < 3 || data[0] != 0x30 || data[1] >= 127) {
+ MONGOC_ERROR ("malformed tlsfeature extension sequence");
+ return false;
+ }
+
+ for (i = 2; i < length; i += 3) {
+ /* Expect an integer, representable in one byte. */
+ if (length < i + 3 || data[i] != 0x02 || data[i + 1] != 1) {
+ MONGOC_ERROR ("malformed tlsfeature extension integer");
+ return false;
+ }
+
+ if (data[i + 2] == TLSFEATURE_STATUS_REQUEST) {
+ TRACE ("%s", "found status request in tlsfeature extension");
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Check that the certificate has a tlsfeature extension with status_request. */
+bool
+_get_must_staple (X509 *cert)
+{
+ const STACK_OF (X509_EXTENSION) *exts = NULL;
+ X509_EXTENSION *ext;
+ ASN1_STRING *ext_data;
+ int idx;
+
+ exts = _get_extensions (cert);
+ if (!exts) {
+ TRACE ("%s", "certificate extensions not found");
+ return false;
+ }
+
+ idx = X509v3_get_ext_by_NID (exts, tlsfeature_nid, -1);
+ if (-1 == idx) {
+ TRACE ("%s", "tlsfeature extension not found");
+ return false;
+ }
+
+ ext = sk_X509_EXTENSION_value (exts, idx);
+ ext_data = X509_EXTENSION_get_data (ext);
+
+ /* Data is a DER encoded sequence of integers. */
+ return _mongoc_tlsfeature_has_status_request (
+ ASN1_STRING_get0_data (ext_data), ASN1_STRING_length (ext_data));
+}
+
+#define ERR_STR (ERR_error_string (ERR_get_error (), NULL))
+#define MONGOC_OCSP_REQUEST_TIMEOUT_MS 5000
+
+static OCSP_RESPONSE *
+_contact_ocsp_responder (OCSP_CERTID *id,
+ X509 *peer,
+ mongoc_ssl_opt_t *ssl_opts,
+ int *ocsp_uri_count)
+{
+ STACK_OF (OPENSSL_STRING) *url_stack = NULL;
+ OPENSSL_STRING url = NULL, host = NULL, path = NULL, port = NULL;
+ OCSP_REQUEST *req = NULL;
+ const unsigned char *resp_data;
+ OCSP_RESPONSE *resp = NULL;
+ int i, ssl;
+
+ url_stack = X509_get1_ocsp (peer);
+ *ocsp_uri_count = sk_OPENSSL_STRING_num (url_stack);
+ for (i = 0; i < *ocsp_uri_count && !resp; i++) {
+ unsigned char *request_der = NULL;
+ int request_der_len;
+ mongoc_http_request_t http_req;
+ mongoc_http_response_t http_res;
+ bson_error_t error;
+
+ _mongoc_http_request_init (&http_req);
+ _mongoc_http_response_init (&http_res);
+ url = sk_OPENSSL_STRING_value (url_stack, i);
+ TRACE ("Contacting OCSP responder '%s'", url);
+
+ /* splits the given url into its host, port and path components */
+ if (!OCSP_parse_url (url, &host, &port, &path, &ssl)) {
+ MONGOC_DEBUG ("Could not parse URL");
+ GOTO (retry);
+ }
+
+ if (!(req = OCSP_REQUEST_new ())) {
+ MONGOC_DEBUG ("Could not create new OCSP request");
+ GOTO (retry);
+ }
+
+ /* add the cert ID to the OCSP request object */
+ if (!id || !OCSP_request_add0_id (req, OCSP_CERTID_dup (id))) {
+ MONGOC_DEBUG ("Could not add cert ID to the OCSP request object");
+ GOTO (retry);
+ }
+
+ /* add nonce to OCSP request object */
+ if (!OCSP_request_add1_nonce (req, 0 /* use random nonce */, -1)) {
+ MONGOC_DEBUG ("Could not add nonce to OCSP request object");
+ GOTO (retry);
+ }
+
+ request_der_len = i2d_OCSP_REQUEST (req, &request_der);
+ if (request_der_len < 0) {
+ MONGOC_DEBUG ("Could not encode OCSP request");
+ GOTO (retry);
+ }
+
+ http_req.method = "POST";
+ http_req.extra_headers = "Content-Type: application/ocsp-request\r\n";
+ http_req.host = host;
+ http_req.path = path;
+ http_req.port = (int) bson_ascii_strtoll (port, NULL, 10);
+ http_req.body = (const char *) request_der;
+ http_req.body_len = request_der_len;
+ if (!_mongoc_http_send (&http_req,
+ MONGOC_OCSP_REQUEST_TIMEOUT_MS,
+ ssl != 0,
+ ssl_opts,
+ &http_res,
+ &error)) {
+ MONGOC_DEBUG ("Could not send HTTP request: %s", error.message);
+ GOTO (retry);
+ }
+
+ resp_data = (const unsigned char *) http_res.body;
+
+ if (http_res.body_len == 0 ||
+ !d2i_OCSP_RESPONSE (&resp, &resp_data, http_res.body_len)) {
+ MONGOC_DEBUG ("Could not parse OCSP response from HTTP response");
+ MONGOC_DEBUG ("Response headers: %s", http_res.headers);
+ GOTO (retry);
+ }
+
+ retry:
+ if (host)
+ OPENSSL_free (host);
+ if (port)
+ OPENSSL_free (port);
+ if (path)
+ OPENSSL_free (path);
+ if (req)
+ OCSP_REQUEST_free (req);
+ if (request_der)
+ OPENSSL_free (request_der);
+ _mongoc_http_response_cleanup (&http_res);
+ }
+
+ if (url_stack)
+ X509_email_free (url_stack);
+ RETURN (resp);
+}
+
+#define SOFT_FAIL(...) \
+ ((stapled_response) ? MONGOC_ERROR (__VA_ARGS__) \
+ : MONGOC_DEBUG (__VA_ARGS__))
+
+#define X509_CHECK_SUCCESS 1
+#define OCSP_VERIFY_SUCCESS 1
+
+int
+_mongoc_ocsp_tlsext_status (SSL *ssl, mongoc_openssl_ocsp_opt_t *opts)
+{
+ enum { OCSP_CB_ERROR = -1, OCSP_CB_REVOKED, OCSP_CB_SUCCESS } ret;
+ bool stapled_response = true;
+ bool must_staple;
+ OCSP_RESPONSE *resp = NULL;
+ OCSP_BASICRESP *basic = NULL;
+ X509_STORE *store = NULL;
+ X509 *peer = NULL, *issuer = NULL;
+ STACK_OF (X509) *cert_chain = NULL;
+ const unsigned char *resp_data = NULL;
+ int cert_status, reason, len, status;
+ OCSP_CERTID *id = NULL;
+ ASN1_GENERALIZEDTIME *produced_at = NULL, *this_update = NULL,
+ *next_update = NULL;
+ int ocsp_uri_count = 0;
+
+ if (opts->weak_cert_validation) {
+ return OCSP_CB_SUCCESS;
+ }
+
+ if (!(peer = SSL_get_peer_certificate (ssl))) {
+ MONGOC_ERROR ("No certificate was presented by the peer");
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+
+ /* Get a STACK_OF(X509) certs forming the cert chain of the peer, including
+ * the peer's cert */
+ if (!(cert_chain = _get_verified_chain (ssl))) {
+ MONGOC_ERROR ("Unable to obtain verified chain");
+ ret = OCSP_CB_REVOKED;
+ GOTO (done);
+ }
+
+ if (!(issuer = _get_issuer (peer, cert_chain))) {
+ MONGOC_ERROR ("Could not get issuer from peer cert");
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+
+ if (!(id = OCSP_cert_to_id (NULL /* SHA1 */, peer, issuer))) {
+ MONGOC_ERROR ("Could not obtain a valid OCSP_CERTID for peer");
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+
+ if (_mongoc_ocsp_cache_get_status (
+ id, &cert_status, &reason, &this_update, &next_update)) {
+ GOTO (validate);
+ }
+
+ /* Get the stapled OCSP response returned by the server */
+ len = SSL_get_tlsext_status_ocsp_resp (ssl, &resp_data);
+ stapled_response = !!resp_data;
+ if (stapled_response) {
+ /* obtain an OCSP_RESPONSE object from the OCSP response */
+ if (!d2i_OCSP_RESPONSE (&resp, &resp_data, len)) {
+ MONGOC_ERROR ("Failed to parse OCSP response");
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+ } else {
+ TRACE ("%s", "Server does not contain a stapled response");
+ must_staple = _get_must_staple (peer);
+ if (must_staple) {
+ MONGOC_ERROR ("Server must contain a stapled response");
+ ret = OCSP_CB_REVOKED;
+ GOTO (done);
+ }
+
+ if (opts->disable_endpoint_check ||
+ !(resp = _contact_ocsp_responder (
+ id, peer, &opts->ssl_opts, &ocsp_uri_count))) {
+ if (ocsp_uri_count > 0) {
+ /* Only log a soft failure if there were OCSP responders listed in
+ * the certificate. */
+ MONGOC_DEBUG ("Soft-fail: No OCSP responder could be reached");
+ }
+ ret = OCSP_CB_SUCCESS;
+ GOTO (done);
+ }
+ }
+
+ TRACE ("%s", "Validating OCSP response");
+ /* Validate the OCSP response status of the OCSP_RESPONSE object */
+ status = OCSP_response_status (resp);
+ if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+ SOFT_FAIL ("OCSP response error %d %s",
+ status,
+ OCSP_response_status_str (status));
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+
+ TRACE ("%s", "OCSP response status successful");
+
+ /* Get the OCSP_BASICRESP structure contained in OCSP_RESPONSE object for the
+ * peer cert */
+ basic = OCSP_response_get1_basic (resp);
+ if (!basic) {
+ SOFT_FAIL ("Could not find BasicOCSPResponse: %s", ERR_STR);
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+
+ store = SSL_CTX_get_cert_store (SSL_get_SSL_CTX (ssl));
+
+ /*
+ * checks that the basic response message is correctly signed and that the
+ * signer certificate can be validated.
+ * 1. The function first verifies the signer cert of the response is in the
+ * given cert chain.
+ * 2. Next, the function verifies the signature of the basic response.
+ * 3. Finally, the function validates the signer cert, constructing the
+ * validation path via the untrusted cert chain.
+ *
+ * cert_chain has already been verified. Use OCSP_TRUSTOTHER so the signer
+ * certificate can be considered verified if it is in cert_chain.
+ */
+ if (OCSP_basic_verify (basic, cert_chain, store, OCSP_TRUSTOTHER) !=
+ OCSP_VERIFY_SUCCESS) {
+ SOFT_FAIL ("OCSP response failed verification: %s", ERR_STR);
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+
+ /* searches the basic response for an OCSP response for the given cert ID */
+ if (!OCSP_resp_find_status (basic,
+ id,
+ &cert_status,
+ &reason,
+ &produced_at,
+ &this_update,
+ &next_update)) {
+ SOFT_FAIL ("No OCSP response found for the peer certificate");
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+
+ /* checks the validity of this_update and next_update values */
+ if (!OCSP_check_validity (this_update, next_update, 0L, -1L)) {
+ SOFT_FAIL ("OCSP response has expired: %s", ERR_STR);
+ ret = OCSP_CB_ERROR;
+ GOTO (done);
+ }
+
+validate:
+ switch (cert_status) {
+ case V_OCSP_CERTSTATUS_GOOD:
+ TRACE ("%s", "OCSP Certificate Status: Good");
+ _mongoc_ocsp_cache_set_resp (
+ id, cert_status, reason, this_update, next_update);
+ break;
+
+ case V_OCSP_CERTSTATUS_REVOKED:
+ MONGOC_ERROR ("OCSP Certificate Status: Revoked. Reason: %s",
+ OCSP_crl_reason_str (reason));
+ ret = OCSP_CB_REVOKED;
+ _mongoc_ocsp_cache_set_resp (
+ id, cert_status, reason, this_update, next_update);
+ GOTO (done);
+
+ default:
+ MONGOC_DEBUG ("OCSP Certificate Status: Unknown");
+ break;
+ }
+
+ /* Validate hostname matches cert */
+ if (!_mongoc_openssl_check_peer_hostname (
+ ssl, opts->host, opts->allow_invalid_hostname)) {
+ ret = OCSP_CB_REVOKED;
+ GOTO (done);
+ }
+
+ ret = OCSP_CB_SUCCESS;
+done:
+ if (ret == OCSP_CB_ERROR && !stapled_response) {
+ ret = OCSP_CB_SUCCESS;
+ }
+ if (basic)
+ OCSP_BASICRESP_free (basic);
+ if (resp)
+ OCSP_RESPONSE_free (resp);
+ if (id)
+ OCSP_CERTID_free (id);
+ if (peer)
+ X509_free (peer);
+ if (cert_chain)
+ _free_verified_chain (cert_chain);
+ RETURN (ret);
+}
+
+#endif /* MONGOC_ENABLE_OCSP_OPENSSL */
/**
* _mongoc_openssl_ctx_new:
*
* Create a new ssl context declaratively
*
* The opt.pem_pwd parameter, if passed, must exist for the life of this
* context object (for storing and loading the associated pem file)
*/
SSL_CTX *
_mongoc_openssl_ctx_new (mongoc_ssl_opt_t *opt)
{
SSL_CTX *ctx = NULL;
int ssl_ctx_options = 0;
/*
* Ensure we are initialized. This is safe to call multiple times.
*/
mongoc_init ();
ctx = SSL_CTX_new (SSLv23_method ());
BSON_ASSERT (ctx);
/* SSL_OP_ALL - Activate all bug workaround options, to support buggy client
* SSL's. */
ssl_ctx_options |= SSL_OP_ALL;
/* SSL_OP_NO_SSLv2 - Disable SSL v2 support */
ssl_ctx_options |= SSL_OP_NO_SSLv2;
/* Disable compression, if we can.
* OpenSSL 0.9.x added compression support which was always enabled when built
* against zlib
* OpenSSL 1.0.0 added the ability to disable it, while keeping it enabled by
* default
* OpenSSL 1.1.0 disabled it by default.
*/
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
ssl_ctx_options |= SSL_OP_NO_COMPRESSION;
#endif
-/* man SSL_get_options says: "SSL_OP_NO_RENEGOTIATION options were added in OpenSSL 1.1.1". */
+/* man SSL_get_options says: "SSL_OP_NO_RENEGOTIATION options were added in
+ * OpenSSL 1.1.1". */
#ifdef SSL_OP_NO_RENEGOTIATION
ssl_ctx_options |= SSL_OP_NO_RENEGOTIATION;
#endif
SSL_CTX_set_options (ctx, ssl_ctx_options);
/* only defined in special build, using:
* --enable-system-crypto-profile (autotools)
* -DENABLE_CRYPTO_SYSTEM_PROFILE:BOOL=ON (cmake) */
#ifndef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE
/* HIGH - Enable strong ciphers
* !EXPORT - Disable export ciphers (40/56 bit)
* !aNULL - Disable anonymous auth ciphers
* @STRENGTH - Sort ciphers based on strength */
SSL_CTX_set_cipher_list (ctx, "HIGH:!EXPORT:!aNULL@STRENGTH");
#endif
/* If renegotiation is needed, don't return from recv() or send() until it's
* successful.
* Note: this is for blocking sockets only. */
SSL_CTX_set_mode (ctx, SSL_MODE_AUTO_RETRY);
/* Load my private keys to present to the server */
if (opt->pem_file &&
!_mongoc_openssl_setup_pem_file (ctx, opt->pem_file, opt->pem_pwd)) {
SSL_CTX_free (ctx);
return NULL;
}
/* Load in my Certificate Authority, to verify the server against
* If none provided, fallback to the distro defaults */
if (opt->ca_file || opt->ca_dir) {
if (!_mongoc_openssl_setup_ca (ctx, opt->ca_file, opt->ca_dir)) {
SSL_CTX_free (ctx);
return NULL;
}
} else {
/* If the server certificate is issued by known CA we trust it by default */
#ifdef _WIN32
_mongoc_openssl_import_cert_stores (ctx);
#else
SSL_CTX_set_default_verify_paths (ctx);
#endif
}
/* Load my revocation list, to verify the server against */
if (opt->crl_file && !_mongoc_openssl_setup_crl (ctx, opt->crl_file)) {
SSL_CTX_free (ctx);
return NULL;
}
return ctx;
}
char *
_mongoc_openssl_extract_subject (const char *filename, const char *passphrase)
{
X509_NAME *subject = NULL;
X509 *cert = NULL;
BIO *certbio = NULL;
BIO *strbio = NULL;
char *str = NULL;
int ret;
if (!filename) {
return NULL;
}
certbio = BIO_new (BIO_s_file ());
strbio = BIO_new (BIO_s_mem ());
;
BSON_ASSERT (certbio);
BSON_ASSERT (strbio);
if (BIO_read_filename (certbio, filename) &&
(cert = PEM_read_bio_X509 (certbio, NULL, 0, NULL))) {
if ((subject = X509_get_subject_name (cert))) {
ret = X509_NAME_print_ex (strbio, subject, 0, XN_FLAG_RFC2253);
if ((ret > 0) && (ret < INT_MAX)) {
str = (char *) bson_malloc (ret + 2);
BIO_gets (strbio, str, ret + 1);
str[ret] = '\0';
}
}
}
if (cert) {
X509_free (cert);
}
if (certbio) {
BIO_free (certbio);
}
if (strbio) {
BIO_free (strbio);
}
return str;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef _WIN32
static unsigned long
_mongoc_openssl_thread_id_callback (void)
{
unsigned long ret;
ret = (unsigned long) GetCurrentThreadId ();
return ret;
}
#else
static unsigned long
_mongoc_openssl_thread_id_callback (void)
{
unsigned long ret;
ret = (unsigned long) pthread_self ();
return ret;
}
#endif
static void
_mongoc_openssl_thread_locking_callback (int mode,
int type,
const char *file,
int line)
{
if (mode & CRYPTO_LOCK) {
bson_mutex_lock (&gMongocOpenSslThreadLocks[type]);
} else {
bson_mutex_unlock (&gMongocOpenSslThreadLocks[type]);
}
}
static void
_mongoc_openssl_thread_startup (void)
{
int i;
gMongocOpenSslThreadLocks = (bson_mutex_t *) OPENSSL_malloc (
CRYPTO_num_locks () * sizeof (bson_mutex_t));
for (i = 0; i < CRYPTO_num_locks (); i++) {
bson_mutex_init (&gMongocOpenSslThreadLocks[i]);
}
if (!CRYPTO_get_locking_callback ()) {
CRYPTO_set_locking_callback (_mongoc_openssl_thread_locking_callback);
CRYPTO_set_id_callback (_mongoc_openssl_thread_id_callback);
}
}
static void
_mongoc_openssl_thread_cleanup (void)
{
int i;
if (CRYPTO_get_locking_callback () ==
_mongoc_openssl_thread_locking_callback) {
CRYPTO_set_locking_callback (NULL);
}
if (CRYPTO_get_id_callback () == _mongoc_openssl_thread_id_callback) {
CRYPTO_set_id_callback (NULL);
}
for (i = 0; i < CRYPTO_num_locks (); i++) {
bson_mutex_destroy (&gMongocOpenSslThreadLocks[i]);
}
OPENSSL_free (gMongocOpenSslThreadLocks);
}
#endif
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
similarity index 92%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
index cae67531..bdb0a034 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
@@ -1,386 +1,409 @@
#include "mongoc-prelude.h"
#ifndef MONGOC_OPTS_H
#define MONGOC_OPTS_H
#include <bson/bson.h>
#include "mongoc-client-session.h"
#include "mongoc-bulk-operation-private.h"
#include "mongoc-opts-helpers-private.h"
/**************************************************
*
* Generated by build/generate-opts.py.
*
* DO NOT EDIT THIS FILE.
*
*************************************************/
/* clang-format off */
typedef struct _mongoc_crud_opts_t {
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bson_validate_flags_t validate;
} mongoc_crud_opts_t;
typedef struct _mongoc_update_opts_t {
mongoc_crud_opts_t crud;
bool bypass;
bson_t collation;
bson_value_t hint;
bool upsert;
} mongoc_update_opts_t;
typedef struct _mongoc_insert_one_opts_t {
mongoc_crud_opts_t crud;
bool bypass;
bson_t extra;
} mongoc_insert_one_opts_t;
typedef struct _mongoc_insert_many_opts_t {
mongoc_crud_opts_t crud;
bool ordered;
bool bypass;
bson_t extra;
} mongoc_insert_many_opts_t;
-typedef struct _mongoc_delete_one_opts_t {
+typedef struct _mongoc_delete_opts_t {
mongoc_crud_opts_t crud;
bson_t collation;
+ bson_value_t hint;
+} mongoc_delete_opts_t;
+
+typedef struct _mongoc_delete_one_opts_t {
+ mongoc_delete_opts_t delete;
bson_t extra;
} mongoc_delete_one_opts_t;
typedef struct _mongoc_delete_many_opts_t {
- mongoc_crud_opts_t crud;
- bson_t collation;
+ mongoc_delete_opts_t delete;
bson_t extra;
} mongoc_delete_many_opts_t;
typedef struct _mongoc_update_one_opts_t {
mongoc_update_opts_t update;
bson_t arrayFilters;
bson_t extra;
} mongoc_update_one_opts_t;
typedef struct _mongoc_update_many_opts_t {
mongoc_update_opts_t update;
bson_t arrayFilters;
bson_t extra;
} mongoc_update_many_opts_t;
typedef struct _mongoc_replace_one_opts_t {
mongoc_update_opts_t update;
bson_t extra;
} mongoc_replace_one_opts_t;
typedef struct _mongoc_bulk_opts_t {
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
bool ordered;
mongoc_client_session_t *client_session;
bson_t extra;
} mongoc_bulk_opts_t;
typedef struct _mongoc_bulk_insert_opts_t {
bson_validate_flags_t validate;
bson_t extra;
} mongoc_bulk_insert_opts_t;
typedef struct _mongoc_bulk_update_opts_t {
bson_validate_flags_t validate;
bson_t collation;
bson_value_t hint;
bool upsert;
bool multi;
} mongoc_bulk_update_opts_t;
typedef struct _mongoc_bulk_update_one_opts_t {
mongoc_bulk_update_opts_t update;
bson_t arrayFilters;
bson_t extra;
} mongoc_bulk_update_one_opts_t;
typedef struct _mongoc_bulk_update_many_opts_t {
mongoc_bulk_update_opts_t update;
bson_t arrayFilters;
bson_t extra;
} mongoc_bulk_update_many_opts_t;
typedef struct _mongoc_bulk_replace_one_opts_t {
mongoc_bulk_update_opts_t update;
bson_t extra;
} mongoc_bulk_replace_one_opts_t;
typedef struct _mongoc_bulk_remove_opts_t {
bson_t collation;
+ bson_value_t hint;
int32_t limit;
} mongoc_bulk_remove_opts_t;
typedef struct _mongoc_bulk_remove_one_opts_t {
mongoc_bulk_remove_opts_t remove;
bson_t extra;
} mongoc_bulk_remove_one_opts_t;
typedef struct _mongoc_bulk_remove_many_opts_t {
mongoc_bulk_remove_opts_t remove;
bson_t extra;
} mongoc_bulk_remove_many_opts_t;
typedef struct _mongoc_change_stream_opts_t {
int32_t batchSize;
bson_t resumeAfter;
bson_t startAfter;
mongoc_timestamp_t startAtOperationTime;
int64_t maxAwaitTimeMS;
const char *fullDocument;
bson_t extra;
} mongoc_change_stream_opts_t;
typedef struct _mongoc_create_index_opts_t {
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bson_t extra;
} mongoc_create_index_opts_t;
typedef struct _mongoc_read_write_opts_t {
bson_t readConcern;
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bson_t collation;
uint32_t serverId;
bson_t extra;
} mongoc_read_write_opts_t;
typedef struct _mongoc_gridfs_bucket_opts_t {
const char *bucketName;
int32_t chunkSizeBytes;
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_read_concern_t *readConcern;
bson_t extra;
} mongoc_gridfs_bucket_opts_t;
typedef struct _mongoc_gridfs_bucket_upload_opts_t {
int32_t chunkSizeBytes;
bson_t metadata;
bson_t extra;
} mongoc_gridfs_bucket_upload_opts_t;
typedef struct _mongoc_aggregate_opts_t {
mongoc_read_concern_t *readConcern;
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bool bypass;
bson_t collation;
uint32_t serverId;
int32_t batchSize;
bool batchSize_is_set;
bson_t extra;
} mongoc_aggregate_opts_t;
+typedef struct _mongoc_find_and_modify_appended_opts_t {
+ mongoc_write_concern_t *writeConcern;
+ bool write_concern_owned;
+ mongoc_client_session_t *client_session;
+ bson_value_t hint;
+ bson_t extra;
+} mongoc_find_and_modify_appended_opts_t;
+
bool
_mongoc_insert_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_insert_one_opts_t *mongoc_insert_one_opts,
bson_error_t *error);
void
_mongoc_insert_one_opts_cleanup (mongoc_insert_one_opts_t *mongoc_insert_one_opts);
bool
_mongoc_insert_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_insert_many_opts_t *mongoc_insert_many_opts,
bson_error_t *error);
void
_mongoc_insert_many_opts_cleanup (mongoc_insert_many_opts_t *mongoc_insert_many_opts);
bool
_mongoc_delete_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_delete_one_opts_t *mongoc_delete_one_opts,
bson_error_t *error);
void
_mongoc_delete_one_opts_cleanup (mongoc_delete_one_opts_t *mongoc_delete_one_opts);
bool
_mongoc_delete_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_delete_many_opts_t *mongoc_delete_many_opts,
bson_error_t *error);
void
_mongoc_delete_many_opts_cleanup (mongoc_delete_many_opts_t *mongoc_delete_many_opts);
bool
_mongoc_update_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_update_one_opts_t *mongoc_update_one_opts,
bson_error_t *error);
void
_mongoc_update_one_opts_cleanup (mongoc_update_one_opts_t *mongoc_update_one_opts);
bool
_mongoc_update_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_update_many_opts_t *mongoc_update_many_opts,
bson_error_t *error);
void
_mongoc_update_many_opts_cleanup (mongoc_update_many_opts_t *mongoc_update_many_opts);
bool
_mongoc_replace_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_replace_one_opts_t *mongoc_replace_one_opts,
bson_error_t *error);
void
_mongoc_replace_one_opts_cleanup (mongoc_replace_one_opts_t *mongoc_replace_one_opts);
bool
_mongoc_bulk_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_opts_t *mongoc_bulk_opts,
bson_error_t *error);
void
_mongoc_bulk_opts_cleanup (mongoc_bulk_opts_t *mongoc_bulk_opts);
bool
_mongoc_bulk_insert_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts,
bson_error_t *error);
void
_mongoc_bulk_insert_opts_cleanup (mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts);
bool
_mongoc_bulk_update_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts,
bson_error_t *error);
void
_mongoc_bulk_update_one_opts_cleanup (mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts);
bool
_mongoc_bulk_update_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts,
bson_error_t *error);
void
_mongoc_bulk_update_many_opts_cleanup (mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts);
bool
_mongoc_bulk_replace_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts,
bson_error_t *error);
void
_mongoc_bulk_replace_one_opts_cleanup (mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts);
bool
_mongoc_bulk_remove_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts,
bson_error_t *error);
void
_mongoc_bulk_remove_one_opts_cleanup (mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts);
bool
_mongoc_bulk_remove_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts,
bson_error_t *error);
void
_mongoc_bulk_remove_many_opts_cleanup (mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts);
bool
_mongoc_change_stream_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_change_stream_opts_t *mongoc_change_stream_opts,
bson_error_t *error);
void
_mongoc_change_stream_opts_cleanup (mongoc_change_stream_opts_t *mongoc_change_stream_opts);
bool
_mongoc_create_index_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_create_index_opts_t *mongoc_create_index_opts,
bson_error_t *error);
void
_mongoc_create_index_opts_cleanup (mongoc_create_index_opts_t *mongoc_create_index_opts);
bool
_mongoc_read_write_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_read_write_opts_t *mongoc_read_write_opts,
bson_error_t *error);
void
_mongoc_read_write_opts_cleanup (mongoc_read_write_opts_t *mongoc_read_write_opts);
bool
_mongoc_gridfs_bucket_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts,
bson_error_t *error);
void
_mongoc_gridfs_bucket_opts_cleanup (mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts);
bool
_mongoc_gridfs_bucket_upload_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts,
bson_error_t *error);
void
_mongoc_gridfs_bucket_upload_opts_cleanup (mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts);
bool
_mongoc_aggregate_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_aggregate_opts_t *mongoc_aggregate_opts,
bson_error_t *error);
void
_mongoc_aggregate_opts_cleanup (mongoc_aggregate_opts_t *mongoc_aggregate_opts);
+bool
+_mongoc_find_and_modify_appended_opts_parse (
+ mongoc_client_t *client,
+ const bson_t *opts,
+ mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts,
+ bson_error_t *error);
+
+void
+_mongoc_find_and_modify_appended_opts_cleanup (mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts);
+
#endif /* MONGOC_OPTS_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
similarity index 90%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
index 34c99ebc..7eb40eb4 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
@@ -1,1953 +1,2082 @@
#include "mongoc-opts-helpers-private.h"
#include "mongoc-opts-private.h"
#include "mongoc-error.h"
#include "mongoc-util-private.h"
#include "mongoc-client-private.h"
/**************************************************
*
* Generated by build/generate-opts.py.
*
* DO NOT EDIT THIS FILE.
*
*************************************************/
/* clang-format off */
bool
_mongoc_insert_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_insert_one_opts_t *mongoc_insert_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_insert_one_opts->crud.writeConcern = NULL;
mongoc_insert_one_opts->crud.write_concern_owned = false;
mongoc_insert_one_opts->crud.client_session = NULL;
mongoc_insert_one_opts->crud.validate = _mongoc_default_insert_vflags;
mongoc_insert_one_opts->bypass = false;
bson_init (&mongoc_insert_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_insert_one_opts->crud.writeConcern,
error)) {
return false;
}
mongoc_insert_one_opts->crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_insert_one_opts->crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_insert_one_opts->crud.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_insert_one_opts->bypass,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_insert_one_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_insert_one_opts_cleanup (mongoc_insert_one_opts_t *mongoc_insert_one_opts)
{
if (mongoc_insert_one_opts->crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_insert_one_opts->crud.writeConcern);
}
bson_destroy (&mongoc_insert_one_opts->extra);
}
bool
_mongoc_insert_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_insert_many_opts_t *mongoc_insert_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_insert_many_opts->crud.writeConcern = NULL;
mongoc_insert_many_opts->crud.write_concern_owned = false;
mongoc_insert_many_opts->crud.client_session = NULL;
mongoc_insert_many_opts->crud.validate = _mongoc_default_insert_vflags;
mongoc_insert_many_opts->ordered = true;
mongoc_insert_many_opts->bypass = false;
bson_init (&mongoc_insert_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_insert_many_opts->crud.writeConcern,
error)) {
return false;
}
mongoc_insert_many_opts->crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_insert_many_opts->crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_insert_many_opts->crud.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "ordered")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_insert_many_opts->ordered,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_insert_many_opts->bypass,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_insert_many_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_insert_many_opts_cleanup (mongoc_insert_many_opts_t *mongoc_insert_many_opts)
{
if (mongoc_insert_many_opts->crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_insert_many_opts->crud.writeConcern);
}
bson_destroy (&mongoc_insert_many_opts->extra);
}
bool
_mongoc_delete_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_delete_one_opts_t *mongoc_delete_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
- mongoc_delete_one_opts->crud.writeConcern = NULL;
- mongoc_delete_one_opts->crud.write_concern_owned = false;
- mongoc_delete_one_opts->crud.client_session = NULL;
- mongoc_delete_one_opts->crud.validate = BSON_VALIDATE_NONE;
- bson_init (&mongoc_delete_one_opts->collation);
+ mongoc_delete_one_opts->delete.crud.writeConcern = NULL;
+ mongoc_delete_one_opts->delete.crud.write_concern_owned = false;
+ mongoc_delete_one_opts->delete.crud.client_session = NULL;
+ mongoc_delete_one_opts->delete.crud.validate = BSON_VALIDATE_NONE;
+ bson_init (&mongoc_delete_one_opts->delete.collation);
+ memset (&mongoc_delete_one_opts->delete.hint, 0, sizeof (bson_value_t));
bson_init (&mongoc_delete_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
- &mongoc_delete_one_opts->crud.writeConcern,
+ &mongoc_delete_one_opts->delete.crud.writeConcern,
error)) {
return false;
}
- mongoc_delete_one_opts->crud.write_concern_owned = true;
+ mongoc_delete_one_opts->delete.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
- &mongoc_delete_one_opts->crud.client_session,
+ &mongoc_delete_one_opts->delete.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
- &mongoc_delete_one_opts->crud.validate,
+ &mongoc_delete_one_opts->delete.crud.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
- &mongoc_delete_one_opts->collation,
+ &mongoc_delete_one_opts->delete.collation,
+ error)) {
+ return false;
+ }
+ }
+ else if (!strcmp (bson_iter_key (&iter), "hint")) {
+ if (!_mongoc_convert_hint (
+ client,
+ &iter,
+ &mongoc_delete_one_opts->delete.hint,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_delete_one_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_delete_one_opts_cleanup (mongoc_delete_one_opts_t *mongoc_delete_one_opts)
{
- if (mongoc_delete_one_opts->crud.write_concern_owned) {
- mongoc_write_concern_destroy (mongoc_delete_one_opts->crud.writeConcern);
+ if (mongoc_delete_one_opts->delete.crud.write_concern_owned) {
+ mongoc_write_concern_destroy (mongoc_delete_one_opts->delete.crud.writeConcern);
}
- bson_destroy (&mongoc_delete_one_opts->collation);
+ bson_destroy (&mongoc_delete_one_opts->delete.collation);
+ bson_value_destroy (&mongoc_delete_one_opts->delete.hint);
bson_destroy (&mongoc_delete_one_opts->extra);
}
bool
_mongoc_delete_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_delete_many_opts_t *mongoc_delete_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
- mongoc_delete_many_opts->crud.writeConcern = NULL;
- mongoc_delete_many_opts->crud.write_concern_owned = false;
- mongoc_delete_many_opts->crud.client_session = NULL;
- mongoc_delete_many_opts->crud.validate = BSON_VALIDATE_NONE;
- bson_init (&mongoc_delete_many_opts->collation);
+ mongoc_delete_many_opts->delete.crud.writeConcern = NULL;
+ mongoc_delete_many_opts->delete.crud.write_concern_owned = false;
+ mongoc_delete_many_opts->delete.crud.client_session = NULL;
+ mongoc_delete_many_opts->delete.crud.validate = BSON_VALIDATE_NONE;
+ bson_init (&mongoc_delete_many_opts->delete.collation);
+ memset (&mongoc_delete_many_opts->delete.hint, 0, sizeof (bson_value_t));
bson_init (&mongoc_delete_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
- &mongoc_delete_many_opts->crud.writeConcern,
+ &mongoc_delete_many_opts->delete.crud.writeConcern,
error)) {
return false;
}
- mongoc_delete_many_opts->crud.write_concern_owned = true;
+ mongoc_delete_many_opts->delete.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
- &mongoc_delete_many_opts->crud.client_session,
+ &mongoc_delete_many_opts->delete.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
- &mongoc_delete_many_opts->crud.validate,
+ &mongoc_delete_many_opts->delete.crud.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
- &mongoc_delete_many_opts->collation,
+ &mongoc_delete_many_opts->delete.collation,
+ error)) {
+ return false;
+ }
+ }
+ else if (!strcmp (bson_iter_key (&iter), "hint")) {
+ if (!_mongoc_convert_hint (
+ client,
+ &iter,
+ &mongoc_delete_many_opts->delete.hint,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_delete_many_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_delete_many_opts_cleanup (mongoc_delete_many_opts_t *mongoc_delete_many_opts)
{
- if (mongoc_delete_many_opts->crud.write_concern_owned) {
- mongoc_write_concern_destroy (mongoc_delete_many_opts->crud.writeConcern);
+ if (mongoc_delete_many_opts->delete.crud.write_concern_owned) {
+ mongoc_write_concern_destroy (mongoc_delete_many_opts->delete.crud.writeConcern);
}
- bson_destroy (&mongoc_delete_many_opts->collation);
+ bson_destroy (&mongoc_delete_many_opts->delete.collation);
+ bson_value_destroy (&mongoc_delete_many_opts->delete.hint);
bson_destroy (&mongoc_delete_many_opts->extra);
}
bool
_mongoc_update_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_update_one_opts_t *mongoc_update_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_update_one_opts->update.crud.writeConcern = NULL;
mongoc_update_one_opts->update.crud.write_concern_owned = false;
mongoc_update_one_opts->update.crud.client_session = NULL;
mongoc_update_one_opts->update.crud.validate = _mongoc_default_update_vflags;
mongoc_update_one_opts->update.bypass = false;
bson_init (&mongoc_update_one_opts->update.collation);
memset (&mongoc_update_one_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_update_one_opts->update.upsert = false;
bson_init (&mongoc_update_one_opts->arrayFilters);
bson_init (&mongoc_update_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_update_one_opts->update.crud.writeConcern,
error)) {
return false;
}
mongoc_update_one_opts->update.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_update_one_opts->update.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_update_one_opts->update.crud.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_update_one_opts->update.bypass,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_update_one_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_update_one_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_update_one_opts->update.upsert,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) {
if (!_mongoc_convert_array (
client,
&iter,
&mongoc_update_one_opts->arrayFilters,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_update_one_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_update_one_opts_cleanup (mongoc_update_one_opts_t *mongoc_update_one_opts)
{
if (mongoc_update_one_opts->update.crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_update_one_opts->update.crud.writeConcern);
}
bson_destroy (&mongoc_update_one_opts->update.collation);
bson_value_destroy (&mongoc_update_one_opts->update.hint);
bson_destroy (&mongoc_update_one_opts->arrayFilters);
bson_destroy (&mongoc_update_one_opts->extra);
}
bool
_mongoc_update_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_update_many_opts_t *mongoc_update_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_update_many_opts->update.crud.writeConcern = NULL;
mongoc_update_many_opts->update.crud.write_concern_owned = false;
mongoc_update_many_opts->update.crud.client_session = NULL;
mongoc_update_many_opts->update.crud.validate = _mongoc_default_update_vflags;
mongoc_update_many_opts->update.bypass = false;
bson_init (&mongoc_update_many_opts->update.collation);
memset (&mongoc_update_many_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_update_many_opts->update.upsert = false;
bson_init (&mongoc_update_many_opts->arrayFilters);
bson_init (&mongoc_update_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_update_many_opts->update.crud.writeConcern,
error)) {
return false;
}
mongoc_update_many_opts->update.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_update_many_opts->update.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_update_many_opts->update.crud.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_update_many_opts->update.bypass,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_update_many_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_update_many_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_update_many_opts->update.upsert,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) {
if (!_mongoc_convert_array (
client,
&iter,
&mongoc_update_many_opts->arrayFilters,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_update_many_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_update_many_opts_cleanup (mongoc_update_many_opts_t *mongoc_update_many_opts)
{
if (mongoc_update_many_opts->update.crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_update_many_opts->update.crud.writeConcern);
}
bson_destroy (&mongoc_update_many_opts->update.collation);
bson_value_destroy (&mongoc_update_many_opts->update.hint);
bson_destroy (&mongoc_update_many_opts->arrayFilters);
bson_destroy (&mongoc_update_many_opts->extra);
}
bool
_mongoc_replace_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_replace_one_opts_t *mongoc_replace_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_replace_one_opts->update.crud.writeConcern = NULL;
mongoc_replace_one_opts->update.crud.write_concern_owned = false;
mongoc_replace_one_opts->update.crud.client_session = NULL;
mongoc_replace_one_opts->update.crud.validate = _mongoc_default_replace_vflags;
mongoc_replace_one_opts->update.bypass = false;
bson_init (&mongoc_replace_one_opts->update.collation);
memset (&mongoc_replace_one_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_replace_one_opts->update.upsert = false;
bson_init (&mongoc_replace_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_replace_one_opts->update.crud.writeConcern,
error)) {
return false;
}
mongoc_replace_one_opts->update.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_replace_one_opts->update.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_replace_one_opts->update.crud.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_replace_one_opts->update.bypass,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_replace_one_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_replace_one_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_replace_one_opts->update.upsert,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_replace_one_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_replace_one_opts_cleanup (mongoc_replace_one_opts_t *mongoc_replace_one_opts)
{
if (mongoc_replace_one_opts->update.crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_replace_one_opts->update.crud.writeConcern);
}
bson_destroy (&mongoc_replace_one_opts->update.collation);
bson_value_destroy (&mongoc_replace_one_opts->update.hint);
bson_destroy (&mongoc_replace_one_opts->extra);
}
bool
_mongoc_bulk_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_opts_t *mongoc_bulk_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_opts->writeConcern = NULL;
mongoc_bulk_opts->write_concern_owned = false;
mongoc_bulk_opts->ordered = true;
mongoc_bulk_opts->client_session = NULL;
bson_init (&mongoc_bulk_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_bulk_opts->writeConcern,
error)) {
return false;
}
mongoc_bulk_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "ordered")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_opts->ordered,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_bulk_opts->client_session,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_opts_cleanup (mongoc_bulk_opts_t *mongoc_bulk_opts)
{
if (mongoc_bulk_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_bulk_opts->writeConcern);
}
bson_destroy (&mongoc_bulk_opts->extra);
}
bool
_mongoc_bulk_insert_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_insert_opts->validate = _mongoc_default_insert_vflags;
bson_init (&mongoc_bulk_insert_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_bulk_insert_opts->validate,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_insert_opts_cleanup (mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts)
{
bson_destroy (&mongoc_bulk_insert_opts->extra);
}
bool
_mongoc_bulk_update_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_update_one_opts->update.validate = _mongoc_default_update_vflags;
bson_init (&mongoc_bulk_update_one_opts->update.collation);
memset (&mongoc_bulk_update_one_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_bulk_update_one_opts->update.upsert = false;
mongoc_bulk_update_one_opts->update.multi = false;
bson_init (&mongoc_bulk_update_one_opts->arrayFilters);
bson_init (&mongoc_bulk_update_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_bulk_update_one_opts->update.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_update_one_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_bulk_update_one_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_update_one_opts->update.upsert,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "multi")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_update_one_opts->update.multi,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) {
if (!_mongoc_convert_array (
client,
&iter,
&mongoc_bulk_update_one_opts->arrayFilters,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_update_one_opts_cleanup (mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts)
{
bson_destroy (&mongoc_bulk_update_one_opts->update.collation);
bson_value_destroy (&mongoc_bulk_update_one_opts->update.hint);
bson_destroy (&mongoc_bulk_update_one_opts->arrayFilters);
bson_destroy (&mongoc_bulk_update_one_opts->extra);
}
bool
_mongoc_bulk_update_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_update_many_opts->update.validate = _mongoc_default_update_vflags;
bson_init (&mongoc_bulk_update_many_opts->update.collation);
memset (&mongoc_bulk_update_many_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_bulk_update_many_opts->update.upsert = false;
mongoc_bulk_update_many_opts->update.multi = true;
bson_init (&mongoc_bulk_update_many_opts->arrayFilters);
bson_init (&mongoc_bulk_update_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_bulk_update_many_opts->update.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_update_many_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_bulk_update_many_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_update_many_opts->update.upsert,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "multi")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_update_many_opts->update.multi,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) {
if (!_mongoc_convert_array (
client,
&iter,
&mongoc_bulk_update_many_opts->arrayFilters,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_update_many_opts_cleanup (mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts)
{
bson_destroy (&mongoc_bulk_update_many_opts->update.collation);
bson_value_destroy (&mongoc_bulk_update_many_opts->update.hint);
bson_destroy (&mongoc_bulk_update_many_opts->arrayFilters);
bson_destroy (&mongoc_bulk_update_many_opts->extra);
}
bool
_mongoc_bulk_replace_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_replace_one_opts->update.validate = _mongoc_default_replace_vflags;
bson_init (&mongoc_bulk_replace_one_opts->update.collation);
memset (&mongoc_bulk_replace_one_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_bulk_replace_one_opts->update.upsert = false;
mongoc_bulk_replace_one_opts->update.multi = false;
bson_init (&mongoc_bulk_replace_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.upsert,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "multi")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.multi,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_replace_one_opts_cleanup (mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts)
{
bson_destroy (&mongoc_bulk_replace_one_opts->update.collation);
bson_value_destroy (&mongoc_bulk_replace_one_opts->update.hint);
bson_destroy (&mongoc_bulk_replace_one_opts->extra);
}
bool
_mongoc_bulk_remove_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
bson_init (&mongoc_bulk_remove_one_opts->remove.collation);
+ memset (&mongoc_bulk_remove_one_opts->remove.hint, 0, sizeof (bson_value_t));
mongoc_bulk_remove_one_opts->remove.limit = 1;
bson_init (&mongoc_bulk_remove_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_remove_one_opts->remove.collation,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "hint")) {
+ if (!_mongoc_convert_hint (
+ client,
+ &iter,
+ &mongoc_bulk_remove_one_opts->remove.hint,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "limit")) {
if (!_mongoc_convert_int32_t (
client,
&iter,
&mongoc_bulk_remove_one_opts->remove.limit,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_remove_one_opts_cleanup (mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts)
{
bson_destroy (&mongoc_bulk_remove_one_opts->remove.collation);
+ bson_value_destroy (&mongoc_bulk_remove_one_opts->remove.hint);
bson_destroy (&mongoc_bulk_remove_one_opts->extra);
}
bool
_mongoc_bulk_remove_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
bson_init (&mongoc_bulk_remove_many_opts->remove.collation);
+ memset (&mongoc_bulk_remove_many_opts->remove.hint, 0, sizeof (bson_value_t));
mongoc_bulk_remove_many_opts->remove.limit = 0;
bson_init (&mongoc_bulk_remove_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_remove_many_opts->remove.collation,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "hint")) {
+ if (!_mongoc_convert_hint (
+ client,
+ &iter,
+ &mongoc_bulk_remove_many_opts->remove.hint,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "limit")) {
if (!_mongoc_convert_int32_t (
client,
&iter,
&mongoc_bulk_remove_many_opts->remove.limit,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_remove_many_opts_cleanup (mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts)
{
bson_destroy (&mongoc_bulk_remove_many_opts->remove.collation);
+ bson_value_destroy (&mongoc_bulk_remove_many_opts->remove.hint);
bson_destroy (&mongoc_bulk_remove_many_opts->extra);
}
bool
_mongoc_change_stream_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_change_stream_opts_t *mongoc_change_stream_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_change_stream_opts->batchSize = 0;
bson_init (&mongoc_change_stream_opts->resumeAfter);
bson_init (&mongoc_change_stream_opts->startAfter);
memset (&mongoc_change_stream_opts->startAtOperationTime, 0, sizeof (mongoc_timestamp_t));
mongoc_change_stream_opts->maxAwaitTimeMS = 0;
mongoc_change_stream_opts->fullDocument = "default";
bson_init (&mongoc_change_stream_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "batchSize")) {
if (!_mongoc_convert_int32_t (
client,
&iter,
&mongoc_change_stream_opts->batchSize,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "resumeAfter")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_change_stream_opts->resumeAfter,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "startAfter")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_change_stream_opts->startAfter,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "startAtOperationTime")) {
if (!_mongoc_convert_timestamp (
client,
&iter,
&mongoc_change_stream_opts->startAtOperationTime,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "maxAwaitTimeMS")) {
if (!_mongoc_convert_int64_positive (
client,
&iter,
&mongoc_change_stream_opts->maxAwaitTimeMS,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "fullDocument")) {
if (!_mongoc_convert_utf8 (
client,
&iter,
&mongoc_change_stream_opts->fullDocument,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_change_stream_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_change_stream_opts_cleanup (mongoc_change_stream_opts_t *mongoc_change_stream_opts)
{
bson_destroy (&mongoc_change_stream_opts->resumeAfter);
bson_destroy (&mongoc_change_stream_opts->startAfter);
bson_destroy (&mongoc_change_stream_opts->extra);
}
bool
_mongoc_create_index_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_create_index_opts_t *mongoc_create_index_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_create_index_opts->writeConcern = NULL;
mongoc_create_index_opts->write_concern_owned = false;
mongoc_create_index_opts->client_session = NULL;
bson_init (&mongoc_create_index_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_create_index_opts->writeConcern,
error)) {
return false;
}
mongoc_create_index_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_create_index_opts->client_session,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_create_index_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_create_index_opts_cleanup (mongoc_create_index_opts_t *mongoc_create_index_opts)
{
if (mongoc_create_index_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_create_index_opts->writeConcern);
}
bson_destroy (&mongoc_create_index_opts->extra);
}
bool
_mongoc_read_write_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_read_write_opts_t *mongoc_read_write_opts,
bson_error_t *error)
{
bson_iter_t iter;
bson_init (&mongoc_read_write_opts->readConcern);
mongoc_read_write_opts->writeConcern = NULL;
mongoc_read_write_opts->write_concern_owned = false;
mongoc_read_write_opts->client_session = NULL;
bson_init (&mongoc_read_write_opts->collation);
mongoc_read_write_opts->serverId = 0;
bson_init (&mongoc_read_write_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "readConcern")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_read_write_opts->readConcern,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_read_write_opts->writeConcern,
error)) {
return false;
}
mongoc_read_write_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_read_write_opts->client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_read_write_opts->collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "serverId")) {
if (!_mongoc_convert_server_id (
client,
&iter,
&mongoc_read_write_opts->serverId,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_read_write_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_read_write_opts_cleanup (mongoc_read_write_opts_t *mongoc_read_write_opts)
{
bson_destroy (&mongoc_read_write_opts->readConcern);
if (mongoc_read_write_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_read_write_opts->writeConcern);
}
bson_destroy (&mongoc_read_write_opts->collation);
bson_destroy (&mongoc_read_write_opts->extra);
}
bool
_mongoc_gridfs_bucket_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_gridfs_bucket_opts->bucketName = "fs";
mongoc_gridfs_bucket_opts->chunkSizeBytes = 261120;
mongoc_gridfs_bucket_opts->writeConcern = NULL;
mongoc_gridfs_bucket_opts->write_concern_owned = false;
mongoc_gridfs_bucket_opts->readConcern = NULL;
bson_init (&mongoc_gridfs_bucket_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "bucketName")) {
if (!_mongoc_convert_utf8 (
client,
&iter,
&mongoc_gridfs_bucket_opts->bucketName,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "chunkSizeBytes")) {
if (!_mongoc_convert_int32_positive (
client,
&iter,
&mongoc_gridfs_bucket_opts->chunkSizeBytes,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_gridfs_bucket_opts->writeConcern,
error)) {
return false;
}
mongoc_gridfs_bucket_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "readConcern")) {
if (!_mongoc_convert_read_concern (
client,
&iter,
&mongoc_gridfs_bucket_opts->readConcern,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_gridfs_bucket_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_gridfs_bucket_opts_cleanup (mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts)
{
if (mongoc_gridfs_bucket_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_gridfs_bucket_opts->writeConcern);
}
mongoc_read_concern_destroy (mongoc_gridfs_bucket_opts->readConcern);
bson_destroy (&mongoc_gridfs_bucket_opts->extra);
}
bool
_mongoc_gridfs_bucket_upload_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_gridfs_bucket_upload_opts->chunkSizeBytes = 0;
bson_init (&mongoc_gridfs_bucket_upload_opts->metadata);
bson_init (&mongoc_gridfs_bucket_upload_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "chunkSizeBytes")) {
if (!_mongoc_convert_int32_positive (
client,
&iter,
&mongoc_gridfs_bucket_upload_opts->chunkSizeBytes,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "metadata")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_gridfs_bucket_upload_opts->metadata,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_gridfs_bucket_upload_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_gridfs_bucket_upload_opts_cleanup (mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts)
{
bson_destroy (&mongoc_gridfs_bucket_upload_opts->metadata);
bson_destroy (&mongoc_gridfs_bucket_upload_opts->extra);
}
bool
_mongoc_aggregate_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_aggregate_opts_t *mongoc_aggregate_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_aggregate_opts->readConcern = NULL;
mongoc_aggregate_opts->writeConcern = NULL;
mongoc_aggregate_opts->write_concern_owned = false;
mongoc_aggregate_opts->client_session = NULL;
mongoc_aggregate_opts->bypass = false;
bson_init (&mongoc_aggregate_opts->collation);
mongoc_aggregate_opts->serverId = 0;
mongoc_aggregate_opts->batchSize = 0;
mongoc_aggregate_opts->batchSize_is_set = false;
bson_init (&mongoc_aggregate_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "readConcern")) {
if (!_mongoc_convert_read_concern (
client,
&iter,
&mongoc_aggregate_opts->readConcern,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_aggregate_opts->writeConcern,
error)) {
return false;
}
mongoc_aggregate_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_aggregate_opts->client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_aggregate_opts->bypass,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_aggregate_opts->collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "serverId")) {
if (!_mongoc_convert_server_id (
client,
&iter,
&mongoc_aggregate_opts->serverId,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "batchSize")) {
if (!_mongoc_convert_int32_t (
client,
&iter,
&mongoc_aggregate_opts->batchSize,
error)) {
return false;
}
mongoc_aggregate_opts->batchSize_is_set = true;
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_aggregate_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_aggregate_opts_cleanup (mongoc_aggregate_opts_t *mongoc_aggregate_opts)
{
mongoc_read_concern_destroy (mongoc_aggregate_opts->readConcern);
if (mongoc_aggregate_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_aggregate_opts->writeConcern);
}
bson_destroy (&mongoc_aggregate_opts->collation);
bson_destroy (&mongoc_aggregate_opts->extra);
}
+
+bool
+_mongoc_find_and_modify_appended_opts_parse (
+ mongoc_client_t *client,
+ const bson_t *opts,
+ mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts,
+ bson_error_t *error)
+{
+ bson_iter_t iter;
+
+ mongoc_find_and_modify_appended_opts->writeConcern = NULL;
+ mongoc_find_and_modify_appended_opts->write_concern_owned = false;
+ mongoc_find_and_modify_appended_opts->client_session = NULL;
+ memset (&mongoc_find_and_modify_appended_opts->hint, 0, sizeof (bson_value_t));
+ bson_init (&mongoc_find_and_modify_appended_opts->extra);
+
+ if (!opts) {
+ return true;
+ }
+
+ if (!bson_iter_init (&iter, opts)) {
+ bson_set_error (error,
+ MONGOC_ERROR_BSON,
+ MONGOC_ERROR_BSON_INVALID,
+ "Invalid 'opts' parameter.");
+ return false;
+ }
+
+ while (bson_iter_next (&iter)) {
+ if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
+ if (!_mongoc_convert_write_concern (
+ client,
+ &iter,
+ &mongoc_find_and_modify_appended_opts->writeConcern,
+ error)) {
+ return false;
+ }
+
+ mongoc_find_and_modify_appended_opts->write_concern_owned = true;
+ }
+ else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
+ if (!_mongoc_convert_session_id (
+ client,
+ &iter,
+ &mongoc_find_and_modify_appended_opts->client_session,
+ error)) {
+ return false;
+ }
+ }
+ else if (!strcmp (bson_iter_key (&iter), "hint")) {
+ if (!_mongoc_convert_hint (
+ client,
+ &iter,
+ &mongoc_find_and_modify_appended_opts->hint,
+ error)) {
+ return false;
+ }
+ }
+ else {
+ /* unrecognized values are copied to "extra" */
+ if (!BSON_APPEND_VALUE (
+ &mongoc_find_and_modify_appended_opts->extra,
+ bson_iter_key (&iter),
+ bson_iter_value (&iter))) {
+ bson_set_error (error,
+ MONGOC_ERROR_BSON,
+ MONGOC_ERROR_BSON_INVALID,
+ "Invalid 'opts' parameter.");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void
+_mongoc_find_and_modify_appended_opts_cleanup (mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts)
+{
+ if (mongoc_find_and_modify_appended_opts->write_concern_owned) {
+ mongoc_write_concern_destroy (mongoc_find_and_modify_appended_opts->writeConcern);
+ }
+ bson_value_destroy (&mongoc_find_and_modify_appended_opts->hint);
+ bson_destroy (&mongoc_find_and_modify_appended_opts->extra);
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h
index 5482e15b..8ae2eeb0 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h
@@ -1,19 +1,19 @@
/*
* Copyright 2018-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
*
* 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.
*/
#if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION)
#error "Only <mongoc/mongoc.h> can be included directly."
-#endif
\ No newline at end of file
+#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c
similarity index 92%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c
index 4aabb904..dd5ff763 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c
@@ -1,75 +1,75 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL
#include "mongoc-rand.h"
#include "mongoc-rand-private.h"
#include "mongoc.h"
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#define NT_SUCCESS(Status) (((NTSTATUS) (Status)) >= 0)
#define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L)
int
_mongoc_rand_bytes (uint8_t *buf, int num)
{
static BCRYPT_ALG_HANDLE algorithm = 0;
NTSTATUS status = 0;
if (!algorithm) {
status = BCryptOpenAlgorithmProvider (
&algorithm, BCRYPT_RNG_ALGORITHM, NULL, 0);
if (!NT_SUCCESS (status)) {
- MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %d", status);
+ MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %ld", status);
return 0;
}
}
status = BCryptGenRandom (algorithm, buf, num, 0);
if (NT_SUCCESS (status)) {
return 1;
}
- MONGOC_ERROR ("BCryptGenRandom(): %d", status);
+ MONGOC_ERROR ("BCryptGenRandom(): %ld", status);
return 0;
}
void
mongoc_rand_seed (const void *buf, int num)
{
/* N/A - OS Does not need entropy seed */
}
void
mongoc_rand_add (const void *buf, int num, double entropy)
{
/* N/A - OS Does not need entropy seed */
}
int
mongoc_rand_status (void)
{
return 1;
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h
index 706b0460..5aae328b 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h
@@ -1,72 +1,73 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_READ_PREFS_PRIVATE_H
#define MONGOC_READ_PREFS_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-cluster-private.h"
#include "mongoc-read-prefs.h"
BSON_BEGIN_DECLS
struct _mongoc_read_prefs_t {
mongoc_read_mode_t mode;
bson_t tags;
int64_t max_staleness_seconds;
+ bson_t hedge;
};
typedef struct _mongoc_assemble_query_result_t {
bson_t *assembled_query;
bool query_owned;
mongoc_query_flags_t flags;
} mongoc_assemble_query_result_t;
#define ASSEMBLE_QUERY_RESULT_INIT \
{ \
NULL, false, MONGOC_QUERY_NONE \
}
const char *
_mongoc_read_mode_as_str (mongoc_read_mode_t mode);
void
assemble_query (const mongoc_read_prefs_t *read_prefs,
const mongoc_server_stream_t *server_stream,
const bson_t *query_bson,
mongoc_query_flags_t initial_flags,
mongoc_assemble_query_result_t *result);
void
assemble_query_result_cleanup (mongoc_assemble_query_result_t *result);
bool
_mongoc_read_prefs_validate (const mongoc_read_prefs_t *read_prefs,
bson_error_t *error);
#define IS_PREF_PRIMARY(_pref) \
(!(_pref) || ((_pref)->mode == MONGOC_READ_PRIMARY))
BSON_END_DECLS
#endif /* MONGOC_READ_PREFS_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c
similarity index 88%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c
index a6263813..9bcffb9d 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c
@@ -1,383 +1,421 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-error.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-trace-private.h"
mongoc_read_prefs_t *
mongoc_read_prefs_new (mongoc_read_mode_t mode)
{
mongoc_read_prefs_t *read_prefs;
read_prefs = (mongoc_read_prefs_t *) bson_malloc0 (sizeof *read_prefs);
read_prefs->mode = mode;
bson_init (&read_prefs->tags);
read_prefs->max_staleness_seconds = MONGOC_NO_MAX_STALENESS;
+ bson_init (&read_prefs->hedge);
return read_prefs;
}
mongoc_read_mode_t
mongoc_read_prefs_get_mode (const mongoc_read_prefs_t *read_prefs)
{
return read_prefs ? read_prefs->mode : MONGOC_READ_PRIMARY;
}
void
mongoc_read_prefs_set_mode (mongoc_read_prefs_t *read_prefs,
mongoc_read_mode_t mode)
{
BSON_ASSERT (read_prefs);
BSON_ASSERT (mode <= MONGOC_READ_NEAREST);
read_prefs->mode = mode;
}
const bson_t *
mongoc_read_prefs_get_tags (const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT (read_prefs);
return &read_prefs->tags;
}
void
mongoc_read_prefs_set_tags (mongoc_read_prefs_t *read_prefs, const bson_t *tags)
{
BSON_ASSERT (read_prefs);
bson_destroy (&read_prefs->tags);
if (tags) {
bson_copy_to (tags, &read_prefs->tags);
} else {
bson_init (&read_prefs->tags);
}
}
void
mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag)
{
bson_t empty = BSON_INITIALIZER;
char str[16];
int key;
BSON_ASSERT (read_prefs);
key = bson_count_keys (&read_prefs->tags);
bson_snprintf (str, sizeof str, "%d", key);
if (tag) {
bson_append_document (&read_prefs->tags, str, -1, tag);
} else {
bson_append_document (&read_prefs->tags, str, -1, &empty);
}
bson_destroy (&empty);
}
int64_t
mongoc_read_prefs_get_max_staleness_seconds (
const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT (read_prefs);
return read_prefs->max_staleness_seconds;
}
void
mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs,
int64_t max_staleness_seconds)
{
BSON_ASSERT (read_prefs);
read_prefs->max_staleness_seconds = max_staleness_seconds;
}
+const bson_t *
+mongoc_read_prefs_get_hedge (const mongoc_read_prefs_t *read_prefs)
+{
+ BSON_ASSERT (read_prefs);
+
+ return &read_prefs->hedge;
+}
+
+
+void
+mongoc_read_prefs_set_hedge (mongoc_read_prefs_t *read_prefs,
+ const bson_t *hedge)
+{
+ BSON_ASSERT (read_prefs);
+
+ bson_destroy (&read_prefs->hedge);
+
+ if (hedge) {
+ bson_copy_to (hedge, &read_prefs->hedge);
+ } else {
+ bson_init (&read_prefs->hedge);
+ }
+}
+
+
bool
mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT (read_prefs);
/*
- * Tags or maxStalenessSeconds are not supported with PRIMARY mode.
+ * Tags, maxStalenessSeconds, and hedge are not supported with PRIMARY mode.
*/
if (read_prefs->mode == MONGOC_READ_PRIMARY) {
if (!bson_empty (&read_prefs->tags) ||
- read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS) {
+ read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS ||
+ !bson_empty (&read_prefs->hedge)) {
return false;
}
}
if (read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS &&
read_prefs->max_staleness_seconds <= 0) {
return false;
}
return true;
}
void
mongoc_read_prefs_destroy (mongoc_read_prefs_t *read_prefs)
{
if (read_prefs) {
bson_destroy (&read_prefs->tags);
+ bson_destroy (&read_prefs->hedge);
bson_free (read_prefs);
}
}
mongoc_read_prefs_t *
mongoc_read_prefs_copy (const mongoc_read_prefs_t *read_prefs)
{
mongoc_read_prefs_t *ret = NULL;
if (read_prefs) {
ret = mongoc_read_prefs_new (read_prefs->mode);
bson_destroy (&ret->tags);
bson_copy_to (&read_prefs->tags, &ret->tags);
ret->max_staleness_seconds = read_prefs->max_staleness_seconds;
+ bson_destroy (&ret->hedge);
+ bson_copy_to (&read_prefs->hedge, &ret->hedge);
}
return ret;
}
const char *
_mongoc_read_mode_as_str (mongoc_read_mode_t mode)
{
switch (mode) {
case MONGOC_READ_PRIMARY:
return "primary";
case MONGOC_READ_PRIMARY_PREFERRED:
return "primaryPreferred";
case MONGOC_READ_SECONDARY:
return "secondary";
case MONGOC_READ_SECONDARY_PREFERRED:
return "secondaryPreferred";
case MONGOC_READ_NEAREST:
return "nearest";
default:
return "";
}
}
/* Update result with the read prefs, following Server Selection Spec.
* The driver must have discovered the server is a mongos.
*/
static void
_apply_read_preferences_mongos (
const mongoc_read_prefs_t *read_prefs,
const bson_t *query_bson,
mongoc_assemble_query_result_t *result /* OUT */)
{
mongoc_read_mode_t mode;
const bson_t *tags = NULL;
bson_t child;
const char *mode_str;
- int64_t max_staleness_seconds;
+ int64_t max_staleness_seconds = MONGOC_NO_MAX_STALENESS;
+ const bson_t *hedge = NULL;
mode = mongoc_read_prefs_get_mode (read_prefs);
if (read_prefs) {
+ max_staleness_seconds =
+ mongoc_read_prefs_get_max_staleness_seconds (read_prefs);
+
tags = mongoc_read_prefs_get_tags (read_prefs);
+ hedge = mongoc_read_prefs_get_hedge (read_prefs);
}
/* Server Selection Spec says:
*
* For mode 'primary', drivers MUST NOT set the slaveOK wire protocol flag
* and MUST NOT use $readPreference
*
* For mode 'secondary', drivers MUST set the slaveOK wire protocol flag and
* MUST also use $readPreference
*
* For mode 'primaryPreferred', drivers MUST set the slaveOK wire protocol
* flag and MUST also use $readPreference
*
* For mode 'secondaryPreferred', drivers MUST set the slaveOK wire protocol
* flag. If the read preference contains a non-empty tag_sets parameter,
- * drivers MUST use $readPreference; otherwise, drivers MUST NOT use
- * $readPreference
+ * maxStalenessSeconds is a positive integer, or the hedge parameter is
+ * non-empty, drivers MUST use $readPreference; otherwise, drivers MUST NOT
+ * use $readPreference
*
* For mode 'nearest', drivers MUST set the slaveOK wire protocol flag and
* MUST also use $readPreference
*/
- if (mode == MONGOC_READ_SECONDARY_PREFERRED && bson_empty0 (tags)) {
+ if (mode == MONGOC_READ_SECONDARY_PREFERRED &&
+ (bson_empty0 (tags) && max_staleness_seconds <= 0 && bson_empty0 (hedge))) {
result->flags |= MONGOC_QUERY_SLAVE_OK;
} else if (mode != MONGOC_READ_PRIMARY) {
result->flags |= MONGOC_QUERY_SLAVE_OK;
/* Server Selection Spec: "When any $ modifier is used, including the
* $readPreference modifier, the query MUST be provided using the $query
* modifier".
*
* This applies to commands, too.
*/
result->assembled_query = bson_new ();
result->query_owned = true;
if (bson_has_field (query_bson, "$query")) {
bson_concat (result->assembled_query, query_bson);
} else {
bson_append_document (
result->assembled_query, "$query", 6, query_bson);
}
bson_append_document_begin (
result->assembled_query, "$readPreference", 15, &child);
mode_str = _mongoc_read_mode_as_str (mode);
bson_append_utf8 (&child, "mode", 4, mode_str, -1);
if (!bson_empty0 (tags)) {
bson_append_array (&child, "tags", 4, tags);
}
- max_staleness_seconds =
- mongoc_read_prefs_get_max_staleness_seconds (read_prefs);
-
if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) {
bson_append_int64 (
&child, "maxStalenessSeconds", 19, max_staleness_seconds);
}
+ if (!bson_empty0 (hedge)) {
+ bson_append_document (&child, "hedge", 5, hedge);
+ }
+
bson_append_document_end (result->assembled_query, &child);
}
}
/*
*--------------------------------------------------------------------------
*
* assemble_query --
*
* Update @result based on @read_prefs, following the Server Selection
* Spec.
*
* Side effects:
* Sets @result->assembled_query and @result->flags.
*
* Note:
* This function, the mongoc_assemble_query_result_t struct, and all
* related functions are only used for find operations with OP_QUERY.
* Remove them once we have implemented exhaust cursors with OP_MSG in
* the server, and all previous server versions are EOL.
*
*--------------------------------------------------------------------------
*/
void
assemble_query (const mongoc_read_prefs_t *read_prefs,
const mongoc_server_stream_t *server_stream,
const bson_t *query_bson,
mongoc_query_flags_t initial_flags,
mongoc_assemble_query_result_t *result /* OUT */)
{
mongoc_server_description_type_t server_type;
ENTRY;
BSON_ASSERT (server_stream);
BSON_ASSERT (query_bson);
BSON_ASSERT (result);
/* default values */
result->assembled_query = (bson_t *) query_bson;
result->query_owned = false;
result->flags = initial_flags;
server_type = server_stream->sd->type;
switch (server_stream->topology_type) {
case MONGOC_TOPOLOGY_SINGLE:
if (server_type == MONGOC_SERVER_MONGOS) {
_apply_read_preferences_mongos (read_prefs, query_bson, result);
} else {
/* Server Selection Spec: for topology type single and server types
* besides mongos, "clients MUST always set the slaveOK wire protocol
* flag on reads to ensure that any server type can handle the
* request."
*/
result->flags |= MONGOC_QUERY_SLAVE_OK;
}
break;
case MONGOC_TOPOLOGY_RS_NO_PRIMARY:
case MONGOC_TOPOLOGY_RS_WITH_PRIMARY:
/* Server Selection Spec: for RS topology types, "For all read
* preferences modes except primary, clients MUST set the slaveOK wire
* protocol flag to ensure that any suitable server can handle the
* request. Clients MUST NOT set the slaveOK wire protocol flag if the
* read preference mode is primary.
*/
if (read_prefs && read_prefs->mode != MONGOC_READ_PRIMARY) {
result->flags |= MONGOC_QUERY_SLAVE_OK;
}
break;
case MONGOC_TOPOLOGY_SHARDED:
_apply_read_preferences_mongos (read_prefs, query_bson, result);
break;
case MONGOC_TOPOLOGY_UNKNOWN:
case MONGOC_TOPOLOGY_DESCRIPTION_TYPES:
default:
/* must not call _apply_read_preferences with unknown topology type */
BSON_ASSERT (false);
}
EXIT;
}
void
assemble_query_result_cleanup (mongoc_assemble_query_result_t *result)
{
ENTRY;
BSON_ASSERT (result);
if (result->query_owned) {
bson_destroy (result->assembled_query);
}
EXIT;
}
bool
_mongoc_read_prefs_validate (const mongoc_read_prefs_t *read_prefs,
bson_error_t *error)
{
if (read_prefs && !mongoc_read_prefs_is_valid (read_prefs)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid mongoc_read_prefs_t");
return false;
}
return true;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h
similarity index 92%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h
index 5a8a7bf4..9a913f29 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h
@@ -1,76 +1,80 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_READ_PREFS_H
#define MONGOC_READ_PREFS_H
#include <bson/bson.h>
#include "mongoc-macros.h"
#include "mongoc-config.h"
BSON_BEGIN_DECLS
#define MONGOC_NO_MAX_STALENESS -1
#define MONGOC_SMALLEST_MAX_STALENESS_SECONDS 90
typedef struct _mongoc_read_prefs_t mongoc_read_prefs_t;
typedef enum {
MONGOC_READ_PRIMARY = (1 << 0),
MONGOC_READ_SECONDARY = (1 << 1),
MONGOC_READ_PRIMARY_PREFERRED = (1 << 2) | MONGOC_READ_PRIMARY,
MONGOC_READ_SECONDARY_PREFERRED = (1 << 2) | MONGOC_READ_SECONDARY,
MONGOC_READ_NEAREST = (1 << 3) | MONGOC_READ_SECONDARY,
} mongoc_read_mode_t;
MONGOC_EXPORT (mongoc_read_prefs_t *)
mongoc_read_prefs_new (mongoc_read_mode_t read_mode);
MONGOC_EXPORT (mongoc_read_prefs_t *)
mongoc_read_prefs_copy (const mongoc_read_prefs_t *read_prefs);
MONGOC_EXPORT (void)
mongoc_read_prefs_destroy (mongoc_read_prefs_t *read_prefs);
MONGOC_EXPORT (mongoc_read_mode_t)
mongoc_read_prefs_get_mode (const mongoc_read_prefs_t *read_prefs);
MONGOC_EXPORT (void)
mongoc_read_prefs_set_mode (mongoc_read_prefs_t *read_prefs,
mongoc_read_mode_t mode);
MONGOC_EXPORT (const bson_t *)
mongoc_read_prefs_get_tags (const mongoc_read_prefs_t *read_prefs);
MONGOC_EXPORT (void)
mongoc_read_prefs_set_tags (mongoc_read_prefs_t *read_prefs,
const bson_t *tags);
MONGOC_EXPORT (void)
mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag);
MONGOC_EXPORT (int64_t)
mongoc_read_prefs_get_max_staleness_seconds (
const mongoc_read_prefs_t *read_prefs);
MONGOC_EXPORT (void)
mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs,
int64_t max_staleness_seconds);
+MONGOC_EXPORT (const bson_t *)
+mongoc_read_prefs_get_hedge (const mongoc_read_prefs_t *read_prefs);
+MONGOC_EXPORT (void)
+mongoc_read_prefs_set_hedge (mongoc_read_prefs_t *read_prefs, const bson_t *hedge);
MONGOC_EXPORT (bool)
mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs);
BSON_END_DECLS
#endif /* MONGOC_READ_PREFS_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
index 87c5b2b2..795ed8e6 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
@@ -1,182 +1,187 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_RPC_PRIVATE_H
#define MONGOC_RPC_PRIVATE_H
#include <bson/bson.h>
#include <stddef.h>
#include "mongoc-array-private.h"
#include "mongoc-cmd-private.h"
#include "mongoc-iovec.h"
#include "mongoc-write-concern.h"
#include "mongoc-flags.h"
/* forward declaration */
struct _mongoc_cluster_t;
BSON_BEGIN_DECLS
typedef struct _mongoc_rpc_section_t {
uint8_t payload_type;
union {
/* payload_type == 0 */
const uint8_t *bson_document;
/* payload_type == 1 */
struct {
int32_t size;
uint32_t size_le;
const char *identifier;
const uint8_t *bson_documents;
} sequence;
} payload;
} mongoc_rpc_section_t;
#define RPC(_name, _code) \
typedef struct { \
_code \
} mongoc_rpc_##_name##_t;
#define ENUM_FIELD(_name) uint32_t _name;
#define INT32_FIELD(_name) int32_t _name;
#define UINT8_FIELD(_name) uint8_t _name;
#define INT64_FIELD(_name) int64_t _name;
#define INT64_ARRAY_FIELD(_len, _name) \
int32_t _len; \
int64_t *_name;
#define CSTRING_FIELD(_name) const char *_name;
#define BSON_FIELD(_name) const uint8_t *_name;
#define BSON_ARRAY_FIELD(_name) \
const uint8_t *_name; \
int32_t _name##_len;
#define IOVEC_ARRAY_FIELD(_name) \
const mongoc_iovec_t *_name; \
int32_t n_##_name; \
mongoc_iovec_t _name##_recv;
#define SECTION_ARRAY_FIELD(_name) \
mongoc_rpc_section_t _name[2]; \
int32_t n_##_name;
#define RAW_BUFFER_FIELD(_name) \
const uint8_t *_name; \
int32_t _name##_len;
#define BSON_OPTIONAL(_check, _code) _code
#pragma pack(1)
#include "op-delete.def"
#include "op-get-more.def"
#include "op-header.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-reply-header.def"
#include "op-update.def"
#include "op-compressed.def"
/* restore default packing */
#pragma pack()
#include "op-msg.def"
typedef union {
mongoc_rpc_delete_t delete_;
mongoc_rpc_get_more_t get_more;
mongoc_rpc_header_t header;
mongoc_rpc_insert_t insert;
mongoc_rpc_kill_cursors_t kill_cursors;
mongoc_rpc_msg_t msg;
mongoc_rpc_query_t query;
mongoc_rpc_reply_t reply;
mongoc_rpc_reply_header_t reply_header;
mongoc_rpc_update_t update;
mongoc_rpc_compressed_t compressed;
} mongoc_rpc_t;
BSON_STATIC_ASSERT2 (sizeof_rpc_header, sizeof (mongoc_rpc_header_t) == 16);
BSON_STATIC_ASSERT2 (offsetof_rpc_header,
offsetof (mongoc_rpc_header_t, opcode) ==
offsetof (mongoc_rpc_reply_t, opcode));
BSON_STATIC_ASSERT2 (sizeof_reply_header,
sizeof (mongoc_rpc_reply_header_t) == 36);
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef BSON_OPTIONAL
#undef RAW_BUFFER_FIELD
void
_mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array);
void
_mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc);
void
_mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc);
void
_mongoc_rpc_printf (mongoc_rpc_t *rpc);
bool
_mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen);
bool
_mongoc_rpc_scatter_reply_header_only (mongoc_rpc_t *rpc,
const uint8_t *buf,
size_t buflen);
bool
_mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply);
bool
_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson);
void
_mongoc_rpc_prep_command (mongoc_rpc_t *rpc,
const char *cmd_ns,
mongoc_cmd_t *cmd);
bool
_mongoc_rpc_check_ok (mongoc_rpc_t *rpc,
int32_t error_api_version,
bson_error_t *error /* OUT */,
bson_t *error_doc /* OUT */);
bool
_mongoc_cmd_check_ok (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error);
bool
_mongoc_cmd_check_ok_no_wce (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error);
bool
_mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen);
char *
_mongoc_rpc_compress (struct _mongoc_cluster_t *cluster,
int32_t compressor_id,
mongoc_rpc_t *rpc_le,
bson_error_t *error);
+bool
+_mongoc_rpc_decompress_if_necessary (mongoc_rpc_t *rpc,
+ mongoc_buffer_t *buffer,
+ bson_error_t *error);
+
BSON_END_DECLS
#endif /* MONGOC_RPC_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
index ac1656b6..52881843 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
@@ -1,1326 +1,1371 @@
/*
* Copyright 2013 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.
*/
#include <bson/bson.h>
#include "mongoc.h"
#include "mongoc-rpc-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#include "mongoc-compression-private.h"
#include "mongoc-cluster-private.h"
#define RPC(_name, _code) \
static void _mongoc_rpc_gather_##_name (mongoc_rpc_##_name##_t *rpc, \
mongoc_rpc_header_t *header, \
mongoc_array_t *array) \
{ \
mongoc_iovec_t iov; \
BSON_ASSERT (rpc); \
BSON_ASSERT (array); \
header->msg_len = 0; \
_code \
}
#define UINT8_FIELD(_name) \
iov.iov_base = (void *) &rpc->_name; \
iov.iov_len = 1; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define INT32_FIELD(_name) \
iov.iov_base = (void *) &rpc->_name; \
iov.iov_len = 4; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define ENUM_FIELD INT32_FIELD
#define INT64_FIELD(_name) \
iov.iov_base = (void *) &rpc->_name; \
iov.iov_len = 8; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define CSTRING_FIELD(_name) \
BSON_ASSERT (rpc->_name); \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = strlen (rpc->_name) + 1; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define BSON_FIELD(_name) \
do { \
int32_t __l; \
memcpy (&__l, rpc->_name, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = __l; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
} while (0);
#define BSON_OPTIONAL(_check, _code) \
if (rpc->_check) { \
_code \
}
#define BSON_ARRAY_FIELD(_name) \
if (rpc->_name##_len) { \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = rpc->_name##_len; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
}
#define IOVEC_ARRAY_FIELD(_name) \
do { \
ssize_t _i; \
BSON_ASSERT (rpc->n_##_name); \
for (_i = 0; _i < rpc->n_##_name; _i++) { \
BSON_ASSERT (rpc->_name[_i].iov_len); \
header->msg_len += (int32_t) rpc->_name[_i].iov_len; \
_mongoc_array_append_val (array, rpc->_name[_i]); \
} \
} while (0);
#define SECTION_ARRAY_FIELD(_name) \
do { \
ssize_t _i; \
BSON_ASSERT (rpc->n_##_name); \
for (_i = 0; _i < rpc->n_##_name; _i++) { \
int32_t __l; \
iov.iov_base = (void *) &rpc->_name[_i].payload_type; \
iov.iov_len = 1; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
switch (rpc->_name[_i].payload_type) { \
case 0: \
memcpy (&__l, rpc->_name[_i].payload.bson_document, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
iov.iov_base = (void *) rpc->_name[_i].payload.bson_document; \
iov.iov_len = __l; \
break; \
case 1: \
rpc->_name[_i].payload.sequence.size_le = \
BSON_UINT32_TO_LE (rpc->_name[_i].payload.sequence.size); \
iov.iov_base = (void *) &rpc->_name[_i].payload.sequence.size_le; \
iov.iov_len = 4; \
header->msg_len += 4; \
_mongoc_array_append_val (array, iov); \
iov.iov_base = \
(void *) rpc->_name[_i].payload.sequence.identifier; \
iov.iov_len = \
strlen (rpc->_name[_i].payload.sequence.identifier) + 1; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
iov.iov_base = \
(void *) rpc->_name[_i].payload.sequence.bson_documents; \
iov.iov_len = \
rpc->_name[_i].payload.sequence.size - iov.iov_len - 4; \
break; \
default: \
MONGOC_ERROR ("Unknown Payload Type: %d", \
rpc->_name[_i].payload_type); \
BSON_ASSERT (0); \
} \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
} \
} while (0);
#define RAW_BUFFER_FIELD(_name) \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = rpc->_name##_len; \
BSON_ASSERT (iov.iov_len); \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define INT64_ARRAY_FIELD(_len, _name) \
iov.iov_base = (void *) &rpc->_len; \
iov.iov_len = 4; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = rpc->_len * 8; \
BSON_ASSERT (iov.iov_len); \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#include "op-delete.def"
#include "op-get-more.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef RAW_BUFFER_FIELD
#undef BSON_OPTIONAL
#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
#define RPC(_name, _code) \
static void _mongoc_rpc_swab_to_le_##_name (mongoc_rpc_##_name##_t *rpc) \
{ \
BSON_ASSERT (rpc); \
_code \
}
#define UINT8_FIELD(_name)
#define INT32_FIELD(_name) rpc->_name = BSON_UINT32_FROM_LE (rpc->_name);
#define ENUM_FIELD INT32_FIELD
#define INT64_FIELD(_name) rpc->_name = BSON_UINT64_FROM_LE (rpc->_name);
#define CSTRING_FIELD(_name)
#define BSON_FIELD(_name)
#define BSON_ARRAY_FIELD(_name)
#define IOVEC_ARRAY_FIELD(_name)
#define SECTION_ARRAY_FIELD(_name)
#define BSON_OPTIONAL(_check, _code) \
if (rpc->_check) { \
_code \
}
#define RAW_BUFFER_FIELD(_name)
#define INT64_ARRAY_FIELD(_len, _name) \
do { \
ssize_t i; \
for (i = 0; i < rpc->_len; i++) { \
rpc->_name[i] = BSON_UINT64_FROM_LE (rpc->_name[i]); \
} \
rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \
} while (0);
#include "op-delete.def"
#include "op-get-more.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef INT64_ARRAY_FIELD
#define RPC(_name, _code) \
static void _mongoc_rpc_swab_from_le_##_name (mongoc_rpc_##_name##_t *rpc) \
{ \
BSON_ASSERT (rpc); \
_code \
}
#define INT64_ARRAY_FIELD(_len, _name) \
do { \
ssize_t i; \
rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \
for (i = 0; i < rpc->_len; i++) { \
rpc->_name[i] = BSON_UINT64_FROM_LE (rpc->_name[i]); \
} \
} while (0);
#include "op-delete.def"
#include "op-get-more.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef BSON_OPTIONAL
#undef RAW_BUFFER_FIELD
#endif /* BSON_BYTE_ORDER == BSON_BIG_ENDIAN */
#define RPC(_name, _code) \
static void _mongoc_rpc_printf_##_name (mongoc_rpc_##_name##_t *rpc) \
{ \
BSON_ASSERT (rpc); \
_code \
}
#define UINT8_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name);
#define INT32_FIELD(_name) printf (" " #_name " : %d\n", rpc->_name);
#define ENUM_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name);
#define INT64_FIELD(_name) \
printf (" " #_name " : %" PRIi64 "\n", (int64_t) rpc->_name);
#define CSTRING_FIELD(_name) printf (" " #_name " : %s\n", rpc->_name);
#define BSON_FIELD(_name) \
do { \
bson_t b; \
char *s; \
int32_t __l; \
memcpy (&__l, rpc->_name, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
BSON_ASSERT (bson_init_static (&b, rpc->_name, __l)); \
s = bson_as_relaxed_extended_json (&b, NULL); \
printf (" " #_name " : %s\n", s); \
bson_free (s); \
bson_destroy (&b); \
} while (0);
#define BSON_ARRAY_FIELD(_name) \
do { \
bson_reader_t *__r; \
bool __eof; \
const bson_t *__b; \
__r = bson_reader_new_from_data (rpc->_name, rpc->_name##_len); \
while ((__b = bson_reader_read (__r, &__eof))) { \
char *s = bson_as_relaxed_extended_json (__b, NULL); \
printf (" " #_name " : %s\n", s); \
bson_free (s); \
} \
bson_reader_destroy (__r); \
} while (0);
#define IOVEC_ARRAY_FIELD(_name) \
do { \
ssize_t _i; \
size_t _j; \
for (_i = 0; _i < rpc->n_##_name; _i++) { \
printf (" " #_name " : "); \
for (_j = 0; _j < rpc->_name[_i].iov_len; _j++) { \
uint8_t u; \
u = ((char *) rpc->_name[_i].iov_base)[_j]; \
printf (" %02x", u); \
} \
printf ("\n"); \
} \
} while (0);
#define SECTION_ARRAY_FIELD(_name) \
do { \
ssize_t _i; \
printf (" " #_name " : %d\n", rpc->n_##_name); \
for (_i = 0; _i < rpc->n_##_name; _i++) { \
if (rpc->_name[_i].payload_type == 0) { \
do { \
bson_t b; \
char *s; \
int32_t __l; \
memcpy (&__l, rpc->_name[_i].payload.bson_document, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
BSON_ASSERT (bson_init_static ( \
&b, rpc->_name[_i].payload.bson_document, __l)); \
s = bson_as_relaxed_extended_json (&b, NULL); \
printf (" Type %d: %s\n", rpc->_name[_i].payload_type, s); \
bson_free (s); \
bson_destroy (&b); \
} while (0); \
} else if (rpc->_name[_i].payload_type == 1) { \
bson_reader_t *__r; \
int max = rpc->_name[_i].payload.sequence.size - \
strlen (rpc->_name[_i].payload.sequence.identifier) - \
1 - sizeof (int32_t); \
bool __eof; \
const bson_t *__b; \
printf (" Identifier: %s\n", \
rpc->_name[_i].payload.sequence.identifier); \
printf (" Size: %d\n", max); \
__r = bson_reader_new_from_data ( \
rpc->_name[_i].payload.sequence.bson_documents, max); \
while ((__b = bson_reader_read (__r, &__eof))) { \
char *s = bson_as_relaxed_extended_json (__b, NULL); \
bson_free (s); \
} \
bson_reader_destroy (__r); \
} \
} \
} while (0);
#define BSON_OPTIONAL(_check, _code) \
if (rpc->_check) { \
_code \
}
#define RAW_BUFFER_FIELD(_name) \
{ \
ssize_t __i; \
printf (" " #_name " :"); \
for (__i = 0; __i < rpc->_name##_len; __i++) { \
uint8_t u; \
u = ((char *) rpc->_name)[__i]; \
printf (" %02x", u); \
} \
printf ("\n"); \
}
#define INT64_ARRAY_FIELD(_len, _name) \
do { \
ssize_t i; \
for (i = 0; i < rpc->_len; i++) { \
printf (" " #_name " : %" PRIi64 "\n", (int64_t) rpc->_name[i]); \
} \
rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \
} while (0);
#include "op-delete.def"
#include "op-get-more.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef BSON_OPTIONAL
#undef RAW_BUFFER_FIELD
#define RPC(_name, _code) \
static bool _mongoc_rpc_scatter_##_name ( \
mongoc_rpc_##_name##_t *rpc, const uint8_t *buf, size_t buflen) \
{ \
BSON_ASSERT (rpc); \
BSON_ASSERT (buf); \
BSON_ASSERT (buflen); \
_code return true; \
}
#define UINT8_FIELD(_name) \
if (buflen < 1) { \
return false; \
} \
memcpy (&rpc->_name, buf, 1); \
buflen -= 1; \
buf += 1;
#define INT32_FIELD(_name) \
if (buflen < 4) { \
return false; \
} \
memcpy (&rpc->_name, buf, 4); \
buflen -= 4; \
buf += 4;
#define ENUM_FIELD INT32_FIELD
#define INT64_FIELD(_name) \
if (buflen < 8) { \
return false; \
} \
memcpy (&rpc->_name, buf, 8); \
buflen -= 8; \
buf += 8;
#define INT64_ARRAY_FIELD(_len, _name) \
do { \
size_t needed; \
if (buflen < 4) { \
return false; \
} \
memcpy (&rpc->_len, buf, 4); \
buflen -= 4; \
buf += 4; \
needed = BSON_UINT32_FROM_LE (rpc->_len) * 8; \
if (needed > buflen) { \
return false; \
} \
rpc->_name = (int64_t *) buf; \
buf += needed; \
buflen -= needed; \
} while (0);
#define CSTRING_FIELD(_name) \
do { \
size_t __i; \
bool found = false; \
for (__i = 0; __i < buflen; __i++) { \
if (!buf[__i]) { \
rpc->_name = (const char *) buf; \
buflen -= __i + 1; \
buf += __i + 1; \
found = true; \
break; \
} \
} \
if (!found) { \
return false; \
} \
} while (0);
#define BSON_FIELD(_name) \
do { \
uint32_t __l; \
if (buflen < 4) { \
return false; \
} \
memcpy (&__l, buf, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
if (__l < 5 || __l > buflen) { \
return false; \
} \
rpc->_name = (uint8_t *) buf; \
buf += __l; \
buflen -= __l; \
} while (0);
#define BSON_ARRAY_FIELD(_name) \
rpc->_name = (uint8_t *) buf; \
rpc->_name##_len = (int32_t) buflen; \
buf = NULL; \
buflen = 0;
#define BSON_OPTIONAL(_check, _code) \
if (buflen) { \
_code \
}
#define IOVEC_ARRAY_FIELD(_name) \
rpc->_name##_recv.iov_base = (void *) buf; \
rpc->_name##_recv.iov_len = buflen; \
rpc->_name = &rpc->_name##_recv; \
rpc->n_##_name = 1; \
buf = NULL; \
buflen = 0;
#define SECTION_ARRAY_FIELD(_name) \
do { \
uint32_t __l; \
mongoc_rpc_section_t *section = &rpc->_name[rpc->n_##_name]; \
section->payload_type = buf[0]; \
buf++; \
buflen -= 1; \
memcpy (&__l, buf, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
if (section->payload_type == 0) { \
section->payload.bson_document = buf; \
} else { \
const uint8_t *section_buf = buf + 4; \
section->payload.sequence.size = __l; \
section->payload.sequence.identifier = (const char *) section_buf; \
section_buf += strlen ((const char *) section_buf) + 1; \
section->payload.sequence.bson_documents = section_buf; \
} \
buf += __l; \
buflen -= __l; \
rpc->n_##_name++; \
} while (buflen);
#define RAW_BUFFER_FIELD(_name) \
rpc->_name = (void *) buf; \
rpc->_name##_len = (int32_t) buflen; \
buf = NULL; \
buflen = 0;
#include "op-delete.def"
#include "op-get-more.def"
#include "op-header.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-reply-header.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef BSON_OPTIONAL
#undef RAW_BUFFER_FIELD
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_gather --
*
* Takes a (native endian) rpc struct and gathers the buffer.
* Caller should swab to little endian after calling gather.
*
* Gather, swab, compress write.
* Read, scatter, uncompress, swab
*
*--------------------------------------------------------------------------
*/
void
_mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array)
{
mongoc_counter_op_egress_total_inc ();
switch ((mongoc_opcode_t) rpc->header.opcode) {
case MONGOC_OPCODE_REPLY:
_mongoc_rpc_gather_reply (&rpc->reply, &rpc->header, array);
return;
case MONGOC_OPCODE_MSG:
_mongoc_rpc_gather_msg (&rpc->msg, &rpc->header, array);
mongoc_counter_op_egress_msg_inc ();
return;
case MONGOC_OPCODE_UPDATE:
_mongoc_rpc_gather_update (&rpc->update, &rpc->header, array);
mongoc_counter_op_egress_update_inc ();
return;
case MONGOC_OPCODE_INSERT:
_mongoc_rpc_gather_insert (&rpc->insert, &rpc->header, array);
mongoc_counter_op_egress_insert_inc ();
return;
case MONGOC_OPCODE_QUERY:
_mongoc_rpc_gather_query (&rpc->query, &rpc->header, array);
mongoc_counter_op_egress_query_inc ();
return;
case MONGOC_OPCODE_GET_MORE:
_mongoc_rpc_gather_get_more (&rpc->get_more, &rpc->header, array);
mongoc_counter_op_egress_getmore_inc ();
return;
case MONGOC_OPCODE_DELETE:
_mongoc_rpc_gather_delete (&rpc->delete_, &rpc->header, array);
mongoc_counter_op_egress_delete_inc ();
return;
case MONGOC_OPCODE_KILL_CURSORS:
_mongoc_rpc_gather_kill_cursors (&rpc->kill_cursors, &rpc->header, array);
mongoc_counter_op_egress_killcursors_inc ();
return;
case MONGOC_OPCODE_COMPRESSED:
_mongoc_rpc_gather_compressed (&rpc->compressed, &rpc->header, array);
mongoc_counter_op_egress_compressed_inc ();
return;
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode);
BSON_ASSERT (false);
break;
}
}
void
_mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc)
{
#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
mongoc_opcode_t opcode;
opcode = rpc->header.opcode;
switch (opcode) {
case MONGOC_OPCODE_REPLY:
_mongoc_rpc_swab_to_le_reply (&rpc->reply);
break;
case MONGOC_OPCODE_MSG:
_mongoc_rpc_swab_to_le_msg (&rpc->msg);
break;
case MONGOC_OPCODE_UPDATE:
_mongoc_rpc_swab_to_le_update (&rpc->update);
break;
case MONGOC_OPCODE_INSERT:
_mongoc_rpc_swab_to_le_insert (&rpc->insert);
break;
case MONGOC_OPCODE_QUERY:
_mongoc_rpc_swab_to_le_query (&rpc->query);
break;
case MONGOC_OPCODE_GET_MORE:
_mongoc_rpc_swab_to_le_get_more (&rpc->get_more);
break;
case MONGOC_OPCODE_DELETE:
_mongoc_rpc_swab_to_le_delete (&rpc->delete_);
break;
case MONGOC_OPCODE_KILL_CURSORS:
_mongoc_rpc_swab_to_le_kill_cursors (&rpc->kill_cursors);
break;
case MONGOC_OPCODE_COMPRESSED:
_mongoc_rpc_swab_to_le_compressed (&rpc->compressed);
break;
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode);
break;
}
#endif
#if 0
_mongoc_rpc_printf (rpc);
#endif
}
void
_mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc)
{
#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
mongoc_opcode_t opcode;
opcode = BSON_UINT32_FROM_LE (rpc->header.opcode);
switch (opcode) {
case MONGOC_OPCODE_REPLY:
_mongoc_rpc_swab_from_le_reply (&rpc->reply);
break;
case MONGOC_OPCODE_MSG:
_mongoc_rpc_swab_from_le_msg (&rpc->msg);
break;
case MONGOC_OPCODE_UPDATE:
_mongoc_rpc_swab_from_le_update (&rpc->update);
break;
case MONGOC_OPCODE_INSERT:
_mongoc_rpc_swab_from_le_insert (&rpc->insert);
break;
case MONGOC_OPCODE_QUERY:
_mongoc_rpc_swab_from_le_query (&rpc->query);
break;
case MONGOC_OPCODE_GET_MORE:
_mongoc_rpc_swab_from_le_get_more (&rpc->get_more);
break;
case MONGOC_OPCODE_DELETE:
_mongoc_rpc_swab_from_le_delete (&rpc->delete_);
break;
case MONGOC_OPCODE_KILL_CURSORS:
_mongoc_rpc_swab_from_le_kill_cursors (&rpc->kill_cursors);
break;
case MONGOC_OPCODE_COMPRESSED:
_mongoc_rpc_swab_from_le_compressed (&rpc->compressed);
break;
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode);
break;
}
#endif
#if 0
_mongoc_rpc_printf (rpc);
#endif
}
void
_mongoc_rpc_printf (mongoc_rpc_t *rpc)
{
switch ((mongoc_opcode_t) rpc->header.opcode) {
case MONGOC_OPCODE_REPLY:
_mongoc_rpc_printf_reply (&rpc->reply);
break;
case MONGOC_OPCODE_MSG:
_mongoc_rpc_printf_msg (&rpc->msg);
break;
case MONGOC_OPCODE_UPDATE:
_mongoc_rpc_printf_update (&rpc->update);
break;
case MONGOC_OPCODE_INSERT:
_mongoc_rpc_printf_insert (&rpc->insert);
break;
case MONGOC_OPCODE_QUERY:
_mongoc_rpc_printf_query (&rpc->query);
break;
case MONGOC_OPCODE_GET_MORE:
_mongoc_rpc_printf_get_more (&rpc->get_more);
break;
case MONGOC_OPCODE_DELETE:
_mongoc_rpc_printf_delete (&rpc->delete_);
break;
case MONGOC_OPCODE_KILL_CURSORS:
_mongoc_rpc_printf_kill_cursors (&rpc->kill_cursors);
break;
case MONGOC_OPCODE_COMPRESSED:
_mongoc_rpc_printf_compressed (&rpc->compressed);
break;
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode);
break;
}
printf ("\n");
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_decompress --
*
* Takes a (little endian) rpc struct assumed to be OP_COMPRESSED
* and decompresses the opcode into its original opcode.
* The in-place updated rpc struct remains little endian.
*
* Side effects:
* Overwrites the RPC, along with the provided buf with the
* compressed results.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen)
{
size_t uncompressed_size =
BSON_UINT32_FROM_LE (rpc_le->compressed.uncompressed_size);
bool ok;
size_t msg_len = BSON_UINT32_TO_LE (buflen);
const size_t original_uncompressed_size = uncompressed_size;
BSON_ASSERT (uncompressed_size <= buflen);
memcpy (buf, (void *) (&msg_len), 4);
memcpy (buf + 4, (void *) (&rpc_le->header.request_id), 4);
memcpy (buf + 8, (void *) (&rpc_le->header.response_to), 4);
memcpy (buf + 12, (void *) (&rpc_le->compressed.original_opcode), 4);
ok = mongoc_uncompress (rpc_le->compressed.compressor_id,
rpc_le->compressed.compressed_message,
rpc_le->compressed.compressed_message_len,
buf + 16,
&uncompressed_size);
-
+
BSON_ASSERT (original_uncompressed_size == uncompressed_size);
if (ok) {
return _mongoc_rpc_scatter (rpc_le, buf, buflen);
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_compress --
*
* Takes a (little endian) rpc struct and creates a OP_COMPRESSED
* compressed opcode based on the provided compressor_id.
* The in-place updated rpc struct remains little endian.
*
* Side effects:
* Overwrites the RPC, and clears and overwrites the cluster buffer
* with the compressed results.
*
*--------------------------------------------------------------------------
*/
char *
_mongoc_rpc_compress (struct _mongoc_cluster_t *cluster,
int32_t compressor_id,
mongoc_rpc_t *rpc_le,
bson_error_t *error)
{
char *output;
size_t output_length = 0;
size_t allocate = BSON_UINT32_FROM_LE (rpc_le->header.msg_len) - 16;
char *data;
int size;
int32_t compression_level = -1;
if (compressor_id == MONGOC_COMPRESSOR_ZLIB_ID) {
compression_level = mongoc_uri_get_option_as_int32 (
cluster->uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, -1);
}
BSON_ASSERT (allocate > 0);
data = bson_malloc0 (allocate);
size = _mongoc_cluster_buffer_iovec (
cluster->iov.data, cluster->iov.len, 16, data);
BSON_ASSERT (size);
output_length =
mongoc_compressor_max_compressed_length (compressor_id, size);
if (!output_length) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Could not determine compression bounds for %s",
mongoc_compressor_id_to_name (compressor_id));
bson_free (data);
return NULL;
}
output = (char *) bson_malloc0 (output_length);
if (mongoc_compress (compressor_id,
compression_level,
data,
size,
output,
&output_length)) {
rpc_le->header.msg_len = 0;
rpc_le->compressed.original_opcode =
BSON_UINT32_FROM_LE (rpc_le->header.opcode);
rpc_le->header.opcode = MONGOC_OPCODE_COMPRESSED;
rpc_le->header.request_id =
BSON_UINT32_FROM_LE (rpc_le->header.request_id);
rpc_le->header.response_to =
BSON_UINT32_FROM_LE (rpc_le->header.response_to);
rpc_le->compressed.uncompressed_size = size;
rpc_le->compressed.compressor_id = compressor_id;
rpc_le->compressed.compressed_message = (const uint8_t *) output;
rpc_le->compressed.compressed_message_len = output_length;
bson_free (data);
_mongoc_array_destroy (&cluster->iov);
_mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t));
_mongoc_rpc_gather (rpc_le, &cluster->iov);
_mongoc_rpc_swab_to_le (rpc_le);
return output;
} else {
MONGOC_WARNING ("Could not compress data with %s",
mongoc_compressor_id_to_name (compressor_id));
}
bson_free (data);
bson_free (output);
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_scatter --
*
* Takes a (little endian) rpc struct and scatters the buffer.
* Caller should check if resulting opcode is OP_COMPRESSED
* BEFORE swabbing to native endianness.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen)
{
mongoc_opcode_t opcode;
memset (rpc, 0, sizeof *rpc);
if (BSON_UNLIKELY (buflen < 16)) {
return false;
}
mongoc_counter_op_ingress_total_inc ();
if (!_mongoc_rpc_scatter_header (&rpc->header, buf, 16)) {
return false;
}
opcode = (mongoc_opcode_t) BSON_UINT32_FROM_LE (rpc->header.opcode);
switch (opcode) {
case MONGOC_OPCODE_COMPRESSED:
mongoc_counter_op_ingress_compressed_inc ();
return _mongoc_rpc_scatter_compressed (&rpc->compressed, buf, buflen);
case MONGOC_OPCODE_REPLY:
mongoc_counter_op_ingress_reply_inc ();
return _mongoc_rpc_scatter_reply (&rpc->reply, buf, buflen);
case MONGOC_OPCODE_MSG:
mongoc_counter_op_ingress_msg_inc ();
return _mongoc_rpc_scatter_msg (&rpc->msg, buf, buflen);
/* useless, we are never *getting* these opcodes */
case MONGOC_OPCODE_UPDATE:
return _mongoc_rpc_scatter_update (&rpc->update, buf, buflen);
case MONGOC_OPCODE_INSERT:
return _mongoc_rpc_scatter_insert (&rpc->insert, buf, buflen);
case MONGOC_OPCODE_QUERY:
return _mongoc_rpc_scatter_query (&rpc->query, buf, buflen);
case MONGOC_OPCODE_GET_MORE:
return _mongoc_rpc_scatter_get_more (&rpc->get_more, buf, buflen);
case MONGOC_OPCODE_DELETE:
return _mongoc_rpc_scatter_delete (&rpc->delete_, buf, buflen);
case MONGOC_OPCODE_KILL_CURSORS:
return _mongoc_rpc_scatter_kill_cursors (&rpc->kill_cursors, buf, buflen);
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode);
return false;
}
}
bool
_mongoc_rpc_scatter_reply_header_only (mongoc_rpc_t *rpc,
const uint8_t *buf,
size_t buflen)
{
if (BSON_UNLIKELY (buflen < sizeof (mongoc_rpc_reply_header_t))) {
return false;
}
mongoc_counter_op_ingress_reply_inc ();
mongoc_counter_op_ingress_total_inc ();
return _mongoc_rpc_scatter_reply_header (&rpc->reply_header, buf, buflen);
}
bool
_mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply)
{
if (rpc->header.opcode == MONGOC_OPCODE_REPLY &&
_mongoc_rpc_reply_get_first (&rpc->reply, reply)) {
return true;
}
return false;
}
bool
_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson)
{
int32_t len;
if (!reply->documents || reply->documents_len < 4) {
return false;
}
memcpy (&len, reply->documents, 4);
len = BSON_UINT32_FROM_LE (len);
if (reply->documents_len < len) {
return false;
}
return bson_init_static (bson, reply->documents, len);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_prep_command --
*
* Prepare an RPC for mongoc_cluster_run_command_rpc. @cmd_ns and
* @cmd must not be freed or modified while the RPC is in use.
*
* Side effects:
* Fills out the RPC, including pointers into @cmd_ns and @command.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_rpc_prep_command (mongoc_rpc_t *rpc,
const char *cmd_ns,
mongoc_cmd_t *cmd)
{
rpc->header.msg_len = 0;
rpc->header.request_id = 0;
rpc->header.response_to = 0;
rpc->header.opcode = MONGOC_OPCODE_QUERY;
rpc->query.collection = cmd_ns;
rpc->query.skip = 0;
rpc->query.n_return = -1;
rpc->query.fields = NULL;
rpc->query.query = bson_get_data (cmd->command);
/* Find, getMore And killCursors Commands Spec: "When sending a find command
* rather than a legacy OP_QUERY find, only the slaveOk flag is honored."
* For other cursor-typed commands like aggregate, only slaveOk can be set.
* Clear bits except slaveOk; leave slaveOk set only if it is already.
*/
rpc->query.flags = cmd->query_flags & MONGOC_QUERY_SLAVE_OK;
}
/* returns true if an error was found. */
static bool
_parse_error_reply (const bson_t *doc,
bool check_wce,
uint32_t *code,
const char **msg)
{
bson_iter_t iter;
bool found_error = false;
ENTRY;
BSON_ASSERT (doc);
BSON_ASSERT (code);
*code = 0;
+ /* The server only returns real error codes as int32.
+ * But it may return as a double or int64 if a failpoint
+ * based on how it is configured to error. */
if (bson_iter_init_find (&iter, doc, "code") &&
- BSON_ITER_HOLDS_INT32 (&iter)) {
- *code = (uint32_t) bson_iter_int32 (&iter);
+ BSON_ITER_HOLDS_NUMBER (&iter)) {
+ *code = (uint32_t) bson_iter_as_int64 (&iter);
+ BSON_ASSERT (*code);
found_error = true;
}
if (bson_iter_init_find (&iter, doc, "errmsg") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
*msg = bson_iter_utf8 (&iter, NULL);
found_error = true;
} else if (bson_iter_init_find (&iter, doc, "$err") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
*msg = bson_iter_utf8 (&iter, NULL);
found_error = true;
}
if (found_error) {
/* there was a command error */
RETURN (true);
}
if (check_wce) {
/* check for a write concern error */
if (bson_iter_init_find (&iter, doc, "writeConcernError") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_iter_t child;
BSON_ASSERT (bson_iter_recurse (&iter, &child));
if (bson_iter_find (&child, "code") &&
- BSON_ITER_HOLDS_INT32 (&child)) {
- *code = (uint32_t) bson_iter_int32 (&child);
+ BSON_ITER_HOLDS_NUMBER (&child)) {
+ *code = (uint32_t) bson_iter_as_int64 (&child);
+ BSON_ASSERT (*code);
found_error = true;
}
BSON_ASSERT (bson_iter_recurse (&iter, &child));
if (bson_iter_find (&child, "errmsg") &&
BSON_ITER_HOLDS_UTF8 (&child)) {
*msg = bson_iter_utf8 (&child, NULL);
found_error = true;
}
}
}
RETURN (found_error);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cmd_check_ok --
*
* Check if a server reply document is an error message.
* Optionally fill out a bson_error_t from the server error.
* Does *not* check for writeConcernError.
*
* Returns:
* false if @doc is an error message, true otherwise.
*
* Side effects:
* If @doc is an error reply and @error is not NULL, set its
* domain, code, and message.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cmd_check_ok (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error)
{
mongoc_error_domain_t domain =
error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER
: MONGOC_ERROR_QUERY;
uint32_t code;
bson_iter_t iter;
const char *msg = "Unknown command error";
ENTRY;
BSON_ASSERT (doc);
if (bson_iter_init_find (&iter, doc, "ok") && bson_iter_as_bool (&iter)) {
/* no error */
RETURN (true);
}
if (!_parse_error_reply (doc, false /* check_wce */, &code, &msg)) {
RETURN (true);
}
if (code == MONGOC_ERROR_PROTOCOL_ERROR || code == 13390) {
code = MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND;
} else if (code == 0) {
code = MONGOC_ERROR_QUERY_FAILURE;
}
bson_set_error (error, domain, code, "%s", msg);
/* there was a command error */
RETURN (false);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cmd_check_ok_no_wce --
*
* Check if a server reply document is an error message.
* Optionally fill out a bson_error_t from the server error.
* If the response contains a writeConcernError, this is considered
* an error and returns false.
*
* Returns:
* false if @doc is an error message, true otherwise.
*
* Side effects:
* If @doc is an error reply and @error is not NULL, set its
* domain, code, and message.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cmd_check_ok_no_wce (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error)
{
mongoc_error_domain_t domain =
error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER
: MONGOC_ERROR_QUERY;
uint32_t code;
const char *msg = "Unknown command error";
ENTRY;
BSON_ASSERT (doc);
if (!_parse_error_reply (doc, true /* check_wce */, &code, &msg)) {
RETURN (true);
}
if (code == MONGOC_ERROR_PROTOCOL_ERROR || code == 13390) {
code = MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND;
} else if (code == 0) {
code = MONGOC_ERROR_QUERY_FAILURE;
}
bson_set_error (error, domain, code, "%s", msg);
/* there was a command error */
RETURN (false);
}
/* helper function to parse error reply document to an OP_QUERY */
static void
_mongoc_populate_query_error (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error)
{
mongoc_error_domain_t domain =
error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER
: MONGOC_ERROR_QUERY;
uint32_t code = MONGOC_ERROR_QUERY_FAILURE;
bson_iter_t iter;
const char *msg = "Unknown query failure";
ENTRY;
BSON_ASSERT (doc);
if (bson_iter_init_find (&iter, doc, "code") &&
- BSON_ITER_HOLDS_INT32 (&iter)) {
- code = (uint32_t) bson_iter_int32 (&iter);
+ BSON_ITER_HOLDS_NUMBER (&iter)) {
+ code = (uint32_t) bson_iter_as_int64 (&iter);
+ BSON_ASSERT (code);
}
if (bson_iter_init_find (&iter, doc, "$err") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
msg = bson_iter_utf8 (&iter, NULL);
}
bson_set_error (error, domain, code, "%s", msg);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_check_ok --
*
* Check if a server OP_REPLY is an error message.
* Optionally fill out a bson_error_t from the server error.
* @error_document must be an initialized bson_t or NULL.
* Does *not* check for writeConcernError.
*
* Returns:
* false if the reply is an error message, true otherwise.
*
* Side effects:
* If rpc is an error reply and @error is not NULL, set its
* domain, code, and message.
*
* If rpc is an error reply and @error_document is not NULL,
* it is reinitialized with the server reply.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_rpc_check_ok (mongoc_rpc_t *rpc,
int32_t error_api_version,
bson_error_t *error /* OUT */,
bson_t *error_doc /* OUT */)
{
bson_t b;
ENTRY;
BSON_ASSERT (rpc);
if (rpc->header.opcode != MONGOC_OPCODE_REPLY) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Received rpc other than OP_REPLY.");
RETURN (false);
}
if (rpc->reply.flags & MONGOC_REPLY_QUERY_FAILURE) {
if (_mongoc_rpc_get_first_document (rpc, &b)) {
_mongoc_populate_query_error (&b, error_api_version, error);
if (error_doc) {
bson_destroy (error_doc);
bson_copy_to (&b, error_doc);
}
bson_destroy (&b);
} else {
bson_set_error (error,
MONGOC_ERROR_QUERY,
MONGOC_ERROR_QUERY_FAILURE,
"Unknown query failure.");
}
RETURN (false);
} else if (rpc->reply.flags & MONGOC_REPLY_CURSOR_NOT_FOUND) {
bson_set_error (error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"The cursor is invalid or has expired.");
RETURN (false);
}
RETURN (true);
}
+
+/* If rpc is OP_COMPRESSED, decompress it into buffer.
+ *
+ * Assumes rpc is still in network little-endian representation (i.e.
+ * _mongoc_rpc_swab_to_le has not been called).
+ * Returns true if rpc is not OP_COMPRESSED (and is a no-op) or if decompression
+ * succeeds.
+ * Return false and sets error otherwise.
+ */
+bool
+_mongoc_rpc_decompress_if_necessary (mongoc_rpc_t *rpc,
+ mongoc_buffer_t *buffer /* IN/OUT */,
+ bson_error_t *error /* OUT */)
+{
+ uint8_t *buf = NULL;
+ size_t len;
+
+ if (BSON_UINT32_FROM_LE (rpc->header.opcode) != MONGOC_OPCODE_COMPRESSED) {
+ return true;
+ }
+
+ len = BSON_UINT32_FROM_LE (rpc->compressed.uncompressed_size) +
+ sizeof (mongoc_rpc_header_t);
+
+ buf = bson_malloc0 (len);
+ if (!_mongoc_rpc_decompress (rpc, buf, len)) {
+ bson_free (buf);
+ bson_set_error (error,
+ MONGOC_ERROR_PROTOCOL,
+ MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
+ "Could not decompress server reply");
+ return false;
+ }
+
+ _mongoc_buffer_destroy (buffer);
+ _mongoc_buffer_init (buffer, buf, len, NULL, NULL);
+
+ return true;
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h
index e8e2c1d9..75f80797 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h
@@ -1,130 +1,129 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_SCRAM_PRIVATE_H
#define MONGOC_SCRAM_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-crypto-private.h"
BSON_BEGIN_DECLS
#define MONGOC_SCRAM_SHA_1_HASH_SIZE 20
#define MONGOC_SCRAM_SHA_256_HASH_SIZE 32
/* SCRAM-SHA-1 uses a hash size of 20, and SCRAM-SHA-256 uses a hash size
* of 32. Stack allocations should be large enough for either. */
#define MONGOC_SCRAM_HASH_MAX_SIZE MONGOC_SCRAM_SHA_256_HASH_SIZE
#define MONGOC_SCRAM_B64_ENCODED_SIZE(n) (2 * n)
#define MONGOC_SCRAM_B64_HASH_MAX_SIZE \
MONGOC_SCRAM_B64_ENCODED_SIZE (MONGOC_SCRAM_HASH_MAX_SIZE)
typedef struct _mongoc_scram_cache_t {
/* pre-secrets */
char *hashed_password;
uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE];
uint32_t iterations;
/* secrets */
uint8_t client_key[MONGOC_SCRAM_HASH_MAX_SIZE];
uint8_t server_key[MONGOC_SCRAM_HASH_MAX_SIZE];
uint8_t salted_password[MONGOC_SCRAM_HASH_MAX_SIZE];
} mongoc_scram_cache_t;
typedef struct _mongoc_scram_t {
- bool done;
int step;
char *user;
char *pass;
char *hashed_password;
uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE];
uint32_t iterations;
uint8_t client_key[MONGOC_SCRAM_HASH_MAX_SIZE];
uint8_t server_key[MONGOC_SCRAM_HASH_MAX_SIZE];
uint8_t salted_password[MONGOC_SCRAM_HASH_MAX_SIZE];
char encoded_nonce[48];
int32_t encoded_nonce_len;
uint8_t *auth_message;
uint32_t auth_messagemax;
uint32_t auth_messagelen;
#ifdef MONGOC_ENABLE_CRYPTO
mongoc_crypto_t crypto;
#endif
mongoc_scram_cache_t *cache;
} mongoc_scram_t;
#ifdef MONGOC_ENABLE_CRYPTO
void
_mongoc_scram_init (mongoc_scram_t *scram, mongoc_crypto_hash_algorithm_t algo);
#endif
mongoc_scram_cache_t *
_mongoc_scram_get_cache (mongoc_scram_t *scram);
void
_mongoc_scram_set_cache (mongoc_scram_t *scram, mongoc_scram_cache_t *cache);
void
_mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass);
void
_mongoc_scram_set_user (mongoc_scram_t *scram, const char *user);
void
_mongoc_scram_set_server_key (mongoc_scram_t *scram,
const uint8_t *server_key,
size_t len);
void
_mongoc_scram_set_salted_password (mongoc_scram_t *scram,
const uint8_t *salted_password,
size_t len);
void
_mongoc_scram_destroy (mongoc_scram_t *scram);
bool
_mongoc_scram_step (mongoc_scram_t *scram,
const uint8_t *inbuf,
uint32_t inbuflen,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error);
void
_mongoc_scram_cache_destroy (mongoc_scram_cache_t *cache);
/* returns false if this string does not need SASLPrep. It returns true
* conservatively, if str might need to be SASLPrep'ed. */
bool
_mongoc_sasl_prep_required (const char *str);
/* returns the output of SASLPrep as a new string which must be freed. Returns
* null on error and sets err.
* `name` should be "username" or "password". */
char *
_mongoc_sasl_prep (const char *in_utf8, int in_utf8_len, bson_error_t *err);
BSON_END_DECLS
#endif /* MONGOC_SCRAM_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
index aabc972b..df308798 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
@@ -1,1146 +1,1149 @@
/* Copyright 2014 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_CRYPTO
#include <string.h>
#include "mongoc-error.h"
#include "mongoc-scram-private.h"
#include "mongoc-rand-private.h"
#include "mongoc-util-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-crypto-private.h"
#include "common-b64-private.h"
#include "mongoc-memcmp-private.h"
#define MONGOC_SCRAM_SERVER_KEY "Server Key"
#define MONGOC_SCRAM_CLIENT_KEY "Client Key"
static int
_scram_hash_size (mongoc_scram_t *scram)
{
if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_1) {
return MONGOC_SCRAM_SHA_1_HASH_SIZE;
} else if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_256) {
return MONGOC_SCRAM_SHA_256_HASH_SIZE;
}
return 0;
}
/* Copies the cache's secrets to scram */
static void
_mongoc_scram_cache_apply_secrets (mongoc_scram_cache_t *cache,
mongoc_scram_t *scram)
{
BSON_ASSERT (cache);
BSON_ASSERT (scram);
memcpy (scram->client_key, cache->client_key, sizeof (scram->client_key));
memcpy (scram->server_key, cache->server_key, sizeof (scram->server_key));
memcpy (scram->salted_password,
cache->salted_password,
sizeof (scram->salted_password));
}
static mongoc_scram_cache_t *
_mongoc_scram_cache_copy (const mongoc_scram_cache_t *cache)
{
mongoc_scram_cache_t *ret = NULL;
if (cache) {
ret = (mongoc_scram_cache_t *) bson_malloc0 (sizeof (*ret));
ret->hashed_password = bson_strdup (cache->hashed_password);
memcpy (
ret->decoded_salt, cache->decoded_salt, sizeof (ret->decoded_salt));
ret->iterations = cache->iterations;
memcpy (ret->client_key, cache->client_key, sizeof (ret->client_key));
memcpy (ret->server_key, cache->server_key, sizeof (ret->server_key));
memcpy (ret->salted_password,
cache->salted_password,
sizeof (ret->salted_password));
}
return ret;
}
#ifdef MONGOC_ENABLE_ICU
#include <unicode/usprep.h>
#include <unicode/ustring.h>
#endif
void
_mongoc_scram_cache_destroy (mongoc_scram_cache_t *cache)
{
BSON_ASSERT (cache);
if (cache->hashed_password) {
bson_zero_free (cache->hashed_password, strlen (cache->hashed_password));
}
bson_free (cache);
}
/* Checks whether the cache contains scram's pre-secrets */
static bool
_mongoc_scram_cache_has_presecrets (mongoc_scram_cache_t *cache,
mongoc_scram_t *scram)
{
BSON_ASSERT (cache);
BSON_ASSERT (scram);
return cache->hashed_password && scram->hashed_password &&
!strcmp (cache->hashed_password, scram->hashed_password) &&
cache->iterations == scram->iterations &&
!memcmp (cache->decoded_salt,
scram->decoded_salt,
sizeof (cache->decoded_salt));
}
mongoc_scram_cache_t *
_mongoc_scram_get_cache (mongoc_scram_t *scram)
{
BSON_ASSERT (scram);
return _mongoc_scram_cache_copy (scram->cache);
}
void
_mongoc_scram_set_cache (mongoc_scram_t *scram, mongoc_scram_cache_t *cache)
{
BSON_ASSERT (scram);
if (scram->cache) {
_mongoc_scram_cache_destroy (scram->cache);
}
scram->cache = _mongoc_scram_cache_copy (cache);
}
void
_mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass)
{
BSON_ASSERT (scram);
if (scram->pass) {
bson_zero_free (scram->pass, strlen (scram->pass));
}
scram->pass = pass ? bson_strdup (pass) : NULL;
}
void
_mongoc_scram_set_user (mongoc_scram_t *scram, const char *user)
{
BSON_ASSERT (scram);
bson_free (scram->user);
scram->user = user ? bson_strdup (user) : NULL;
}
void
_mongoc_scram_init (mongoc_scram_t *scram, mongoc_crypto_hash_algorithm_t algo)
{
BSON_ASSERT (scram);
memset (scram, 0, sizeof *scram);
mongoc_crypto_init (&scram->crypto, algo);
}
void
_mongoc_scram_destroy (mongoc_scram_t *scram)
{
BSON_ASSERT (scram);
bson_free (scram->user);
if (scram->pass) {
bson_zero_free (scram->pass, strlen (scram->pass));
}
if (scram->hashed_password) {
bson_zero_free (scram->hashed_password, strlen (scram->hashed_password));
}
bson_free (scram->auth_message);
if (scram->cache) {
_mongoc_scram_cache_destroy (scram->cache);
}
+
+ memset (scram, 0, sizeof *scram);
}
/* Updates the cache with scram's last-used pre-secrets and secrets */
static void
_mongoc_scram_update_cache (mongoc_scram_t *scram)
{
mongoc_scram_cache_t *cache;
BSON_ASSERT (scram);
if (scram->cache) {
_mongoc_scram_cache_destroy (scram->cache);
}
cache = (mongoc_scram_cache_t *) bson_malloc0 (sizeof (*cache));
cache->hashed_password = bson_strdup (scram->hashed_password);
memcpy (
cache->decoded_salt, scram->decoded_salt, sizeof (cache->decoded_salt));
cache->iterations = scram->iterations;
memcpy (cache->client_key, scram->client_key, sizeof (cache->client_key));
memcpy (cache->server_key, scram->server_key, sizeof (cache->server_key));
memcpy (cache->salted_password,
scram->salted_password,
sizeof (cache->salted_password));
scram->cache = cache;
}
static bool
_mongoc_scram_buf_write (const char *src,
int32_t src_len,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen)
{
if (src_len < 0) {
src_len = (int32_t) strlen (src);
}
if (*outbuflen + src_len >= outbufmax) {
return false;
}
memcpy (outbuf + *outbuflen, src, src_len);
*outbuflen += src_len;
return true;
}
/* generate client-first-message:
* n,a=authzid,n=encoded-username,r=client-nonce
*
* note that a= is optional, so we aren't dealing with that here
*/
static bool
_mongoc_scram_start (mongoc_scram_t *scram,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error)
{
uint8_t nonce[24];
const char *ptr;
bool rval = true;
BSON_ASSERT (scram);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbufmax);
BSON_ASSERT (outbuflen);
if (!scram->user) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: username is not set");
goto FAIL;
}
/* auth message is as big as the outbuf just because */
scram->auth_message = (uint8_t *) bson_malloc (outbufmax);
scram->auth_messagemax = outbufmax;
/* the server uses a 24 byte random nonce. so we do as well */
if (1 != _mongoc_rand_bytes (nonce, sizeof (nonce))) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not generate a cryptographically "
"secure nonce in sasl step 1");
goto FAIL;
}
- scram->encoded_nonce_len = bson_b64_ntop (nonce,
- sizeof (nonce),
- scram->encoded_nonce,
- sizeof (scram->encoded_nonce));
+ scram->encoded_nonce_len =
+ COMMON_PREFIX (bson_b64_ntop (nonce,
+ sizeof (nonce),
+ scram->encoded_nonce,
+ sizeof (scram->encoded_nonce)));
if (-1 == scram->encoded_nonce_len) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not encode nonce");
goto FAIL;
}
if (!_mongoc_scram_buf_write ("n,,n=", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
for (ptr = scram->user; *ptr; ptr++) {
/* RFC 5802 specifies that ',' and '=' and encoded as '=2C' and '=3D'
* respectively in the user name */
switch (*ptr) {
case ',':
if (!_mongoc_scram_buf_write (
"=2C", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
break;
case '=':
if (!_mongoc_scram_buf_write (
"=3D", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
break;
default:
if (!_mongoc_scram_buf_write (ptr, 1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
break;
}
}
if (!_mongoc_scram_buf_write (",r=", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
if (!_mongoc_scram_buf_write (scram->encoded_nonce,
scram->encoded_nonce_len,
outbuf,
outbufmax,
outbuflen)) {
goto BUFFER;
}
/* we have to keep track of the conversation to create a client proof later
* on. This copies the message we're crafting from the 'n=' portion onwards
* into a buffer we're managing */
if (!_mongoc_scram_buf_write ((char *) outbuf + 3,
*outbuflen - 3,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
if (!_mongoc_scram_buf_write (",",
-1,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
goto CLEANUP;
BUFFER_AUTH:
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not buffer auth message in sasl step1");
goto FAIL;
BUFFER:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not buffer sasl step1");
goto FAIL;
FAIL:
rval = false;
CLEANUP:
return rval;
}
/* Compute the SCRAM step Hi() as defined in RFC5802 */
static void
_mongoc_scram_salt_password (mongoc_scram_t *scram,
const char *password,
uint32_t password_len,
const uint8_t *salt,
uint32_t salt_len,
uint32_t iterations)
{
uint8_t intermediate_digest[MONGOC_SCRAM_HASH_MAX_SIZE];
uint8_t start_key[MONGOC_SCRAM_HASH_MAX_SIZE];
int i;
int k;
uint8_t *output = scram->salted_password;
memcpy (start_key, salt, salt_len);
start_key[salt_len] = 0;
start_key[salt_len + 1] = 0;
start_key[salt_len + 2] = 0;
start_key[salt_len + 3] = 1;
mongoc_crypto_hmac (&scram->crypto,
password,
password_len,
start_key,
_scram_hash_size (scram),
output);
memcpy (intermediate_digest, output, _scram_hash_size (scram));
/* intermediateDigest contains Ui and output contains the accumulated XOR:ed
* result */
for (i = 2; i <= iterations; i++) {
mongoc_crypto_hmac (&scram->crypto,
password,
password_len,
intermediate_digest,
_scram_hash_size (scram),
intermediate_digest);
for (k = 0; k < _scram_hash_size (scram); k++) {
output[k] ^= intermediate_digest[k];
}
}
}
static bool
_mongoc_scram_generate_client_proof (mongoc_scram_t *scram,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen)
{
uint8_t stored_key[MONGOC_SCRAM_HASH_MAX_SIZE];
uint8_t client_signature[MONGOC_SCRAM_HASH_MAX_SIZE];
unsigned char client_proof[MONGOC_SCRAM_HASH_MAX_SIZE];
int i;
int r = 0;
if (!*scram->client_key) {
/* ClientKey := HMAC(saltedPassword, "Client Key") */
mongoc_crypto_hmac (&scram->crypto,
scram->salted_password,
_scram_hash_size (scram),
(uint8_t *) MONGOC_SCRAM_CLIENT_KEY,
(int) strlen (MONGOC_SCRAM_CLIENT_KEY),
scram->client_key);
}
/* StoredKey := H(client_key) */
mongoc_crypto_hash (&scram->crypto,
scram->client_key,
(size_t) _scram_hash_size (scram),
stored_key);
/* ClientSignature := HMAC(StoredKey, AuthMessage) */
mongoc_crypto_hmac (&scram->crypto,
stored_key,
_scram_hash_size (scram),
scram->auth_message,
scram->auth_messagelen,
client_signature);
/* ClientProof := ClientKey XOR ClientSignature */
for (i = 0; i < _scram_hash_size (scram); i++) {
client_proof[i] = scram->client_key[i] ^ client_signature[i];
}
- r = bson_b64_ntop (client_proof,
- _scram_hash_size (scram),
- (char *) outbuf + *outbuflen,
- outbufmax - *outbuflen);
+ r = COMMON_PREFIX (bson_b64_ntop (client_proof,
+ _scram_hash_size (scram),
+ (char *) outbuf + *outbuflen,
+ outbufmax - *outbuflen));
if (-1 == r) {
return false;
}
*outbuflen += r;
return true;
}
/* Parse server-first-message of the form:
* r=client-nonce|server-nonce,s=user-salt,i=iteration-count
*
* Generate client-final-message of the form:
* c=channel-binding(base64),r=client-nonce|server-nonce,p=client-proof
*/
static bool
_mongoc_scram_step2 (mongoc_scram_t *scram,
const uint8_t *inbuf,
uint32_t inbuflen,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error)
{
uint8_t *val_r = NULL;
uint32_t val_r_len;
uint8_t *val_s = NULL;
uint32_t val_s_len;
uint8_t *val_i = NULL;
uint32_t val_i_len;
uint8_t **current_val;
uint32_t *current_val_len;
const uint8_t *ptr;
const uint8_t *next_comma;
char *tmp;
char *hashed_password;
uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE] = {0};
int32_t decoded_salt_len;
/* the decoded salt leaves four trailing bytes to add the int32 0x00000001 */
const int32_t expected_salt_length = _scram_hash_size (scram) - 4;
bool rval = true;
int iterations;
BSON_ASSERT (scram);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbufmax);
BSON_ASSERT (outbuflen);
if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_1) {
/* Auth spec for SCRAM-SHA-1: "The password variable MUST be the mongodb
* hashed variant. The mongo hashed variant is computed as hash = HEX(
* MD5( UTF8( username + ':mongo:' + plain_text_password )))" */
tmp = bson_strdup_printf ("%s:mongo:%s", scram->user, scram->pass);
hashed_password = _mongoc_hex_md5 (tmp);
bson_zero_free (tmp, strlen (tmp));
} else if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_256) {
/* Auth spec for SCRAM-SHA-256: "Passwords MUST be prepared with SASLprep,
* per RFC 5802. Passwords are used directly for key derivation; they
* MUST NOT be digested as they are in SCRAM-SHA-1." */
hashed_password =
_mongoc_sasl_prep (scram->pass, (int) strlen (scram->pass), error);
if (!hashed_password) {
goto FAIL;
}
} else {
BSON_ASSERT (false);
}
/* we need all of the incoming message for the final client proof */
if (!_mongoc_scram_buf_write ((char *) inbuf,
inbuflen,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
if (!_mongoc_scram_buf_write (",",
-1,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
for (ptr = inbuf; ptr < inbuf + inbuflen;) {
switch (*ptr) {
case 'r':
current_val = &val_r;
current_val_len = &val_r_len;
break;
case 's':
current_val = &val_s;
current_val_len = &val_s_len;
break;
case 'i':
current_val = &val_i;
current_val_len = &val_i_len;
break;
default:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: unknown key (%c) in sasl step 2",
*ptr);
goto FAIL;
}
ptr++;
if (*ptr != '=') {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: invalid parse state in sasl step 2");
goto FAIL;
}
ptr++;
next_comma =
(const uint8_t *) memchr (ptr, ',', (inbuf + inbuflen) - ptr);
if (next_comma) {
*current_val_len = (uint32_t) (next_comma - ptr);
} else {
*current_val_len = (uint32_t) ((inbuf + inbuflen) - ptr);
}
*current_val = (uint8_t *) bson_malloc (*current_val_len + 1);
memcpy (*current_val, ptr, *current_val_len);
(*current_val)[*current_val_len] = '\0';
if (next_comma) {
ptr = next_comma + 1;
} else {
break;
}
}
if (!val_r) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: no r param in sasl step 2");
goto FAIL;
}
if (!val_s) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: no s param in sasl step 2");
goto FAIL;
}
if (!val_i) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: no i param in sasl step 2");
goto FAIL;
}
/* verify our nonce */
if (val_r_len < scram->encoded_nonce_len ||
mongoc_memcmp (val_r, scram->encoded_nonce, scram->encoded_nonce_len)) {
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: client nonce not repeated in sasl step 2");
}
*outbuflen = 0;
if (!_mongoc_scram_buf_write (
"c=biws,r=", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
if (!_mongoc_scram_buf_write (
(char *) val_r, val_r_len, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
if (!_mongoc_scram_buf_write ((char *) outbuf,
*outbuflen,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
if (!_mongoc_scram_buf_write (",p=", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
- decoded_salt_len =
- bson_b64_pton ((char *) val_s, decoded_salt, sizeof (decoded_salt));
+ decoded_salt_len = COMMON_PREFIX (bson_b64_pton (
+ (char *) val_s, decoded_salt, sizeof (decoded_salt)));
if (-1 == decoded_salt_len) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: unable to decode salt in sasl step2");
goto FAIL;
}
if (expected_salt_length != decoded_salt_len) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: invalid salt length of %d in sasl step2",
decoded_salt_len);
goto FAIL;
}
iterations = (int) bson_ascii_strtoll ((char *) val_i, &tmp, 10);
/* tmp holds the location of the failed to parse character. So if it's
* null, we got to the end of the string and didn't have a parse error */
if (*tmp) {
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: unable to parse iterations in sasl step2");
goto FAIL;
}
if (iterations < 0) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: iterations is negative in sasl step2");
goto FAIL;
}
/* drivers MUST enforce a minimum iteration count of 4096 and MUST error if
* the authentication conversation specifies a lower count. This mitigates
* downgrade attacks by a man-in-the-middle attacker. */
if (iterations < 4096) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: iterations must be at least 4096");
goto FAIL;
}
/* Save the presecrets for caching */
scram->hashed_password = bson_strdup (hashed_password);
scram->iterations = iterations;
memcpy (scram->decoded_salt, decoded_salt, sizeof (scram->decoded_salt));
if (scram->cache &&
_mongoc_scram_cache_has_presecrets (scram->cache, scram)) {
_mongoc_scram_cache_apply_secrets (scram->cache, scram);
}
if (!*scram->salted_password) {
_mongoc_scram_salt_password (scram,
hashed_password,
(uint32_t) strlen (hashed_password),
decoded_salt,
decoded_salt_len,
(uint32_t) iterations);
}
_mongoc_scram_generate_client_proof (scram, outbuf, outbufmax, outbuflen);
goto CLEANUP;
BUFFER_AUTH:
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not buffer auth message in sasl step2");
goto FAIL;
BUFFER:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not buffer sasl step2");
goto FAIL;
FAIL:
rval = false;
CLEANUP:
bson_free (val_r);
bson_free (val_s);
bson_free (val_i);
if (hashed_password) {
bson_zero_free (hashed_password, strlen (hashed_password));
}
return rval;
}
static bool
_mongoc_scram_verify_server_signature (mongoc_scram_t *scram,
uint8_t *verification,
uint32_t len)
{
char encoded_server_signature[MONGOC_SCRAM_B64_HASH_MAX_SIZE];
int32_t encoded_server_signature_len;
uint8_t server_signature[MONGOC_SCRAM_HASH_MAX_SIZE];
if (!*scram->server_key) {
/* ServerKey := HMAC(SaltedPassword, "Server Key") */
mongoc_crypto_hmac (&scram->crypto,
scram->salted_password,
_scram_hash_size (scram),
(uint8_t *) MONGOC_SCRAM_SERVER_KEY,
strlen (MONGOC_SCRAM_SERVER_KEY),
scram->server_key);
}
/* ServerSignature := HMAC(ServerKey, AuthMessage) */
mongoc_crypto_hmac (&scram->crypto,
scram->server_key,
_scram_hash_size (scram),
scram->auth_message,
scram->auth_messagelen,
server_signature);
encoded_server_signature_len =
- bson_b64_ntop (server_signature,
- _scram_hash_size (scram),
- encoded_server_signature,
- sizeof (encoded_server_signature));
+ COMMON_PREFIX (bson_b64_ntop (server_signature,
+ _scram_hash_size (scram),
+ encoded_server_signature,
+ sizeof (encoded_server_signature)));
if (encoded_server_signature_len == -1) {
return false;
}
return (len == encoded_server_signature_len) &&
(mongoc_memcmp (verification, encoded_server_signature, len) == 0);
}
static bool
_mongoc_scram_step3 (mongoc_scram_t *scram,
const uint8_t *inbuf,
uint32_t inbuflen,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error)
{
uint8_t *val_e = NULL;
uint32_t val_e_len;
uint8_t *val_v = NULL;
uint32_t val_v_len;
uint8_t **current_val;
uint32_t *current_val_len;
const uint8_t *ptr;
const uint8_t *next_comma;
bool rval = true;
BSON_ASSERT (scram);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbufmax);
BSON_ASSERT (outbuflen);
for (ptr = inbuf; ptr < inbuf + inbuflen;) {
switch (*ptr) {
case 'e':
current_val = &val_e;
current_val_len = &val_e_len;
break;
case 'v':
current_val = &val_v;
current_val_len = &val_v_len;
break;
default:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: unknown key (%c) in sasl step 3",
*ptr);
goto FAIL;
}
ptr++;
if (*ptr != '=') {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: invalid parse state in sasl step 3");
goto FAIL;
}
ptr++;
next_comma =
(const uint8_t *) memchr (ptr, ',', (inbuf + inbuflen) - ptr);
if (next_comma) {
*current_val_len = (uint32_t) (next_comma - ptr);
} else {
*current_val_len = (uint32_t) ((inbuf + inbuflen) - ptr);
}
*current_val = (uint8_t *) bson_malloc (*current_val_len + 1);
memcpy (*current_val, ptr, *current_val_len);
(*current_val)[*current_val_len] = '\0';
if (next_comma) {
ptr = next_comma + 1;
} else {
break;
}
}
*outbuflen = 0;
if (val_e) {
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: authentication failure in sasl step 3 : %s",
val_e);
goto FAIL;
}
if (!val_v) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: no v param in sasl step 3");
goto FAIL;
}
if (!_mongoc_scram_verify_server_signature (scram, val_v, val_v_len)) {
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not verify server signature in sasl step 3");
goto FAIL;
}
/* Update the cache if authentication succeeds */
_mongoc_scram_update_cache (scram);
goto CLEANUP;
FAIL:
rval = false;
CLEANUP:
bson_free (val_e);
bson_free (val_v);
return rval;
}
bool
_mongoc_scram_step (mongoc_scram_t *scram,
const uint8_t *inbuf,
uint32_t inbuflen,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error)
{
BSON_ASSERT (scram);
BSON_ASSERT (inbuf);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbuflen);
scram->step++;
switch (scram->step) {
case 1:
return _mongoc_scram_start (scram, outbuf, outbufmax, outbuflen, error);
case 2:
return _mongoc_scram_step2 (
scram, inbuf, inbuflen, outbuf, outbufmax, outbuflen, error);
case 3:
return _mongoc_scram_step3 (
scram, inbuf, inbuflen, outbuf, outbufmax, outbuflen, error);
default:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_NOT_DONE,
"SCRAM Failure: maximum steps detected");
return false;
}
}
bool
_mongoc_sasl_prep_required (const char *str)
{
unsigned char c;
while (*str) {
c = (unsigned char) *str;
/* characters below 32 contain all of the control characters.
* characters above 127 are multibyte UTF-8 characters.
* character 127 is the DEL character. */
if (c < 32 || c >= 127) {
return true;
}
str++;
}
return false;
}
#ifdef MONGOC_ENABLE_ICU
char *
_mongoc_sasl_prep_impl (const char *name,
const char *in_utf8,
int in_utf8_len,
bson_error_t *err)
{
/* The flow is in_utf8 -> in_utf16 -> SASLPrep -> out_utf16 -> out_utf8. */
UChar *in_utf16, *out_utf16;
char *out_utf8;
int32_t in_utf16_len, out_utf16_len, out_utf8_len;
UErrorCode error_code = U_ZERO_ERROR;
UStringPrepProfile *prep;
#define SASL_PREP_ERR_RETURN(msg) \
do { \
bson_set_error (err, \
MONGOC_ERROR_SCRAM, \
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, \
(msg), \
name); \
return NULL; \
} while (0)
/* 1. convert str to UTF-16. */
/* preflight to get the destination length. */
(void) u_strFromUTF8 (
NULL, 0, &in_utf16_len, in_utf8, in_utf8_len, &error_code);
if (error_code != U_BUFFER_OVERFLOW_ERROR) {
SASL_PREP_ERR_RETURN ("could not calculate UTF-16 length of %s");
}
/* convert to UTF-16. */
error_code = U_ZERO_ERROR;
in_utf16 = bson_malloc (sizeof (UChar) *
(in_utf16_len + 1)); /* add one for null byte. */
(void) u_strFromUTF8 (
in_utf16, in_utf16_len + 1, NULL, in_utf8, in_utf8_len, &error_code);
if (error_code) {
bson_free (in_utf16);
SASL_PREP_ERR_RETURN ("could not convert %s to UTF-16");
}
/* 2. perform SASLPrep. */
prep = usprep_openByType (USPREP_RFC4013_SASLPREP, &error_code);
if (error_code) {
bson_free (in_utf16);
SASL_PREP_ERR_RETURN ("could not start SASLPrep for %s");
}
/* preflight. */
out_utf16_len = usprep_prepare (
prep, in_utf16, in_utf16_len, NULL, 0, USPREP_DEFAULT, NULL, &error_code);
if (error_code != U_BUFFER_OVERFLOW_ERROR) {
bson_free (in_utf16);
usprep_close (prep);
SASL_PREP_ERR_RETURN ("could not calculate SASLPrep length of %s");
}
/* convert. */
error_code = U_ZERO_ERROR;
out_utf16 = bson_malloc (sizeof (UChar) * (out_utf16_len + 1));
(void) usprep_prepare (prep,
in_utf16,
in_utf16_len,
out_utf16,
out_utf16_len + 1,
USPREP_DEFAULT,
NULL,
&error_code);
if (error_code) {
bson_free (in_utf16);
bson_free (out_utf16);
usprep_close (prep);
SASL_PREP_ERR_RETURN ("could not execute SASLPrep for %s");
}
bson_free (in_utf16);
usprep_close (prep);
/* 3. convert back to UTF-8. */
/* preflight. */
(void) u_strToUTF8 (
NULL, 0, &out_utf8_len, out_utf16, out_utf16_len, &error_code);
if (error_code != U_BUFFER_OVERFLOW_ERROR) {
bson_free (out_utf16);
SASL_PREP_ERR_RETURN ("could not calculate UTF-8 length of %s");
}
/* convert. */
error_code = U_ZERO_ERROR;
out_utf8 = (char *) bson_malloc (
sizeof (char) * (out_utf8_len + 1)); /* add one for null byte. */
(void) u_strToUTF8 (
out_utf8, out_utf8_len + 1, NULL, out_utf16, out_utf16_len, &error_code);
if (error_code) {
bson_free (out_utf8);
bson_free (out_utf16);
SASL_PREP_ERR_RETURN ("could not convert %s back to UTF-8");
}
bson_free (out_utf16);
return out_utf8;
#undef SASL_PREP_ERR_RETURN
}
#endif
char *
_mongoc_sasl_prep (const char *in_utf8, int in_utf8_len, bson_error_t *err)
{
#ifdef MONGOC_ENABLE_ICU
return _mongoc_sasl_prep_impl ("password", in_utf8, in_utf8_len, err);
#else
if (_mongoc_sasl_prep_required (in_utf8)) {
bson_set_error (err,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: ICU required to SASLPrep password");
return NULL;
}
return bson_strdup (in_utf8);
#endif
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c
index beb44be5..81096372 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c
@@ -1,945 +1,941 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL
#include <bson/bson.h>
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-ssl.h"
#include "mongoc-stream-tls.h"
#include "mongoc-stream-tls-private.h"
#include "mongoc-secure-channel-private.h"
#include "mongoc-stream-tls-secure-channel-private.h"
#include "mongoc-errno-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "stream-secure-channel"
/* mingw doesn't define this */
#ifndef SECBUFFER_ALERT
#define SECBUFFER_ALERT 17
#endif
PCCERT_CONTEXT
mongoc_secure_channel_setup_certificate_from_file (const char *filename)
{
char *pem;
FILE *file;
bool success;
HCRYPTKEY hKey;
long pem_length;
HCRYPTPROV provider;
CERT_BLOB public_blob;
const char *pem_public;
const char *pem_private;
LPBYTE blob_private = NULL;
PCCERT_CONTEXT cert = NULL;
DWORD blob_private_len = 0;
- HCERTSTORE cert_store = NULL;
- DWORD encrypted_cert_len = 0;
- LPBYTE encrypted_cert = NULL;
DWORD encrypted_private_len = 0;
LPBYTE encrypted_private = NULL;
file = fopen (filename, "rb");
if (!file) {
MONGOC_ERROR ("Couldn't open file '%s'", filename);
return false;
}
fseek (file, 0, SEEK_END);
pem_length = ftell (file);
fseek (file, 0, SEEK_SET);
if (pem_length < 1) {
MONGOC_ERROR ("Couldn't determine file size of '%s'", filename);
return false;
}
pem = (char *) bson_malloc0 (pem_length);
fread ((void *) pem, 1, pem_length, file);
fclose (file);
pem_public = strstr (pem, "-----BEGIN CERTIFICATE-----");
pem_private = strstr (pem, "-----BEGIN ENCRYPTED PRIVATE KEY-----");
if (pem_private) {
MONGOC_ERROR ("Detected unsupported encrypted private key");
goto fail;
}
pem_private = strstr (pem, "-----BEGIN RSA PRIVATE KEY-----");
if (!pem_private) {
pem_private = strstr (pem, "-----BEGIN PRIVATE KEY-----");
}
if (!pem_private) {
MONGOC_ERROR ("Can't find private key in '%s'", filename);
goto fail;
}
public_blob.cbData = (DWORD) strlen (pem_public);
public_blob.pbData = (BYTE *) pem_public;
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380264%28v=vs.85%29.aspx
*/
CryptQueryObject (
CERT_QUERY_OBJECT_BLOB, /* dwObjectType, blob or file */
&public_blob, /* pvObject, Unicode filename */
CERT_QUERY_CONTENT_FLAG_ALL, /* dwExpectedContentTypeFlags */
CERT_QUERY_FORMAT_FLAG_ALL, /* dwExpectedFormatTypeFlags */
0, /* dwFlags, reserved for "future use" */
NULL, /* pdwMsgAndCertEncodingType, OUT, unused */
NULL, /* pdwContentType (dwExpectedContentTypeFlags), OUT, unused */
NULL, /* pdwFormatType (dwExpectedFormatTypeFlags,), OUT, unused */
NULL, /* phCertStore, OUT, HCERTSTORE.., unused, for now */
NULL, /* phMsg, OUT, HCRYPTMSG, only for PKC7, unused */
(const void **) &cert /* ppvContext, OUT, the Certificate Context */
);
if (!cert) {
MONGOC_ERROR ("Failed to extract public key from '%s'. Error 0x%.8X",
filename,
- GetLastError ());
+ (unsigned int) GetLastError ());
goto fail;
}
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380285%28v=vs.85%29.aspx
*/
success =
CryptStringToBinaryA (pem_private, /* pszString */
0, /* cchString */
CRYPT_STRING_BASE64HEADER, /* dwFlags */
NULL, /* pbBinary */
&encrypted_private_len, /* pcBinary, IN/OUT */
NULL, /* pdwSkip */
NULL); /* pdwFlags */
if (!success) {
MONGOC_ERROR ("Failed to convert base64 private key. Error 0x%.8X",
- GetLastError ());
+ (unsigned int) GetLastError ());
goto fail;
}
encrypted_private = (LPBYTE) bson_malloc0 (encrypted_private_len);
success = CryptStringToBinaryA (pem_private,
0,
CRYPT_STRING_BASE64HEADER,
encrypted_private,
&encrypted_private_len,
NULL,
NULL);
if (!success) {
MONGOC_ERROR ("Failed to convert base64 private key. Error 0x%.8X",
- GetLastError ());
+ (unsigned int) GetLastError ());
goto fail;
}
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa379912%28v=vs.85%29.aspx
*/
success = CryptDecodeObjectEx (
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* dwCertEncodingType */
PKCS_RSA_PRIVATE_KEY, /* lpszStructType */
encrypted_private, /* pbEncoded */
encrypted_private_len, /* cbEncoded */
0, /* dwFlags */
NULL, /* pDecodePara */
NULL, /* pvStructInfo */
&blob_private_len); /* pcbStructInfo */
if (!success) {
LPTSTR msg = NULL;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError (),
LANG_NEUTRAL,
(LPTSTR) &msg,
0,
NULL);
- MONGOC_ERROR (
- "Failed to parse private key. %s (0x%.8X)", msg, GetLastError ());
+ MONGOC_ERROR ("Failed to parse private key. %s (0x%.8X)",
+ msg,
+ (unsigned int) GetLastError ());
LocalFree (msg);
goto fail;
}
blob_private = (LPBYTE) bson_malloc0 (blob_private_len);
success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
PKCS_RSA_PRIVATE_KEY,
encrypted_private,
encrypted_private_len,
0,
NULL,
blob_private,
&blob_private_len);
if (!success) {
MONGOC_ERROR ("Failed to parse private key. Error 0x%.8X",
- GetLastError ());
+ (unsigned int) GetLastError ());
goto fail;
}
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa379886%28v=vs.85%29.aspx
*/
success = CryptAcquireContext (&provider, /* phProv */
NULL, /* pszContainer */
MS_ENHANCED_PROV, /* pszProvider */
PROV_RSA_FULL, /* dwProvType */
CRYPT_VERIFYCONTEXT); /* dwFlags */
if (!success) {
MONGOC_ERROR ("CryptAcquireContext failed with error 0x%.8X",
- GetLastError ());
+ (unsigned int) GetLastError ());
goto fail;
}
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380207%28v=vs.85%29.aspx
*/
success = CryptImportKey (provider, /* hProv */
blob_private, /* pbData */
blob_private_len, /* dwDataLen */
0, /* hPubKey */
0, /* dwFlags */
&hKey); /* phKey, OUT */
if (!success) {
MONGOC_ERROR ("CryptImportKey for private key failed with error 0x%.8X",
- GetLastError ());
+ (unsigned int) GetLastError ());
goto fail;
}
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa376573%28v=vs.85%29.aspx
*/
success = CertSetCertificateContextProperty (
cert, /* pCertContext */
CERT_KEY_PROV_HANDLE_PROP_ID, /* dwPropId */
0, /* dwFlags */
(const void *) provider); /* pvData */
if (success) {
TRACE ("%s", "Successfully loaded client certificate");
return cert;
}
MONGOC_ERROR ("Can't associate private key with public key: 0x%.8X",
- GetLastError ());
+ (unsigned int) GetLastError ());
fail:
SecureZeroMemory (pem, pem_length);
bson_free (pem);
if (encrypted_private) {
SecureZeroMemory (encrypted_private, encrypted_private_len);
bson_free (encrypted_private);
}
if (blob_private) {
SecureZeroMemory (blob_private, blob_private_len);
bson_free (blob_private);
}
return NULL;
}
PCCERT_CONTEXT
mongoc_secure_channel_setup_certificate (
mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt)
{
return mongoc_secure_channel_setup_certificate_from_file (opt->pem_file);
}
void
_bson_append_szoid (bson_string_t *retval,
PCCERT_CONTEXT cert,
const char *label,
void *oid)
{
DWORD oid_len =
CertGetNameString (cert, CERT_NAME_ATTR_TYPE, 0, oid, NULL, 0);
if (oid_len > 1) {
char *tmp = bson_malloc0 (oid_len);
CertGetNameString (cert, CERT_NAME_ATTR_TYPE, 0, oid, tmp, oid_len);
bson_string_append_printf (retval, "%s%s", label, tmp);
bson_free (tmp);
}
}
char *
_mongoc_secure_channel_extract_subject (const char *filename,
const char *passphrase)
{
bson_string_t *retval;
PCCERT_CONTEXT cert;
cert = mongoc_secure_channel_setup_certificate_from_file (filename);
if (!cert) {
return NULL;
}
retval = bson_string_new ("");
;
_bson_append_szoid (retval, cert, "C=", szOID_COUNTRY_NAME);
_bson_append_szoid (retval, cert, ",ST=", szOID_STATE_OR_PROVINCE_NAME);
_bson_append_szoid (retval, cert, ",L=", szOID_LOCALITY_NAME);
_bson_append_szoid (retval, cert, ",O=", szOID_ORGANIZATION_NAME);
_bson_append_szoid (retval, cert, ",OU=", szOID_ORGANIZATIONAL_UNIT_NAME);
_bson_append_szoid (retval, cert, ",CN=", szOID_COMMON_NAME);
_bson_append_szoid (retval, cert, ",STREET=", szOID_STREET_ADDRESS);
return bson_string_free (retval, false);
}
bool
mongoc_secure_channel_setup_ca (
mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt)
{
FILE *file;
long length;
const char *pem_key;
HCERTSTORE cert_store = NULL;
PCCERT_CONTEXT cert = NULL;
DWORD encrypted_cert_len = 0;
LPBYTE encrypted_cert = NULL;
file = fopen (opt->ca_file, "rb");
if (!file) {
MONGOC_ERROR ("Couldn't open file '%s'", opt->ca_file);
return false;
}
fseek (file, 0, SEEK_END);
length = ftell (file);
fseek (file, 0, SEEK_SET);
if (length < 1) {
MONGOC_WARNING ("Couldn't determine file size of '%s'", opt->ca_file);
return false;
}
pem_key = (const char *) bson_malloc0 (length);
fread ((void *) pem_key, 1, length, file);
fclose (file);
/* If we have private keys or other fuzz, seek to the good stuff */
pem_key = strstr (pem_key, "-----BEGIN CERTIFICATE-----");
/*printf ("%s\n", pem_key);*/
if (!pem_key) {
- MONGOC_WARNING ("Couldn't find certificate in '%d'", opt->ca_file);
+ MONGOC_WARNING ("Couldn't find certificate in '%s'", opt->ca_file);
return false;
}
if (!CryptStringToBinaryA (pem_key,
0,
CRYPT_STRING_BASE64HEADER,
NULL,
&encrypted_cert_len,
NULL,
NULL)) {
MONGOC_ERROR ("Failed to convert BASE64 public key. Error 0x%.8X",
- GetLastError ());
+ (unsigned int) GetLastError ());
return false;
}
encrypted_cert = (LPBYTE) LocalAlloc (0, encrypted_cert_len);
if (!CryptStringToBinaryA (pem_key,
0,
CRYPT_STRING_BASE64HEADER,
encrypted_cert,
&encrypted_cert_len,
NULL,
NULL)) {
MONGOC_ERROR ("Failed to convert BASE64 public key. Error 0x%.8X",
- GetLastError ());
+ (unsigned int) GetLastError ());
return false;
}
cert = CertCreateCertificateContext (
X509_ASN_ENCODING, encrypted_cert, encrypted_cert_len);
if (!cert) {
MONGOC_WARNING ("Could not convert certificate");
return false;
}
cert_store = CertOpenStore (
CERT_STORE_PROV_SYSTEM, /* provider */
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */
0, /* unused */
CERT_SYSTEM_STORE_LOCAL_MACHINE, /* dwFlags */
L"Root"); /* system store name. "My" or "Root" */
if (cert_store == NULL) {
MONGOC_ERROR ("Error opening certificate store");
return false;
}
if (CertAddCertificateContextToStore (
cert_store, cert, CERT_STORE_ADD_USE_EXISTING, NULL)) {
TRACE ("%s", "Added the certificate !");
CertCloseStore (cert_store, 0);
return true;
}
MONGOC_WARNING ("Failed adding the cert");
CertCloseStore (cert_store, 0);
return false;
}
bool
mongoc_secure_channel_setup_crl (
mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt)
{
HCERTSTORE cert_store = NULL;
PCCERT_CONTEXT cert = NULL;
LPWSTR str;
int chars;
chars = MultiByteToWideChar (CP_ACP, 0, opt->crl_file, -1, NULL, 0);
if (chars < 1) {
MONGOC_WARNING ("Can't determine opt->crl_file length");
return false;
}
- str = (LPWSTR) bson_malloc0 (chars);
+ str = (LPWSTR) bson_malloc0 (chars * sizeof (*str));
MultiByteToWideChar (CP_ACP, 0, opt->crl_file, -1, str, chars);
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380264%28v=vs.85%29.aspx
*/
CryptQueryObject (
CERT_QUERY_OBJECT_FILE, /* dwObjectType, blob or file */
str, /* pvObject, Unicode filename */
CERT_QUERY_CONTENT_FLAG_CRL, /* dwExpectedContentTypeFlags */
CERT_QUERY_FORMAT_FLAG_ALL, /* dwExpectedFormatTypeFlags */
0, /* dwFlags, reserved for "future use" */
NULL, /* pdwMsgAndCertEncodingType, OUT, unused */
NULL, /* pdwContentType (dwExpectedContentTypeFlags), OUT, unused */
NULL, /* pdwFormatType (dwExpectedFormatTypeFlags,), OUT, unused */
NULL, /* phCertStore, OUT, HCERTSTORE.., unused, for now */
NULL, /* phMsg, OUT, HCRYPTMSG, only for PKC7, unused */
(const void **) &cert /* ppvContext, OUT, the Certificate Context */
);
bson_free (str);
if (!cert) {
MONGOC_WARNING ("Can't extract CRL from '%s'", opt->crl_file);
return false;
}
cert_store = CertOpenStore (
CERT_STORE_PROV_SYSTEM, /* provider */
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */
0, /* unused */
CERT_SYSTEM_STORE_LOCAL_MACHINE, /* dwFlags */
L"Root"); /* system store name. "My" or "Root" */
if (cert_store == NULL) {
MONGOC_ERROR ("Error opening certificate store");
CertFreeCertificateContext (cert);
return false;
}
if (CertAddCertificateContextToStore (
cert_store, cert, CERT_STORE_ADD_USE_EXISTING, NULL)) {
TRACE ("%s", "Added the certificate !");
CertFreeCertificateContext (cert);
CertCloseStore (cert_store, 0);
return true;
}
MONGOC_WARNING ("Failed adding the cert");
CertFreeCertificateContext (cert);
CertCloseStore (cert_store, 0);
return false;
}
size_t
mongoc_secure_channel_read (mongoc_stream_tls_t *tls,
void *data,
size_t data_length)
{
ssize_t length;
errno = 0;
TRACE ("Wanting to read: %d, timeout is %d", data_length, tls->timeout_msec);
/* 4th argument is minimum bytes, while the data_length is the
* size of the buffer. We are totally fine with just one TLS record (few
*bytes)
**/
length = mongoc_stream_read (
tls->base_stream, data, data_length, 0, tls->timeout_msec);
TRACE ("Got %d", length);
if (length > 0) {
return length;
}
return 0;
}
size_t
mongoc_secure_channel_write (mongoc_stream_tls_t *tls,
const void *data,
size_t data_length)
{
ssize_t length;
errno = 0;
TRACE ("Wanting to write: %d", data_length);
length = mongoc_stream_write (
tls->base_stream, (void *) data, data_length, tls->timeout_msec);
TRACE ("Wrote: %d", length);
return length;
}
void
mongoc_secure_channel_realloc_buf (size_t *size, uint8_t **buf, size_t new_size)
{
*size = bson_next_power_of_two (new_size);
*buf = bson_realloc (*buf, *size);
}
/**
* The follow functions comes from one of my favorite project, cURL!
* Thank you so much for having gone through the Secure Channel pain for me.
*
*
* Copyright (C) 2012 - 2015, Marc Hoersken, <info@marc-hoersken.de>
* Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
* Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* Thanks for code and inspiration!
*/
void
_mongoc_secure_channel_init_sec_buffer (SecBuffer *buffer,
unsigned long buf_type,
void *buf_data_ptr,
unsigned long buf_byte_size)
{
buffer->cbBuffer = buf_byte_size;
buffer->BufferType = buf_type;
buffer->pvBuffer = buf_data_ptr;
}
void
_mongoc_secure_channel_init_sec_buffer_desc (SecBufferDesc *desc,
SecBuffer *buffer_array,
unsigned long buffer_count)
{
desc->ulVersion = SECBUFFER_VERSION;
desc->pBuffers = buffer_array;
desc->cBuffers = buffer_count;
}
bool
mongoc_secure_channel_handshake_step_1 (mongoc_stream_tls_t *tls,
char *hostname)
{
SecBuffer outbuf;
ssize_t written = -1;
SecBufferDesc outbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
TRACE ("SSL/TLS connection with '%s' (step 1/3)", hostname);
/* setup output buffer */
_mongoc_secure_channel_init_sec_buffer (&outbuf, SECBUFFER_EMPTY, NULL, 0);
_mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, &outbuf, 1);
/* setup request flags */
secure_channel->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONFIDENTIALITY |
ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM;
/* allocate memory for the security context handle */
secure_channel->ctxt = (mongoc_secure_channel_ctxt *) bson_malloc0 (
sizeof (mongoc_secure_channel_ctxt));
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
sspi_status = InitializeSecurityContext (
&secure_channel->cred->cred_handle, /* phCredential */
NULL, /* phContext */
hostname, /* pszTargetName */
secure_channel->req_flags, /* fContextReq */
0, /* Reserved1, must be 0 */
0, /* TargetDataRep, unused */
NULL, /* pInput */
0, /* Reserved2, must be 0 */
&secure_channel->ctxt->ctxt_handle, /* phNewContext OUT param */
&outbuf_desc, /* pOutput OUT param */
&secure_channel->ret_flags, /* pfContextAttr OUT param */
&secure_channel->ctxt->time_stamp /* ptsExpiry OUT param */
);
if (sspi_status != SEC_I_CONTINUE_NEEDED) {
- MONGOC_ERROR ("initial InitializeSecurityContext failed: %d",
+ MONGOC_ERROR ("initial InitializeSecurityContext failed: %ld",
sspi_status);
return false;
}
TRACE ("sending initial handshake data: sending %lu bytes...",
outbuf.cbBuffer);
/* send initial handshake data which is now stored in output buffer */
written =
mongoc_secure_channel_write (tls, outbuf.pvBuffer, outbuf.cbBuffer);
FreeContextBuffer (outbuf.pvBuffer);
if (outbuf.cbBuffer != (size_t) written) {
MONGOC_ERROR ("failed to send initial handshake data: "
"sent %zd of %lu bytes",
written,
outbuf.cbBuffer);
return false;
}
TRACE ("sent initial handshake data: sent %zd bytes", written);
secure_channel->recv_unrecoverable_err = 0;
secure_channel->recv_sspi_close_notify = false;
secure_channel->recv_connection_closed = false;
/* continue to second handshake step */
secure_channel->connecting_state = ssl_connect_2;
return true;
}
bool
mongoc_secure_channel_handshake_step_2 (mongoc_stream_tls_t *tls,
char *hostname)
{
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
SECURITY_STATUS sspi_status = SEC_E_OK;
ssize_t nread = -1, written = -1;
SecBufferDesc outbuf_desc;
SecBufferDesc inbuf_desc;
SecBuffer outbuf[3];
SecBuffer inbuf[2];
bool doread;
int i;
doread = (secure_channel->connecting_state != ssl_connect_2_writing) ? true
: false;
TRACE ("%s", "SSL/TLS connection with endpoint (step 2/3)");
if (!secure_channel->cred || !secure_channel->ctxt) {
return false;
}
/* grow the buffer if necessary */
if (secure_channel->encdata_length == secure_channel->encdata_offset) {
mongoc_secure_channel_realloc_buf (&secure_channel->encdata_length,
&secure_channel->encdata_buffer,
secure_channel->encdata_length + 1);
}
for (;;) {
if (doread) {
/* read encrypted handshake data from socket */
nread = mongoc_secure_channel_read (
tls,
(char *) (secure_channel->encdata_buffer +
secure_channel->encdata_offset),
secure_channel->encdata_length - secure_channel->encdata_offset);
if (!nread) {
if (MONGOC_ERRNO_IS_AGAIN (errno)) {
if (secure_channel->connecting_state != ssl_connect_2_writing) {
secure_channel->connecting_state = ssl_connect_2_reading;
}
TRACE ("%s", "failed to receive handshake, need more data");
return true;
}
MONGOC_ERROR (
"failed to receive handshake, SSL/TLS connection failed");
return false;
}
/* increase encrypted data buffer offset */
secure_channel->encdata_offset += nread;
}
TRACE ("encrypted data buffer: offset %d length %d",
(int) secure_channel->encdata_offset,
(int) secure_channel->encdata_length);
/* setup input buffers */
_mongoc_secure_channel_init_sec_buffer (
&inbuf[0],
SECBUFFER_TOKEN,
malloc (secure_channel->encdata_offset),
(unsigned long) (secure_channel->encdata_offset &
(size_t) 0xFFFFFFFFUL));
_mongoc_secure_channel_init_sec_buffer (
&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
_mongoc_secure_channel_init_sec_buffer_desc (&inbuf_desc, inbuf, 2);
/* setup output buffers */
_mongoc_secure_channel_init_sec_buffer (
&outbuf[0], SECBUFFER_TOKEN, NULL, 0);
_mongoc_secure_channel_init_sec_buffer (
&outbuf[1], SECBUFFER_ALERT, NULL, 0);
_mongoc_secure_channel_init_sec_buffer (
&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
_mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, outbuf, 3);
if (inbuf[0].pvBuffer == NULL) {
MONGOC_ERROR ("unable to allocate memory");
return false;
}
/* copy received handshake data into input buffer */
memcpy (inbuf[0].pvBuffer,
secure_channel->encdata_buffer,
secure_channel->encdata_offset);
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
*/
sspi_status =
InitializeSecurityContext (&secure_channel->cred->cred_handle,
&secure_channel->ctxt->ctxt_handle,
hostname,
secure_channel->req_flags,
0,
0,
&inbuf_desc,
0,
NULL,
&outbuf_desc,
&secure_channel->ret_flags,
&secure_channel->ctxt->time_stamp);
/* free buffer for received handshake data */
free (inbuf[0].pvBuffer);
/* check if the handshake was incomplete */
if (sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
secure_channel->connecting_state = ssl_connect_2_reading;
TRACE ("%s", "received incomplete message, need more data");
return true;
}
/* If the server has requested a client certificate, attempt to continue
* the handshake without one. This will allow connections to servers which
* request a client certificate but do not require it. */
if (sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
!(secure_channel->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
secure_channel->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
secure_channel->connecting_state = ssl_connect_2_writing;
TRACE ("%s", "A client certificate has been requested");
return true;
}
/* check if the handshake needs to be continued */
if (sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) {
for (i = 0; i < 3; i++) {
/* search for handshake tokens that need to be send */
if (outbuf[i].BufferType == SECBUFFER_TOKEN &&
outbuf[i].cbBuffer > 0) {
TRACE ("sending next handshake data: sending %lu bytes...",
outbuf[i].cbBuffer);
/* send handshake token to server */
written = mongoc_secure_channel_write (
tls, outbuf[i].pvBuffer, outbuf[i].cbBuffer);
if (outbuf[i].cbBuffer != (size_t) written) {
MONGOC_ERROR ("failed to send next handshake data: "
"sent %zd of %lu bytes",
written,
outbuf[i].cbBuffer);
return false;
}
}
/* free obsolete buffer */
if (outbuf[i].pvBuffer != NULL) {
FreeContextBuffer (outbuf[i].pvBuffer);
}
}
} else {
switch (sspi_status) {
case SEC_E_WRONG_PRINCIPAL:
MONGOC_ERROR ("SSL Certification verification failed: hostname "
"doesn't match certificate");
break;
case SEC_E_UNTRUSTED_ROOT:
MONGOC_ERROR ("SSL Certification verification failed: Untrusted "
"root certificate");
break;
case SEC_E_CERT_EXPIRED:
MONGOC_ERROR ("SSL Certification verification failed: certificate "
"has expired");
break;
case CRYPT_E_NO_REVOCATION_CHECK:
- /* This seems to be raised also when hostname doesn't match the
- * certificate */
- MONGOC_ERROR ("SSL Certification verification failed: failed "
- "revocation/hostname check");
+ MONGOC_ERROR ("SSL Certification verification failed: certificate "
+ "does not include revocation check.");
break;
case SEC_E_INSUFFICIENT_MEMORY:
case SEC_E_INTERNAL_ERROR:
case SEC_E_INVALID_HANDLE:
case SEC_E_INVALID_TOKEN:
case SEC_E_LOGON_DENIED:
case SEC_E_NO_AUTHENTICATING_AUTHORITY:
case SEC_E_NO_CREDENTIALS:
case SEC_E_TARGET_UNKNOWN:
case SEC_E_UNSUPPORTED_FUNCTION:
#ifdef SEC_E_APPLICATION_PROTOCOL_MISMATCH
/* Not available in VS2010 */
case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
#endif
default: {
LPTSTR msg = NULL;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError (),
LANG_NEUTRAL,
(LPTSTR) &msg,
0,
NULL);
MONGOC_ERROR ("Failed to initialize security context, error code: "
"0x%04X%04X: %s",
- (sspi_status >> 16) & 0xffff,
- sspi_status & 0xffff,
+ (unsigned int) (sspi_status >> 16) & 0xffff,
+ (unsigned int) sspi_status & 0xffff,
msg);
LocalFree (msg);
}
}
return false;
}
/* check if there was additional remaining encrypted data */
if (inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
TRACE ("encrypted data length: %lu", inbuf[1].cbBuffer);
/*
* There are two cases where we could be getting extra data here:
* 1) If we're renegotiating a connection and the handshake is already
* complete (from the server perspective), it can encrypted app data
* (not handshake data) in an extra buffer at this point.
* 2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a
* connection and this extra data is part of the handshake.
* We should process the data immediately; waiting for the socket to
* be ready may fail since the server is done sending handshake data.
*/
/* check if the remaining data is less than the total amount
* and therefore begins after the already processed data */
if (secure_channel->encdata_offset > inbuf[1].cbBuffer) {
memmove (secure_channel->encdata_buffer,
(secure_channel->encdata_buffer +
secure_channel->encdata_offset) -
inbuf[1].cbBuffer,
inbuf[1].cbBuffer);
secure_channel->encdata_offset = inbuf[1].cbBuffer;
if (sspi_status == SEC_I_CONTINUE_NEEDED) {
doread = FALSE;
continue;
}
}
} else {
secure_channel->encdata_offset = 0;
}
break;
}
/* check if the handshake needs to be continued */
if (sspi_status == SEC_I_CONTINUE_NEEDED) {
secure_channel->connecting_state = ssl_connect_2_reading;
return true;
}
/* check if the handshake is complete */
if (sspi_status == SEC_E_OK) {
secure_channel->connecting_state = ssl_connect_3;
TRACE ("%s", "SSL/TLS handshake complete");
}
return true;
}
bool
mongoc_secure_channel_handshake_step_3 (mongoc_stream_tls_t *tls,
char *hostname)
{
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
BSON_ASSERT (ssl_connect_3 == secure_channel->connecting_state);
TRACE ("SSL/TLS connection with %s (step 3/3)", hostname);
if (!secure_channel->cred) {
return false;
}
/* check if the required context attributes are met */
if (secure_channel->ret_flags != secure_channel->req_flags) {
MONGOC_ERROR ("Failed handshake");
return false;
}
secure_channel->connecting_state = ssl_connect_done;
return true;
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h
index ea6e6fa2..c5403837 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h
@@ -1,60 +1,63 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_SECURE_TRANSPORT_PRIVATE_H
#define MONGOC_SECURE_TRANSPORT_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-ssl.h"
#include "mongoc-stream-tls-secure-transport-private.h"
#include <Security/Security.h>
BSON_BEGIN_DECLS
char *
_mongoc_cfstringref_to_cstring (CFStringRef ref);
char *
_mongoc_secure_transport_extract_subject (const char *filename,
const char *passphrase);
OSStatus
mongoc_secure_transport_write (SSLConnectionRef connection,
const void *data,
size_t *data_length);
OSStatus
mongoc_secure_transport_read (SSLConnectionRef connection,
void *data,
size_t *data_length);
bool
mongoc_secure_transport_setup_ca (
mongoc_stream_tls_secure_transport_t *secure_transport,
mongoc_ssl_opt_t *opt);
bool
mongoc_secure_transport_setup_certificate (
mongoc_stream_tls_secure_transport_t *secure_transport,
mongoc_ssl_opt_t *opt);
+void
+CFReleaseSafe (CFTypeRef cf);
+
BSON_END_DECLS
#endif /* MONGOC_SECURE_TRANSPORT_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c
index a634d0dd..af41a1d7 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c
@@ -1,519 +1,528 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT
#include <bson/bson.h>
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-ssl.h"
#include "mongoc-stream-tls.h"
#include "mongoc-stream-tls-private.h"
#include "mongoc-secure-transport-private.h"
#include "mongoc-stream-tls-secure-transport-private.h"
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#include <Security/SecKey.h>
#include <Security/SecureTransport.h>
#include <CommonCrypto/CommonDigest.h>
#include <Security/Security.h>
#include <Security/SecureTransport.h>
#include <CoreFoundation/CoreFoundation.h>
/* Jailbreak Darwin Private API */
/*
* An alternative to using SecIdentityCreate is to use
* SecIdentityCreateWithCertificate with a temporary keychain. However, doing so
* leads to memory bugs. Unfortunately, using this private API seems to be the
* best solution.
*/
SecIdentityRef
SecIdentityCreate (CFAllocatorRef allocator,
SecCertificateRef certificate,
SecKeyRef privateKey);
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "stream-secure_transport"
char *
_mongoc_cfstringref_to_cstring (CFStringRef str)
{
CFIndex length;
CFStringEncoding encoding;
CFIndex max_size;
char *cs;
if (!str) {
return NULL;
}
if (CFGetTypeID (str) != CFStringGetTypeID ()) {
return NULL;
}
length = CFStringGetLength (str);
encoding = kCFStringEncodingASCII;
max_size = CFStringGetMaximumSizeForEncoding (length, encoding) + 1;
cs = bson_malloc ((size_t) max_size);
if (CFStringGetCString (str, cs, max_size, encoding)) {
return cs;
}
bson_free (cs);
return NULL;
}
static void
_bson_append_cftyperef (bson_string_t *retval, const char *label, CFTypeRef str)
{
char *cs;
if (str) {
cs = _mongoc_cfstringref_to_cstring (str);
if (cs) {
bson_string_append_printf (retval, "%s%s", label, cs);
bson_free (cs);
} else {
bson_string_append_printf (retval, "%s(null)", label);
}
}
}
CFTypeRef
_mongoc_secure_transport_dict_get (CFArrayRef values, CFStringRef label)
{
if (!values || CFGetTypeID (values) != CFArrayGetTypeID ()) {
return NULL;
}
for (CFIndex i = 0; i < CFArrayGetCount (values); ++i) {
CFStringRef item_label;
CFDictionaryRef item = CFArrayGetValueAtIndex (values, i);
if (CFGetTypeID (item) != CFDictionaryGetTypeID ()) {
continue;
}
item_label = CFDictionaryGetValue (item, kSecPropertyKeyLabel);
if (item_label &&
CFStringCompare (item_label, label, 0) == kCFCompareEqualTo) {
return CFDictionaryGetValue (item, kSecPropertyKeyValue);
}
}
return NULL;
}
char *
_mongoc_secure_transport_RFC2253_from_cert (SecCertificateRef cert)
{
CFTypeRef value;
bson_string_t *retval;
CFTypeRef subject_name;
CFDictionaryRef cert_dict;
cert_dict = SecCertificateCopyValues (cert, NULL, NULL);
if (!cert_dict) {
return NULL;
}
subject_name = CFDictionaryGetValue (cert_dict, kSecOIDX509V1SubjectName);
if (!subject_name) {
CFRelease (cert_dict);
return NULL;
}
subject_name = CFDictionaryGetValue (subject_name, kSecPropertyKeyValue);
if (!subject_name) {
CFRelease (cert_dict);
return NULL;
}
retval = bson_string_new ("");
;
value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDCountryName);
_bson_append_cftyperef (retval, "C=", value);
value = _mongoc_secure_transport_dict_get (subject_name,
kSecOIDStateProvinceName);
_bson_append_cftyperef (retval, ",ST=", value);
value =
_mongoc_secure_transport_dict_get (subject_name, kSecOIDLocalityName);
_bson_append_cftyperef (retval, ",L=", value);
value =
_mongoc_secure_transport_dict_get (subject_name, kSecOIDOrganizationName);
_bson_append_cftyperef (retval, ",O=", value);
value = _mongoc_secure_transport_dict_get (subject_name,
kSecOIDOrganizationalUnitName);
if (value) {
/* Can be either one unit name, or array of unit names */
if (CFGetTypeID (value) == CFStringGetTypeID ()) {
_bson_append_cftyperef (retval, ",OU=", value);
} else if (CFGetTypeID (value) == CFArrayGetTypeID ()) {
CFIndex len = CFArrayGetCount (value);
if (len > 0) {
_bson_append_cftyperef (
retval, ",OU=", CFArrayGetValueAtIndex (value, 0));
}
if (len > 1) {
_bson_append_cftyperef (
retval, ",", CFArrayGetValueAtIndex (value, 1));
}
if (len > 2) {
_bson_append_cftyperef (
retval, ",", CFArrayGetValueAtIndex (value, 2));
}
}
}
value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDCommonName);
_bson_append_cftyperef (retval, ",CN=", value);
value =
_mongoc_secure_transport_dict_get (subject_name, kSecOIDStreetAddress);
_bson_append_cftyperef (retval, ",STREET", value);
CFRelease (cert_dict);
return bson_string_free (retval, false);
}
static void
safe_release (CFTypeRef ref)
{
if (ref) {
CFRelease (ref);
}
}
bool
_mongoc_secure_transport_import_pem (const char *filename,
const char *passphrase,
CFArrayRef *items,
SecExternalItemType *type)
{
SecExternalFormat format = kSecFormatPEMSequence;
SecItemImportExportKeyParameters params = {0};
SecTransformRef sec_transform = NULL;
CFReadStreamRef read_stream = NULL;
CFDataRef dataref = NULL;
CFErrorRef error = NULL;
CFURLRef url = NULL;
OSStatus res;
bool r = false;
if (!filename) {
TRACE ("%s", "No certificate provided");
return false;
}
params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
params.flags = 0;
params.passphrase = NULL;
params.alertTitle = NULL;
params.alertPrompt = NULL;
params.accessRef = NULL;
params.keyUsage = NULL;
params.keyAttributes = NULL;
if (passphrase) {
params.passphrase = CFStringCreateWithCString (
kCFAllocatorDefault, passphrase, kCFStringEncodingUTF8);
}
url = CFURLCreateFromFileSystemRepresentation (
kCFAllocatorDefault, (const UInt8 *) filename, strlen (filename), false);
read_stream = CFReadStreamCreateWithFile (kCFAllocatorDefault, url);
if (!CFReadStreamOpen (read_stream)) {
MONGOC_ERROR ("Cannot find certificate in '%s', error reading file",
filename);
goto done;
}
sec_transform = SecTransformCreateReadTransformWithReadStream (read_stream);
dataref = SecTransformExecute (sec_transform, &error);
if (error) {
CFStringRef str = CFErrorCopyDescription (error);
MONGOC_ERROR (
"Failed importing PEM '%s': %s",
filename,
CFStringGetCStringPtr (str, CFStringGetFastestEncoding (str)));
CFRelease (str);
goto done;
}
res = SecItemImport (
dataref, CFSTR (".pem"), &format, type, 0, &params, NULL, items);
if (res) {
MONGOC_ERROR ("Failed importing PEM '%s' (code: %d)", filename, res);
goto done;
}
r = true;
done:
safe_release (dataref);
safe_release (sec_transform);
safe_release (read_stream);
safe_release (url);
safe_release (params.passphrase);
return r;
}
char *
_mongoc_secure_transport_extract_subject (const char *filename,
const char *passphrase)
{
bool success;
char *retval = NULL;
CFArrayRef items = NULL;
SecExternalItemType type = kSecItemTypeCertificate;
success =
_mongoc_secure_transport_import_pem (filename, passphrase, &items, &type);
if (!success) {
return NULL;
}
if (type == kSecItemTypeAggregate) {
for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) {
CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i));
if (item_id == SecCertificateGetTypeID ()) {
retval = _mongoc_secure_transport_RFC2253_from_cert (
(SecCertificateRef) CFArrayGetValueAtIndex (items, i));
break;
}
}
} else if (type == kSecItemTypeCertificate) {
retval =
_mongoc_secure_transport_RFC2253_from_cert ((SecCertificateRef) items);
}
if (items) {
CFRelease (items);
}
return retval;
}
bool
mongoc_secure_transport_setup_certificate (
mongoc_stream_tls_secure_transport_t *secure_transport,
mongoc_ssl_opt_t *opt)
{
bool success;
CFArrayRef items;
SecIdentityRef id;
SecKeyRef key = NULL;
SecCertificateRef cert = NULL;
SecExternalItemType type = kSecItemTypeCertificate;
if (!opt->pem_file) {
TRACE ("%s",
"No private key provided, the server won't be able to verify us");
return false;
}
success = _mongoc_secure_transport_import_pem (
opt->pem_file, opt->pem_pwd, &items, &type);
if (!success) {
/* caller will log an error */
return false;
}
if (type != kSecItemTypeAggregate) {
MONGOC_ERROR ("Cannot work with keys of type \"%d\". Please file a JIRA",
type);
CFRelease (items);
return false;
}
for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) {
CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i));
if (item_id == SecCertificateGetTypeID ()) {
cert = (SecCertificateRef) CFArrayGetValueAtIndex (items, i);
} else if (item_id == SecKeyGetTypeID ()) {
key = (SecKeyRef) CFArrayGetValueAtIndex (items, i);
}
}
if (!cert || !key) {
MONGOC_ERROR ("Couldn't find valid private key");
CFRelease (items);
return false;
}
id = SecIdentityCreate (kCFAllocatorDefault, cert, key);
secure_transport->my_cert =
CFArrayCreateMutable (kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks);
CFArrayAppendValue (secure_transport->my_cert, id);
CFArrayAppendValue (secure_transport->my_cert, cert);
CFRelease (id);
/*
* Secure Transport assumes the following:
* * The certificate references remain valid for the lifetime of the
* session.
* * The identity specified in certRefs[0] is capable of signing.
*/
success = !SSLSetCertificate (secure_transport->ssl_ctx_ref,
secure_transport->my_cert);
TRACE ("Setting client certificate %s", success ? "succeeded" : "failed");
CFRelease (items);
return true;
}
bool
mongoc_secure_transport_setup_ca (
mongoc_stream_tls_secure_transport_t *secure_transport,
mongoc_ssl_opt_t *opt)
{
CFArrayRef items;
SecExternalItemType type = kSecItemTypeCertificate;
bool success;
if (!opt->ca_file) {
TRACE ("%s", "No CA provided, using defaults");
return false;
}
success =
_mongoc_secure_transport_import_pem (opt->ca_file, NULL, &items, &type);
if (!success) {
MONGOC_ERROR ("Cannot load Certificate Authorities from file \'%s\'",
opt->ca_file);
return false;
}
if (type == kSecItemTypeAggregate) {
CFMutableArrayRef anchors =
CFArrayCreateMutable (kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) {
CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i));
if (item_id == SecCertificateGetTypeID ()) {
CFArrayAppendValue (anchors, CFArrayGetValueAtIndex (items, i));
}
}
secure_transport->anchors = anchors;
CFRelease (items);
} else if (type == kSecItemTypeCertificate) {
secure_transport->anchors = items;
} else {
CFRelease (items);
}
/* This should be SSLSetCertificateAuthorities But the /TLS/ tests fail
* when it is */
success = !SSLSetTrustedRoots (
secure_transport->ssl_ctx_ref, secure_transport->anchors, true);
TRACE ("Setting certificate authority %s (%s)",
success ? "succeeded" : "failed",
opt->ca_file);
return true;
}
OSStatus
mongoc_secure_transport_read (SSLConnectionRef connection,
void *data,
size_t *data_length)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) connection;
ssize_t length;
ENTRY;
errno = 0;
/* 4 arguments is *min_bytes* -- This is not a negotiation.
* Secure Transport wants all or nothing. We must continue reading until
* we get this amount, or timeout */
length = mongoc_stream_read (
tls->base_stream, data, *data_length, *data_length, tls->timeout_msec);
if (length > 0) {
*data_length = length;
RETURN (noErr);
}
if (length == 0) {
RETURN (errSSLClosedGraceful);
}
switch (errno) {
case ENOENT:
RETURN (errSSLClosedGraceful);
break;
case ECONNRESET:
RETURN (errSSLClosedAbort);
break;
case EAGAIN:
RETURN (errSSLWouldBlock);
break;
default:
RETURN (-36); /* ioErr */
break;
}
}
OSStatus
mongoc_secure_transport_write (SSLConnectionRef connection,
const void *data,
size_t *data_length)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) connection;
ssize_t length;
ENTRY;
errno = 0;
length = mongoc_stream_write (
tls->base_stream, (void *) data, *data_length, tls->timeout_msec);
if (length >= 0) {
*data_length = length;
RETURN (noErr);
}
switch (errno) {
case EAGAIN:
RETURN (errSSLWouldBlock);
default:
RETURN (-36); /* ioErr */
}
}
+
+void
+CFReleaseSafe (CFTypeRef cf)
+{
+ if (cf != NULL) {
+ CFRelease (cf);
+ }
+}
+
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
similarity index 76%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
index c544382f..7d3a01f8 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
@@ -1,150 +1,184 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_SERVER_DESCRIPTION_PRIVATE_H
#define MONGOC_SERVER_DESCRIPTION_PRIVATE_H
#include "mongoc-server-description.h"
#define MONGOC_DEFAULT_WIRE_VERSION 0
#define MONGOC_DEFAULT_WRITE_BATCH_SIZE 1000
#define MONGOC_DEFAULT_BSON_OBJ_SIZE 16 * 1024 * 1024
#define MONGOC_DEFAULT_MAX_MSG_SIZE 48000000
/* This is slightly out-of-spec as of the current version of the spec (1.0.0),
* but SPEC-1397 plans to amend "Size limits and Wire Protocol Considerations"
* to say that drivers MAY split with a reduced maxBsonObjectSize or
* maxMessageSizeBytes
* depending on the implementation. It is less invasive for libmongoc to split
* OP_MSG payload type 1 with a reduced maxMessageSizeBytes and convert it to a
* payload type 0
* rather than split a payload type 0 with a reduced maxBsonObjectSize.
*/
#define MONGOC_REDUCED_MAX_MSG_SIZE_FOR_FLE 2097152
#define MONGOC_NO_SESSIONS -1
#define MONGOC_IDLE_WRITE_PERIOD_MS 10 * 1000
/* represent a server or topology with no replica set config version */
#define MONGOC_NO_SET_VERSION -1
+#define MONGOC_RTT_UNSET -1
+
typedef enum {
MONGOC_SERVER_UNKNOWN,
MONGOC_SERVER_STANDALONE,
MONGOC_SERVER_MONGOS,
MONGOC_SERVER_POSSIBLE_PRIMARY,
MONGOC_SERVER_RS_PRIMARY,
MONGOC_SERVER_RS_SECONDARY,
MONGOC_SERVER_RS_ARBITER,
MONGOC_SERVER_RS_OTHER,
MONGOC_SERVER_RS_GHOST,
MONGOC_SERVER_DESCRIPTION_TYPES,
} mongoc_server_description_type_t;
struct _mongoc_server_description_t {
uint32_t id;
mongoc_host_list_t host;
int64_t round_trip_time_msec;
int64_t last_update_time_usec;
bson_t last_is_master;
bool has_is_master;
const char *connection_address;
+ /* SDAM dictates storing me/hosts/passives/arbiters after being "normalized
+ * to lower-case" Instead, they are stored in the casing they are received,
+ * but compared case insensitively. This should be addressed in CDRIVER-3527.
+ */
const char *me;
/* whether an APM server-opened callback has been fired before */
bool opened;
const char *set_name;
bson_error_t error;
mongoc_server_description_type_t type;
int32_t min_wire_version;
int32_t max_wire_version;
int32_t max_msg_size;
int32_t max_bson_obj_size;
int32_t max_write_batch_size;
int64_t session_timeout_minutes;
+ /* hosts, passives, and arbiters are stored as a BSON array, but compared
+ * case insensitively. This should be improved in CDRIVER-3527. */
bson_t hosts;
bson_t passives;
bson_t arbiters;
bson_t tags;
const char *current_primary;
int64_t set_version;
bson_oid_t election_id;
int64_t last_write_date_ms;
bson_t compressors;
+ bson_t topology_version;
+ /*
+ The generation is incremented every time connections to this server should be
+ invalidated.
+ This happens when:
+ 1. a monitor receives a network error
+ 2. an app thread receives any network error before completing a handshake
+ 3. an app thread receives a non-timeout network error after the handshake
+ 4. an app thread receives a "not master" or "node is recovering" error from a
+ pre-4.2 server.
+ */
+ uint32_t generation;
};
void
mongoc_server_description_init (mongoc_server_description_t *sd,
const char *address,
uint32_t id);
bool
mongoc_server_description_has_rs_member (
mongoc_server_description_t *description, const char *address);
bool
mongoc_server_description_has_set_version (
mongoc_server_description_t *description);
bool
mongoc_server_description_has_election_id (
mongoc_server_description_t *description);
void
mongoc_server_description_cleanup (mongoc_server_description_t *sd);
void
mongoc_server_description_reset (mongoc_server_description_t *sd);
void
mongoc_server_description_set_state (mongoc_server_description_t *description,
mongoc_server_description_type_t type);
void
mongoc_server_description_set_set_version (
mongoc_server_description_t *description, int64_t set_version);
void
mongoc_server_description_set_election_id (
mongoc_server_description_t *description, const bson_oid_t *election_id);
void
mongoc_server_description_update_rtt (mongoc_server_description_t *server,
int64_t rtt_msec);
void
mongoc_server_description_handle_ismaster (mongoc_server_description_t *sd,
const bson_t *reply,
int64_t rtt_msec,
const bson_error_t *error /* IN */);
void
mongoc_server_description_filter_stale (mongoc_server_description_t **sds,
size_t sds_len,
mongoc_server_description_t *primary,
int64_t heartbeat_frequency_ms,
const mongoc_read_prefs_t *read_prefs);
void
mongoc_server_description_filter_tags (
mongoc_server_description_t **descriptions,
size_t description_len,
const mongoc_read_prefs_t *read_prefs);
+/* Compares server descriptions following the "Server Description Equality"
+ * rules. Not all fields are considered. */
+bool
+_mongoc_server_description_equal (mongoc_server_description_t *sd1,
+ mongoc_server_description_t *sd2);
+
+int
+mongoc_server_description_topology_version_cmp (const bson_t *tv1,
+ const bson_t *tv2);
+
+void
+mongoc_server_description_set_topology_version (mongoc_server_description_t *sd,
+ const bson_t *tv);
+
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
similarity index 84%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
index cbbf743f..da15fc4b 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
@@ -1,1007 +1,1206 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-config.h"
#include "mongoc-host-list.h"
#include "mongoc-host-list-private.h"
#include "mongoc-read-prefs.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-server-description-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-uri.h"
#include "mongoc-util-private.h"
#include "mongoc-compression-private.h"
#include <stdio.h>
#define ALPHA 0.2
static bson_oid_t kObjectIdZero = {{0}};
static bool
_match_tag_set (const mongoc_server_description_t *sd,
bson_iter_t *tag_set_iter);
/* Destroy allocated resources within @description, but don't free it */
void
mongoc_server_description_cleanup (mongoc_server_description_t *sd)
{
BSON_ASSERT (sd);
bson_destroy (&sd->last_is_master);
bson_destroy (&sd->hosts);
bson_destroy (&sd->passives);
bson_destroy (&sd->arbiters);
bson_destroy (&sd->tags);
bson_destroy (&sd->compressors);
+ bson_destroy (&sd->topology_version);
}
-/* Reset fields inside this sd, but keep same id, host information, and RTT,
- and leave ismaster in empty inited state */
+/* Reset fields inside this sd, but keep same id, host information, RTT,
+ generation, topology version, and leave ismaster in empty inited state */
void
mongoc_server_description_reset (mongoc_server_description_t *sd)
{
BSON_ASSERT (sd);
memset (&sd->error, 0, sizeof sd->error);
sd->set_name = NULL;
sd->type = MONGOC_SERVER_UNKNOWN;
sd->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION;
sd->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION;
sd->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE;
sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE;
sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE;
sd->session_timeout_minutes = MONGOC_NO_SESSIONS;
sd->last_write_date_ms = -1;
/* always leave last ismaster in an init-ed state until we destroy sd */
bson_destroy (&sd->last_is_master);
bson_init (&sd->last_is_master);
sd->has_is_master = false;
sd->last_update_time_usec = bson_get_monotonic_time ();
bson_destroy (&sd->hosts);
bson_destroy (&sd->passives);
bson_destroy (&sd->arbiters);
bson_destroy (&sd->tags);
bson_destroy (&sd->compressors);
bson_init (&sd->hosts);
bson_init (&sd->passives);
bson_init (&sd->arbiters);
bson_init (&sd->tags);
bson_init (&sd->compressors);
sd->me = NULL;
sd->current_primary = NULL;
sd->set_version = MONGOC_NO_SET_VERSION;
bson_oid_copy_unsafe (&kObjectIdZero, &sd->election_id);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_init --
*
* Initialize a new server_description_t.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_init (mongoc_server_description_t *sd,
const char *address,
uint32_t id)
{
ENTRY;
BSON_ASSERT (sd);
BSON_ASSERT (address);
sd->id = id;
sd->type = MONGOC_SERVER_UNKNOWN;
- sd->round_trip_time_msec = -1;
+ sd->round_trip_time_msec = MONGOC_RTT_UNSET;
if (!_mongoc_host_list_from_string (&sd->host, address)) {
MONGOC_WARNING ("Failed to parse uri for %s", address);
return;
}
sd->connection_address = sd->host.host_and_port;
bson_init (&sd->last_is_master);
bson_init (&sd->hosts);
bson_init (&sd->passives);
bson_init (&sd->arbiters);
bson_init (&sd->tags);
bson_init (&sd->compressors);
+ bson_init (&sd->topology_version);
mongoc_server_description_reset (sd);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_destroy --
*
* Destroy allocated resources within @description and free
* @description.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_destroy (mongoc_server_description_t *description)
{
ENTRY;
if (!description) {
EXIT;
}
mongoc_server_description_cleanup (description);
bson_free (description);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_has_rs_member --
*
* Return true if this address is included in server's list of rs
* members, false otherwise.
*
* Returns:
* true, false
*
* Side effects:
* None
*
*--------------------------------------------------------------------------
*/
bool
mongoc_server_description_has_rs_member (mongoc_server_description_t *server,
const char *address)
{
bson_iter_t member_iter;
const bson_t *rs_members[3];
int i;
if (server->type != MONGOC_SERVER_UNKNOWN) {
rs_members[0] = &server->hosts;
rs_members[1] = &server->arbiters;
rs_members[2] = &server->passives;
for (i = 0; i < 3; i++) {
BSON_ASSERT (bson_iter_init (&member_iter, rs_members[i]));
while (bson_iter_next (&member_iter)) {
if (strcasecmp (address, bson_iter_utf8 (&member_iter, NULL)) ==
0) {
return true;
}
}
}
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_has_set_version --
*
* Did this server's ismaster response have a "setVersion" field?
*
* Returns:
* True if the server description's setVersion is set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_server_description_has_set_version (
mongoc_server_description_t *description)
{
return description->set_version != MONGOC_NO_SET_VERSION;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_has_election_id --
*
* Did this server's ismaster response have an "electionId" field?
*
* Returns:
* True if the server description's electionId is set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_server_description_has_election_id (
mongoc_server_description_t *description)
{
return 0 != bson_oid_compare (&description->election_id, &kObjectIdZero);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_id --
*
* Get the id of this server.
*
* Returns:
* Server's id.
*
*--------------------------------------------------------------------------
*/
uint32_t
mongoc_server_description_id (const mongoc_server_description_t *description)
{
return description->id;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_host --
*
* Return a reference to the host associated with this server description.
*
* Returns:
* This server description's host, a mongoc_host_list_t * you must
* not modify or free.
*
*--------------------------------------------------------------------------
*/
mongoc_host_list_t *
mongoc_server_description_host (const mongoc_server_description_t *description)
{
return &((mongoc_server_description_t *) description)->host;
}
int64_t
mongoc_server_description_last_update_time (
const mongoc_server_description_t *description)
{
return description->last_update_time_usec;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_round_trip_time --
*
* Get the round trip time of this server, which is the client's
* measurement of the duration of an "ismaster" command.
*
* Returns:
* The server's round trip time in milliseconds.
*
*--------------------------------------------------------------------------
*/
int64_t
mongoc_server_description_round_trip_time (
const mongoc_server_description_t *description)
{
return description->round_trip_time_msec;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_type --
*
* Get this server's type, one of the types defined in the Server
* Discovery And Monitoring Spec.
*
* Returns:
* A string.
*
*--------------------------------------------------------------------------
*/
const char *
mongoc_server_description_type (const mongoc_server_description_t *description)
{
switch (description->type) {
case MONGOC_SERVER_UNKNOWN:
return "Unknown";
case MONGOC_SERVER_STANDALONE:
return "Standalone";
case MONGOC_SERVER_MONGOS:
return "Mongos";
case MONGOC_SERVER_POSSIBLE_PRIMARY:
return "PossiblePrimary";
case MONGOC_SERVER_RS_PRIMARY:
return "RSPrimary";
case MONGOC_SERVER_RS_SECONDARY:
return "RSSecondary";
case MONGOC_SERVER_RS_ARBITER:
return "RSArbiter";
case MONGOC_SERVER_RS_OTHER:
return "RSOther";
case MONGOC_SERVER_RS_GHOST:
return "RSGhost";
case MONGOC_SERVER_DESCRIPTION_TYPES:
default:
MONGOC_ERROR ("Invalid mongoc_server_description_t type");
return "Invalid";
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_ismaster --
*
* Return this server's most recent "ismaster" command response.
*
* Returns:
* A reference to a BSON document, owned by the server description.
*
*--------------------------------------------------------------------------
*/
const bson_t *
mongoc_server_description_ismaster (
const mongoc_server_description_t *description)
{
return &description->last_is_master;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_set_state --
*
* Set the server description's server type.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_set_state (mongoc_server_description_t *description,
mongoc_server_description_type_t type)
{
description->type = type;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_set_set_version --
*
* Set the replica set version of this server.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_set_set_version (
mongoc_server_description_t *description, int64_t set_version)
{
description->set_version = set_version;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_set_election_id --
*
* Set the election_id of this server. Copies the given ObjectId or,
* if it is NULL, zeroes description's election_id.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_set_election_id (
mongoc_server_description_t *description, const bson_oid_t *election_id)
{
if (election_id) {
bson_oid_copy_unsafe (election_id, &description->election_id);
} else {
bson_oid_copy_unsafe (&kObjectIdZero, &description->election_id);
}
}
/*
*-------------------------------------------------------------------------
*
* mongoc_server_description_update_rtt --
*
* Calculate this server's rtt calculation using an exponentially-
* weighted moving average formula.
*
* Side effects:
* None.
*
+ * If rtt_msec is MONGOC_RTT_UNSET, the value is not updated.
+ *
*-------------------------------------------------------------------------
*/
void
mongoc_server_description_update_rtt (mongoc_server_description_t *server,
int64_t rtt_msec)
{
- if (server->round_trip_time_msec == -1) {
+ if (rtt_msec == MONGOC_RTT_UNSET) {
+ return;
+ }
+ if (server->round_trip_time_msec == MONGOC_RTT_UNSET) {
server->round_trip_time_msec = rtt_msec;
} else {
server->round_trip_time_msec = (int64_t) (
ALPHA * rtt_msec + (1 - ALPHA) * server->round_trip_time_msec);
}
}
static void
_mongoc_server_description_set_error (mongoc_server_description_t *sd,
const bson_error_t *error)
{
if (error && error->code) {
memcpy (&sd->error, error, sizeof (bson_error_t));
} else {
bson_set_error (&sd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"unknown error calling ismaster");
}
/* Server Discovery and Monitoring Spec: if the server type changes from a
* known type to Unknown its RTT is set to null. */
- sd->round_trip_time_msec = -1;
+ sd->round_trip_time_msec = MONGOC_RTT_UNSET;
}
/*
*-------------------------------------------------------------------------
*
* Called during SDAM, from topology description's ismaster handler, or
* when handshaking a connection in _mongoc_cluster_stream_for_server.
*
* If @ismaster_response is empty, @error must say why ismaster failed.
*
*-------------------------------------------------------------------------
*/
void
mongoc_server_description_handle_ismaster (mongoc_server_description_t *sd,
const bson_t *ismaster_response,
int64_t rtt_msec,
const bson_error_t *error /* IN */)
{
bson_iter_t iter;
bson_iter_t child;
bool is_master = false;
bool is_shard = false;
bool is_secondary = false;
bool is_arbiter = false;
bool is_replicaset = false;
bool is_hidden = false;
const uint8_t *bytes;
uint32_t len;
int num_keys = 0;
ENTRY;
BSON_ASSERT (sd);
mongoc_server_description_reset (sd);
if (!ismaster_response) {
_mongoc_server_description_set_error (sd, error);
EXIT;
}
bson_destroy (&sd->last_is_master);
- bson_copy_to (ismaster_response, &sd->last_is_master);
+ bson_init (&sd->last_is_master);
+ bson_copy_to_excluding_noinit (
+ ismaster_response, &sd->last_is_master, "speculativeAuthenticate", NULL);
sd->has_is_master = true;
+ /* Only reinitialize the topology version if we have an ismaster response.
+ * Resetting a server description should not effect the topology version. */
+ bson_reinit (&sd->topology_version);
+
BSON_ASSERT (bson_iter_init (&iter, &sd->last_is_master));
while (bson_iter_next (&iter)) {
num_keys++;
if (strcmp ("ok", bson_iter_key (&iter)) == 0) {
if (!bson_iter_as_bool (&iter)) {
/* it doesn't really matter what error API we use. the code and
* domain will be overwritten. */
(void) _mongoc_cmd_check_ok (
ismaster_response, MONGOC_ERROR_API_VERSION_2, &sd->error);
+ /* TODO CDRIVER-3696: this is an existing bug. If this is handling
+ * an ismaster reply that is NOT from a handshake, this should not
+ * be considered an auth error. */
/* ismaster response returned ok: 0. According to auth spec: "If the
* isMaster of the MongoDB Handshake fails with an error, drivers
* MUST treat this an authentication error." */
sd->error.domain = MONGOC_ERROR_CLIENT;
sd->error.code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
goto failure;
}
} else if (strcmp ("ismaster", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
is_master = bson_iter_bool (&iter);
} else if (strcmp ("me", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_UTF8 (&iter))
goto failure;
sd->me = bson_iter_utf8 (&iter, NULL);
} else if (strcmp ("maxMessageSizeBytes", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->max_msg_size = bson_iter_int32 (&iter);
} else if (strcmp ("maxBsonObjectSize", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->max_bson_obj_size = bson_iter_int32 (&iter);
} else if (strcmp ("maxWriteBatchSize", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->max_write_batch_size = bson_iter_int32 (&iter);
} else if (strcmp ("logicalSessionTimeoutMinutes",
bson_iter_key (&iter)) == 0) {
if (BSON_ITER_HOLDS_NUMBER (&iter)) {
sd->session_timeout_minutes = bson_iter_as_int64 (&iter);
} else if (BSON_ITER_HOLDS_NULL (&iter)) {
/* this arises executing standard JSON tests */
sd->session_timeout_minutes = MONGOC_NO_SESSIONS;
} else {
goto failure;
}
} else if (strcmp ("minWireVersion", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->min_wire_version = bson_iter_int32 (&iter);
} else if (strcmp ("maxWireVersion", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->max_wire_version = bson_iter_int32 (&iter);
} else if (strcmp ("msg", bson_iter_key (&iter)) == 0) {
+ const char *msg;
if (!BSON_ITER_HOLDS_UTF8 (&iter))
goto failure;
- is_shard = !!bson_iter_utf8 (&iter, NULL);
+ msg = bson_iter_utf8 (&iter, NULL);
+ if (msg && 0 == strcmp (msg, "isdbgrid")) {
+ is_shard = true;
+ }
} else if (strcmp ("setName", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_UTF8 (&iter))
goto failure;
sd->set_name = bson_iter_utf8 (&iter, NULL);
} else if (strcmp ("setVersion", bson_iter_key (&iter)) == 0) {
mongoc_server_description_set_set_version (sd,
bson_iter_as_int64 (&iter));
} else if (strcmp ("electionId", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_OID (&iter))
goto failure;
mongoc_server_description_set_election_id (sd, bson_iter_oid (&iter));
} else if (strcmp ("secondary", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
is_secondary = bson_iter_bool (&iter);
} else if (strcmp ("hosts", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_ARRAY (&iter))
goto failure;
bson_iter_array (&iter, &len, &bytes);
bson_destroy (&sd->hosts);
BSON_ASSERT (bson_init_static (&sd->hosts, bytes, len));
} else if (strcmp ("passives", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_ARRAY (&iter))
goto failure;
bson_iter_array (&iter, &len, &bytes);
bson_destroy (&sd->passives);
BSON_ASSERT (bson_init_static (&sd->passives, bytes, len));
} else if (strcmp ("arbiters", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_ARRAY (&iter))
goto failure;
bson_iter_array (&iter, &len, &bytes);
bson_destroy (&sd->arbiters);
BSON_ASSERT (bson_init_static (&sd->arbiters, bytes, len));
} else if (strcmp ("primary", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_UTF8 (&iter))
goto failure;
sd->current_primary = bson_iter_utf8 (&iter, NULL);
} else if (strcmp ("arbiterOnly", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
is_arbiter = bson_iter_bool (&iter);
} else if (strcmp ("isreplicaset", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
is_replicaset = bson_iter_bool (&iter);
} else if (strcmp ("tags", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_DOCUMENT (&iter))
goto failure;
bson_iter_document (&iter, &len, &bytes);
bson_destroy (&sd->tags);
BSON_ASSERT (bson_init_static (&sd->tags, bytes, len));
} else if (strcmp ("hidden", bson_iter_key (&iter)) == 0) {
is_hidden = bson_iter_bool (&iter);
} else if (strcmp ("lastWrite", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_DOCUMENT (&iter) ||
!bson_iter_recurse (&iter, &child) ||
!bson_iter_find (&child, "lastWriteDate") ||
!BSON_ITER_HOLDS_DATE_TIME (&child)) {
goto failure;
}
sd->last_write_date_ms = bson_iter_date_time (&child);
- } else if (strcmp ("idleWritePeriodMillis", bson_iter_key (&iter)) == 0) {
- sd->last_write_date_ms = bson_iter_as_int64 (&iter);
} else if (strcmp ("compression", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_ARRAY (&iter))
goto failure;
bson_iter_array (&iter, &len, &bytes);
bson_destroy (&sd->compressors);
BSON_ASSERT (bson_init_static (&sd->compressors, bytes, len));
+ } else if (strcmp ("topologyVersion", bson_iter_key (&iter)) == 0) {
+ bson_t incoming_topology_version;
+
+ if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ goto failure;
+ }
+
+ bson_iter_document (&iter, &len, &bytes);
+ bson_init_static (&incoming_topology_version, bytes, len);
+ mongoc_server_description_set_topology_version (
+ sd, &incoming_topology_version);
+ bson_destroy (&incoming_topology_version);
}
}
if (is_shard) {
sd->type = MONGOC_SERVER_MONGOS;
} else if (sd->set_name) {
if (is_hidden) {
sd->type = MONGOC_SERVER_RS_OTHER;
} else if (is_master) {
sd->type = MONGOC_SERVER_RS_PRIMARY;
} else if (is_secondary) {
sd->type = MONGOC_SERVER_RS_SECONDARY;
} else if (is_arbiter) {
sd->type = MONGOC_SERVER_RS_ARBITER;
} else {
sd->type = MONGOC_SERVER_RS_OTHER;
}
} else if (is_replicaset) {
sd->type = MONGOC_SERVER_RS_GHOST;
} else if (num_keys > 0) {
sd->type = MONGOC_SERVER_STANDALONE;
} else {
sd->type = MONGOC_SERVER_UNKNOWN;
}
if (!num_keys) {
/* empty reply means ismaster failed */
_mongoc_server_description_set_error (sd, error);
}
mongoc_server_description_update_rtt (sd, rtt_msec);
EXIT;
failure:
sd->type = MONGOC_SERVER_UNKNOWN;
- sd->round_trip_time_msec = -1;
+ sd->round_trip_time_msec = MONGOC_RTT_UNSET;
EXIT;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_server_description_new_copy --
*
* A copy of a server description that you must destroy, or NULL.
*
*-------------------------------------------------------------------------
*/
mongoc_server_description_t *
mongoc_server_description_new_copy (
const mongoc_server_description_t *description)
{
mongoc_server_description_t *copy;
if (!description) {
return NULL;
}
copy = (mongoc_server_description_t *) bson_malloc0 (sizeof (*copy));
copy->id = description->id;
copy->opened = description->opened;
memcpy (&copy->host, &description->host, sizeof (copy->host));
- copy->round_trip_time_msec = -1;
+ copy->round_trip_time_msec = MONGOC_RTT_UNSET;
copy->connection_address = copy->host.host_and_port;
bson_init (&copy->last_is_master);
bson_init (&copy->hosts);
bson_init (&copy->passives);
bson_init (&copy->arbiters);
bson_init (&copy->tags);
bson_init (&copy->compressors);
+ bson_copy_to (&description->topology_version, &copy->topology_version);
if (description->has_is_master) {
/* calls mongoc_server_description_reset */
mongoc_server_description_handle_ismaster (
copy,
&description->last_is_master,
description->round_trip_time_msec,
&description->error);
} else {
mongoc_server_description_reset (copy);
}
/* Preserve the error */
memcpy (&copy->error, &description->error, sizeof copy->error);
+
+ copy->generation = description->generation;
return copy;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_server_description_filter_stale --
*
* Estimate servers' staleness according to the Server Selection Spec.
* Determines the number of eligible servers, and sets any servers that
* are too stale to NULL in the descriptions set.
*
*-------------------------------------------------------------------------
*/
void
mongoc_server_description_filter_stale (mongoc_server_description_t **sds,
size_t sds_len,
mongoc_server_description_t *primary,
int64_t heartbeat_frequency_ms,
const mongoc_read_prefs_t *read_prefs)
{
int64_t max_staleness_seconds;
size_t i;
int64_t heartbeat_frequency_usec;
int64_t max_last_write_date_usec;
int64_t staleness_usec;
int64_t max_staleness_usec;
if (!read_prefs) {
/* NULL read_prefs is PRIMARY, no maxStalenessSeconds to filter by */
return;
}
max_staleness_seconds =
mongoc_read_prefs_get_max_staleness_seconds (read_prefs);
if (max_staleness_seconds == MONGOC_NO_MAX_STALENESS) {
return;
}
BSON_ASSERT (max_staleness_seconds > 0);
max_staleness_usec = max_staleness_seconds * 1000 * 1000;
heartbeat_frequency_usec = heartbeat_frequency_ms * 1000;
if (primary) {
for (i = 0; i < sds_len; i++) {
if (!sds[i] || sds[i]->type != MONGOC_SERVER_RS_SECONDARY) {
continue;
}
/* See max-staleness.rst for explanation of these formulae. */
staleness_usec =
primary->last_write_date_ms * 1000 +
(sds[i]->last_update_time_usec - primary->last_update_time_usec) -
sds[i]->last_write_date_ms * 1000 + heartbeat_frequency_usec;
if (staleness_usec > max_staleness_usec) {
TRACE ("Rejected stale RSSecondary [%s]",
sds[i]->host.host_and_port);
sds[i] = NULL;
}
}
} else {
/* find max last_write_date */
max_last_write_date_usec = 0;
for (i = 0; i < sds_len; i++) {
if (sds[i] && sds[i]->type == MONGOC_SERVER_RS_SECONDARY) {
max_last_write_date_usec = BSON_MAX (
max_last_write_date_usec, sds[i]->last_write_date_ms * 1000);
}
}
/* use max last_write_date to estimate each secondary's staleness */
for (i = 0; i < sds_len; i++) {
if (!sds[i] || sds[i]->type != MONGOC_SERVER_RS_SECONDARY) {
continue;
}
staleness_usec = max_last_write_date_usec -
sds[i]->last_write_date_ms * 1000 +
heartbeat_frequency_usec;
if (staleness_usec > max_staleness_usec) {
TRACE ("Rejected stale RSSecondary [%s]",
sds[i]->host.host_and_port);
sds[i] = NULL;
}
}
}
}
/*
*-------------------------------------------------------------------------
*
* mongoc_server_description_filter_tags --
*
* Given a set of server descriptions, set to NULL any that don't
* match the read preference's tag sets.
*
* https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#tag-set
*
*-------------------------------------------------------------------------
*/
void
mongoc_server_description_filter_tags (
mongoc_server_description_t **descriptions,
size_t description_len,
const mongoc_read_prefs_t *read_prefs)
{
const bson_t *rp_tags;
bson_iter_t rp_tagset_iter;
bson_iter_t tag_set_iter;
bool *sd_matched = NULL;
bool found;
size_t i;
if (!read_prefs) {
/* NULL read_prefs is PRIMARY, no tags to filter by */
return;
}
rp_tags = mongoc_read_prefs_get_tags (read_prefs);
if (bson_count_keys (rp_tags) == 0) {
/* no tags to filter by */
return;
}
sd_matched = (bool *) bson_malloc0 (sizeof (bool) * description_len);
bson_iter_init (&rp_tagset_iter, rp_tags);
/* for each read preference tag set */
while (bson_iter_next (&rp_tagset_iter)) {
found = false;
for (i = 0; i < description_len; i++) {
if (!descriptions[i]) {
/* NULLed earlier in mongoc_topology_description_suitable_servers */
continue;
}
BSON_ASSERT (bson_iter_recurse (&rp_tagset_iter, &tag_set_iter));
sd_matched[i] = _match_tag_set (descriptions[i], &tag_set_iter);
if (sd_matched[i]) {
found = true;
}
}
if (found) {
for (i = 0; i < description_len; i++) {
if (!sd_matched[i] && descriptions[i]) {
TRACE ("Rejected [%s] [%s], doesn't match tags",
mongoc_server_description_type (descriptions[i]),
descriptions[i]->host.host_and_port);
descriptions[i] = NULL;
}
}
goto CLEANUP;
}
}
/* tried each */
for (i = 0; i < description_len; i++) {
if (!sd_matched[i]) {
TRACE ("Rejected [%s] [%s], reached end of tags array without match",
mongoc_server_description_type (descriptions[i]),
descriptions[i]->host.host_and_port);
descriptions[i] = NULL;
}
}
CLEANUP:
bson_free (sd_matched);
}
/*
*-------------------------------------------------------------------------
*
* _match_tag_set --
*
* Check if a server's tags match one tag set, like
* {'tag1': 'value1', 'tag2': 'value2'}.
*
*-------------------------------------------------------------------------
*/
static bool
_match_tag_set (const mongoc_server_description_t *sd,
bson_iter_t *tag_set_iter)
{
bson_iter_t sd_iter;
uint32_t read_pref_tag_len;
uint32_t sd_len;
const char *read_pref_tag;
const char *read_pref_val;
const char *server_val;
while (bson_iter_next (tag_set_iter)) {
/* one {'tag': 'value'} pair from the read preference's tag set */
read_pref_tag = bson_iter_key (tag_set_iter);
read_pref_val = bson_iter_utf8 (tag_set_iter, &read_pref_tag_len);
if (bson_iter_init_find (&sd_iter, &sd->tags, read_pref_tag)) {
/* The server has this tag - does it have the right value? */
server_val = bson_iter_utf8 (&sd_iter, &sd_len);
if (sd_len != read_pref_tag_len ||
memcmp (read_pref_val, server_val, read_pref_tag_len)) {
/* If the values don't match, no match */
return false;
}
} else {
/* If the server description doesn't have that key, no match */
return false;
}
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_compressor_id --
*
* Get the compressor id if compression was negotiated.
*
* Returns:
* The compressor ID, or -1 if none was negotiated.
*
*--------------------------------------------------------------------------
*/
int32_t
mongoc_server_description_compressor_id (
const mongoc_server_description_t *description)
{
int id;
bson_iter_t iter;
BSON_ASSERT (bson_iter_init (&iter, &description->compressors));
while (bson_iter_next (&iter)) {
id = mongoc_compressor_name_to_id (bson_iter_utf8 (&iter, NULL));
if (id != -1) {
return id;
}
}
return -1;
}
+
+/* Returns true if either or both is NULL. out is 1 if exactly one NULL, 0 if
+ * both NULL */
+typedef int (*strcmp_fn) (const char *, const char *);
+
+static int
+_nullable_cmp (const char *a, const char *b, strcmp_fn cmp_fn)
+{
+ if (!a && b) {
+ return 1;
+ }
+
+ if (a && !b) {
+ return 1;
+ }
+
+ if (!a && !b) {
+ return 0;
+ }
+
+ /* Both not NULL. */
+ return cmp_fn (a, b);
+}
+static int
+_nullable_strcasecmp (const char *a, const char *b)
+{
+ return _nullable_cmp (a, b, strcasecmp);
+}
+
+static int
+_nullable_strcmp (const char *a, const char *b)
+{
+ return _nullable_cmp (a, b, strcmp);
+}
+
+bool
+_mongoc_server_description_equal (mongoc_server_description_t *sd1,
+ mongoc_server_description_t *sd2)
+{
+ if (sd1->type != sd2->type) {
+ return false;
+ }
+
+ if (sd1->min_wire_version != sd2->min_wire_version) {
+ return false;
+ }
+
+ if (sd1->max_wire_version != sd2->max_wire_version) {
+ return false;
+ }
+
+ if (0 != _nullable_strcasecmp (sd1->me, sd2->me)) {
+ return false;
+ }
+
+ /* CDRIVER-3527: The hosts/passives/arbiters checks should really be a set
+ * comparison of case insensitive hostnames. */
+ if (!bson_equal (&sd1->hosts, &sd2->hosts)) {
+ return false;
+ }
+
+ if (!bson_equal (&sd1->passives, &sd2->passives)) {
+ return false;
+ }
+
+ if (!bson_equal (&sd1->arbiters, &sd2->arbiters)) {
+ return false;
+ }
+
+ if (!bson_equal (&sd1->tags, &sd2->tags)) {
+ return false;
+ }
+
+ if (0 != _nullable_strcmp (sd1->set_name, sd2->set_name)) {
+ return false;
+ }
+
+ if (sd1->set_version != sd2->set_version) {
+ return false;
+ }
+
+ if (!bson_oid_equal (&sd1->election_id, &sd2->election_id)) {
+ return false;
+ }
+
+ if (0 != _nullable_strcasecmp (sd1->current_primary, sd2->current_primary)) {
+ return false;
+ }
+
+ if (sd1->session_timeout_minutes != sd2->session_timeout_minutes) {
+ return false;
+ }
+
+ if (0 != memcmp (&sd1->error, &sd2->error, sizeof (bson_error_t))) {
+ return false;
+ }
+
+ if (!bson_equal (&sd1->topology_version, &sd2->topology_version)) {
+ return false;
+ }
+
+ return true;
+}
+
+int
+mongoc_server_description_topology_version_cmp (const bson_t *tv1,
+ const bson_t *tv2)
+{
+ const bson_oid_t *pid1;
+ const bson_oid_t *pid2;
+ int64_t counter1;
+ int64_t counter2;
+ bson_iter_t iter;
+
+ BSON_ASSERT (tv1);
+ BSON_ASSERT (tv2);
+
+ if (bson_empty (tv1) || bson_empty (tv2)) {
+ return -1;
+ }
+
+ if (!bson_iter_init_find (&iter, tv1, "processId") ||
+ !BSON_ITER_HOLDS_OID (&iter)) {
+ return -1;
+ }
+ pid1 = bson_iter_oid (&iter);
+
+ if (!bson_iter_init_find (&iter, tv2, "processId") ||
+ !BSON_ITER_HOLDS_OID (&iter)) {
+ return -1;
+ }
+ pid2 = bson_iter_oid (&iter);
+
+ if (0 != bson_oid_compare (pid1, pid2)) {
+ /* Assume greater. */
+ return -1;
+ }
+
+ if (!bson_iter_init_find (&iter, tv1, "counter") ||
+ !BSON_ITER_HOLDS_INT (&iter)) {
+ return -1;
+ }
+ counter1 = bson_iter_as_int64 (&iter);
+
+ if (!bson_iter_init_find (&iter, tv2, "counter") ||
+ !BSON_ITER_HOLDS_INT (&iter)) {
+ return -1;
+ }
+ counter2 = bson_iter_as_int64 (&iter);
+
+ if (counter1 < counter2) {
+ return -1;
+ } else if (counter1 > counter2) {
+ return 1;
+ }
+ return 0;
+}
+
+void
+mongoc_server_description_set_topology_version (mongoc_server_description_t *sd,
+ const bson_t *tv)
+{
+ BSON_ASSERT (tv);
+ bson_destroy (&sd->topology_version);
+ bson_copy_to (tv, &sd->topology_version);
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h
new file mode 100644
index 00000000..4a846891
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "mongoc-prelude.h"
+
+#ifndef MONGOC_SERVER_MONITOR_PRIVATE_H
+#define MONGOC_SERVER_MONITOR_PRIVATE_H
+
+#include "mongoc.h"
+#include "mongoc-server-description-private.h"
+#include "mongoc-topology-private.h"
+
+/* For background monitoring of a single server. */
+
+typedef struct _mongoc_server_monitor_t mongoc_server_monitor_t;
+
+mongoc_server_monitor_t *
+mongoc_server_monitor_new (mongoc_topology_t *topology,
+ mongoc_server_description_t *init_description);
+
+mongoc_server_description_t *
+mongoc_server_monitor_check_server (
+ mongoc_server_monitor_t *server_monitor,
+ const mongoc_server_description_t *previous_description,
+ bool *cancelled);
+
+void
+mongoc_server_monitor_request_cancel (mongoc_server_monitor_t *server_monitor);
+
+void
+mongoc_server_monitor_request_scan (mongoc_server_monitor_t *server_monitor);
+
+bool
+mongoc_server_monitor_request_shutdown (
+ mongoc_server_monitor_t *server_monitor);
+
+void
+mongoc_server_monitor_wait_for_shutdown (
+ mongoc_server_monitor_t *server_monitor);
+
+void
+mongoc_server_monitor_destroy (mongoc_server_monitor_t *server_monitor);
+
+void
+mongoc_server_monitor_run (mongoc_server_monitor_t *server_monitor);
+
+void
+mongoc_server_monitor_run_as_rtt (mongoc_server_monitor_t *server_monitor);
+
+#endif /* MONGOC_SERVER_MONITOR_PRIVATE_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c
new file mode 100644
index 00000000..53f90ef5
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c
@@ -0,0 +1,1268 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "common-thread-private.h"
+#include "mongoc-server-monitor-private.h"
+
+#include "mongoc/mongoc-client-private.h"
+#include "mongoc/mongoc-error-private.h"
+#include "mongoc/mongoc-flags-private.h"
+#include "mongoc/mongoc-ssl-private.h"
+#include "mongoc/mongoc-stream-private.h"
+#include "mongoc/mongoc-topology-background-monitoring-private.h"
+#include "mongoc/mongoc-topology-private.h"
+#include "mongoc/mongoc-trace-private.h"
+
+#undef MONGOC_LOG_DOMAIN
+#define MONGOC_LOG_DOMAIN "monitor"
+
+typedef enum {
+ MONGOC_THREAD_OFF = 0,
+ MONGOC_THREAD_RUNNING,
+ MONGOC_THREAD_SHUTTING_DOWN,
+ MONGOC_THREAD_JOINABLE
+} thread_state_t;
+
+/* Use a signed and wide return type for timeouts as long as you can. Cast only
+ * when you know what you're doing with it. */
+static int64_t
+_now_us (void)
+{
+ return bson_get_monotonic_time ();
+}
+
+static int64_t
+_now_ms (void)
+{
+ return _now_us () / 1000;
+}
+
+struct _mongoc_server_monitor_t {
+ mongoc_topology_t *topology;
+ bson_thread_t thread;
+
+ /* State accessed from multiple threads. */
+ struct {
+ bson_mutex_t mutex;
+ mongoc_cond_t cond;
+ thread_state_t state;
+ bool scan_requested;
+ bool cancel_requested;
+ } shared;
+
+ /* Default time to sleep between ismaster checks (reduced when a scan is
+ * requested) */
+ uint64_t heartbeat_frequency_ms;
+ /* The minimum time to sleep between ismaster checks. */
+ uint64_t min_heartbeat_frequency_ms;
+ int64_t connect_timeout_ms;
+ bool use_tls;
+#ifdef MONGOC_ENABLE_SSL
+ mongoc_ssl_opt_t *ssl_opts;
+#endif
+ mongoc_uri_t *uri;
+ /* A custom initiator may be set if a user provides overrides to create a
+ * stream. */
+ mongoc_stream_initiator_t initiator;
+ void *initiator_context;
+ int64_t request_id;
+ mongoc_apm_callbacks_t apm_callbacks;
+ void *apm_context;
+
+ mongoc_stream_t *stream;
+ bool more_to_come;
+ mongoc_server_description_t *description;
+ uint32_t server_id;
+ bool is_rtt;
+};
+
+static BSON_GNUC_PRINTF (3, 4) void _server_monitor_log (
+ mongoc_server_monitor_t *server_monitor,
+ mongoc_log_level_t level,
+ const char *format,
+ ...)
+{
+ va_list ap;
+ char *msg;
+
+ va_start (ap, format);
+ msg = bson_strdupv_printf (format, ap);
+ va_end (ap);
+
+ mongoc_log (level,
+ MONGOC_LOG_DOMAIN,
+ "[%s%s] %s",
+ server_monitor->description->host.host_and_port,
+ server_monitor->is_rtt ? "-RTT" : "",
+ msg);
+ bson_free (msg);
+}
+
+#ifdef MONGOC_TRACE
+#define MONITOR_LOG(sm, ...) \
+ _server_monitor_log (sm, MONGOC_LOG_LEVEL_TRACE, __VA_ARGS__)
+#else
+#define MONITOR_LOG(sm, ...) (void) 0
+#endif
+
+/* TODO CDRIVER-3710 use MONGOC_LOG_LEVEL_ERROR */
+#define MONITOR_LOG_ERROR(sm, ...) \
+ _server_monitor_log (sm, MONGOC_LOG_LEVEL_DEBUG, __VA_ARGS__)
+/* TODO CDRIVER-3710 use MONGOC_LOG_LEVEL_WARNING */
+#define MONITOR_LOG_WARNING(sm, ...) \
+ _server_monitor_log (sm, MONGOC_LOG_LEVEL_DEBUG, __VA_ARGS__)
+
+/* Called only from server monitor thread.
+ * Caller must hold no locks (user's callback may lock topology mutex).
+ * Locks APM mutex.
+ */
+static void
+_server_monitor_heartbeat_started (mongoc_server_monitor_t *server_monitor,
+ bool awaited)
+{
+ mongoc_apm_server_heartbeat_started_t event;
+
+ if (!server_monitor->apm_callbacks.server_heartbeat_started) {
+ return;
+ }
+
+ event.host = &server_monitor->description->host;
+ event.context = server_monitor->apm_context;
+ MONITOR_LOG (server_monitor,
+ "%s heartbeat started",
+ awaited ? "awaitable" : "regular");
+ event.awaited = awaited;
+ bson_mutex_lock (&server_monitor->topology->apm_mutex);
+ server_monitor->apm_callbacks.server_heartbeat_started (&event);
+ bson_mutex_unlock (&server_monitor->topology->apm_mutex);
+}
+
+/* Called only from server monitor thread.
+ * Caller must hold no locks (user's callback may lock topology mutex).
+ * Locks APM mutex.
+ */
+static void
+_server_monitor_heartbeat_succeeded (mongoc_server_monitor_t *server_monitor,
+ const bson_t *reply,
+ int64_t duration_usec,
+ bool awaited)
+{
+ mongoc_apm_server_heartbeat_succeeded_t event;
+
+ if (!server_monitor->apm_callbacks.server_heartbeat_succeeded) {
+ return;
+ }
+
+ event.host = &server_monitor->description->host;
+ event.context = server_monitor->apm_context;
+ event.reply = reply;
+ event.duration_usec = duration_usec;
+ MONITOR_LOG (server_monitor,
+ "%s heartbeat succeeded",
+ awaited ? "awaitable" : "regular");
+ event.awaited = awaited;
+ bson_mutex_lock (&server_monitor->topology->apm_mutex);
+ server_monitor->apm_callbacks.server_heartbeat_succeeded (&event);
+ bson_mutex_unlock (&server_monitor->topology->apm_mutex);
+}
+
+/* Called only from server monitor thread.
+ * Caller must hold no locks (user's callback may lock topology mutex).
+ * Locks APM mutex.
+ */
+static void
+_server_monitor_heartbeat_failed (mongoc_server_monitor_t *server_monitor,
+ const bson_error_t *error,
+ int64_t duration_usec,
+ bool awaited)
+{
+ mongoc_apm_server_heartbeat_failed_t event;
+
+ if (!server_monitor->apm_callbacks.server_heartbeat_failed) {
+ return;
+ }
+
+ event.host = &server_monitor->description->host;
+ event.context = server_monitor->apm_context;
+ event.error = error;
+ event.duration_usec = duration_usec;
+ MONITOR_LOG (
+ server_monitor, "%s heartbeat failed", awaited ? "awaitable" : "regular");
+ event.awaited = awaited;
+ bson_mutex_lock (&server_monitor->topology->apm_mutex);
+ server_monitor->apm_callbacks.server_heartbeat_failed (&event);
+ bson_mutex_unlock (&server_monitor->topology->apm_mutex);
+}
+
+static void
+_server_monitor_append_cluster_time (mongoc_server_monitor_t *server_monitor,
+ bson_t *cmd)
+{
+ mongoc_topology_t *topology;
+
+ topology = server_monitor->topology;
+ /* Cluster time is updated on every reply. */
+ bson_mutex_lock (&topology->mutex);
+ if (!bson_empty (&topology->description.cluster_time)) {
+ bson_append_document (
+ cmd, "$clusterTime", 12, &topology->description.cluster_time);
+ }
+ bson_mutex_unlock (&topology->mutex);
+}
+
+static bool
+_server_monitor_send_and_recv_opquery (mongoc_server_monitor_t *server_monitor,
+ const bson_t *cmd,
+ bson_t *reply,
+ bson_error_t *error)
+{
+ mongoc_rpc_t rpc;
+ mongoc_array_t array_to_write;
+ mongoc_iovec_t *iovec;
+ int niovec;
+ mongoc_buffer_t buffer;
+ uint32_t reply_len;
+ bson_t temp_reply;
+ bool ret = false;
+
+ rpc.header.msg_len = 0;
+ rpc.header.request_id = server_monitor->request_id++;
+ rpc.header.response_to = 0;
+ rpc.header.opcode = MONGOC_OPCODE_QUERY;
+ rpc.query.flags = MONGOC_QUERY_SLAVE_OK;
+ rpc.query.collection = "admin.$cmd";
+ rpc.query.skip = 0;
+ rpc.query.n_return = -1;
+ rpc.query.query = bson_get_data (cmd);
+ rpc.query.fields = NULL;
+
+ _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL);
+ _mongoc_array_init (&array_to_write, sizeof (mongoc_iovec_t));
+ _mongoc_rpc_gather (&rpc, &array_to_write);
+ iovec = (mongoc_iovec_t *) array_to_write.data;
+ niovec = array_to_write.len;
+ _mongoc_rpc_swab_to_le (&rpc);
+
+ if (!_mongoc_stream_writev_full (server_monitor->stream,
+ iovec,
+ niovec,
+ server_monitor->connect_timeout_ms,
+ error)) {
+ GOTO (fail);
+ }
+
+ if (!_mongoc_buffer_append_from_stream (&buffer,
+ server_monitor->stream,
+ 4,
+ server_monitor->connect_timeout_ms,
+ error)) {
+ GOTO (fail);
+ }
+
+ memcpy (&reply_len, buffer.data, 4);
+ reply_len = BSON_UINT32_FROM_LE (reply_len);
+
+ if (!_mongoc_buffer_append_from_stream (&buffer,
+ server_monitor->stream,
+ reply_len - buffer.len,
+ server_monitor->connect_timeout_ms,
+ error)) {
+ GOTO (fail);
+ }
+
+ if (!_mongoc_rpc_scatter (&rpc, buffer.data, buffer.len)) {
+ bson_set_error (error,
+ MONGOC_ERROR_PROTOCOL,
+ MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
+ "Invalid reply from server.");
+
+ GOTO (fail);
+ }
+
+ if (!_mongoc_rpc_decompress_if_necessary (&rpc, &buffer, error)) {
+ GOTO (fail);
+ }
+ _mongoc_rpc_swab_from_le (&rpc);
+
+ if (!_mongoc_rpc_get_first_document (&rpc, &temp_reply)) {
+ bson_set_error (error,
+ MONGOC_ERROR_PROTOCOL,
+ MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
+ "Invalid reply from server");
+ GOTO (fail);
+ }
+ bson_copy_to (&temp_reply, reply);
+
+ ret = true;
+fail:
+ if (!ret) {
+ bson_init (reply);
+ }
+ _mongoc_array_destroy (&array_to_write);
+ _mongoc_buffer_destroy (&buffer);
+ return ret;
+}
+
+static bool
+_server_monitor_polling_ismaster (mongoc_server_monitor_t *server_monitor,
+ bson_t *ismaster_reply,
+ bson_error_t *error)
+{
+ bson_t cmd;
+ bool ret;
+
+ bson_init (&cmd);
+ bson_append_int32 (&cmd, "isMaster", 8, 1);
+ _server_monitor_append_cluster_time (server_monitor, &cmd);
+ ret = _server_monitor_send_and_recv_opquery (
+ server_monitor, &cmd, ismaster_reply, error);
+ bson_destroy (&cmd);
+ return ret;
+}
+
+static bool
+_server_monitor_awaitable_ismaster_send (
+ mongoc_server_monitor_t *server_monitor, bson_t *cmd, bson_error_t *error)
+{
+ mongoc_rpc_t rpc = {0};
+ mongoc_array_t array_to_write;
+ mongoc_iovec_t *iovec;
+ int niovec;
+
+ rpc.header.msg_len = 0;
+ rpc.header.request_id = server_monitor->request_id++;
+ rpc.header.response_to = 0;
+ rpc.header.opcode = MONGOC_OPCODE_MSG;
+ rpc.msg.flags = MONGOC_MSG_EXHAUST_ALLOWED;
+ rpc.msg.n_sections = 1;
+ rpc.msg.sections[0].payload_type = 0;
+ rpc.msg.sections[0].payload.bson_document = bson_get_data (cmd);
+
+ _mongoc_array_init (&array_to_write, sizeof (mongoc_iovec_t));
+ _mongoc_rpc_gather (&rpc, &array_to_write);
+
+ iovec = (mongoc_iovec_t *) array_to_write.data;
+ niovec = array_to_write.len;
+ _mongoc_rpc_swab_to_le (&rpc);
+
+ MONITOR_LOG (server_monitor,
+ "sending with timeout %" PRId64,
+ server_monitor->connect_timeout_ms);
+
+ if (!_mongoc_stream_writev_full (server_monitor->stream,
+ iovec,
+ niovec,
+ server_monitor->connect_timeout_ms,
+ error)) {
+ MONITOR_LOG_ERROR (server_monitor,
+ "failed to write awaitable ismaster: %s",
+ error->message);
+ _mongoc_array_destroy (&array_to_write);
+ return false;
+ }
+ _mongoc_array_destroy (&array_to_write);
+ return true;
+}
+
+/* Poll the server monitor stream for reading. Allows cancellation.
+ *
+ * Called only from server monitor thread.
+ * Locks server monitor mutex.
+ * Returns true if stream is readable. False on error or cancellation.
+ * On cancellation, no error is set, but cancelled is set to true.
+ */
+static bool
+_server_monitor_poll_with_interrupt (mongoc_server_monitor_t *server_monitor,
+ int64_t expire_at_ms,
+ bool *cancelled,
+ bson_error_t *error)
+{
+ /* How many milliseconds we should poll for on each tick.
+ * On every tick, check whether the awaitable ismaster was cancelled. */
+ const int32_t monitor_tick_ms = 500;
+ int64_t timeleft_ms;
+
+ while ((timeleft_ms = expire_at_ms - _now_ms ()) > 0) {
+ ssize_t ret;
+ mongoc_stream_poll_t poller[1];
+
+ MONITOR_LOG (server_monitor,
+ "_server_monitor_poll_with_interrupt expires in: %" PRIu64
+ "ms",
+ timeleft_ms);
+ poller[0].stream = server_monitor->stream;
+ poller[0].events =
+ POLLIN; /* POLLERR and POLLHUP are added in mongoc_socket_poll. */
+ poller[0].revents = 0;
+
+ MONITOR_LOG (
+ server_monitor,
+ "polling for awaitable ismaster reply with timeleft_ms: %" PRId64,
+ timeleft_ms);
+ ret = mongoc_stream_poll (
+ poller, 1, (int32_t) BSON_MIN (timeleft_ms, monitor_tick_ms));
+ if (ret == -1) {
+ MONITOR_LOG (server_monitor, "mongoc_stream_poll error");
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "poll error");
+ return false;
+ }
+
+ if (poller[0].revents & (POLLERR | POLLHUP)) {
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "connection closed while polling");
+ return false;
+ }
+
+ /* Check for cancellation. */
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ *cancelled = server_monitor->shared.cancel_requested;
+ server_monitor->shared.cancel_requested = false;
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+
+ if (*cancelled) {
+ MONITOR_LOG (server_monitor, "polling cancelled");
+ return false;
+ }
+
+ if (poller[0].revents & POLLIN) {
+ MONITOR_LOG (server_monitor, "mongoc_stream_poll ready to read");
+ return true;
+ }
+ }
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "connection timeout while polling");
+ return false;
+}
+
+/* Calculate the timeout between the current time and an absolute expiration
+ * time in milliseconds.
+ *
+ * Returns 0 and sets error if time expired.
+ */
+int64_t
+_get_timeout_ms (int64_t expire_at_ms, bson_error_t *error)
+{
+ int64_t timeout_ms;
+
+ timeout_ms = expire_at_ms - _now_ms ();
+ if (timeout_ms <= 0) {
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "connection timed out reading message length");
+ return 0;
+ }
+ return timeout_ms;
+}
+
+/* Receive an awaitable ismaster reply.
+ *
+ * May be used to receive additional replies when moreToCome is set.
+ * Called only from server monitor thread.
+ * May lock server monitor mutex in functions that are called.
+ * May block for up to heartbeatFrequencyMS + connectTimeoutMS waiting for
+ * reply.
+ * Returns true if a reply was received. False on error or cancellation.
+ * On cancellation, no error is set, but cancelled is set to true.
+ */
+static bool
+_server_monitor_awaitable_ismaster_recv (
+ mongoc_server_monitor_t *server_monitor,
+ bson_t *ismaster_reply,
+ bool *cancelled,
+ bson_error_t *error)
+{
+ bool ret = false;
+ mongoc_buffer_t buffer;
+ int32_t msg_len;
+ mongoc_rpc_t rpc;
+ bson_t reply_local;
+ int64_t expire_at_ms;
+ int64_t timeout_ms;
+
+ expire_at_ms = _now_ms () + server_monitor->heartbeat_frequency_ms +
+ server_monitor->connect_timeout_ms;
+ _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL);
+ if (!_server_monitor_poll_with_interrupt (
+ server_monitor, expire_at_ms, cancelled, error)) {
+ GOTO (fail);
+ }
+
+ timeout_ms = _get_timeout_ms (expire_at_ms, error);
+ if (!timeout_ms) {
+ GOTO (fail);
+ }
+ MONITOR_LOG (server_monitor,
+ "reading first 4 bytes with timeout: %" PRId64,
+ timeout_ms);
+ if (!_mongoc_buffer_append_from_stream (
+ &buffer, server_monitor->stream, 4, (int32_t) timeout_ms, error)) {
+ GOTO (fail);
+ }
+
+ BSON_ASSERT (buffer.len == 4);
+ memcpy (&msg_len, buffer.data, 4);
+ msg_len = BSON_UINT32_FROM_LE (msg_len);
+
+ if ((msg_len < 16) ||
+ (msg_len > server_monitor->description->max_msg_size)) {
+ bson_set_error (
+ error,
+ MONGOC_ERROR_PROTOCOL,
+ MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
+ "Message size %d is not within expected range 16-%d bytes",
+ msg_len,
+ server_monitor->description->max_msg_size);
+ GOTO (fail);
+ }
+
+ timeout_ms = _get_timeout_ms (expire_at_ms, error);
+ if (!timeout_ms) {
+ GOTO (fail);
+ }
+ MONITOR_LOG (server_monitor,
+ "reading remaining %d bytes. Timeout %" PRId64,
+ (int) (msg_len - 4),
+ timeout_ms);
+ if (!_mongoc_buffer_append_from_stream (
+ &buffer, server_monitor->stream, msg_len - 4, timeout_ms, error)) {
+ GOTO (fail);
+ }
+
+ if (!_mongoc_rpc_scatter (&rpc, buffer.data, buffer.len)) {
+ bson_set_error (error,
+ MONGOC_ERROR_PROTOCOL,
+ MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
+ "Malformed message from server");
+ GOTO (fail);
+ }
+
+ if (!_mongoc_rpc_decompress_if_necessary (&rpc, &buffer, error)) {
+ GOTO (fail);
+ }
+
+ _mongoc_rpc_swab_from_le (&rpc);
+ memcpy (&msg_len, rpc.msg.sections[0].payload.bson_document, 4);
+ msg_len = BSON_UINT32_FROM_LE (msg_len);
+ if (!bson_init_static (
+ &reply_local, rpc.msg.sections[0].payload.bson_document, msg_len)) {
+ bson_set_error (error,
+ MONGOC_ERROR_PROTOCOL,
+ MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
+ "Malformed BSON payload from server");
+ GOTO (fail);
+ }
+
+ bson_copy_to (&reply_local, ismaster_reply);
+ server_monitor->more_to_come =
+ (rpc.msg.flags & MONGOC_MSG_MORE_TO_COME) != 0;
+
+ ret = true;
+fail:
+ if (!ret) {
+ bson_init (ismaster_reply);
+ }
+ _mongoc_buffer_destroy (&buffer);
+ return ret;
+}
+
+/* Send and receive an awaitable ismaster.
+ *
+ * Called only from server monitor thread.
+ * May lock server monitor mutex in functions that are called.
+ * May block for up to heartbeatFrequencyMS waiting for reply.
+ */
+static bool
+_server_monitor_awaitable_ismaster (mongoc_server_monitor_t *server_monitor,
+ const bson_t *topology_version,
+ bson_t *ismaster_reply,
+ bool *cancelled,
+ bson_error_t *error)
+{
+ bson_t cmd = BSON_INITIALIZER;
+ bool ret = false;
+
+ bson_append_int32 (&cmd, "isMaster", 8, 1);
+ _server_monitor_append_cluster_time (server_monitor, &cmd);
+ bson_append_document (&cmd, "topologyVersion", 15, topology_version);
+ bson_append_int32 (
+ &cmd, "maxAwaitTimeMS", 14, server_monitor->heartbeat_frequency_ms);
+ bson_append_utf8 (&cmd, "$db", 3, "admin", 5);
+
+ if (!_server_monitor_awaitable_ismaster_send (server_monitor, &cmd, error)) {
+ GOTO (fail);
+ }
+
+ if (!_server_monitor_awaitable_ismaster_recv (
+ server_monitor, ismaster_reply, cancelled, error)) {
+ bson_destroy (ismaster_reply);
+ GOTO (fail);
+ }
+
+ ret = true;
+fail:
+ if (!ret) {
+ bson_init (ismaster_reply);
+ }
+ bson_destroy (&cmd);
+ return ret;
+}
+
+/* Update the topology description with a reply or an error.
+ *
+ * Called only from server monitor thread.
+ * Caller must hold no locks.
+ * Locks topology mutex and server monitor mutex.
+ */
+static void
+_server_monitor_update_topology_description (
+ mongoc_server_monitor_t *server_monitor,
+ mongoc_server_description_t *description)
+{
+ mongoc_topology_t *topology;
+ bson_t *ismaster_reply = NULL;
+
+ topology = server_monitor->topology;
+ if (description->has_is_master) {
+ ismaster_reply = &description->last_is_master;
+ }
+
+ if (ismaster_reply) {
+ _mongoc_topology_update_cluster_time (topology, ismaster_reply);
+ }
+
+ bson_mutex_lock (&topology->mutex);
+ if (topology->scanner_state != MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN) {
+ /* This is the another case of holding both locks. topology->mutex is
+ * always locked first, then server monitor mutex after. */
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ server_monitor->shared.scan_requested = false;
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+
+ mongoc_topology_description_handle_ismaster (
+ &server_monitor->topology->description,
+ server_monitor->server_id,
+ ismaster_reply,
+ description->round_trip_time_msec,
+ &description->error);
+ /* Reconcile server monitors. */
+ _mongoc_topology_background_monitoring_reconcile (topology);
+ }
+ /* Wake threads performing server selection. */
+ mongoc_cond_broadcast (&server_monitor->topology->cond_client);
+ bson_mutex_unlock (&server_monitor->topology->mutex);
+}
+
+/* Create a new server monitor.
+ *
+ * Called during reconcile.
+ * Caller must hold topology lock.
+ */
+mongoc_server_monitor_t *
+mongoc_server_monitor_new (mongoc_topology_t *topology,
+ mongoc_server_description_t *init_description)
+{
+ mongoc_server_monitor_t *server_monitor;
+
+ server_monitor = bson_malloc0 (sizeof (*server_monitor));
+ server_monitor->description =
+ mongoc_server_description_new_copy (init_description);
+ server_monitor->server_id = init_description->id;
+ server_monitor->topology = topology;
+ server_monitor->heartbeat_frequency_ms =
+ topology->description.heartbeat_msec;
+ server_monitor->min_heartbeat_frequency_ms =
+ topology->min_heartbeat_frequency_msec;
+ server_monitor->connect_timeout_ms = topology->connect_timeout_msec;
+ server_monitor->uri = mongoc_uri_copy (topology->uri);
+/* TODO CDRIVER-3682: Do not retrieve ssl opts from topology scanner. They
+ * should be stored somewhere else. */
+#ifdef MONGOC_ENABLE_SSL
+ if (topology->scanner->ssl_opts) {
+ server_monitor->ssl_opts = bson_malloc0 (sizeof (mongoc_ssl_opt_t));
+
+ _mongoc_ssl_opts_copy_to (
+ topology->scanner->ssl_opts, server_monitor->ssl_opts, true);
+ }
+#endif
+ memcpy (&server_monitor->apm_callbacks,
+ &topology->description.apm_callbacks,
+ sizeof (mongoc_apm_callbacks_t));
+ server_monitor->apm_context = topology->description.apm_context;
+ server_monitor->initiator = topology->scanner->initiator;
+ server_monitor->initiator_context = topology->scanner->initiator_context;
+ mongoc_cond_init (&server_monitor->shared.cond);
+ bson_mutex_init (&server_monitor->shared.mutex);
+ return server_monitor;
+}
+
+/* Creates a stream and performs the initial ismaster handshake.
+ *
+ * Called only by server monitor thread.
+ * Returns true if both connection and handshake succeeds.
+ * Returns false and sets error otherwise.
+ * ismaster_reply is always initialized.
+ */
+static bool
+_server_monitor_setup_connection (mongoc_server_monitor_t *server_monitor,
+ bson_t *ismaster_reply,
+ int64_t *start_us,
+ bson_error_t *error)
+{
+ bson_t cmd = BSON_INITIALIZER;
+ const bson_t *handshake;
+ bool ret = false;
+
+ ENTRY;
+
+ BSON_ASSERT (!server_monitor->stream);
+ bson_init (ismaster_reply);
+
+ server_monitor->more_to_come = false;
+
+ /* Using an initiator isn't really necessary. Users can't set them on
+ * pools. But it is used for tests. */
+ if (server_monitor->initiator) {
+ server_monitor->stream =
+ server_monitor->initiator (server_monitor->uri,
+ &server_monitor->description->host,
+ server_monitor->initiator_context,
+ error);
+ } else {
+ void *ssl_opts_void = NULL;
+
+#ifdef MONGOC_ENABLE_SSL
+ ssl_opts_void = server_monitor->ssl_opts;
+#endif
+ server_monitor->stream =
+ mongoc_client_connect (false,
+ ssl_opts_void != NULL,
+ ssl_opts_void,
+ server_monitor->uri,
+ &server_monitor->description->host,
+ error);
+ }
+
+ if (!server_monitor->stream) {
+ GOTO (fail);
+ }
+
+ /* Update the start time just before the handshake. */
+ *start_us = _now_us ();
+ /* Perform handshake. */
+ handshake = _mongoc_topology_get_ismaster (server_monitor->topology);
+ bson_destroy (&cmd);
+ bson_copy_to (handshake, &cmd);
+ _server_monitor_append_cluster_time (server_monitor, &cmd);
+ bson_destroy (ismaster_reply);
+ if (!_server_monitor_send_and_recv_opquery (
+ server_monitor, &cmd, ismaster_reply, error)) {
+ GOTO (fail);
+ }
+
+ ret = true;
+fail:
+ bson_destroy (&cmd);
+ RETURN (ret);
+}
+
+/* Perform an ismaster check of a server.
+ *
+ * Called only by server monitor thread.
+ * Caller must not hold any locks.
+ * May lock server monitor mutex. May lock topology mutex.
+ * Upon network error, the returned server description will contain the error,
+ * but no ismaster reply.
+ * Upon ismaster cancellation, cancelled will be true, and the returned server
+ * description will not contain an error or ismaster reply.
+ * Upon command error ("ok":0 reply), the returned server description have the
+ * ismaster reply and error set.
+ * Returns a new server description that the caller must destroy.
+ */
+mongoc_server_description_t *
+mongoc_server_monitor_check_server (
+ mongoc_server_monitor_t *server_monitor,
+ const mongoc_server_description_t *previous_description,
+ bool *cancelled)
+{
+ bool ret = false;
+ bson_error_t error;
+ bson_t ismaster_reply;
+ int64_t duration_us;
+ int64_t start_us;
+ bool command_or_network_error = false;
+ bool awaited = false;
+ mongoc_server_description_t *description;
+
+ ENTRY;
+
+ *cancelled = false;
+ memset (&error, 0, sizeof (bson_error_t));
+ description = bson_malloc0 (sizeof (mongoc_server_description_t));
+ mongoc_server_description_init (
+ description,
+ server_monitor->description->connection_address,
+ server_monitor->description->id);
+ start_us = _now_us ();
+
+ if (!server_monitor->stream) {
+ MONITOR_LOG (server_monitor, "setting up connection");
+ awaited = false;
+ _server_monitor_heartbeat_started (server_monitor, awaited);
+ ret = _server_monitor_setup_connection (
+ server_monitor, &ismaster_reply, &start_us, &error);
+ GOTO (exit);
+ }
+
+ if (server_monitor->more_to_come) {
+ awaited = true;
+ /* Publish a heartbeat started for each additional response read. */
+ _server_monitor_heartbeat_started (server_monitor, awaited);
+ MONITOR_LOG (server_monitor, "more to come");
+ ret = _server_monitor_awaitable_ismaster_recv (
+ server_monitor, &ismaster_reply, cancelled, &error);
+ GOTO (exit);
+ }
+
+ if (!bson_empty (&previous_description->topology_version)) {
+ awaited = true;
+ _server_monitor_heartbeat_started (server_monitor, awaited);
+ MONITOR_LOG (server_monitor, "awaitable ismaster");
+ ret = _server_monitor_awaitable_ismaster (
+ server_monitor,
+ &previous_description->topology_version,
+ &ismaster_reply,
+ cancelled,
+ &error);
+ GOTO (exit);
+ }
+
+ MONITOR_LOG (server_monitor, "polling ismaster");
+ awaited = false;
+ _server_monitor_heartbeat_started (server_monitor, awaited);
+ ret = _server_monitor_polling_ismaster (
+ server_monitor, &ismaster_reply, &error);
+
+exit:
+ duration_us = _now_us () - start_us;
+ MONITOR_LOG (
+ server_monitor, "server check duration (us): %" PRId64, duration_us);
+
+ /* If ret is true, we have a reply. Check if "ok": 1. */
+ if (ret && _mongoc_cmd_check_ok (
+ &ismaster_reply, MONGOC_ERROR_API_VERSION_2, &error)) {
+ int64_t rtt_ms = MONGOC_RTT_UNSET;
+
+ /* rtt remains MONGOC_RTT_UNSET if awaited. */
+ if (!awaited) {
+ rtt_ms = duration_us / 1000;
+ }
+
+ mongoc_server_description_handle_ismaster (
+ description, &ismaster_reply, rtt_ms, NULL);
+ /* If the ismaster reply could not be parsed, consider this a command
+ * error. */
+ if (description->error.code) {
+ MONITOR_LOG_ERROR (server_monitor,
+ "error parsing server reply: %s",
+ description->error.message);
+ command_or_network_error = true;
+ _server_monitor_heartbeat_failed (
+ server_monitor, &description->error, duration_us, awaited);
+ } else {
+ _server_monitor_heartbeat_succeeded (
+ server_monitor, &ismaster_reply, duration_us, awaited);
+ }
+ } else if (*cancelled) {
+ MONITOR_LOG (server_monitor, "server monitor cancelled");
+ if (server_monitor->stream) {
+ mongoc_stream_destroy (server_monitor->stream);
+ }
+ server_monitor->stream = NULL;
+ server_monitor->more_to_come = false;
+ _server_monitor_heartbeat_failed (
+ server_monitor, &description->error, duration_us, awaited);
+ } else {
+ /* The ismaster reply had "ok":0 or a network error occurred. */
+ MONITOR_LOG_ERROR (server_monitor,
+ "command or network error occurred: %s",
+ error.message);
+ command_or_network_error = true;
+ mongoc_server_description_handle_ismaster (
+ description, NULL, MONGOC_RTT_UNSET, &error);
+ _server_monitor_heartbeat_failed (
+ server_monitor, &description->error, duration_us, awaited);
+ }
+
+ if (command_or_network_error) {
+ if (server_monitor->stream) {
+ mongoc_stream_failed (server_monitor->stream);
+ }
+ server_monitor->stream = NULL;
+ server_monitor->more_to_come = false;
+ bson_mutex_lock (&server_monitor->topology->mutex);
+ _mongoc_topology_clear_connection_pool (server_monitor->topology,
+ server_monitor->description->id);
+ bson_mutex_unlock (&server_monitor->topology->mutex);
+ }
+
+ bson_destroy (&ismaster_reply);
+ return description;
+}
+
+/* Request scan of a single server.
+ *
+ * Caller does not need to have topology mutex locked.
+ * Locks server monitor mutex to deliver scan_requested.
+ */
+void
+mongoc_server_monitor_request_scan (mongoc_server_monitor_t *server_monitor)
+{
+ MONITOR_LOG (server_monitor, "requesting scan");
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ server_monitor->shared.scan_requested = true;
+ mongoc_cond_signal (&server_monitor->shared.cond);
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+}
+
+/* Request cancellation of an in progress awaitable ismaster.
+ *
+ * Called from app threads on network errors and during shutdown.
+ * Locks server monitor mutex.
+ */
+void
+mongoc_server_monitor_request_cancel (mongoc_server_monitor_t *server_monitor)
+{
+ MONITOR_LOG (server_monitor, "requesting cancel");
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ server_monitor->shared.cancel_requested = true;
+ mongoc_cond_signal (&server_monitor->shared.cond);
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+}
+
+/* Wait for heartbeatFrequencyMS or minHeartbeatFrequencyMS if a scan is
+ * requested.
+ *
+ * Locks server monitor mutex.
+ */
+void
+mongoc_server_monitor_wait (mongoc_server_monitor_t *server_monitor)
+{
+ int64_t start_ms;
+ int64_t scan_due_ms;
+
+ start_ms = _now_ms ();
+ scan_due_ms = start_ms + server_monitor->heartbeat_frequency_ms;
+
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ while (true) {
+ int64_t sleep_duration_ms;
+ int cond_ret;
+
+ if (server_monitor->shared.state != MONGOC_THREAD_RUNNING) {
+ break;
+ }
+
+ if (server_monitor->shared.scan_requested) {
+ server_monitor->shared.scan_requested = false;
+ scan_due_ms = start_ms + server_monitor->min_heartbeat_frequency_ms;
+ }
+
+ sleep_duration_ms = scan_due_ms - _now_ms ();
+
+ if (sleep_duration_ms <= 0) {
+ break;
+ }
+
+ MONITOR_LOG (server_monitor, "sleeping for %" PRId64, sleep_duration_ms);
+ cond_ret = mongoc_cond_timedwait (&server_monitor->shared.cond,
+ &server_monitor->shared.mutex,
+ sleep_duration_ms);
+ if (mongo_cond_ret_is_timedout (cond_ret)) {
+ break;
+ }
+ }
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+}
+
+/* The server monitor thread function.
+ *
+ * Server monitor must be in state MONGOC_THREAD_OFF.
+ */
+static BSON_THREAD_FUN (_server_monitor_thread, server_monitor_void)
+{
+ mongoc_server_monitor_t *server_monitor;
+ mongoc_server_description_t *description;
+ mongoc_server_description_t *previous_description;
+
+ server_monitor = (mongoc_server_monitor_t *) server_monitor_void;
+ description =
+ mongoc_server_description_new_copy (server_monitor->description);
+ previous_description = NULL;
+
+ while (true) {
+ bool cancelled = false;
+
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ if (server_monitor->shared.state != MONGOC_THREAD_RUNNING) {
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+ break;
+ }
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+
+ mongoc_server_description_destroy (previous_description);
+ previous_description = mongoc_server_description_new_copy (description);
+ mongoc_server_description_destroy (description);
+ description = mongoc_server_monitor_check_server (
+ server_monitor, previous_description, &cancelled);
+
+ if (cancelled) {
+ mongoc_server_monitor_wait (server_monitor);
+ continue;
+ }
+
+ _server_monitor_update_topology_description (server_monitor, description);
+
+ /* Immediately proceed to the next check if the previous response was
+ * successful and included the topologyVersion field. */
+ if (description->type != MONGOC_SERVER_UNKNOWN &&
+ !bson_empty (&description->topology_version)) {
+ MONITOR_LOG (server_monitor,
+ "immediately proceeding due to topologyVersion");
+ continue;
+ }
+
+ /* ... or the previous response included the moreToCome flag */
+ if (server_monitor->more_to_come) {
+ MONITOR_LOG (server_monitor,
+ "immediately proceeding due to moreToCome");
+ continue;
+ }
+
+ /* ... or the server has just transitioned to Unknown due to a network
+ * error. */
+ if (_mongoc_error_is_network (&description->error) &&
+ previous_description->type != MONGOC_SERVER_UNKNOWN) {
+ MONITOR_LOG (server_monitor,
+ "immediately proceeding due to network error");
+ continue;
+ }
+
+ mongoc_server_monitor_wait (server_monitor);
+ }
+
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ server_monitor->shared.state = MONGOC_THREAD_JOINABLE;
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+ mongoc_server_description_destroy (previous_description);
+ mongoc_server_description_destroy (description);
+ BSON_THREAD_RETURN;
+}
+
+static bool
+_server_monitor_ping_server (mongoc_server_monitor_t *server_monitor,
+ int64_t *rtt_ms)
+{
+ bool ret = false;
+ int64_t start_us = _now_us ();
+ bson_t ismaster_reply;
+ bson_error_t error;
+
+ *rtt_ms = MONGOC_RTT_UNSET;
+
+ if (!server_monitor->stream) {
+ MONITOR_LOG (server_monitor, "rtt setting up connection");
+ ret = _server_monitor_setup_connection (
+ server_monitor, &ismaster_reply, &start_us, &error);
+ bson_destroy (&ismaster_reply);
+ }
+
+ if (server_monitor->stream) {
+ MONITOR_LOG (server_monitor, "rtt polling ismaster");
+ ret = _server_monitor_polling_ismaster (
+ server_monitor, &ismaster_reply, &error);
+ if (ret) {
+ *rtt_ms = (_now_us () - start_us) / 1000;
+ }
+ bson_destroy (&ismaster_reply);
+ }
+ return ret;
+}
+
+/* The RTT monitor thread function.
+ *
+ * Server monitor must be in state MONGOC_THREAD_OFF.
+ */
+static BSON_THREAD_FUN (_server_monitor_rtt_thread, server_monitor_void)
+{
+ mongoc_server_monitor_t *server_monitor;
+
+ server_monitor = (mongoc_server_monitor_t *) server_monitor_void;
+
+ while (true) {
+ int64_t rtt_ms;
+ bson_error_t error;
+
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ if (server_monitor->shared.state != MONGOC_THREAD_RUNNING) {
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+ break;
+ }
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+
+ _server_monitor_ping_server (server_monitor, &rtt_ms);
+ if (rtt_ms != MONGOC_RTT_UNSET) {
+ mongoc_server_description_t *sd;
+
+ bson_mutex_lock (&server_monitor->topology->mutex);
+ sd = mongoc_topology_description_server_by_id (
+ &server_monitor->topology->description,
+ server_monitor->description->id,
+ &error);
+ if (sd) {
+ /* If the server description has been removed, the RTT thread will
+ * be terminated by background monitoring soon. */
+ mongoc_server_description_update_rtt (sd, rtt_ms);
+ }
+ bson_mutex_unlock (&server_monitor->topology->mutex);
+ }
+ mongoc_server_monitor_wait (server_monitor);
+ }
+
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ server_monitor->shared.state = MONGOC_THREAD_JOINABLE;
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+ BSON_THREAD_RETURN;
+}
+
+void
+mongoc_server_monitor_run (mongoc_server_monitor_t *server_monitor)
+{
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ if (server_monitor->shared.state == MONGOC_THREAD_OFF) {
+ server_monitor->is_rtt = false;
+ server_monitor->shared.state = MONGOC_THREAD_RUNNING;
+ COMMON_PREFIX (thread_create)
+ (&server_monitor->thread, _server_monitor_thread, server_monitor);
+ }
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+}
+
+void
+mongoc_server_monitor_run_as_rtt (mongoc_server_monitor_t *server_monitor)
+{
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ if (server_monitor->shared.state == MONGOC_THREAD_OFF) {
+ server_monitor->is_rtt = true;
+ server_monitor->shared.state = MONGOC_THREAD_RUNNING;
+ COMMON_PREFIX (thread_create)
+ (&server_monitor->thread, _server_monitor_rtt_thread, server_monitor);
+ }
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+}
+
+/* Request thread shutdown.
+ *
+ * Returns true if in state MONGOC_THREAD_OFF and the server monitor can be
+ * safely destroyed.
+ * Called during topology description reconcile.
+ * Caller may hold topology mutex.
+ * Locks server monitor mutex.
+ */
+bool
+mongoc_server_monitor_request_shutdown (mongoc_server_monitor_t *server_monitor)
+{
+ bool off = false;
+
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ if (server_monitor->shared.state == MONGOC_THREAD_RUNNING) {
+ server_monitor->shared.state = MONGOC_THREAD_SHUTTING_DOWN;
+ }
+ if (server_monitor->shared.state == MONGOC_THREAD_JOINABLE) {
+ COMMON_PREFIX (thread_join) (server_monitor->thread);
+ server_monitor->shared.state = MONGOC_THREAD_OFF;
+ }
+ if (server_monitor->shared.state == MONGOC_THREAD_OFF) {
+ off = true;
+ }
+ mongoc_cond_signal (&server_monitor->shared.cond);
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+ /* Cancel an in-progress ismaster check. */
+ if (!off) {
+ mongoc_server_monitor_request_cancel (server_monitor);
+ }
+ return off;
+}
+
+/* Request thread shutdown and block until the server monitor thread terminates.
+ *
+ * Called by one thread.
+ * Caller must not hold topology mutex. Server monitor thread may need to lock
+ * it again in the process of shutting down.
+ * Locks the server monitor mutex.
+ */
+void
+mongoc_server_monitor_wait_for_shutdown (
+ mongoc_server_monitor_t *server_monitor)
+{
+ if (mongoc_server_monitor_request_shutdown (server_monitor)) {
+ return;
+ }
+
+ /* Shutdown requested, but thread is not yet off. Wait. */
+ COMMON_PREFIX (thread_join) (server_monitor->thread);
+ bson_mutex_lock (&server_monitor->shared.mutex);
+ server_monitor->shared.state = MONGOC_THREAD_OFF;
+ bson_mutex_unlock (&server_monitor->shared.mutex);
+}
+
+/* Destroy a server monitor.
+ *
+ * Called only by one thread.
+ * Caller must not hold server monitor lock.
+ * Server monitor thread is in state MONGOC_THREAD_OFF.
+ */
+void
+mongoc_server_monitor_destroy (mongoc_server_monitor_t *server_monitor)
+{
+ if (!server_monitor) {
+ return;
+ }
+
+ /* Locking not necessary since this is only called by one thread, and server
+ * monitor thread is no longer running. */
+ BSON_ASSERT (server_monitor->shared.state == MONGOC_THREAD_OFF);
+
+ mongoc_server_description_destroy (server_monitor->description);
+ mongoc_stream_destroy (server_monitor->stream);
+ mongoc_uri_destroy (server_monitor->uri);
+ mongoc_cond_destroy (&server_monitor->shared.cond);
+ bson_mutex_destroy (&server_monitor->shared.mutex);
+#ifdef MONGOC_ENABLE_SSL
+ if (server_monitor->ssl_opts) {
+ _mongoc_ssl_opts_cleanup (server_monitor->ssl_opts, true);
+ bson_free (server_monitor->ssl_opts);
+ }
+#endif
+ bson_free (server_monitor);
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
index b73948ea..86694dce 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
@@ -1,1569 +1,1569 @@
/*
* Copyright 2014 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.
*/
#include <errno.h>
#include <string.h>
#include "mongoc-counters-private.h"
#include "mongoc-errno-private.h"
#include "mongoc-socket-private.h"
#include "mongoc-host-list.h"
#include "mongoc-socket-private.h"
#include "mongoc-trace-private.h"
#ifdef _WIN32
#include <Mstcpip.h>
#include <process.h>
#endif
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "socket"
#define OPERATION_EXPIRED(expire_at) \
((expire_at >= 0) && (expire_at < (bson_get_monotonic_time ())))
/* either struct sockaddr or void, depending on platform */
typedef MONGOC_SOCKET_ARG2 mongoc_sockaddr_t;
/*
*--------------------------------------------------------------------------
*
* _mongoc_socket_capture_errno --
*
* Save the errno state for contextual use.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_socket_capture_errno (mongoc_socket_t *sock) /* IN */
{
#ifdef _WIN32
errno = sock->errno_ = WSAGetLastError ();
#else
sock->errno_ = errno;
#endif
TRACE ("setting errno: %d %s", sock->errno_, strerror (sock->errno_));
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_socket_setflags --
*
* A helper to set socket flags. Sets to nonblocking mode. On
* POSIX sets closeonexec.
*
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
#ifdef _WIN32
_mongoc_socket_setflags (SOCKET sd)
#else
_mongoc_socket_setflags (int sd)
#endif
{
#ifdef _WIN32
u_long io_mode = 1;
return (NO_ERROR == ioctlsocket (sd, FIONBIO, &io_mode));
#else
int flags;
- flags = fcntl (sd, F_GETFL, sd);
+ flags = fcntl (sd, F_GETFL);
if (-1 == fcntl (sd, F_SETFL, (flags | O_NONBLOCK))) {
return false;
}
#ifdef FD_CLOEXEC
- flags = fcntl (sd, F_GETFD, sd);
+ flags = fcntl (sd, F_GETFD);
if (-1 == fcntl (sd, F_SETFD, (flags | FD_CLOEXEC))) {
return false;
}
#endif
return true;
#endif
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_socket_wait --
*
* A single socket poll helper.
*
* @events: in most cases should be POLLIN or POLLOUT.
*
* @expire_at should be an absolute time at which to expire using
* the monotonic clock (bson_get_monotonic_time(), which is in
* microseconds). Or zero to not block at all. Or -1 to block
* forever.
*
* Returns:
* true if an event matched. otherwise false.
* a timeout will return false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_socket_wait (mongoc_socket_t *sock, /* IN */
int events, /* IN */
int64_t expire_at) /* IN */
{
#ifdef _WIN32
fd_set read_fds;
fd_set write_fds;
fd_set error_fds;
struct timeval timeout_tv;
#else
struct pollfd pfd;
#endif
int ret;
int timeout;
int64_t now;
ENTRY;
BSON_ASSERT (sock);
BSON_ASSERT (events);
#ifdef _WIN32
FD_ZERO (&read_fds);
FD_ZERO (&write_fds);
FD_ZERO (&error_fds);
if (events & POLLIN) {
FD_SET (sock->sd, &read_fds);
}
if (events & POLLOUT) {
FD_SET (sock->sd, &write_fds);
}
FD_SET (sock->sd, &error_fds);
#else
pfd.fd = sock->sd;
pfd.events = events | POLLERR | POLLHUP;
pfd.revents = 0;
#endif
now = bson_get_monotonic_time ();
for (;;) {
if (expire_at < 0) {
timeout = -1;
} else if (expire_at == 0) {
timeout = 0;
} else {
timeout = (int) ((expire_at - now) / 1000L);
if (timeout < 0) {
timeout = 0;
}
}
#ifdef _WIN32
if (timeout == -1) {
/* not WSAPoll: daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken */
ret = select (0 /*unused*/, &read_fds, &write_fds, &error_fds, NULL);
} else {
timeout_tv.tv_sec = timeout / 1000;
timeout_tv.tv_usec = (timeout % 1000) * 1000;
ret = select (
0 /*unused*/, &read_fds, &write_fds, &error_fds, &timeout_tv);
}
if (ret == SOCKET_ERROR) {
_mongoc_socket_capture_errno (sock);
ret = -1;
} else if (FD_ISSET (sock->sd, &error_fds)) {
errno = WSAECONNRESET;
ret = -1;
}
#else
ret = poll (&pfd, 1, timeout);
#endif
if (ret > 0) {
/* Something happened, so return that */
#ifdef _WIN32
return (FD_ISSET (sock->sd, &read_fds) ||
FD_ISSET (sock->sd, &write_fds));
#else
RETURN (0 != (pfd.revents & events));
#endif
} else if (ret < 0) {
/* poll itself failed */
TRACE ("errno is: %d", errno);
if (MONGOC_ERRNO_IS_AGAIN (errno)) {
if (OPERATION_EXPIRED (expire_at)) {
_mongoc_socket_capture_errno (sock);
RETURN (false);
} else {
continue;
}
} else {
/* poll failed for some non-transient reason */
_mongoc_socket_capture_errno (sock);
RETURN (false);
}
} else {
/* ret == 0, poll timed out */
if (timeout) {
mongoc_counter_streams_timeout_inc ();
}
#ifdef _WIN32
sock->errno_ = timeout ? WSAETIMEDOUT : EAGAIN;
#else
sock->errno_ = timeout ? ETIMEDOUT : EAGAIN;
#endif
RETURN (false);
}
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_poll --
*
* A multi-socket poll helper.
*
* @expire_at should be an absolute time at which to expire using
* the monotonic clock (bson_get_monotonic_time(), which is in
* microseconds). Or zero to not block at all. Or -1 to block
* forever.
*
* Returns:
* The number of sockets ready.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
ssize_t
mongoc_socket_poll (mongoc_socket_poll_t *sds, /* IN */
size_t nsds, /* IN */
int32_t timeout) /* IN */
{
#ifdef _WIN32
fd_set read_fds;
fd_set write_fds;
fd_set error_fds;
struct timeval timeout_tv;
#else
struct pollfd *pfds;
#endif
int ret;
int i;
ENTRY;
BSON_ASSERT (sds);
#ifdef _WIN32
FD_ZERO (&read_fds);
FD_ZERO (&write_fds);
FD_ZERO (&error_fds);
for (i = 0; i < nsds; i++) {
if (sds[i].events & POLLIN) {
FD_SET (sds[i].socket->sd, &read_fds);
}
if (sds[i].events & POLLOUT) {
FD_SET (sds[i].socket->sd, &write_fds);
}
FD_SET (sds[i].socket->sd, &error_fds);
}
timeout_tv.tv_sec = timeout / 1000;
timeout_tv.tv_usec = (timeout % 1000) * 1000;
/* not WSAPoll: daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken */
ret = select (0 /*unused*/, &read_fds, &write_fds, &error_fds, &timeout_tv);
if (ret == SOCKET_ERROR) {
errno = WSAGetLastError ();
return -1;
}
for (i = 0; i < nsds; i++) {
if (FD_ISSET (sds[i].socket->sd, &read_fds)) {
sds[i].revents = POLLIN;
} else if (FD_ISSET (sds[i].socket->sd, &write_fds)) {
sds[i].revents = POLLOUT;
} else if (FD_ISSET (sds[i].socket->sd, &error_fds)) {
sds[i].revents = POLLHUP;
} else {
sds[i].revents = 0;
}
}
#else
pfds = (struct pollfd *) bson_malloc (sizeof (*pfds) * nsds);
for (i = 0; i < nsds; i++) {
pfds[i].fd = sds[i].socket->sd;
pfds[i].events = sds[i].events | POLLERR | POLLHUP;
pfds[i].revents = 0;
}
ret = poll (pfds, nsds, timeout);
for (i = 0; i < nsds; i++) {
sds[i].revents = pfds[i].revents;
}
bson_free (pfds);
#endif
return ret;
}
/* https://jira.mongodb.org/browse/CDRIVER-2176 */
#define MONGODB_KEEPALIVEINTVL 10
-#define MONGODB_KEEPIDLE 300
+#define MONGODB_KEEPIDLE 120
#define MONGODB_KEEPALIVECNT 9
#ifdef _WIN32
static void
_mongoc_socket_setkeepalive_windows (SOCKET sd)
{
struct tcp_keepalive keepalive;
DWORD lpcbBytesReturned = 0;
HKEY hKey;
DWORD type;
DWORD data;
DWORD data_size = sizeof data;
const char *reg_key =
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
keepalive.onoff = true;
keepalive.keepalivetime = MONGODB_KEEPIDLE * 1000;
keepalive.keepaliveinterval = MONGODB_KEEPALIVEINTVL * 1000;
/*
* Windows hardcodes probes to 10:
* https://msdn.microsoft.com/en-us/library/windows/desktop/dd877220(v=vs.85).aspx
* "On Windows Vista and later, the number of keep-alive probes (data
* retransmissions) is set to 10 and cannot be changed."
*
* Note that win2k (and seeminly all versions thereafter) do not set the
* registry value by default so there is no way to derive the default value
* programmatically. It is however listed in the docs. A user can however
* change the default value by setting the registry values.
*/
if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, reg_key, 0, KEY_QUERY_VALUE, &hKey) ==
ERROR_SUCCESS) {
/* https://technet.microsoft.com/en-us/library/cc957549.aspx */
DWORD default_keepalivetime = 7200000; /* 2 hours */
/* https://technet.microsoft.com/en-us/library/cc957548.aspx */
DWORD default_keepaliveinterval = 1000; /* 1 second */
if (RegQueryValueEx (
hKey, "KeepAliveTime", NULL, &type, (LPBYTE) &data, &data_size) ==
ERROR_SUCCESS) {
if (type == REG_DWORD && data < keepalive.keepalivetime) {
keepalive.keepalivetime = data;
}
} else if (default_keepalivetime < keepalive.keepalivetime) {
keepalive.keepalivetime = default_keepalivetime;
}
if (RegQueryValueEx (hKey,
"KeepAliveInterval",
NULL,
&type,
(LPBYTE) &data,
&data_size) == ERROR_SUCCESS) {
if (type == REG_DWORD && data < keepalive.keepaliveinterval) {
keepalive.keepaliveinterval = data;
}
} else if (default_keepaliveinterval < keepalive.keepaliveinterval) {
keepalive.keepaliveinterval = default_keepaliveinterval;
}
RegCloseKey (hKey);
}
if (WSAIoctl (sd,
SIO_KEEPALIVE_VALS,
&keepalive,
sizeof keepalive,
NULL,
0,
&lpcbBytesReturned,
NULL,
NULL) == SOCKET_ERROR) {
TRACE ("%s", "Could not set keepalive values");
} else {
TRACE ("%s", "KeepAlive values updated");
TRACE ("KeepAliveTime: %d", keepalive.keepalivetime);
TRACE ("KeepAliveInterval: %d", keepalive.keepaliveinterval);
}
}
#else
#ifdef MONGOC_TRACE
static const char *
_mongoc_socket_sockopt_value_to_name (int value)
{
switch (value) {
#ifdef TCP_KEEPIDLE
case TCP_KEEPIDLE:
return "TCP_KEEPIDLE";
#endif
#ifdef TCP_KEEPALIVE
case TCP_KEEPALIVE:
return "TCP_KEEPALIVE";
#endif
#ifdef TCP_KEEPINTVL
case TCP_KEEPINTVL:
return "TCP_KEEPINTVL";
#endif
#ifdef TCP_KEEPCNT
case TCP_KEEPCNT:
return "TCP_KEEPCNT";
#endif
default:
MONGOC_WARNING ("Don't know what socketopt %d is", value);
return "Unknown option name";
}
}
#endif
static void
_mongoc_socket_set_sockopt_if_less (int sd, int name, int value)
{
int optval = 1;
mongoc_socklen_t optlen;
optlen = sizeof optval;
if (getsockopt (sd, IPPROTO_TCP, name, (char *) &optval, &optlen)) {
TRACE ("Getting '%s' failed, errno: %d",
_mongoc_socket_sockopt_value_to_name (name),
errno);
} else {
TRACE ("'%s' is %d, target value is %d",
_mongoc_socket_sockopt_value_to_name (name),
optval,
value);
if (optval > value) {
optval = value;
if (setsockopt (
sd, IPPROTO_TCP, name, (char *) &optval, sizeof optval)) {
TRACE ("Setting '%s' failed, errno: %d",
_mongoc_socket_sockopt_value_to_name (name),
errno);
} else {
TRACE ("'%s' value changed to %d",
_mongoc_socket_sockopt_value_to_name (name),
optval);
}
}
}
}
static void
_mongoc_socket_setkeepalive_nix (int sd)
{
#if defined(TCP_KEEPIDLE)
_mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPIDLE, MONGODB_KEEPIDLE);
#elif defined(TCP_KEEPALIVE)
_mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPALIVE, MONGODB_KEEPIDLE);
#else
TRACE ("%s", "Neither TCP_KEEPIDLE nor TCP_KEEPALIVE available");
#endif
#ifdef TCP_KEEPINTVL
_mongoc_socket_set_sockopt_if_less (
sd, TCP_KEEPINTVL, MONGODB_KEEPALIVEINTVL);
#else
TRACE ("%s", "TCP_KEEPINTVL not available");
#endif
#ifdef TCP_KEEPCNT
_mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPCNT, MONGODB_KEEPALIVECNT);
#else
TRACE ("%s", "TCP_KEEPCNT not available");
#endif
}
#endif
static void
#ifdef _WIN32
_mongoc_socket_setkeepalive (SOCKET sd) /* IN */
#else
_mongoc_socket_setkeepalive (int sd) /* IN */
#endif
{
#ifdef SO_KEEPALIVE
int optval = 1;
ENTRY;
#ifdef SO_KEEPALIVE
if (!setsockopt (
sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof optval)) {
TRACE ("%s", "Setting SO_KEEPALIVE");
#ifdef _WIN32
_mongoc_socket_setkeepalive_windows (sd);
#else
_mongoc_socket_setkeepalive_nix (sd);
#endif
} else {
TRACE ("%s", "Failed setting SO_KEEPALIVE");
}
#else
TRACE ("%s", "SO_KEEPALIVE not available");
#endif
EXIT;
#endif
}
static bool
#ifdef _WIN32
_mongoc_socket_setnodelay (SOCKET sd) /* IN */
#else
_mongoc_socket_setnodelay (int sd) /* IN */
#endif
{
#ifdef _WIN32
BOOL optval = 1;
#else
int optval = 1;
#endif
int ret;
ENTRY;
errno = 0;
ret = setsockopt (
sd, IPPROTO_TCP, TCP_NODELAY, (char *) &optval, sizeof optval);
#ifdef _WIN32
if (ret == SOCKET_ERROR) {
MONGOC_WARNING ("WSAGetLastError(): %d", (int) WSAGetLastError ());
}
#endif
RETURN (ret == 0);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_errno --
*
* Returns the last error on the socket.
*
* Returns:
* An integer errno, or 0 on no error.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int
mongoc_socket_errno (mongoc_socket_t *sock) /* IN */
{
BSON_ASSERT (sock);
TRACE ("Current errno: %d", sock->errno_);
return sock->errno_;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_socket_errno_is_again --
*
* Check to see if we should attempt to make further progress
* based on the error of the last operation.
*
* Returns:
* true if we should try again. otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_socket_errno_is_again (mongoc_socket_t *sock) /* IN */
{
TRACE ("errno is: %d", sock->errno_);
return MONGOC_ERRNO_IS_AGAIN (sock->errno_);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_accept --
*
* Wrapper for BSD socket accept(). Handles portability between
* BSD sockets and WinSock2 on Windows Vista and newer.
*
* Returns:
* NULL upon failure to accept or timeout.
* A newly allocated mongoc_socket_t on success.
*
* Side effects:
* *port contains the client port number.
*
*--------------------------------------------------------------------------
*/
mongoc_socket_t *
mongoc_socket_accept (mongoc_socket_t *sock, /* IN */
int64_t expire_at) /* IN */
{
return mongoc_socket_accept_ex (sock, expire_at, NULL);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_accept_ex --
*
* Private synonym for mongoc_socket_accept, returning client port.
*
* Returns:
* NULL upon failure to accept or timeout.
* A newly allocated mongoc_socket_t on success.
*
* Side effects:
* *port contains the client port number.
*
*--------------------------------------------------------------------------
*/
mongoc_socket_t *
mongoc_socket_accept_ex (mongoc_socket_t *sock, /* IN */
int64_t expire_at, /* IN */
uint16_t *port) /* OUT */
{
mongoc_socket_t *client;
struct sockaddr_storage addr = {0};
mongoc_socklen_t addrlen = sizeof addr;
bool try_again = false;
bool failed = false;
#ifdef _WIN32
SOCKET sd;
#else
int sd;
#endif
ENTRY;
BSON_ASSERT (sock);
again:
errno = 0;
sd = accept (sock->sd, (mongoc_sockaddr_t *) &addr, &addrlen);
_mongoc_socket_capture_errno (sock);
#ifdef _WIN32
failed = (sd == INVALID_SOCKET);
#else
failed = (sd == -1);
#endif
try_again = (failed && _mongoc_socket_errno_is_again (sock));
if (failed && try_again) {
if (_mongoc_socket_wait (sock, POLLIN, expire_at)) {
GOTO (again);
}
RETURN (NULL);
} else if (failed) {
RETURN (NULL);
} else if (!_mongoc_socket_setflags (sd)) {
#ifdef _WIN32
closesocket (sd);
#else
close (sd);
#endif
RETURN (NULL);
}
client = (mongoc_socket_t *) bson_malloc0 (sizeof *client);
client->sd = sd;
if (port) {
if (addr.ss_family == AF_INET) {
struct sockaddr_in *tmp = (struct sockaddr_in *) &addr;
*port = ntohs (tmp->sin_port);
} else {
struct sockaddr_in6 *tmp = (struct sockaddr_in6 *) &addr;
*port = ntohs (tmp->sin6_port);
}
}
if (!_mongoc_socket_setnodelay (client->sd)) {
MONGOC_WARNING ("Failed to enable TCP_NODELAY.");
}
RETURN (client);
}
/*
*--------------------------------------------------------------------------
*
* mongo_socket_bind --
*
* A wrapper around bind().
*
* Returns:
* 0 on success, -1 on failure and errno is set.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int
mongoc_socket_bind (mongoc_socket_t *sock, /* IN */
const struct sockaddr *addr, /* IN */
mongoc_socklen_t addrlen) /* IN */
{
int ret;
ENTRY;
BSON_ASSERT (sock);
BSON_ASSERT (addr);
BSON_ASSERT (addrlen);
ret = bind (sock->sd, addr, addrlen);
_mongoc_socket_capture_errno (sock);
RETURN (ret);
}
int
mongoc_socket_close (mongoc_socket_t *sock) /* IN */
{
bool owned;
ENTRY;
BSON_ASSERT (sock);
#ifdef _WIN32
owned = (sock->pid == (int) _getpid ());
if (sock->sd != INVALID_SOCKET) {
if (owned) {
shutdown (sock->sd, SD_BOTH);
}
if (0 == closesocket (sock->sd)) {
sock->sd = INVALID_SOCKET;
} else {
_mongoc_socket_capture_errno (sock);
RETURN (-1);
}
}
RETURN (0);
#else
owned = (sock->pid == (int) getpid ());
if (sock->sd != -1) {
if (owned) {
shutdown (sock->sd, SHUT_RDWR);
}
if (0 == close (sock->sd)) {
sock->sd = -1;
} else {
_mongoc_socket_capture_errno (sock);
RETURN (-1);
}
}
RETURN (0);
#endif
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_connect --
*
* Performs a socket connection but will fail if @expire_at is
* reached by the monotonic clock.
*
* Returns:
* 0 if success, otherwise -1 and errno is set.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int
mongoc_socket_connect (mongoc_socket_t *sock, /* IN */
const struct sockaddr *addr, /* IN */
mongoc_socklen_t addrlen, /* IN */
int64_t expire_at) /* IN */
{
bool try_again = false;
bool failed = false;
int ret;
int optval;
/* getsockopt parameter types vary, we check in CheckCompiler.m4 */
mongoc_socklen_t optlen = (mongoc_socklen_t) sizeof optval;
ENTRY;
BSON_ASSERT (sock);
BSON_ASSERT (addr);
BSON_ASSERT (addrlen);
ret = connect (sock->sd, addr, addrlen);
#ifdef _WIN32
if (ret == SOCKET_ERROR) {
#else
if (ret == -1) {
#endif
_mongoc_socket_capture_errno (sock);
failed = true;
try_again = _mongoc_socket_errno_is_again (sock);
}
if (failed && try_again) {
if (_mongoc_socket_wait (sock, POLLOUT, expire_at)) {
optval = -1;
ret = getsockopt (
sock->sd, SOL_SOCKET, SO_ERROR, (char *) &optval, &optlen);
if ((ret == 0) && (optval == 0)) {
RETURN (0);
} else {
errno = sock->errno_ = optval;
}
}
RETURN (-1);
} else if (failed) {
RETURN (-1);
} else {
RETURN (0);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_destroy --
*
* Cleanup after a mongoc_socket_t structure, possibly closing
* underlying sockets.
*
* Returns:
* None.
*
* Side effects:
* @sock is freed and should be considered invalid.
*
*--------------------------------------------------------------------------
*/
void
mongoc_socket_destroy (mongoc_socket_t *sock) /* IN */
{
if (sock) {
mongoc_socket_close (sock);
bson_free (sock);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_listen --
*
* Listen for incoming requests with a backlog up to @backlog.
*
* If @backlog is zero, a sensible default will be chosen.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int
mongoc_socket_listen (mongoc_socket_t *sock, /* IN */
unsigned int backlog) /* IN */
{
int ret;
ENTRY;
BSON_ASSERT (sock);
if (backlog == 0) {
backlog = 10;
}
ret = listen (sock->sd, backlog);
_mongoc_socket_capture_errno (sock);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_new --
*
* Create a new socket and store the current process id on it.
*
* Free the result with mongoc_socket_destroy().
*
* Returns:
* A newly allocated socket.
* NULL on failure.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_socket_t *
mongoc_socket_new (int domain, /* IN */
int type, /* IN */
int protocol) /* IN */
{
mongoc_socket_t *sock;
#ifdef _WIN32
SOCKET sd;
#else
int sd;
#endif
ENTRY;
sd = socket (domain, type, protocol);
#ifdef _WIN32
if (sd == INVALID_SOCKET) {
#else
if (sd == -1) {
#endif
RETURN (NULL);
}
if (!_mongoc_socket_setflags (sd)) {
GOTO (fail);
}
if (domain != AF_UNIX) {
if (!_mongoc_socket_setnodelay (sd)) {
MONGOC_WARNING ("Failed to enable TCP_NODELAY.");
}
_mongoc_socket_setkeepalive (sd);
}
sock = (mongoc_socket_t *) bson_malloc0 (sizeof *sock);
sock->sd = sd;
sock->domain = domain;
#ifdef _WIN32
sock->pid = (int) _getpid ();
#else
sock->pid = (int) getpid ();
#endif
RETURN (sock);
fail:
#ifdef _WIN32
closesocket (sd);
#else
close (sd);
#endif
RETURN (NULL);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_recv --
*
* A portable wrapper around recv() that also respects an absolute
* timeout.
*
* @expire_at is 0 for no blocking, -1 for infinite blocking,
* or a time using the monotonic clock to expire. Calculate this
* using bson_get_monotonic_time() + N_MICROSECONDS.
*
* Returns:
* The number of bytes received on success.
* 0 on end of stream.
* -1 on failure.
*
* Side effects:
* @buf will be read into.
*
*--------------------------------------------------------------------------
*/
ssize_t
mongoc_socket_recv (mongoc_socket_t *sock, /* IN */
void *buf, /* OUT */
size_t buflen, /* IN */
int flags, /* IN */
int64_t expire_at) /* IN */
{
ssize_t ret = 0;
bool failed = false;
ENTRY;
BSON_ASSERT (sock);
BSON_ASSERT (buf);
BSON_ASSERT (buflen);
again:
sock->errno_ = 0;
#ifdef _WIN32
ret = recv (sock->sd, (char *) buf, (int) buflen, flags);
failed = (ret == SOCKET_ERROR);
#else
ret = recv (sock->sd, buf, buflen, flags);
failed = (ret == -1);
#endif
if (failed) {
_mongoc_socket_capture_errno (sock);
if (_mongoc_socket_errno_is_again (sock) &&
_mongoc_socket_wait (sock, POLLIN, expire_at)) {
GOTO (again);
}
}
if (failed) {
RETURN (-1);
}
mongoc_counter_streams_ingress_add (ret);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_setsockopt --
*
* A wrapper around setsockopt().
*
* Returns:
* 0 on success, -1 on failure.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int
mongoc_socket_setsockopt (mongoc_socket_t *sock, /* IN */
int level, /* IN */
int optname, /* IN */
const void *optval, /* IN */
mongoc_socklen_t optlen) /* IN */
{
int ret;
ENTRY;
BSON_ASSERT (sock);
ret = setsockopt (sock->sd, level, optname, optval, optlen);
_mongoc_socket_capture_errno (sock);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_send --
*
* A simplified wrapper around mongoc_socket_sendv().
*
* @expire_at is 0 for no blocking, -1 for infinite blocking,
* or a time using the monotonic clock to expire. Calculate this
* using bson_get_monotonic_time() + N_MICROSECONDS.
*
* Returns:
* -1 on failure. number of bytes written on success.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
ssize_t
mongoc_socket_send (mongoc_socket_t *sock, /* IN */
const void *buf, /* IN */
size_t buflen, /* IN */
int64_t expire_at) /* IN */
{
mongoc_iovec_t iov;
BSON_ASSERT (sock);
BSON_ASSERT (buf);
BSON_ASSERT (buflen);
iov.iov_base = (void *) buf;
iov.iov_len = buflen;
return mongoc_socket_sendv (sock, &iov, 1, expire_at);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_socket_try_sendv_slow --
*
* A slow variant of _mongoc_socket_try_sendv() that sends each
* iovec entry one by one. This can happen if we hit EMSGSIZE
* with sendmsg() on various POSIX systems or WSASend()+WSAEMSGSIZE
* on Windows.
*
* Returns:
* the number of bytes sent or -1 and errno is set.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static ssize_t
_mongoc_socket_try_sendv_slow (mongoc_socket_t *sock, /* IN */
mongoc_iovec_t *iov, /* IN */
size_t iovcnt) /* IN */
{
ssize_t ret = 0;
size_t i;
ssize_t wrote;
ENTRY;
BSON_ASSERT (sock);
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
for (i = 0; i < iovcnt; i++) {
wrote = send (sock->sd, iov[i].iov_base, iov[i].iov_len, 0);
#ifdef _WIN32
if (wrote == SOCKET_ERROR) {
#else
if (wrote == -1) {
#endif
_mongoc_socket_capture_errno (sock);
if (!_mongoc_socket_errno_is_again (sock)) {
RETURN (-1);
}
RETURN (ret ? ret : -1);
}
ret += wrote;
if (wrote != iov[i].iov_len) {
RETURN (ret);
}
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_socket_try_sendv --
*
* Helper used by mongoc_socket_sendv() to try to write as many
* bytes to the underlying socket until the socket buffer is full.
*
* This is performed in a non-blocking fashion.
*
* Returns:
* -1 on failure. the number of bytes written on success.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static ssize_t
_mongoc_socket_try_sendv (mongoc_socket_t *sock, /* IN */
mongoc_iovec_t *iov, /* IN */
size_t iovcnt) /* IN */
{
#ifdef _WIN32
DWORD dwNumberofBytesSent = 0;
int ret;
#else
struct msghdr msg;
ssize_t ret;
#endif
ENTRY;
BSON_ASSERT (sock);
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
DUMP_IOVEC (sendbuf, iov, iovcnt);
#ifdef _WIN32
ret = WSASend (
sock->sd, (LPWSABUF) iov, iovcnt, &dwNumberofBytesSent, 0, NULL, NULL);
TRACE ("WSASend sent: %ld (out of: %ld), ret: %d",
dwNumberofBytesSent,
iov->iov_len,
ret);
#else
memset (&msg, 0, sizeof msg);
msg.msg_iov = iov;
msg.msg_iovlen = (int) iovcnt;
ret = sendmsg (sock->sd,
&msg,
#ifdef MSG_NOSIGNAL
MSG_NOSIGNAL);
#else
0);
#endif
TRACE ("Send %ld out of %ld bytes", ret, iov->iov_len);
#endif
#ifdef _WIN32
if (ret == SOCKET_ERROR) {
#else
if (ret == -1) {
#endif
_mongoc_socket_capture_errno (sock);
/*
* Check to see if we have sent an iovec too large for sendmsg to
* complete. If so, we need to fallback to the slow path of multiple
* send() commands.
*/
#ifdef _WIN32
if (mongoc_socket_errno (sock) == WSAEMSGSIZE) {
#else
if (mongoc_socket_errno (sock) == EMSGSIZE) {
#endif
RETURN (_mongoc_socket_try_sendv_slow (sock, iov, iovcnt));
}
RETURN (-1);
}
#ifdef _WIN32
RETURN (dwNumberofBytesSent);
#else
RETURN (ret);
#endif
}
/*
*--------------------------------------------------------------------------
*
* mongoc_socket_sendv --
*
* A wrapper around using sendmsg() to send an iovec.
* This also deals with the structure differences between
* WSABUF and struct iovec.
*
* @expire_at is 0 for no blocking, -1 for infinite blocking,
* or a time using the monotonic clock to expire. Calculate this
* using bson_get_monotonic_time() + N_MICROSECONDS.
*
* Returns:
* -1 on failure.
* the number of bytes written on success.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
ssize_t
mongoc_socket_sendv (mongoc_socket_t *sock, /* IN */
mongoc_iovec_t *in_iov, /* IN */
size_t iovcnt, /* IN */
int64_t expire_at) /* IN */
{
ssize_t ret = 0;
ssize_t sent;
size_t cur = 0;
mongoc_iovec_t *iov;
ENTRY;
BSON_ASSERT (sock);
BSON_ASSERT (in_iov);
BSON_ASSERT (iovcnt);
iov = bson_malloc (sizeof (*iov) * iovcnt);
memcpy (iov, in_iov, sizeof (*iov) * iovcnt);
for (;;) {
sent = _mongoc_socket_try_sendv (sock, &iov[cur], iovcnt - cur);
TRACE (
"Sent %ld (of %ld) out of iovcnt=%ld", sent, iov[cur].iov_len, iovcnt);
/*
* If we failed with anything other than EAGAIN or EWOULDBLOCK,
* we should fail immediately as there is another issue with the
* underlying socket.
*/
if (sent == -1) {
if (!_mongoc_socket_errno_is_again (sock)) {
ret = -1;
GOTO (CLEANUP);
}
}
/*
* Update internal stream counters.
*/
if (sent > 0) {
ret += sent;
mongoc_counter_streams_egress_add (sent);
/*
* Subtract the sent amount from what we still need to send.
*/
while ((cur < iovcnt) && (sent >= (ssize_t) iov[cur].iov_len)) {
TRACE ("still got bytes left: sent -= iov_len: %ld -= %ld",
sent,
iov[cur].iov_len);
sent -= iov[cur++].iov_len;
}
/*
* Check if that made us finish all of the iovecs. If so, we are done
* sending data over the socket.
*/
if (cur == iovcnt) {
TRACE ("%s", "Finished the iovecs");
break;
}
/*
* Increment the current iovec buffer to its proper offset and adjust
* the number of bytes to write.
*/
TRACE ("Seeked io_base+%ld", sent);
TRACE (
"Subtracting iov_len -= sent; %ld -= %ld", iov[cur].iov_len, sent);
iov[cur].iov_base = ((char *) iov[cur].iov_base) + sent;
iov[cur].iov_len -= sent;
TRACE ("iov_len remaining %ld", iov[cur].iov_len);
BSON_ASSERT (iovcnt - cur);
BSON_ASSERT (iov[cur].iov_len);
} else if (OPERATION_EXPIRED (expire_at)) {
if (expire_at > 0) {
mongoc_counter_streams_timeout_inc ();
}
GOTO (CLEANUP);
}
/*
* Block on poll() until our desired condition is met.
*/
if (!_mongoc_socket_wait (sock, POLLOUT, expire_at)) {
GOTO (CLEANUP);
}
}
CLEANUP:
bson_free (iov);
RETURN (ret);
}
int
mongoc_socket_getsockname (mongoc_socket_t *sock, /* IN */
struct sockaddr *addr, /* OUT */
mongoc_socklen_t *addrlen) /* INOUT */
{
int ret;
ENTRY;
BSON_ASSERT (sock);
ret = getsockname (sock->sd, addr, addrlen);
_mongoc_socket_capture_errno (sock);
RETURN (ret);
}
char *
mongoc_socket_getnameinfo (mongoc_socket_t *sock) /* IN */
{
/* getpeername parameter types vary, we check in CheckCompiler.m4 */
struct sockaddr_storage addr;
mongoc_socklen_t len = (mongoc_socklen_t) sizeof addr;
char *ret;
char host[BSON_HOST_NAME_MAX + 1];
ENTRY;
BSON_ASSERT (sock);
if (getpeername (sock->sd, (struct sockaddr *) &addr, &len)) {
RETURN (NULL);
}
if (getnameinfo (
(struct sockaddr *) &addr, len, host, sizeof host, NULL, 0, 0)) {
RETURN (NULL);
}
ret = bson_strdup (host);
RETURN (ret);
}
bool
mongoc_socket_check_closed (mongoc_socket_t *sock) /* IN */
{
bool closed = false;
char buf[1];
ssize_t r;
if (_mongoc_socket_wait (sock, POLLIN, 0)) {
sock->errno_ = 0;
r = recv (sock->sd, buf, 1, MSG_PEEK);
if (r < 0) {
_mongoc_socket_capture_errno (sock);
}
if (r < 1) {
closed = true;
}
}
return closed;
}
/*
*
*--------------------------------------------------------------------------
*
* mongoc_socket_inet_ntop --
*
* Convert the ip from addrinfo into a c string.
*
* Returns:
* The value is returned into 'buffer'. The memory has to be allocated
* by the caller
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_socket_inet_ntop (struct addrinfo *rp, /* IN */
char *buf, /* INOUT */
size_t buflen) /* IN */
{
void *ptr;
char tmp[256];
switch (rp->ai_family) {
case AF_INET:
ptr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr;
inet_ntop (rp->ai_family, ptr, tmp, sizeof (tmp));
bson_snprintf (buf, buflen, "ipv4 %s", tmp);
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr;
inet_ntop (rp->ai_family, ptr, tmp, sizeof (tmp));
bson_snprintf (buf, buflen, "ipv6 %s", tmp);
break;
default:
bson_snprintf (buf, buflen, "unknown ip %d", rp->ai_family);
break;
}
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h
similarity index 56%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h
index f3a35b26..26de3478 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h
@@ -1,42 +1,58 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_SSL_PRIVATE_H
#define MONGOC_SSL_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-uri-private.h"
BSON_BEGIN_DECLS
+typedef struct {
+ bool tls_disable_certificate_revocation_check;
+ bool tls_disable_ocsp_endpoint_check;
+} _mongoc_internal_tls_opts_t;
char *
mongoc_ssl_extract_subject (const char *filename, const char *passphrase);
void
-_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt, mongoc_uri_t *uri);
+_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt,
+ _mongoc_internal_tls_opts_t *internal,
+ mongoc_uri_t *uri);
void
-_mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src, mongoc_ssl_opt_t *dst);
+_mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src,
+ mongoc_ssl_opt_t *dst,
+ bool copy_internal);
+
+bool
+_mongoc_ssl_opts_disable_certificate_revocation_check (
+ const mongoc_ssl_opt_t *ssl_opt);
+
+bool
+_mongoc_ssl_opts_disable_ocsp_endpoint_check (const mongoc_ssl_opt_t *ssl_opt);
+
void
-_mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt);
+_mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt, bool free_internal);
BSON_END_DECLS
#endif /* MONGOC_SSL_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c
similarity index 72%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c
index 69e48f9b..ad0f95db 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c
@@ -1,140 +1,182 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL
#include <bson/bson.h>
#include "mongoc-ssl.h"
#include "mongoc-ssl-private.h"
#include "mongoc-log.h"
#include "mongoc-uri.h"
#if defined(MONGOC_ENABLE_SSL_OPENSSL)
#include "mongoc-openssl-private.h"
#elif defined(MONGOC_ENABLE_SSL_LIBRESSL)
#include "mongoc-libressl-private.h"
#elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT)
#include "mongoc-secure-transport-private.h"
#elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL)
#include "mongoc-secure-channel-private.h"
#endif
/* TODO: we could populate these from a config or something further down the
* road for providing defaults */
#ifndef MONGOC_SSL_DEFAULT_TRUST_FILE
#define MONGOC_SSL_DEFAULT_TRUST_FILE NULL
#endif
#ifndef MONGOC_SSL_DEFAULT_TRUST_DIR
#define MONGOC_SSL_DEFAULT_TRUST_DIR NULL
#endif
static mongoc_ssl_opt_t gMongocSslOptDefault = {
NULL, NULL, MONGOC_SSL_DEFAULT_TRUST_FILE, MONGOC_SSL_DEFAULT_TRUST_DIR,
};
const mongoc_ssl_opt_t *
mongoc_ssl_opt_get_default (void)
{
return &gMongocSslOptDefault;
}
char *
mongoc_ssl_extract_subject (const char *filename, const char *passphrase)
{
char *retval;
if (!filename) {
MONGOC_ERROR ("No filename provided to extract subject from");
return NULL;
}
#ifdef _WIN32
if (_access (filename, 0) != 0) {
#else
if (access (filename, R_OK) != 0) {
#endif
MONGOC_ERROR ("Can't extract subject from unreadable file: '%s'",
filename);
return NULL;
}
#if defined(MONGOC_ENABLE_SSL_OPENSSL)
retval = _mongoc_openssl_extract_subject (filename, passphrase);
#elif defined(MONGOC_ENABLE_SSL_LIBRESSL)
MONGOC_WARNING (
"libtls doesn't support automatically extracting subject from "
"certificate to use with authentication");
retval = NULL;
#elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT)
retval = _mongoc_secure_transport_extract_subject (filename, passphrase);
#elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL)
retval = _mongoc_secure_channel_extract_subject (filename, passphrase);
#endif
if (!retval) {
MONGOC_ERROR ("Can't extract subject from file '%s'", filename);
}
return retval;
}
void
-_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt, mongoc_uri_t *uri)
+_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt,
+ _mongoc_internal_tls_opts_t *internal,
+ mongoc_uri_t *uri)
{
bool insecure =
mongoc_uri_get_option_as_bool (uri, MONGOC_URI_TLSINSECURE, false);
ssl_opt->pem_file = mongoc_uri_get_option_as_utf8 (
uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, NULL);
ssl_opt->pem_pwd = mongoc_uri_get_option_as_utf8 (
uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, NULL);
ssl_opt->ca_file =
mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCAFILE, NULL);
ssl_opt->weak_cert_validation = mongoc_uri_get_option_as_bool (
uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, insecure);
ssl_opt->allow_invalid_hostname = mongoc_uri_get_option_as_bool (
uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, insecure);
+ ssl_opt->internal = internal;
+ internal->tls_disable_certificate_revocation_check =
+ mongoc_uri_get_option_as_bool (
+ uri, MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK, false);
+ internal->tls_disable_ocsp_endpoint_check = mongoc_uri_get_option_as_bool (
+ uri, MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK, false);
}
void
-_mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src, mongoc_ssl_opt_t *dst)
+_mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src,
+ mongoc_ssl_opt_t *dst,
+ bool copy_internal)
{
BSON_ASSERT (src);
BSON_ASSERT (dst);
dst->pem_file = bson_strdup (src->pem_file);
dst->pem_pwd = bson_strdup (src->pem_pwd);
dst->ca_file = bson_strdup (src->ca_file);
dst->ca_dir = bson_strdup (src->ca_dir);
dst->crl_file = bson_strdup (src->crl_file);
dst->weak_cert_validation = src->weak_cert_validation;
dst->allow_invalid_hostname = src->allow_invalid_hostname;
+ if (copy_internal) {
+ dst->internal = NULL;
+ if (src->internal) {
+ dst->internal = bson_malloc (sizeof (_mongoc_internal_tls_opts_t));
+ memcpy (
+ dst->internal, src->internal, sizeof (_mongoc_internal_tls_opts_t));
+ }
+ }
}
void
-_mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt)
+_mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt, bool free_internal)
{
bson_free ((char *) opt->pem_file);
bson_free ((char *) opt->pem_pwd);
bson_free ((char *) opt->ca_file);
bson_free ((char *) opt->ca_dir);
bson_free ((char *) opt->crl_file);
+ if (free_internal) {
+ bson_free (opt->internal);
+ }
+}
+
+bool
+_mongoc_ssl_opts_disable_certificate_revocation_check (
+ const mongoc_ssl_opt_t *ssl_opt)
+{
+ if (!ssl_opt->internal) {
+ return false;
+ }
+ return ((_mongoc_internal_tls_opts_t *) ssl_opt->internal)
+ ->tls_disable_certificate_revocation_check;
+}
+
+bool
+_mongoc_ssl_opts_disable_ocsp_endpoint_check (const mongoc_ssl_opt_t *ssl_opt)
+{
+ if (!ssl_opt->internal) {
+ return false;
+ }
+ return ((_mongoc_internal_tls_opts_t *) ssl_opt->internal)
+ ->tls_disable_ocsp_endpoint_check;
}
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h
index 3816a536..26347ef0 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h
@@ -1,51 +1,52 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_SSL_H
#define MONGOC_SSL_H
#include <bson/bson.h>
#include "mongoc-macros.h"
BSON_BEGIN_DECLS
typedef struct _mongoc_ssl_opt_t mongoc_ssl_opt_t;
struct _mongoc_ssl_opt_t {
const char *pem_file;
const char *pem_pwd;
const char *ca_file;
const char *ca_dir;
const char *crl_file;
bool weak_cert_validation;
bool allow_invalid_hostname;
- void *padding[7];
+ void *internal;
+ void *padding[6];
};
MONGOC_EXPORT (const mongoc_ssl_opt_t *)
mongoc_ssl_opt_get_default (void) BSON_GNUC_PURE;
BSON_END_DECLS
#endif /* MONGOC_SSL_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c
index 8da639d2..82289b63 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c
@@ -1,543 +1,554 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_LIBRESSL
#include <bson/bson.h>
#include "mongoc-trace-private.h"
#include "mongoc-log.h"
#include "mongoc-stream-tls.h"
#include "mongoc-stream-tls-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-tls-libressl-private.h"
#include "mongoc-libressl-private.h"
#include "mongoc-ssl.h"
+#include "mongoc-ssl-private.h"
#include "mongoc-error.h"
#include "mongoc-counters-private.h"
#include "mongoc-stream-socket.h"
#include "mongoc-socket-private.h"
#include <tls.h>
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "stream-tls-libressl"
static void
_mongoc_stream_tls_libressl_destroy (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
ENTRY;
BSON_ASSERT (libressl);
tls_close (libressl->ctx);
tls_free (libressl->ctx);
tls_config_free (libressl->config);
mongoc_stream_destroy (tls->base_stream);
bson_free (libressl);
bson_free (stream);
mongoc_counter_streams_active_dec ();
mongoc_counter_streams_disposed_inc ();
EXIT;
}
static void
_mongoc_stream_tls_libressl_failed (mongoc_stream_t *stream)
{
ENTRY;
_mongoc_stream_tls_libressl_destroy (stream);
EXIT;
}
static int
_mongoc_stream_tls_libressl_close (mongoc_stream_t *stream)
{
int ret = 0;
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
ENTRY;
BSON_ASSERT (libressl);
ret = mongoc_stream_close (tls->base_stream);
RETURN (ret);
}
static int
_mongoc_stream_tls_libressl_flush (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
ENTRY;
BSON_ASSERT (libressl);
RETURN (0);
}
static ssize_t
_mongoc_stream_tls_libressl_write (mongoc_stream_t *stream,
char *buf,
size_t buf_len)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
mongoc_stream_poll_t poller;
ssize_t total_write = 0;
ssize_t ret;
int64_t now;
int64_t expire = 0;
ENTRY;
BSON_ASSERT (libressl);
if (tls->timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL);
}
do {
poller.stream = stream;
poller.revents = 0;
poller.events = POLLOUT;
ret = tls_write (libressl->ctx, buf, buf_len);
if (ret == TLS_WANT_POLLIN) {
poller.events = POLLIN;
mongoc_stream_poll (&poller, 1, tls->timeout_msec);
} else if (ret == TLS_WANT_POLLOUT) {
poller.events = POLLOUT;
mongoc_stream_poll (&poller, 1, tls->timeout_msec);
} else if (ret < 0) {
RETURN (total_write);
} else {
buf += ret;
buf_len -= ret;
total_write += ret;
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (ret == 0) {
mongoc_counter_streams_timeout_inc ();
break;
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
} while (buf_len > 0);
RETURN (total_write);
}
/* This is copypasta from _mongoc_stream_tls_openssl_writev */
#define MONGOC_STREAM_TLS_BUFFER_SIZE 4096
static ssize_t
_mongoc_stream_tls_libressl_writev (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
char buf[MONGOC_STREAM_TLS_BUFFER_SIZE];
ssize_t ret = 0;
ssize_t child_ret;
size_t i;
size_t iov_pos = 0;
/* There's a bit of a dance to coalesce vectorized writes into
* MONGOC_STREAM_TLS_BUFFER_SIZE'd writes to avoid lots of small tls
* packets.
*
* The basic idea is that we want to combine writes in the buffer if they're
* smaller than the buffer, flushing as it gets full. For larger writes, or
* the last write in the iovec array, we want to ignore the buffer and just
* write immediately. We take care of doing buffer writes by re-invoking
* ourself with a single iovec_t, pointing at our stack buffer.
*/
char *buf_head = buf;
char *buf_tail = buf;
char *buf_end = buf + MONGOC_STREAM_TLS_BUFFER_SIZE;
size_t bytes;
char *to_write = NULL;
size_t to_write_len;
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
BSON_ASSERT (libressl);
ENTRY;
tls->timeout_msec = timeout_msec;
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
if (buf_head != buf_tail ||
((i + 1 < iovcnt) &&
((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) {
/* If we have either of:
* - buffered bytes already
* - another iovec to send after this one and we don't have more
* bytes to send than the size of the buffer.
*
* copy into the buffer */
bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail);
memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes);
buf_tail += bytes;
iov_pos += bytes;
if (buf_tail == buf_end) {
/* If we're full, request send */
to_write = buf_head;
to_write_len = buf_tail - buf_head;
buf_tail = buf_head = buf;
}
} else {
/* Didn't buffer, so just write it through */
to_write = (char *) iov[i].iov_base + iov_pos;
to_write_len = iov[i].iov_len - iov_pos;
iov_pos += to_write_len;
}
if (to_write) {
/* We get here if we buffered some bytes and filled the buffer, or
* if we didn't buffer and have to send out of the iovec */
child_ret = _mongoc_stream_tls_libressl_write (
stream, to_write, to_write_len);
if (child_ret < 0) {
RETURN (ret);
}
ret += child_ret;
if (child_ret < to_write_len) {
/* we timed out, so send back what we could send */
RETURN (ret);
}
to_write = NULL;
}
}
}
if (buf_head != buf_tail) {
/* If we have any bytes buffered, send */
child_ret = _mongoc_stream_tls_libressl_write (
stream, buf_head, buf_tail - buf_head);
if (child_ret < 0) {
RETURN (child_ret);
}
ret += child_ret;
}
if (ret >= 0) {
mongoc_counter_streams_egress_add (ret);
}
TRACE ("Returning %d", (int) ret);
RETURN (ret);
}
/* This function is copypasta of _mongoc_stream_tls_openssl_readv */
static ssize_t
_mongoc_stream_tls_libressl_readv (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
size_t min_bytes,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
ssize_t ret = 0;
ssize_t read_ret;
size_t i;
size_t iov_pos = 0;
int64_t now;
int64_t expire = 0;
mongoc_stream_poll_t poller;
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
BSON_ASSERT (libressl);
ENTRY;
tls->timeout_msec = timeout_msec;
if (timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (timeout_msec * 1000UL);
}
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
poller.stream = stream;
poller.revents = 0;
poller.events = POLLIN;
read_ret = tls_read (libressl->ctx,
(char *) iov[i].iov_base + iov_pos,
(int) (iov[i].iov_len - iov_pos));
if (read_ret == TLS_WANT_POLLIN) {
poller.events = POLLIN;
mongoc_stream_poll (&poller, 1, tls->timeout_msec);
} else if (read_ret == TLS_WANT_POLLOUT) {
poller.events = POLLOUT;
mongoc_stream_poll (&poller, 1, tls->timeout_msec);
} else if (read_ret < 0) {
RETURN (ret);
} else {
iov_pos += read_ret;
ret += read_ret;
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (read_ret == 0) {
mongoc_counter_streams_timeout_inc ();
errno = ETIMEDOUT;
RETURN (-1);
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
if (ret > 0 && (size_t) ret >= min_bytes) {
mongoc_counter_streams_ingress_add (ret);
RETURN (ret);
}
}
}
if (ret >= 0) {
mongoc_counter_streams_ingress_add (ret);
}
RETURN (ret);
}
static int
_mongoc_stream_tls_libressl_setsockopt (mongoc_stream_t *stream,
int level,
int optname,
void *optval,
mongoc_socklen_t optlen)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
ENTRY;
BSON_ASSERT (libressl);
RETURN (mongoc_stream_setsockopt (
tls->base_stream, level, optname, optval, optlen));
}
static mongoc_stream_t *
_mongoc_stream_tls_libressl_get_base_stream (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
ENTRY;
BSON_ASSERT (libressl);
RETURN (tls->base_stream);
}
static bool
_mongoc_stream_tls_libressl_check_closed (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
ENTRY;
BSON_ASSERT (libressl);
RETURN (mongoc_stream_check_closed (tls->base_stream));
}
bool
mongoc_stream_tls_libressl_handshake (mongoc_stream_t *stream,
const char *host,
int *events,
bson_error_t *error)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_libressl_t *libressl =
(mongoc_stream_tls_libressl_t *) tls->ctx;
int ret;
ENTRY;
BSON_ASSERT (libressl);
ret = tls_handshake (libressl->ctx);
if (ret == TLS_WANT_POLLIN) {
*events = POLLIN;
} else if (ret == TLS_WANT_POLLOUT) {
*events = POLLOUT;
} else if (ret < 0) {
*events = 0;
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"TLS handshake failed: %s",
tls_error (libressl->ctx));
RETURN (false);
} else {
RETURN (true);
}
RETURN (false);
}
static bool
_mongoc_stream_tls_libressl_timed_out (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
ENTRY;
RETURN (mongoc_stream_timed_out (tls->base_stream));
}
static bool
_mongoc_stream_tls_libressl_should_retry (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
ENTRY;
RETURN (mongoc_stream_should_retry (tls->base_stream));
}
mongoc_stream_t *
mongoc_stream_tls_libressl_new (mongoc_stream_t *base_stream,
const char *host,
mongoc_ssl_opt_t *opt,
int client)
{
mongoc_stream_tls_t *tls;
mongoc_stream_tls_libressl_t *libressl;
ENTRY;
BSON_ASSERT (base_stream);
BSON_ASSERT (opt);
if (opt->crl_file) {
MONGOC_ERROR (
"Setting mongoc_ssl_opt_t.crl_file has no effect when built "
"against libtls");
RETURN (false);
}
libressl = (mongoc_stream_tls_libressl_t *) bson_malloc0 (sizeof *libressl);
tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls);
tls->parent.type = MONGOC_STREAM_TLS;
tls->parent.destroy = _mongoc_stream_tls_libressl_destroy;
tls->parent.failed = _mongoc_stream_tls_libressl_failed;
tls->parent.close = _mongoc_stream_tls_libressl_close;
tls->parent.flush = _mongoc_stream_tls_libressl_flush;
tls->parent.writev = _mongoc_stream_tls_libressl_writev;
tls->parent.readv = _mongoc_stream_tls_libressl_readv;
tls->parent.setsockopt = _mongoc_stream_tls_libressl_setsockopt;
tls->parent.get_base_stream = _mongoc_stream_tls_libressl_get_base_stream;
tls->parent.check_closed = _mongoc_stream_tls_libressl_check_closed;
tls->parent.timed_out = _mongoc_stream_tls_libressl_timed_out;
tls->parent.should_retry = _mongoc_stream_tls_libressl_should_retry;
memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts);
tls->handshake = mongoc_stream_tls_libressl_handshake;
tls->ctx = (void *) libressl;
tls->timeout_msec = -1;
tls->base_stream = base_stream;
libressl->ctx = client ? tls_client () : tls_server ();
libressl->config = tls_config_new ();
if (opt->weak_cert_validation) {
tls_config_insecure_noverifycert (libressl->config);
tls_config_insecure_noverifytime (libressl->config);
}
if (opt->allow_invalid_hostname) {
tls_config_insecure_noverifyname (libressl->config);
}
tls_config_set_ciphers (libressl->config, "compat");
mongoc_libressl_setup_certificate (libressl, opt);
mongoc_libressl_setup_ca (libressl, opt);
{
mongoc_stream_t *stream = base_stream;
do {
if (stream->type == MONGOC_STREAM_SOCKET) {
int socket = mongoc_stream_socket_get_socket (
(mongoc_stream_socket_t *) stream)
->sd;
if (tls_configure (libressl->ctx, libressl->config) == -1) {
MONGOC_ERROR ("%s", tls_config_error (libressl->config));
RETURN (false);
}
if (tls_connect_socket (libressl->ctx, socket, host) == -1) {
MONGOC_ERROR ("%s", tls_error (libressl->ctx));
RETURN (false);
}
break;
}
} while ((stream = mongoc_stream_get_base_stream (stream)));
}
mongoc_counter_streams_active_inc ();
+
+ if (_mongoc_ssl_opts_disable_certificate_revocation_check (opt)) {
+ MONGOC_ERROR ("Setting tlsDisableCertificateRevocationCheck has no "
+ "effect when built against libtls");
+ }
+
+ if (_mongoc_ssl_opts_disable_ocsp_endpoint_check (opt)) {
+ MONGOC_ERROR ("Setting tlsDisableOCSPEndpointCheck has no effect when "
+ "built against libtls");
+ }
RETURN ((mongoc_stream_t *) tls);
}
#endif /* MONGOC_ENABLE_SSL_LIBRESSL */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h
similarity index 73%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h
index c5bdd62f..2d8443ae 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h
@@ -1,43 +1,56 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_STREAM_TLS_OPENSSL_PRIVATE_H
#define MONGOC_STREAM_TLS_OPENSSL_PRIVATE_H
#ifdef MONGOC_ENABLE_SSL_OPENSSL
#include <bson/bson.h>
BSON_BEGIN_DECLS
+typedef struct {
+ char *host;
+ bool allow_invalid_hostname;
+ bool weak_cert_validation;
+ bool disable_endpoint_check;
+ /* If reaching out to an OCSP responder requires TLS,
+ * use the same TLS options that the user provided. */
+ mongoc_ssl_opt_t ssl_opts;
+} mongoc_openssl_ocsp_opt_t;
+
+void
+mongoc_openssl_ocsp_opt_destroy (void *ocsp_opt);
/**
* mongoc_stream_tls_openssl_t:
*
* Private storage for handling callbacks from mongoc_stream and BIO_*
*/
typedef struct {
BIO *bio;
BIO_METHOD *meth;
SSL_CTX *ctx;
+ mongoc_openssl_ocsp_opt_t *ocsp_opts;
} mongoc_stream_tls_openssl_t;
BSON_END_DECLS
#endif /* MONGOC_ENABLE_SSL_OPENSSL */
#endif /* MONGOC_STREAM_TLS_OPENSSL_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
similarity index 88%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
index 809419cc..7ed203d1 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
@@ -1,779 +1,844 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_OPENSSL
#include <bson/bson.h>
#include <errno.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "mongoc-counters-private.h"
#include "mongoc-errno-private.h"
+#include "mongoc-ssl.h"
+#include "mongoc-ssl-private.h"
#include "mongoc-stream-tls.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-tls-private.h"
#include "mongoc-stream-tls-openssl-bio-private.h"
#include "mongoc-stream-tls-openssl-private.h"
#include "mongoc-openssl-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-log.h"
#include "mongoc-error.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "stream-tls-openssl"
#define MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE 4096
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
static void
BIO_meth_free (BIO_METHOD *meth)
{
/* Nothing to free pre OpenSSL 1.1.0 */
}
#endif
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_destroy --
*
* Cleanup after usage of a mongoc_stream_tls_openssl_t. Free all
*allocated
* resources and ensure connections are closed.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_stream_tls_openssl_destroy (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
BSON_ASSERT (tls);
BIO_free_all (openssl->bio);
openssl->bio = NULL;
BIO_meth_free (openssl->meth);
openssl->meth = NULL;
mongoc_stream_destroy (tls->base_stream);
tls->base_stream = NULL;
SSL_CTX_free (openssl->ctx);
openssl->ctx = NULL;
+ mongoc_openssl_ocsp_opt_destroy (openssl->ocsp_opts);
+ openssl->ocsp_opts = NULL;
+
bson_free (openssl);
bson_free (stream);
mongoc_counter_streams_active_dec ();
mongoc_counter_streams_disposed_inc ();
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_failed --
*
* Called on stream failure. Same as _mongoc_stream_tls_openssl_destroy()
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_stream_tls_openssl_failed (mongoc_stream_t *stream)
{
_mongoc_stream_tls_openssl_destroy (stream);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_close --
*
* Close the underlying socket.
*
* Linus dictates that you should not check the result of close()
* since there is a race condition with EAGAIN and a new file
* descriptor being opened.
*
* Returns:
* 0 on success; otherwise -1.
*
* Side effects:
* The BIO fd is closed.
*
*--------------------------------------------------------------------------
*/
static int
_mongoc_stream_tls_openssl_close (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
int ret = 0;
ENTRY;
BSON_ASSERT (tls);
ret = mongoc_stream_close (tls->base_stream);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_flush --
*
* Flush the underlying stream.
*
* Returns:
* 0 if successful; otherwise -1.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static int
_mongoc_stream_tls_openssl_flush (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
BSON_ASSERT (openssl);
return BIO_flush (openssl->bio);
}
static ssize_t
_mongoc_stream_tls_openssl_write (mongoc_stream_tls_t *tls,
char *buf,
size_t buf_len)
{
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
ssize_t ret;
int64_t now;
int64_t expire = 0;
ENTRY;
BSON_ASSERT (tls);
BSON_ASSERT (buf);
BSON_ASSERT (buf_len);
if (tls->timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL);
}
ret = BIO_write (openssl->bio, buf, buf_len);
if (ret <= 0) {
return ret;
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (ret < buf_len) {
mongoc_counter_streams_timeout_inc ();
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_writev --
*
* Write the iovec to the stream. This function will try to write
* all of the bytes or fail. If the number of bytes is not equal
* to the number requested, a failure or EOF has occurred.
*
* Returns:
* -1 on failure, otherwise the number of bytes written.
*
* Side effects:
* None.
*
* This function is copied as _mongoc_stream_tls_secure_transport_writev
*--------------------------------------------------------------------------
*/
static ssize_t
_mongoc_stream_tls_openssl_writev (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
char buf[MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE];
ssize_t ret = 0;
ssize_t child_ret;
size_t i;
size_t iov_pos = 0;
/* There's a bit of a dance to coalesce vectorized writes into
* MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE'd writes to avoid lots of small tls
* packets.
*
* The basic idea is that we want to combine writes in the buffer if they're
* smaller than the buffer, flushing as it gets full. For larger writes, or
* the last write in the iovec array, we want to ignore the buffer and just
* write immediately. We take care of doing buffer writes by re-invoking
* ourself with a single iovec_t, pointing at our stack buffer.
*/
char *buf_head = buf;
char *buf_tail = buf;
char *buf_end = buf + MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE;
size_t bytes;
char *to_write = NULL;
size_t to_write_len;
BSON_ASSERT (tls);
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
ENTRY;
tls->timeout_msec = timeout_msec;
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
if (buf_head != buf_tail ||
((i + 1 < iovcnt) &&
((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) {
/* If we have either of:
* - buffered bytes already
* - another iovec to send after this one and we don't have more
* bytes to send than the size of the buffer.
*
* copy into the buffer */
bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail);
memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes);
buf_tail += bytes;
iov_pos += bytes;
if (buf_tail == buf_end) {
/* If we're full, request send */
to_write = buf_head;
to_write_len = buf_tail - buf_head;
buf_tail = buf_head = buf;
}
} else {
/* Didn't buffer, so just write it through */
to_write = (char *) iov[i].iov_base + iov_pos;
to_write_len = iov[i].iov_len - iov_pos;
iov_pos += to_write_len;
}
if (to_write) {
/* We get here if we buffered some bytes and filled the buffer, or
* if we didn't buffer and have to send out of the iovec */
child_ret =
_mongoc_stream_tls_openssl_write (tls, to_write, to_write_len);
if (child_ret != to_write_len) {
TRACE ("Got child_ret: %ld while to_write_len is: %ld",
child_ret,
to_write_len);
}
if (child_ret < 0) {
TRACE ("Returning what I had (%ld) as apposed to the error "
"(%ld, errno:%d)",
ret,
child_ret,
errno);
RETURN (ret);
}
ret += child_ret;
if (child_ret < to_write_len) {
/* we timed out, so send back what we could send */
RETURN (ret);
}
to_write = NULL;
}
}
}
if (buf_head != buf_tail) {
/* If we have any bytes buffered, send */
child_ret =
_mongoc_stream_tls_openssl_write (tls, buf_head, buf_tail - buf_head);
if (child_ret < 0) {
RETURN (child_ret);
}
ret += child_ret;
}
if (ret >= 0) {
mongoc_counter_streams_egress_add (ret);
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_readv --
*
* Read from the stream into iov. This function will try to read
* all of the bytes or fail. If the number of bytes is not equal
* to the number requested, a failure or EOF has occurred.
*
* Returns:
* -1 on failure, 0 on EOF, otherwise the number of bytes read.
*
* Side effects:
* iov buffers will be written to.
*
* This function is copied as _mongoc_stream_tls_secure_transport_readv
*
*--------------------------------------------------------------------------
*/
static ssize_t
_mongoc_stream_tls_openssl_readv (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
size_t min_bytes,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
ssize_t ret = 0;
size_t i;
int read_ret;
size_t iov_pos = 0;
int64_t now;
int64_t expire = 0;
ENTRY;
BSON_ASSERT (tls);
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
tls->timeout_msec = timeout_msec;
if (timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (timeout_msec * 1000UL);
}
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
read_ret = BIO_read (openssl->bio,
(char *) iov[i].iov_base + iov_pos,
(int) (iov[i].iov_len - iov_pos));
/* https://www.openssl.org/docs/crypto/BIO_should_retry.html:
*
* If BIO_should_retry() returns false then the precise "error
* condition" depends on the BIO type that caused it and the return
* code of the BIO operation. For example if a call to BIO_read() on a
* socket BIO returns 0 and BIO_should_retry() is false then the cause
* will be that the connection closed.
*/
if (read_ret < 0 ||
(read_ret == 0 && !BIO_should_retry (openssl->bio))) {
return -1;
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (read_ret == 0) {
mongoc_counter_streams_timeout_inc ();
#ifdef _WIN32
errno = WSAETIMEDOUT;
#else
errno = ETIMEDOUT;
#endif
RETURN (-1);
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
ret += read_ret;
if ((size_t) ret >= min_bytes) {
mongoc_counter_streams_ingress_add (ret);
RETURN (ret);
}
iov_pos += read_ret;
}
}
if (ret >= 0) {
mongoc_counter_streams_ingress_add (ret);
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_setsockopt --
*
* Perform a setsockopt on the underlying stream.
*
* Returns:
* -1 on failure, otherwise opt specific value.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static int
_mongoc_stream_tls_openssl_setsockopt (mongoc_stream_t *stream,
int level,
int optname,
void *optval,
mongoc_socklen_t optlen)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
BSON_ASSERT (tls);
return mongoc_stream_setsockopt (
tls->base_stream, level, optname, optval, optlen);
}
static mongoc_stream_t *
_mongoc_stream_tls_openssl_get_base_stream (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
return tls->base_stream;
}
static bool
_mongoc_stream_tls_openssl_check_closed (mongoc_stream_t *stream) /* IN */
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
BSON_ASSERT (stream);
return mongoc_stream_check_closed (tls->base_stream);
}
/**
* mongoc_stream_tls_openssl_handshake:
*/
-bool
-mongoc_stream_tls_openssl_handshake (mongoc_stream_t *stream,
- const char *host,
- int *events,
- bson_error_t *error)
+static bool
+_mongoc_stream_tls_openssl_handshake (mongoc_stream_t *stream,
+ const char *host,
+ int *events,
+ bson_error_t *error)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
SSL *ssl;
BSON_ASSERT (tls);
BSON_ASSERT (host);
ENTRY;
BIO_get_ssl (openssl->bio, &ssl);
if (BIO_do_handshake (openssl->bio) == 1) {
- if (_mongoc_openssl_check_cert (
+ *events = 0;
+
+#ifdef MONGOC_ENABLE_OCSP_OPENSSL
+ /* Validate OCSP */
+ if (openssl->ocsp_opts &&
+ 1 != _mongoc_ocsp_tlsext_status (ssl, openssl->ocsp_opts)) {
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "TLS handshake failed: Failed OCSP verification");
+ RETURN (false);
+ }
+#endif
+
+ if (_mongoc_openssl_check_peer_hostname (
ssl, host, tls->ssl_opts.allow_invalid_hostname)) {
RETURN (true);
}
- *events = 0;
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"TLS handshake failed: Failed certificate verification");
RETURN (false);
}
if (BIO_should_retry (openssl->bio)) {
*events = BIO_should_read (openssl->bio) ? POLLIN : POLLOUT;
RETURN (false);
}
if (!errno) {
#ifdef _WIN32
errno = WSAETIMEDOUT;
#else
errno = ETIMEDOUT;
#endif
}
*events = 0;
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"TLS handshake failed: %s",
ERR_error_string (ERR_get_error (), NULL));
RETURN (false);
}
/* Callback to get the client provided SNI, if any
* It is only called in SSL "server mode" (e.g. when using the Mock Server),
* and we don't actually use the hostname for anything, just debug print it
*/
static int
_mongoc_stream_tls_openssl_sni (SSL *ssl, int *ad, void *arg)
{
const char *hostname;
if (ssl == NULL) {
TRACE ("%s", "No SNI hostname provided");
return SSL_TLSEXT_ERR_NOACK;
}
hostname = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name);
/* This is intentionally debug since its only used by the mock test server */
MONGOC_DEBUG ("Got SNI: '%s'", hostname);
return SSL_TLSEXT_ERR_OK;
}
static bool
_mongoc_stream_tls_openssl_timed_out (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
ENTRY;
RETURN (mongoc_stream_timed_out (tls->base_stream));
}
static bool
_mongoc_stream_tls_openssl_should_retry (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
ENTRY;
if (BIO_should_retry (openssl->bio)) {
RETURN (true);
}
RETURN (mongoc_stream_should_retry (tls->base_stream));
}
/*
*--------------------------------------------------------------------------
*
* mongoc_stream_tls_openssl_new --
*
* Creates a new mongoc_stream_tls_openssl_t to communicate with a remote
* server using a TLS stream.
*
* @base_stream should be a stream that will become owned by the
* resulting tls stream. It will be used for raw I/O.
*
* @trust_store_dir should be a path to the SSL cert db to use for
* verifying trust of the remote server.
*
* Returns:
* NULL on failure, otherwise a mongoc_stream_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_stream_t *
mongoc_stream_tls_openssl_new (mongoc_stream_t *base_stream,
const char *host,
mongoc_ssl_opt_t *opt,
int client)
{
mongoc_stream_tls_t *tls;
mongoc_stream_tls_openssl_t *openssl;
+ mongoc_openssl_ocsp_opt_t *ocsp_opts = NULL;
SSL_CTX *ssl_ctx = NULL;
BIO *bio_ssl = NULL;
BIO *bio_mongoc_shim = NULL;
BIO_METHOD *meth;
BSON_ASSERT (base_stream);
BSON_ASSERT (opt);
ENTRY;
ssl_ctx = _mongoc_openssl_ctx_new (opt);
if (!ssl_ctx) {
RETURN (NULL);
}
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
if (!opt->allow_invalid_hostname) {
struct in_addr addr;
X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new ();
X509_VERIFY_PARAM_set_hostflags (param,
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
if (inet_pton (AF_INET, host, &addr) ||
inet_pton (AF_INET6, host, &addr)) {
X509_VERIFY_PARAM_set1_ip_asc (param, host);
} else {
X509_VERIFY_PARAM_set1_host (param, host, 0);
}
SSL_CTX_set1_param (ssl_ctx, param);
X509_VERIFY_PARAM_free (param);
}
#endif
if (!client) {
/* Only used by the Mock Server.
* Set a callback to get the SNI, if provided */
SSL_CTX_set_tlsext_servername_callback (ssl_ctx,
_mongoc_stream_tls_openssl_sni);
}
if (opt->weak_cert_validation) {
SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);
} else {
SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER, NULL);
}
bio_ssl = BIO_new_ssl (ssl_ctx, client);
if (!bio_ssl) {
SSL_CTX_free (ssl_ctx);
RETURN (NULL);
}
meth = mongoc_stream_tls_openssl_bio_meth_new ();
bio_mongoc_shim = BIO_new (meth);
if (!bio_mongoc_shim) {
BIO_free_all (bio_ssl);
BIO_meth_free (meth);
+ SSL_CTX_free (ssl_ctx);
RETURN (NULL);
}
/* Added in OpenSSL 0.9.8f, as a build time option */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
if (client) {
SSL *ssl;
/* Set the SNI hostname we are expecting certificate for */
BIO_get_ssl (bio_ssl, &ssl);
SSL_set_tlsext_host_name (ssl, host);
#endif
}
-
BIO_push (bio_ssl, bio_mongoc_shim);
+#ifdef MONGOC_ENABLE_OCSP_OPENSSL
+ if (client && !opt->weak_cert_validation &&
+ !_mongoc_ssl_opts_disable_certificate_revocation_check (opt)) {
+ SSL *ssl;
+
+ BIO_get_ssl (bio_ssl, &ssl);
+
+ /* Set the status_request extension on the SSL object.
+ * Do not use SSL_CTX_set_tlsext_status_type, since that requires OpenSSL
+ * 1.1.0.
+ */
+ if (!SSL_set_tlsext_status_type (ssl, TLSEXT_STATUSTYPE_ocsp)) {
+ MONGOC_ERROR ("cannot enable OCSP status request extension");
+ mongoc_openssl_ocsp_opt_destroy (ocsp_opts);
+ BIO_free_all (bio_ssl);
+ BIO_meth_free (meth);
+ SSL_CTX_free (ssl_ctx);
+ RETURN (NULL);
+ }
+
+ ocsp_opts = bson_malloc0 (sizeof (mongoc_openssl_ocsp_opt_t));
+ ocsp_opts->allow_invalid_hostname = opt->allow_invalid_hostname;
+ ocsp_opts->weak_cert_validation = opt->weak_cert_validation;
+ ocsp_opts->disable_endpoint_check =
+ _mongoc_ssl_opts_disable_ocsp_endpoint_check (opt);
+ ocsp_opts->host = bson_strdup (host);
+ _mongoc_ssl_opts_copy_to (opt, &ocsp_opts->ssl_opts, true);
+ }
+#endif /* MONGOC_ENABLE_OCSP_OPENSSL */
+
openssl = (mongoc_stream_tls_openssl_t *) bson_malloc0 (sizeof *openssl);
openssl->bio = bio_ssl;
openssl->meth = meth;
openssl->ctx = ssl_ctx;
+ openssl->ocsp_opts = ocsp_opts;
tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls);
tls->parent.type = MONGOC_STREAM_TLS;
tls->parent.destroy = _mongoc_stream_tls_openssl_destroy;
tls->parent.failed = _mongoc_stream_tls_openssl_failed;
tls->parent.close = _mongoc_stream_tls_openssl_close;
tls->parent.flush = _mongoc_stream_tls_openssl_flush;
tls->parent.writev = _mongoc_stream_tls_openssl_writev;
tls->parent.readv = _mongoc_stream_tls_openssl_readv;
tls->parent.setsockopt = _mongoc_stream_tls_openssl_setsockopt;
tls->parent.get_base_stream = _mongoc_stream_tls_openssl_get_base_stream;
tls->parent.check_closed = _mongoc_stream_tls_openssl_check_closed;
tls->parent.timed_out = _mongoc_stream_tls_openssl_timed_out;
tls->parent.should_retry = _mongoc_stream_tls_openssl_should_retry;
memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts);
- tls->handshake = mongoc_stream_tls_openssl_handshake;
+ tls->handshake = _mongoc_stream_tls_openssl_handshake;
tls->ctx = (void *) openssl;
tls->timeout_msec = -1;
tls->base_stream = base_stream;
mongoc_stream_tls_openssl_bio_set_data (bio_mongoc_shim, tls);
mongoc_counter_streams_active_inc ();
RETURN ((mongoc_stream_t *) tls);
}
+void
+mongoc_openssl_ocsp_opt_destroy (void *ocsp_opt)
+{
+ mongoc_openssl_ocsp_opt_t *casted;
+
+ if (!ocsp_opt) {
+ return;
+ }
+ casted = (mongoc_openssl_ocsp_opt_t *) ocsp_opt;
+ bson_free (casted->host);
+ _mongoc_ssl_opts_cleanup (&casted->ssl_opts, true);
+ bson_free (ocsp_opt);
+}
+
#endif /* MONGOC_ENABLE_SSL_OPENSSL */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c
similarity index 93%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c
index 783e9c06..2ae1b87e 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c
@@ -1,1060 +1,1071 @@
/*
* Copyright 2016 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.
*/
/**
* Significant portion of this file, such as
* _mongoc_stream_tls_secure_channel_write &
*_mongoc_stream_tls_secure_channel_read
* comes straight from one of my favorite projects, cURL!
* Thank you so much for having gone through the Secure Channel pain for me.
*
*
* Copyright (C) 2012 - 2015, Marc Hoersken, <info@marc-hoersken.de>
* Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
* Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* Thanks for code and inspiration!
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL
#include <bson/bson.h>
#include "mongoc-trace-private.h"
#include "mongoc-log.h"
#include "mongoc-stream-tls.h"
#include "mongoc-stream-tls-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-tls-secure-channel-private.h"
#include "mongoc-secure-channel-private.h"
#include "mongoc-ssl.h"
+#include "mongoc-ssl-private.h"
#include "mongoc-error.h"
#include "mongoc-counters-private.h"
#include "mongoc-errno-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "stream-tls-secure-channel"
#define SECURITY_WIN32
#include <security.h>
#include <schnlsp.h>
#include <schannel.h>
/* mingw doesn't define these */
#ifndef SP_PROT_TLS1_1_CLIENT
#define SP_PROT_TLS1_1_CLIENT 0x00000200
#endif
#ifndef SP_PROT_TLS1_2_CLIENT
#define SP_PROT_TLS1_2_CLIENT 0x00000800
#endif
size_t
mongoc_secure_channel_write (mongoc_stream_tls_t *tls,
const void *data,
size_t data_length);
static void
_mongoc_stream_tls_secure_channel_destroy (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_channel);
/* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx
* Shutting Down an Schannel Connection
*/
- TRACE ("shutting down SSL/TLS connection");
+ TRACE ("%s", "shutting down SSL/TLS connection");
if (secure_channel->cred && secure_channel->ctxt) {
SecBufferDesc BuffDesc;
SecBuffer Buffer;
SECURITY_STATUS sspi_status;
SecBuffer outbuf;
SecBufferDesc outbuf_desc;
DWORD dwshut = SCHANNEL_SHUTDOWN;
_mongoc_secure_channel_init_sec_buffer (
&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof (dwshut));
_mongoc_secure_channel_init_sec_buffer_desc (&BuffDesc, &Buffer, 1);
sspi_status =
ApplyControlToken (&secure_channel->ctxt->ctxt_handle, &BuffDesc);
if (sspi_status != SEC_E_OK) {
- MONGOC_ERROR ("ApplyControlToken failure: %d", sspi_status);
+ MONGOC_ERROR ("ApplyControlToken failure: %ld", sspi_status);
}
/* setup output buffer */
_mongoc_secure_channel_init_sec_buffer (
&outbuf, SECBUFFER_EMPTY, NULL, 0);
_mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, &outbuf, 1);
sspi_status =
InitializeSecurityContext (&secure_channel->cred->cred_handle,
&secure_channel->ctxt->ctxt_handle,
/*tls->hostname*/ NULL,
secure_channel->req_flags,
0,
0,
NULL,
0,
&secure_channel->ctxt->ctxt_handle,
&outbuf_desc,
&secure_channel->ret_flags,
&secure_channel->ctxt->time_stamp);
if ((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
/* send close message which is in output buffer */
ssize_t written =
mongoc_secure_channel_write (tls, outbuf.pvBuffer, outbuf.cbBuffer);
FreeContextBuffer (outbuf.pvBuffer);
if (outbuf.cbBuffer != (size_t) written) {
TRACE ("failed to send close msg (wrote %zd out of %zd)",
written,
outbuf.cbBuffer);
}
}
}
/* free SSPI Schannel API security context handle */
if (secure_channel->ctxt) {
- TRACE ("clear security context handle");
+ TRACE ("%s", "clear security context handle");
DeleteSecurityContext (&secure_channel->ctxt->ctxt_handle);
bson_free (secure_channel->ctxt);
}
/* free SSPI Schannel API credential handle */
if (secure_channel->cred) {
/* decrement the reference counter of the credential/session handle */
/* if the handle was not cached and the refcount is zero */
- TRACE ("clear credential handle");
+ TRACE ("%s", "clear credential handle");
FreeCredentialsHandle (&secure_channel->cred->cred_handle);
bson_free (secure_channel->cred);
}
/* free internal buffer for received encrypted data */
if (secure_channel->encdata_buffer != NULL) {
bson_free (secure_channel->encdata_buffer);
secure_channel->encdata_length = 0;
secure_channel->encdata_offset = 0;
}
/* free internal buffer for received decrypted data */
if (secure_channel->decdata_buffer != NULL) {
bson_free (secure_channel->decdata_buffer);
secure_channel->decdata_length = 0;
secure_channel->decdata_offset = 0;
}
mongoc_stream_destroy (tls->base_stream);
bson_free (secure_channel);
bson_free (stream);
mongoc_counter_streams_active_dec ();
mongoc_counter_streams_disposed_inc ();
EXIT;
}
static void
_mongoc_stream_tls_secure_channel_failed (mongoc_stream_t *stream)
{
ENTRY;
_mongoc_stream_tls_secure_channel_destroy (stream);
EXIT;
}
static int
_mongoc_stream_tls_secure_channel_close (mongoc_stream_t *stream)
{
int ret = 0;
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_channel);
ret = mongoc_stream_close (tls->base_stream);
RETURN (ret);
}
static int
_mongoc_stream_tls_secure_channel_flush (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_channel);
RETURN (0);
}
static ssize_t
_mongoc_stream_tls_secure_channel_write (mongoc_stream_t *stream,
char *buf,
size_t buf_len)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ssize_t written = -1;
size_t data_len = 0;
unsigned char *data = NULL;
SecBuffer outbuf[4];
SecBufferDesc outbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
ENTRY;
BSON_ASSERT (secure_channel);
TRACE ("The entire buffer is: %d", buf_len);
/* check if the maximum stream sizes were queried */
if (secure_channel->stream_sizes.cbMaximumMessage == 0) {
sspi_status = QueryContextAttributes (&secure_channel->ctxt->ctxt_handle,
SECPKG_ATTR_STREAM_SIZES,
&secure_channel->stream_sizes);
if (sspi_status != SEC_E_OK) {
TRACE ("failing here: %d", __LINE__);
return -1;
}
}
/* check if the buffer is longer than the maximum message length */
if (buf_len > secure_channel->stream_sizes.cbMaximumMessage) {
TRACE ("SHRINKING buf_len from %lu to %lu",
buf_len,
secure_channel->stream_sizes.cbMaximumMessage);
buf_len = secure_channel->stream_sizes.cbMaximumMessage;
}
/* calculate the complete message length and allocate a buffer for it */
data_len = secure_channel->stream_sizes.cbHeader + buf_len +
secure_channel->stream_sizes.cbTrailer;
data = (unsigned char *) bson_malloc (data_len);
/* setup output buffers (header, data, trailer, empty) */
_mongoc_secure_channel_init_sec_buffer (
&outbuf[0],
SECBUFFER_STREAM_HEADER,
data,
secure_channel->stream_sizes.cbHeader);
_mongoc_secure_channel_init_sec_buffer (
&outbuf[1],
SECBUFFER_DATA,
data + secure_channel->stream_sizes.cbHeader,
(unsigned long) (buf_len & (size_t) 0xFFFFFFFFUL));
_mongoc_secure_channel_init_sec_buffer (
&outbuf[2],
SECBUFFER_STREAM_TRAILER,
data + secure_channel->stream_sizes.cbHeader + buf_len,
secure_channel->stream_sizes.cbTrailer);
_mongoc_secure_channel_init_sec_buffer (
&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
_mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, outbuf, 4);
/* copy data into output buffer */
memcpy (outbuf[1].pvBuffer, buf, buf_len);
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
sspi_status =
EncryptMessage (&secure_channel->ctxt->ctxt_handle, 0, &outbuf_desc, 0);
/* check if the message was encrypted */
if (sspi_status == SEC_E_OK) {
written = 0;
/* send the encrypted message including header, data and trailer */
buf_len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
written = mongoc_secure_channel_write (tls, data, buf_len);
} else {
written = -1;
}
bson_free (data);
if (buf_len == (size_t) written) {
/* Encrypted message including header, data and trailer entirely sent.
* The return value is the number of unencrypted bytes that were sent. */
written = outbuf[1].cbBuffer;
}
return written;
}
/* This is copypasta from _mongoc_stream_tls_openssl_writev */
#define MONGOC_STREAM_TLS_BUFFER_SIZE 4096
static ssize_t
_mongoc_stream_tls_secure_channel_writev (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
char buf[MONGOC_STREAM_TLS_BUFFER_SIZE];
ssize_t ret = 0;
ssize_t child_ret;
size_t i;
size_t iov_pos = 0;
/* There's a bit of a dance to coalesce vectorized writes into
* MONGOC_STREAM_TLS_BUFFER_SIZE'd writes to avoid lots of small tls
* packets.
*
* The basic idea is that we want to combine writes in the buffer if they're
* smaller than the buffer, flushing as it gets full. For larger writes, or
* the last write in the iovec array, we want to ignore the buffer and just
* write immediately. We take care of doing buffer writes by re-invoking
* ourself with a single iovec_t, pointing at our stack buffer.
*/
char *buf_head = buf;
char *buf_tail = buf;
char *buf_end = buf + MONGOC_STREAM_TLS_BUFFER_SIZE;
size_t bytes;
char *to_write = NULL;
size_t to_write_len;
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
BSON_ASSERT (secure_channel);
ENTRY;
- TRACE ("Trying to write to the server");
+ TRACE ("%s", "Trying to write to the server");
tls->timeout_msec = timeout_msec;
TRACE ("count: %d, 0th: %lu", iovcnt, iov[0].iov_len);
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
TRACE ("iov %d size: %lu", i, iov[i].iov_len);
while (iov_pos < iov[i].iov_len) {
if (buf_head != buf_tail ||
((i + 1 < iovcnt) &&
((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) {
/* If we have either of:
* - buffered bytes already
* - another iovec to send after this one and we don't have more
* bytes to send than the size of the buffer.
*
* copy into the buffer */
bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail);
memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes);
buf_tail += bytes;
iov_pos += bytes;
if (buf_tail == buf_end) {
/* If we're full, request send */
to_write = buf_head;
to_write_len = buf_tail - buf_head;
buf_tail = buf_head = buf;
}
} else {
/* Didn't buffer, so just write it through */
to_write = (char *) iov[i].iov_base + iov_pos;
to_write_len = iov[i].iov_len - iov_pos;
iov_pos += to_write_len;
}
if (to_write) {
/* We get here if we buffered some bytes and filled the buffer, or
* if we didn't buffer and have to send out of the iovec */
child_ret = _mongoc_stream_tls_secure_channel_write (
stream, to_write, to_write_len);
TRACE ("Child0wrote: %d, was supposed to write: %d",
child_ret,
to_write_len);
if (child_ret < 0) {
RETURN (ret);
}
ret += child_ret;
iov_pos -= to_write_len - child_ret;
to_write = NULL;
}
}
}
if (buf_head != buf_tail) {
/* If we have any bytes buffered, send */
child_ret = _mongoc_stream_tls_secure_channel_write (
stream, buf_head, buf_tail - buf_head);
TRACE ("Child1wrote: %d, was supposed to write: %d",
child_ret,
buf_tail - buf_head);
if (child_ret < 0) {
RETURN (child_ret);
}
ret += child_ret;
}
if (ret >= 0) {
mongoc_counter_streams_egress_add (ret);
}
TRACE ("Returning %d", (int) ret);
RETURN (ret);
}
/* move up to "len" decrypted bytes to buf, return number of bytes */
static ssize_t
_mongoc_stream_tls_secure_channel_debuf (
mongoc_stream_tls_secure_channel_t *secure_channel, char *buf, size_t size)
{
size_t s = BSON_MIN (size, secure_channel->decdata_offset);
memcpy (buf, secure_channel->decdata_buffer, s);
memmove (secure_channel->decdata_buffer,
secure_channel->decdata_buffer + s,
secure_channel->decdata_offset - s);
secure_channel->decdata_offset -= s;
TRACE ("decrypted data returned %d", (int) s);
TRACE ("decrypted data buffer: offset %d length %d",
(int) secure_channel->decdata_offset,
(int) secure_channel->decdata_length);
return (ssize_t) s;
}
/* decrypt as many received bytes as possible to secure_channel.decdata_buf */
static void
_mongoc_stream_tls_secure_channel_decrypt (
mongoc_stream_tls_secure_channel_t *secure_channel)
{
size_t size = 0;
size_t remaining;
- ssize_t nread = -1;
- bool done = false;
SecBuffer inbuf[4];
SecBufferDesc inbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
TRACE ("encrypted data buffer: offset %d length %d",
(int) secure_channel->encdata_offset,
(int) secure_channel->encdata_length);
/* decrypt loop */
while (secure_channel->encdata_offset > 0 && sspi_status == SEC_E_OK) {
/* prepare data buffer for DecryptMessage call */
_mongoc_secure_channel_init_sec_buffer (
&inbuf[0],
SECBUFFER_DATA,
secure_channel->encdata_buffer,
(unsigned long) (secure_channel->encdata_offset &
(size_t) 0xFFFFFFFFUL));
/* we need 3 more empty input buffers for possible output */
_mongoc_secure_channel_init_sec_buffer (
&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
_mongoc_secure_channel_init_sec_buffer (
&inbuf[2], SECBUFFER_EMPTY, NULL, 0);
_mongoc_secure_channel_init_sec_buffer (
&inbuf[3], SECBUFFER_EMPTY, NULL, 0);
_mongoc_secure_channel_init_sec_buffer_desc (&inbuf_desc, inbuf, 4);
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
*/
sspi_status = DecryptMessage (
&secure_channel->ctxt->ctxt_handle, &inbuf_desc, 0, NULL);
/* check if everything went fine (server may want to renegotiate
* or shutdown the connection context) */
if (sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE ||
sspi_status == SEC_I_CONTEXT_EXPIRED) {
/* check for successfully decrypted data, even before actual
* renegotiation or shutdown of the connection context */
if (inbuf[1].BufferType == SECBUFFER_DATA) {
TRACE ("decrypted data length: %lu", inbuf[1].cbBuffer);
size = inbuf[1].cbBuffer;
remaining =
secure_channel->decdata_length - secure_channel->decdata_offset;
if (remaining < size) {
mongoc_secure_channel_realloc_buf (
&secure_channel->decdata_length,
&secure_channel->decdata_buffer,
size);
}
/* copy decrypted data to internal buffer */
if (size) {
memcpy (secure_channel->decdata_buffer +
secure_channel->decdata_offset,
inbuf[1].pvBuffer,
size);
secure_channel->decdata_offset += size;
}
TRACE ("decrypted data added: %d", (int) size);
TRACE ("decrypted data cached: offset %d length %d",
(int) secure_channel->decdata_offset,
(int) secure_channel->decdata_length);
}
/* check for remaining encrypted data */
if (inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
TRACE ("encrypted data length: %lu", inbuf[3].cbBuffer);
/* check if the remaining data is less than the total amount
* and therefore begins after the already processed data
*/
if (secure_channel->encdata_offset > inbuf[3].cbBuffer) {
/* move remaining encrypted data forward to the beginning of
* buffer */
memmove (secure_channel->encdata_buffer,
(secure_channel->encdata_buffer +
secure_channel->encdata_offset) -
inbuf[3].cbBuffer,
inbuf[3].cbBuffer);
secure_channel->encdata_offset = inbuf[3].cbBuffer;
}
TRACE ("encrypted data cached: offset %d length %d",
(int) secure_channel->encdata_offset,
(int) secure_channel->encdata_length);
} else {
/* reset encrypted buffer offset, because there is no data remaining
*/
secure_channel->encdata_offset = 0;
}
/* check if server wants to renegotiate the connection context */
if (sspi_status == SEC_I_RENEGOTIATE) {
- TRACE ("remote party requests renegotiation");
+ TRACE ("%s", "remote party requests renegotiation");
}
/* check if the server closed the connection */
else if (sspi_status == SEC_I_CONTEXT_EXPIRED) {
/* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
* returned so we have to work around that in cleanup. */
secure_channel->recv_sspi_close_notify = true;
if (!secure_channel->recv_connection_closed) {
secure_channel->recv_connection_closed = true;
- TRACE ("server closed the connection");
+ TRACE ("%s", "server closed the connection");
}
}
} else if (sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
- TRACE ("failed to decrypt data, need more data");
+ TRACE ("%s", "failed to decrypt data, need more data");
} else {
TRACE ("failed to read data from server: %d", sspi_status);
secure_channel->recv_unrecoverable_err = true;
}
}
TRACE ("encrypted data buffer: offset %d length %d",
(int) secure_channel->encdata_offset,
(int) secure_channel->encdata_length);
TRACE ("decrypted data buffer: offset %d length %d",
(int) secure_channel->decdata_offset,
(int) secure_channel->decdata_length);
}
static ssize_t
_mongoc_stream_tls_secure_channel_read (mongoc_stream_t *stream,
char *buf,
size_t len)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ssize_t size = 0;
ssize_t nread;
TRACE ("client wants to read %d bytes", (int) len);
BSON_ASSERT (len > 0);
/*
* Our priority is to always return as much decrypted data to the caller as
* possible, even if an error occurs. The state of the decrypted buffer must
* always be valid.
*/
if (secure_channel->decdata_offset) {
- TRACE ("decrypted data is already available");
+ TRACE ("%s", "decrypted data is already available");
return _mongoc_stream_tls_secure_channel_debuf (secure_channel, buf, len);
}
/* is a complete encrypted block left from last network read? */
if (secure_channel->encdata_offset) {
_mongoc_stream_tls_secure_channel_decrypt (secure_channel);
if (secure_channel->decdata_offset) {
return _mongoc_stream_tls_secure_channel_debuf (
secure_channel, buf, len);
}
}
/* keep these checks separated, for more detailed tracing */
if (secure_channel->recv_unrecoverable_err) {
- TRACE ("an unrecoverable error occurred in a prior call");
+ TRACE ("%s", "an unrecoverable error occurred in a prior call");
return -1;
}
if (secure_channel->recv_sspi_close_notify) {
- TRACE ("server indicated shutdown in a prior call");
+ TRACE ("%s", "server indicated shutdown in a prior call");
return -1;
}
if (secure_channel->recv_connection_closed) {
- TRACE ("connection closed");
+ TRACE ("%s", "connection closed");
return -1;
}
size = secure_channel->encdata_length - secure_channel->encdata_offset;
/* read encrypted data from socket. returns 0 on shutdown or error */
nread =
mongoc_secure_channel_read (tls,
(char *) (secure_channel->encdata_buffer +
secure_channel->encdata_offset),
(size_t) size);
if (!nread) {
if (MONGOC_ERRNO_IS_AGAIN (errno)) {
- TRACE ("Try again");
+ TRACE ("%s", "Try again");
return 0;
} else {
secure_channel->recv_connection_closed = true;
TRACE ("reading failed: %d", errno);
return -1;
}
}
secure_channel->encdata_offset += (size_t) nread;
TRACE ("encrypted data got %zd", nread);
_mongoc_stream_tls_secure_channel_decrypt (secure_channel);
return _mongoc_stream_tls_secure_channel_debuf (secure_channel, buf, len);
}
/* This function is copypasta of _mongoc_stream_tls_openssl_readv */
static ssize_t
_mongoc_stream_tls_secure_channel_readv (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
size_t min_bytes,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ssize_t ret = 0;
size_t i;
size_t iov_pos = 0;
int64_t now;
int64_t expire = 0;
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
BSON_ASSERT (secure_channel);
ENTRY;
tls->timeout_msec = timeout_msec;
if (timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (timeout_msec * 1000UL);
}
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
ssize_t read_ret = _mongoc_stream_tls_secure_channel_read (
stream,
(char *) iov[i].iov_base + iov_pos,
(int) (iov[i].iov_len - iov_pos));
if (read_ret < 0) {
RETURN (-1);
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (read_ret == 0) {
mongoc_counter_streams_timeout_inc ();
errno = ETIMEDOUT;
RETURN (-1);
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
ret += read_ret;
if ((size_t) ret >= min_bytes) {
mongoc_counter_streams_ingress_add (ret);
RETURN (ret);
}
iov_pos += read_ret;
}
}
if (ret >= 0) {
mongoc_counter_streams_ingress_add (ret);
}
RETURN (ret);
}
static int
_mongoc_stream_tls_secure_channel_setsockopt (mongoc_stream_t *stream,
int level,
int optname,
void *optval,
mongoc_socklen_t optlen)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_channel);
RETURN (mongoc_stream_setsockopt (
tls->base_stream, level, optname, optval, optlen));
}
static mongoc_stream_t *
_mongoc_stream_tls_secure_channel_get_base_stream (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_channel);
RETURN (tls->base_stream);
}
static bool
_mongoc_stream_tls_secure_channel_check_closed (
mongoc_stream_t *stream) /* IN */
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_channel);
RETURN (mongoc_stream_check_closed (tls->base_stream));
}
bool
mongoc_stream_tls_secure_channel_handshake (mongoc_stream_t *stream,
const char *host,
int *events,
bson_error_t *error)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_channel_t *secure_channel =
(mongoc_stream_tls_secure_channel_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_channel);
TRACE ("Getting ready for state: %d, timeout is %d",
secure_channel->connecting_state + 1,
tls->timeout_msec);
switch (secure_channel->connecting_state) {
case ssl_connect_1:
if (mongoc_secure_channel_handshake_step_1 (tls, (char *) host)) {
- TRACE ("Step#1 Worked!\n\n");
+ TRACE ("%s", "Step#1 Worked!\n\n");
*events = POLLIN;
RETURN (false);
} else {
- TRACE ("Step#1 FAILED!");
+ TRACE ("%s", "Step#1 FAILED!");
}
break;
case ssl_connect_2:
case ssl_connect_2_reading:
case ssl_connect_2_writing:
if (mongoc_secure_channel_handshake_step_2 (tls, (char *) host)) {
if (secure_channel->connecting_state == ssl_connect_2_reading) {
*events = POLLIN;
} else {
*events = POLLOUT;
}
RETURN (false);
} else {
- TRACE ("Step#2 FAILED!");
+ TRACE ("%s", "Step#2 FAILED!");
}
break;
case ssl_connect_3:
if (mongoc_secure_channel_handshake_step_3 (tls, (char *) host)) {
- TRACE ("Step#3 Worked!\n\n");
+ TRACE ("%s", "Step#3 Worked!\n\n");
*events = POLLIN | POLLOUT;
RETURN (false);
} else {
- TRACE ("Step#3 FAILED!");
+ TRACE ("%s", "Step#3 FAILED!");
}
break;
case ssl_connect_done:
- TRACE ("Connect DONE!");
+ TRACE ("%s", "Connect DONE!");
/* reset our connection state machine */
secure_channel->connecting_state = ssl_connect_1;
RETURN (true);
break;
+ default: /* do nothing */
+ break;
}
*events = 0;
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"TLS handshake failed");
RETURN (false);
}
static bool
_mongoc_stream_tls_secure_channel_timed_out (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
ENTRY;
RETURN (mongoc_stream_timed_out (tls->base_stream));
}
static bool
_mongoc_stream_tls_secure_channel_should_retry (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
ENTRY;
RETURN (mongoc_stream_should_retry (tls->base_stream));
}
mongoc_stream_t *
mongoc_stream_tls_secure_channel_new (mongoc_stream_t *base_stream,
const char *host,
mongoc_ssl_opt_t *opt,
int client)
{
SECURITY_STATUS sspi_status = SEC_E_OK;
SCHANNEL_CRED schannel_cred;
mongoc_stream_tls_t *tls;
mongoc_stream_tls_secure_channel_t *secure_channel;
PCCERT_CONTEXT cert = NULL;
ENTRY;
BSON_ASSERT (base_stream);
BSON_ASSERT (opt);
secure_channel = (mongoc_stream_tls_secure_channel_t *) bson_malloc0 (
sizeof *secure_channel);
secure_channel->decdata_buffer =
bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE);
secure_channel->decdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE;
secure_channel->encdata_buffer =
bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE);
secure_channel->encdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE;
tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls);
tls->parent.type = MONGOC_STREAM_TLS;
tls->parent.destroy = _mongoc_stream_tls_secure_channel_destroy;
tls->parent.failed = _mongoc_stream_tls_secure_channel_failed;
tls->parent.close = _mongoc_stream_tls_secure_channel_close;
tls->parent.flush = _mongoc_stream_tls_secure_channel_flush;
tls->parent.writev = _mongoc_stream_tls_secure_channel_writev;
tls->parent.readv = _mongoc_stream_tls_secure_channel_readv;
tls->parent.setsockopt = _mongoc_stream_tls_secure_channel_setsockopt;
tls->parent.get_base_stream =
_mongoc_stream_tls_secure_channel_get_base_stream;
tls->parent.check_closed = _mongoc_stream_tls_secure_channel_check_closed;
tls->parent.timed_out = _mongoc_stream_tls_secure_channel_timed_out;
tls->parent.should_retry = _mongoc_stream_tls_secure_channel_should_retry;
memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts);
tls->handshake = mongoc_stream_tls_secure_channel_handshake;
tls->ctx = (void *) secure_channel;
tls->timeout_msec = -1;
tls->base_stream = base_stream;
- TRACE ("SSL/TLS connection with endpoint AcquireCredentialsHandle");
+ TRACE ("%s", "SSL/TLS connection with endpoint AcquireCredentialsHandle");
/* setup Schannel API options */
memset (&schannel_cred, 0, sizeof (schannel_cred));
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
/* SCHANNEL_CRED:
* SCH_USE_STRONG_CRYPTO is not available in VS2010
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa379810.aspx */
#ifdef SCH_USE_STRONG_CRYPTO
schannel_cred.dwFlags = SCH_USE_STRONG_CRYPTO;
#endif
+
+ /* By default, enable soft failing.
+ * A certificate with no revocation check is a soft failure. */
+ schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK;
+ /* An offline OCSP responder / CRL distribution list is a soft failure. */
+ schannel_cred.dwFlags |= SCH_CRED_IGNORE_REVOCATION_OFFLINE;
if (opt->weak_cert_validation) {
- schannel_cred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION |
- SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
- SCH_CRED_IGNORE_REVOCATION_OFFLINE;
- TRACE ("disabled server certificate checks");
+ schannel_cred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION;
+ TRACE ("%s", "disabled server certificate checks");
} else {
- schannel_cred.dwFlags |=
- SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_REVOCATION_CHECK_CHAIN;
- TRACE ("enabled server certificate checks");
+ schannel_cred.dwFlags |= SCH_CRED_AUTO_CRED_VALIDATION;
+ if (!_mongoc_ssl_opts_disable_certificate_revocation_check (opt)) {
+ schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+ TRACE ("%s", "enabled server certificate revocation checks");
+ }
+ TRACE ("%s", "enabled server certificate checks");
}
if (opt->allow_invalid_hostname) {
- schannel_cred.dwFlags |=
- SCH_CRED_NO_SERVERNAME_CHECK | SCH_CRED_IGNORE_NO_REVOCATION_CHECK;
+ schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
}
if (opt->ca_file) {
mongoc_secure_channel_setup_ca (secure_channel, opt);
}
if (opt->crl_file) {
mongoc_secure_channel_setup_crl (secure_channel, opt);
}
if (opt->pem_file) {
cert = mongoc_secure_channel_setup_certificate (secure_channel, opt);
if (cert) {
schannel_cred.cCreds = 1;
schannel_cred.paCred = &cert;
}
}
schannel_cred.grbitEnabledProtocols =
SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT;
secure_channel->cred = (mongoc_secure_channel_cred *) bson_malloc0 (
sizeof (mongoc_secure_channel_cred));
/* Example:
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375454%28v=vs.85%29.aspx
* AcquireCredentialsHandle:
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
*/
sspi_status = AcquireCredentialsHandle (
NULL, /* principal */
UNISP_NAME, /* security package */
SECPKG_CRED_OUTBOUND, /* we are preparing outbound connection */
NULL, /* Optional logon */
&schannel_cred, /* TLS "configuration", "auth data" */
NULL, /* unused */
NULL, /* unused */
&secure_channel->cred->cred_handle, /* credential OUT param */
&secure_channel->cred->time_stamp); /* certificate expiration time */
if (sspi_status != SEC_E_OK) {
LPTSTR msg = NULL;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError (),
LANG_NEUTRAL,
(LPTSTR) &msg,
0,
NULL);
MONGOC_ERROR (
"Failed to initialize security context, error code: 0x%04X%04X: '%s'",
- (sspi_status >> 16) & 0xffff,
- sspi_status & 0xffff,
+ (unsigned int) (sspi_status >> 16) & 0xffff,
+ (unsigned int) sspi_status & 0xffff,
msg);
LocalFree (msg);
RETURN (NULL);
}
if (opt->ca_dir) {
MONGOC_ERROR ("Setting mongoc_ssl_opt_t.ca_dir has no effect when built "
"against Secure Channel");
}
+ if (_mongoc_ssl_opts_disable_ocsp_endpoint_check (opt)) {
+ MONGOC_ERROR ("Setting tlsDisableOCSPEndpointCheck has no effect when "
+ "built against Secure Channel");
+ }
mongoc_counter_streams_active_inc ();
RETURN ((mongoc_stream_t *) tls);
}
#endif /* MONGOC_ENABLE_SSL_SECURE_CHANNEL */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c
similarity index 70%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c
index c568c1c1..f20ec6b0 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c
@@ -1,578 +1,760 @@
/*
* Copyright 2016 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.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT
#include <Security/Security.h>
#include <Security/SecureTransport.h>
#include <CoreFoundation/CoreFoundation.h>
#include <bson/bson.h>
#include "mongoc-trace-private.h"
#include "mongoc-log.h"
#include "mongoc-secure-transport-private.h"
#include "mongoc-ssl.h"
+#include "mongoc-ssl-private.h"
#include "mongoc-error.h"
#include "mongoc-counters-private.h"
#include "mongoc-stream-tls.h"
#include "mongoc-stream-tls-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-tls-secure-transport-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "stream-tls-secure_transport"
static void
_mongoc_stream_tls_secure_transport_destroy (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_transport);
SSLClose (secure_transport->ssl_ctx_ref);
CFRelease (secure_transport->ssl_ctx_ref);
secure_transport->ssl_ctx_ref = NULL;
/* SSLClose will do IO so destroy must come after */
mongoc_stream_destroy (tls->base_stream);
if (secure_transport->anchors) {
CFRelease (secure_transport->anchors);
}
if (secure_transport->my_cert) {
CFRelease (secure_transport->my_cert);
}
bson_free (secure_transport);
bson_free (stream);
mongoc_counter_streams_active_dec ();
mongoc_counter_streams_disposed_inc ();
EXIT;
}
static void
_mongoc_stream_tls_secure_transport_failed (mongoc_stream_t *stream)
{
ENTRY;
_mongoc_stream_tls_secure_transport_destroy (stream);
EXIT;
}
static int
_mongoc_stream_tls_secure_transport_close (mongoc_stream_t *stream)
{
int ret = 0;
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_transport);
ret = mongoc_stream_close (tls->base_stream);
RETURN (ret);
}
static int
_mongoc_stream_tls_secure_transport_flush (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_transport);
RETURN (0);
}
static ssize_t
_mongoc_stream_tls_secure_transport_write (mongoc_stream_t *stream,
char *buf,
size_t buf_len)
{
OSStatus status;
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ssize_t write_ret;
int64_t now;
int64_t expire = 0;
ENTRY;
BSON_ASSERT (secure_transport);
if (tls->timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL);
}
status = SSLWrite (
secure_transport->ssl_ctx_ref, buf, buf_len, (size_t *) &write_ret);
switch (status) {
case errSSLWouldBlock:
case noErr:
break;
case errSSLClosedAbort:
errno = ECONNRESET;
default:
RETURN (-1);
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (write_ret < buf_len) {
mongoc_counter_streams_timeout_inc ();
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
RETURN (write_ret);
}
/* This is copypasta from _mongoc_stream_tls_openssl_writev */
#define MONGOC_STREAM_TLS_BUFFER_SIZE 4096
static ssize_t
_mongoc_stream_tls_secure_transport_writev (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
char buf[MONGOC_STREAM_TLS_BUFFER_SIZE];
ssize_t ret = 0;
ssize_t child_ret;
size_t i;
size_t iov_pos = 0;
/* There's a bit of a dance to coalesce vectorized writes into
* MONGOC_STREAM_TLS_BUFFER_SIZE'd writes to avoid lots of small tls
* packets.
*
* The basic idea is that we want to combine writes in the buffer if they're
* smaller than the buffer, flushing as it gets full. For larger writes, or
* the last write in the iovec array, we want to ignore the buffer and just
* write immediately. We take care of doing buffer writes by re-invoking
* ourself with a single iovec_t, pointing at our stack buffer.
*/
char *buf_head = buf;
char *buf_tail = buf;
char *buf_end = buf + MONGOC_STREAM_TLS_BUFFER_SIZE;
size_t bytes;
char *to_write = NULL;
size_t to_write_len;
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
BSON_ASSERT (secure_transport);
ENTRY;
tls->timeout_msec = timeout_msec;
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
if (buf_head != buf_tail ||
((i + 1 < iovcnt) &&
((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) {
/* If we have either of:
* - buffered bytes already
* - another iovec to send after this one and we don't have more
* bytes to send than the size of the buffer.
*
* copy into the buffer */
bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail);
memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes);
buf_tail += bytes;
iov_pos += bytes;
if (buf_tail == buf_end) {
/* If we're full, request send */
to_write = buf_head;
to_write_len = buf_tail - buf_head;
buf_tail = buf_head = buf;
}
} else {
/* Didn't buffer, so just write it through */
to_write = (char *) iov[i].iov_base + iov_pos;
to_write_len = iov[i].iov_len - iov_pos;
iov_pos += to_write_len;
}
if (to_write) {
/* We get here if we buffered some bytes and filled the buffer, or
* if we didn't buffer and have to send out of the iovec */
child_ret = _mongoc_stream_tls_secure_transport_write (
stream, to_write, to_write_len);
if (child_ret < 0) {
RETURN (ret);
}
ret += child_ret;
if (child_ret < to_write_len) {
/* we timed out, so send back what we could send */
RETURN (ret);
}
to_write = NULL;
}
}
}
if (buf_head != buf_tail) {
/* If we have any bytes buffered, send */
child_ret = _mongoc_stream_tls_secure_transport_write (
stream, buf_head, buf_tail - buf_head);
if (child_ret < 0) {
RETURN (child_ret);
}
ret += child_ret;
}
if (ret >= 0) {
mongoc_counter_streams_egress_add (ret);
}
TRACE ("Returning %d", (int) ret);
RETURN (ret);
}
/* This function is copypasta of _mongoc_stream_tls_openssl_readv */
static ssize_t
_mongoc_stream_tls_secure_transport_readv (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
size_t min_bytes,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ssize_t ret = 0;
size_t i;
size_t read_ret;
size_t iov_pos = 0;
int64_t now;
int64_t expire = 0;
size_t to_read;
size_t remaining_buf_size;
size_t remaining_to_read;
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
BSON_ASSERT (secure_transport);
ENTRY;
tls->timeout_msec = timeout_msec;
if (timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (timeout_msec * 1000UL);
}
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
-
- remaining_buf_size = iov[i].iov_len - iov_pos;
- remaining_to_read = min_bytes - ret;
-
- /* The third argument passed to SSLRead is an all-or-nothing
- dataLength, which it will attempt to read until it succeeds or
- times out. If our buffer is larger than the message we expect
- to read, choose the smaller number of the two. */
- if (remaining_to_read > 0 && remaining_to_read < remaining_buf_size) {
- to_read = remaining_to_read;
- } else {
- to_read = remaining_buf_size;
- }
+ remaining_buf_size = iov[i].iov_len - iov_pos;
+ remaining_to_read = min_bytes - ret;
+
+ /* The third argument passed to SSLRead is an all-or-nothing
+ dataLength, which it will attempt to read until it succeeds or
+ times out. If our buffer is larger than the message we expect
+ to read, choose the smaller number of the two. */
+ if (remaining_to_read > 0 && remaining_to_read < remaining_buf_size) {
+ to_read = remaining_to_read;
+ } else {
+ to_read = remaining_buf_size;
+ }
OSStatus status = SSLRead (secure_transport->ssl_ctx_ref,
(char *) iov[i].iov_base + iov_pos,
- to_read,
+ to_read,
&read_ret);
if (status != noErr) {
RETURN (-1);
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (read_ret == 0) {
mongoc_counter_streams_timeout_inc ();
errno = ETIMEDOUT;
RETURN (-1);
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
ret += read_ret;
if ((size_t) ret >= min_bytes) {
mongoc_counter_streams_ingress_add (ret);
RETURN (ret);
}
iov_pos += read_ret;
}
}
if (ret >= 0) {
mongoc_counter_streams_ingress_add (ret);
}
RETURN (ret);
}
static int
_mongoc_stream_tls_secure_transport_setsockopt (mongoc_stream_t *stream,
int level,
int optname,
void *optval,
mongoc_socklen_t optlen)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_transport);
RETURN (mongoc_stream_setsockopt (
tls->base_stream, level, optname, optval, optlen));
}
static mongoc_stream_t *
_mongoc_stream_tls_secure_transport_get_base_stream (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_transport);
RETURN (tls->base_stream);
}
static bool
_mongoc_stream_tls_secure_transport_check_closed (
mongoc_stream_t *stream) /* IN */
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_transport);
RETURN (mongoc_stream_check_closed (tls->base_stream));
}
+static void
+_set_error_from_osstatus (OSStatus status,
+ const char *prefix,
+ bson_error_t *error)
+{
+ CFStringRef err;
+ char *err_str;
+
+ err = SecCopyErrorMessageString (status, NULL);
+ err_str = _mongoc_cfstringref_to_cstring (err);
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "%s: %s (%d)",
+ prefix,
+ err_str,
+ status);
+
+ bson_free (err_str);
+ CFRelease (err);
+}
+
+/* Always returns a string that must be freed. */
+static char *
+explain_trust_result (SecTrustRef trust, SecTrustResultType trust_result)
+{
+ bson_string_t *reason;
+ CFArrayRef cfprops = NULL;
+ CFIndex count, i;
+
+ reason = bson_string_new ("");
+ switch (trust_result) {
+ case kSecTrustResultDeny:
+ bson_string_append (reason, "Certificate trust denied");
+ break;
+ case kSecTrustResultRecoverableTrustFailure:
+ bson_string_append (reason, "Certificate trust failure");
+ break;
+ case kSecTrustResultFatalTrustFailure:
+ bson_string_append (reason, "Certificate trust fatal failure");
+ break;
+ case kSecTrustResultInvalid:
+ bson_string_append (reason, "Certificate trust evaluation failure");
+ break;
+ default:
+ bson_string_append_printf (
+ reason, "Certificate trust failure #%d", (int) trust_result);
+ break;
+ }
+ bson_string_append (reason, ": ");
+
+ cfprops = SecTrustCopyProperties (trust);
+ /* This contains an array of dictionaries, each representing a cert in the
+ * chain. Append the first failure reason found. */
+ if (!cfprops) {
+ bson_string_append (reason, "Unable to retreive cause for trust failure");
+ goto done;
+ }
+
+ count = CFArrayGetCount (cfprops);
+ for (i = 0; i < count; ++i) {
+ const void *elem = NULL;
+ const void *reason_elem = NULL;
+ char *reason_str;
+ CFDictionaryRef dict;
+
+ elem = CFArrayGetValueAtIndex (cfprops, i);
+ if (CFGetTypeID (elem) != CFDictionaryGetTypeID ()) {
+ bson_string_append (reason, "Unable to parse cause for trust failure");
+ goto done;
+ }
+
+ dict = (CFDictionaryRef) elem;
+ reason_elem = CFDictionaryGetValue (dict, kSecPropertyTypeError);
+ if (!reason_elem) {
+ continue;
+ }
+ if (CFGetTypeID (reason_elem) != CFStringGetTypeID ()) {
+ bson_string_append (reason, "Unable to parse trust failure error");
+ goto done;
+ }
+ reason_str = _mongoc_cfstringref_to_cstring (reason_elem);
+ if (reason_str) {
+ bson_string_append (reason, reason_str);
+ bson_free (reason_str);
+ goto done;
+ } else {
+ bson_string_append (reason, "Unable to express trust failure error");
+ goto done;
+ }
+ }
+
+ bson_string_append (reason, "No trust failure reason available");
+done:
+ CFReleaseSafe (cfprops);
+ return bson_string_free (reason, false);
+}
+
+/* Returns a boolean indicating success. If false is returned, then an error is
+ * set.
+ */
+static bool
+_verify_peer (mongoc_stream_t *stream, bson_error_t *error)
+{
+ CFArrayRef policies = NULL;
+ SecTrustRef trust = NULL;
+ OSStatus status;
+ CFMutableArrayRef policies_mutable = NULL;
+ SecPolicyRef rev_policy = NULL;
+ SecTrustResultType trust_result;
+ mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
+ mongoc_stream_tls_secure_transport_t *secure_transport =
+ (mongoc_stream_tls_secure_transport_t *) tls->ctx;
+ bool ret = false;
+
+ status = SSLCopyPeerTrust (secure_transport->ssl_ctx_ref, &trust);
+ if (status != noErr) {
+ _set_error_from_osstatus (
+ status, "Certificate validation errored", error);
+ goto fail;
+ }
+
+ status = SecTrustCopyPolicies (trust, &policies);
+
+ if (status != noErr) {
+ _set_error_from_osstatus (
+ status, "Certificate validation errored", error);
+ goto fail;
+ }
+
+ /* Add explicit OCSP revocation policy. */
+ policies_mutable = CFArrayCreateMutableCopy (NULL, 0, policies);
+
+ /* TODO: possibly disable endpoint checking by adding the flag
+ * kSecRevocationNetworkAccessDisabled once the option
+ * tlsDisableOCSPEndpointCheck is implemented. */
+ rev_policy = SecPolicyCreateRevocation (kSecRevocationOCSPMethod);
+ CFArrayAppendValue (policies_mutable, rev_policy);
+
+ status = SecTrustSetPolicies (trust, policies_mutable);
+
+ if (status != noErr) {
+ _set_error_from_osstatus (
+ status, "Certificate validation errored", error);
+ goto fail;
+ }
+
+ /* TODO: SecTrustEvaluate is blocking. When making Secure Transport's
+ * handshake is made non-blocking in CDRIVER-2885, this will need to be
+ * addressed. */
+ status = SecTrustEvaluate (trust, &trust_result);
+ if (status != noErr) {
+ _set_error_from_osstatus (
+ status, "Certificate validation errored", error);
+ goto fail;
+ }
+
+ if (trust_result != kSecTrustResultProceed &&
+ trust_result != kSecTrustResultUnspecified) {
+ char *reason = explain_trust_result (trust, trust_result);
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "TLS handshake failed (%s)",
+ reason);
+ bson_free (reason);
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ CFReleaseSafe (trust);
+ CFReleaseSafe (policies);
+ CFReleaseSafe (policies_mutable);
+ CFReleaseSafe (rev_policy);
+ return ret;
+}
+
bool
mongoc_stream_tls_secure_transport_handshake (mongoc_stream_t *stream,
const char *host,
int *events,
bson_error_t *error)
{
OSStatus ret = 0;
- CFStringRef err;
- char *err_str;
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_secure_transport_t *secure_transport =
(mongoc_stream_tls_secure_transport_t *) tls->ctx;
ENTRY;
BSON_ASSERT (secure_transport);
ret = SSLHandshake (secure_transport->ssl_ctx_ref);
- /* Weak certificate validation requested, eg: none */
if (ret == errSSLServerAuthCompleted) {
+ if (!tls->ssl_opts.weak_cert_validation &&
+ !_verify_peer (stream, error)) {
+ *events = 0;
+ RETURN (false);
+ }
ret = errSSLWouldBlock;
}
if (ret == noErr) {
RETURN (true);
}
if (ret == errSSLWouldBlock) {
*events = POLLIN | POLLOUT;
} else {
*events = 0;
- err = SecCopyErrorMessageString (ret, NULL);
- err_str = _mongoc_cfstringref_to_cstring (err);
- bson_set_error (error,
- MONGOC_ERROR_STREAM,
- MONGOC_ERROR_STREAM_SOCKET,
- "TLS handshake failed: %s (%d)",
- err_str,
- ret);
-
- bson_free (err_str);
- CFRelease (err);
+ _set_error_from_osstatus (ret, "TLS handshake failed", error);
}
RETURN (false);
}
static bool
_mongoc_stream_tls_secure_channel_timed_out (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
ENTRY;
RETURN (mongoc_stream_timed_out (tls->base_stream));
}
static bool
_mongoc_stream_tls_secure_channel_should_retry (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
ENTRY;
RETURN (mongoc_stream_should_retry (tls->base_stream));
}
mongoc_stream_t *
mongoc_stream_tls_secure_transport_new (mongoc_stream_t *base_stream,
const char *host,
mongoc_ssl_opt_t *opt,
int client)
{
mongoc_stream_tls_t *tls;
mongoc_stream_tls_secure_transport_t *secure_transport;
ENTRY;
BSON_ASSERT (base_stream);
BSON_ASSERT (opt);
if (opt->ca_dir) {
MONGOC_ERROR ("Setting mongoc_ssl_opt_t.ca_dir has no effect when built "
"against Secure Transport");
RETURN (NULL);
}
if (opt->crl_file) {
MONGOC_ERROR (
"Setting mongoc_ssl_opt_t.crl_file has no effect when built "
"against Secure Transport");
RETURN (NULL);
}
secure_transport = (mongoc_stream_tls_secure_transport_t *) bson_malloc0 (
sizeof *secure_transport);
tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls);
tls->parent.type = MONGOC_STREAM_TLS;
tls->parent.destroy = _mongoc_stream_tls_secure_transport_destroy;
tls->parent.failed = _mongoc_stream_tls_secure_transport_failed;
tls->parent.close = _mongoc_stream_tls_secure_transport_close;
tls->parent.flush = _mongoc_stream_tls_secure_transport_flush;
tls->parent.writev = _mongoc_stream_tls_secure_transport_writev;
tls->parent.readv = _mongoc_stream_tls_secure_transport_readv;
tls->parent.setsockopt = _mongoc_stream_tls_secure_transport_setsockopt;
tls->parent.get_base_stream =
_mongoc_stream_tls_secure_transport_get_base_stream;
tls->parent.check_closed = _mongoc_stream_tls_secure_transport_check_closed;
tls->parent.timed_out = _mongoc_stream_tls_secure_channel_timed_out;
tls->parent.should_retry = _mongoc_stream_tls_secure_channel_should_retry;
memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts);
tls->handshake = mongoc_stream_tls_secure_transport_handshake;
tls->ctx = (void *) secure_transport;
tls->timeout_msec = -1;
secure_transport->ssl_ctx_ref =
SSLCreateContext (kCFAllocatorDefault,
client ? kSSLClientSide : kSSLServerSide,
kSSLStreamType);
SSLSetIOFuncs (secure_transport->ssl_ctx_ref,
mongoc_secure_transport_read,
mongoc_secure_transport_write);
SSLSetProtocolVersionMin (secure_transport->ssl_ctx_ref, kTLSProtocol1);
if (opt->pem_file &&
!mongoc_secure_transport_setup_certificate (secure_transport, opt)) {
mongoc_stream_destroy ((mongoc_stream_t *) tls);
RETURN (NULL);
}
if (opt->ca_file &&
!mongoc_secure_transport_setup_ca (secure_transport, opt)) {
mongoc_stream_destroy ((mongoc_stream_t *) tls);
RETURN (NULL);
}
/* don't link base_stream to tls until we're sure we won't destroy tls */
tls->base_stream = base_stream;
if (client) {
+ /* This option has SSL_Handshake stop before it verifies peer cert. Set
+ * this since we verify peer cert manually later. */
SSLSetSessionOption (secure_transport->ssl_ctx_ref,
kSSLSessionOptionBreakOnServerAuth,
- opt->weak_cert_validation);
+ true);
} else if (!opt->allow_invalid_hostname) {
/* used only in mock_server_t tests */
SSLSetClientSideAuthenticate (secure_transport->ssl_ctx_ref,
kAlwaysAuthenticate);
}
if (!opt->allow_invalid_hostname) {
SSLSetPeerDomainName (secure_transport->ssl_ctx_ref, host, strlen (host));
}
SSLSetConnection (secure_transport->ssl_ctx_ref, tls);
mongoc_counter_streams_active_inc ();
+
+ if (_mongoc_ssl_opts_disable_certificate_revocation_check (opt)) {
+ MONGOC_ERROR ("Setting tlsDisableCertificateRevocationCheck has no "
+ "effect when built against Secure Transport");
+ }
+
+ if (_mongoc_ssl_opts_disable_ocsp_endpoint_check (opt)) {
+ MONGOC_ERROR ("Setting tlsDisableOCSPEndpointCheck has no effect when "
+ "built against Secure Transport");
+ }
RETURN ((mongoc_stream_t *) tls);
}
#endif /* MONGOC_ENABLE_SSL_SECURE_TRANSPORT */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c
similarity index 95%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c
index 87136bbd..3c43a939 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c
@@ -1,476 +1,476 @@
/*
* Copyright 2013 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.
*/
#include <bson/bson.h>
#include "mongoc-array-private.h"
#include "mongoc-buffer-private.h"
#include "mongoc-error.h"
#include "mongoc-errno-private.h"
#include "mongoc-flags.h"
#include "mongoc-log.h"
#include "mongoc-opcode.h"
#include "mongoc-rpc-private.h"
#include "mongoc-stream.h"
#include "mongoc-stream-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "stream"
#ifndef MONGOC_DEFAULT_TIMEOUT_MSEC
#define MONGOC_DEFAULT_TIMEOUT_MSEC (60L * 60L * 1000L)
#endif
/**
* mongoc_stream_close:
* @stream: A mongoc_stream_t.
*
* Closes the underlying file-descriptor used by @stream.
*
* Returns: 0 on success, -1 on failure.
*/
int
mongoc_stream_close (mongoc_stream_t *stream)
{
int ret;
ENTRY;
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
BSON_ASSERT (stream->close);
ret = stream->close (stream);
RETURN (ret);
}
/**
* mongoc_stream_failed:
* @stream: A mongoc_stream_t.
*
* Frees any resources referenced by @stream, including the memory allocation
* for @stream.
* This handler is called upon stream failure, such as network errors, invalid
* replies
* or replicaset reconfigures deleting the stream
*/
void
mongoc_stream_failed (mongoc_stream_t *stream)
{
ENTRY;
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
if (stream->failed) {
stream->failed (stream);
} else {
stream->destroy (stream);
}
EXIT;
}
/**
* mongoc_stream_destroy:
* @stream: A mongoc_stream_t.
*
* Frees any resources referenced by @stream, including the memory allocation
* for @stream.
*/
void
mongoc_stream_destroy (mongoc_stream_t *stream)
{
ENTRY;
if (!stream) {
EXIT;
}
BSON_ASSERT (stream->destroy);
stream->destroy (stream);
EXIT;
}
/**
* mongoc_stream_flush:
* @stream: A mongoc_stream_t.
*
* Flushes the data in the underlying stream to the transport.
*
* Returns: 0 on success, -1 on failure.
*/
int
mongoc_stream_flush (mongoc_stream_t *stream)
{
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
return stream->flush (stream);
}
/**
* mongoc_stream_writev:
* @stream: A mongoc_stream_t.
* @iov: An array of iovec to write to the stream.
* @iovcnt: The number of elements in @iov.
*
* Writes an array of iovec buffers to the underlying stream.
*
* Returns: the number of bytes written, or -1 upon failure.
*/
ssize_t
mongoc_stream_writev (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
int32_t timeout_msec)
{
ssize_t ret;
ENTRY;
- BSON_ASSERT (stream);
- BSON_ASSERT (iov);
+ BSON_ASSERT_PARAM (stream);
+ BSON_ASSERT_PARAM (iov);
BSON_ASSERT (iovcnt);
BSON_ASSERT (stream->writev);
if (timeout_msec < 0) {
timeout_msec = MONGOC_DEFAULT_TIMEOUT_MSEC;
}
DUMP_IOVEC (writev, iov, iovcnt);
ret = stream->writev (stream, iov, iovcnt, timeout_msec);
RETURN (ret);
}
/**
* mongoc_stream_write:
* @stream: A mongoc_stream_t.
* @buf: A buffer to write.
* @count: The number of bytes to write into @buf.
*
* Simplified access to mongoc_stream_writev(). Creates a single iovec
* with the buffer provided.
*
* Returns: -1 on failure, otherwise the number of bytes written.
*/
ssize_t
mongoc_stream_write (mongoc_stream_t *stream,
void *buf,
size_t count,
int32_t timeout_msec)
{
mongoc_iovec_t iov;
ssize_t ret;
ENTRY;
- BSON_ASSERT (stream);
- BSON_ASSERT (buf);
+ BSON_ASSERT_PARAM (stream);
+ BSON_ASSERT_PARAM (buf);
iov.iov_base = buf;
iov.iov_len = count;
BSON_ASSERT (stream->writev);
ret = mongoc_stream_writev (stream, &iov, 1, timeout_msec);
RETURN (ret);
}
/**
* mongoc_stream_readv:
* @stream: A mongoc_stream_t.
* @iov: An array of iovec containing the location and sizes to read.
* @iovcnt: the number of elements in @iov.
* @min_bytes: the minimum number of bytes to return, or -1.
*
* Reads into the various buffers pointed to by @iov and associated
* buffer lengths.
*
* If @min_bytes is specified, then at least min_bytes will be returned unless
* eof is encountered. This may result in ETIMEDOUT
*
* Returns: the number of bytes read or -1 on failure.
*/
ssize_t
mongoc_stream_readv (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
size_t min_bytes,
int32_t timeout_msec)
{
ssize_t ret;
ENTRY;
- BSON_ASSERT (stream);
- BSON_ASSERT (iov);
+ BSON_ASSERT_PARAM (stream);
+ BSON_ASSERT_PARAM (iov);
BSON_ASSERT (iovcnt);
BSON_ASSERT (stream->readv);
ret = stream->readv (stream, iov, iovcnt, min_bytes, timeout_msec);
if (ret >= 0) {
DUMP_IOVEC (readv, iov, iovcnt);
}
RETURN (ret);
}
/**
* mongoc_stream_read:
* @stream: A mongoc_stream_t.
* @buf: A buffer to write into.
* @count: The number of bytes to write into @buf.
* @min_bytes: The minimum number of bytes to receive
*
* Simplified access to mongoc_stream_readv(). Creates a single iovec
* with the buffer provided.
*
* If @min_bytes is specified, then at least min_bytes will be returned unless
* eof is encountered. This may result in ETIMEDOUT
*
* Returns: -1 on failure, otherwise the number of bytes read.
*/
ssize_t
mongoc_stream_read (mongoc_stream_t *stream,
void *buf,
size_t count,
size_t min_bytes,
int32_t timeout_msec)
{
mongoc_iovec_t iov;
ssize_t ret;
ENTRY;
- BSON_ASSERT (stream);
- BSON_ASSERT (buf);
+ BSON_ASSERT_PARAM (stream);
+ BSON_ASSERT_PARAM (buf);
iov.iov_base = buf;
iov.iov_len = count;
BSON_ASSERT (stream->readv);
ret = mongoc_stream_readv (stream, &iov, 1, min_bytes, timeout_msec);
RETURN (ret);
}
int
mongoc_stream_setsockopt (mongoc_stream_t *stream,
int level,
int optname,
void *optval,
mongoc_socklen_t optlen)
{
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
if (stream->setsockopt) {
return stream->setsockopt (stream, level, optname, optval, optlen);
}
return 0;
}
mongoc_stream_t *
mongoc_stream_get_base_stream (mongoc_stream_t *stream) /* IN */
{
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
if (stream->get_base_stream) {
return stream->get_base_stream (stream);
}
return stream;
}
mongoc_stream_t *
mongoc_stream_get_root_stream (mongoc_stream_t *stream)
{
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
while (stream->get_base_stream) {
stream = stream->get_base_stream (stream);
}
return stream;
}
mongoc_stream_t *
mongoc_stream_get_tls_stream (mongoc_stream_t *stream) /* IN */
{
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
for (; stream && stream->type != MONGOC_STREAM_TLS;
stream = stream->get_base_stream (stream))
;
return stream;
}
ssize_t
mongoc_stream_poll (mongoc_stream_poll_t *streams,
size_t nstreams,
int32_t timeout)
{
mongoc_stream_poll_t *poller =
(mongoc_stream_poll_t *) bson_malloc (sizeof (*poller) * nstreams);
int i;
int last_type = 0;
ssize_t rval = -1;
errno = 0;
for (i = 0; i < nstreams; i++) {
poller[i].stream = mongoc_stream_get_root_stream (streams[i].stream);
poller[i].events = streams[i].events;
poller[i].revents = 0;
if (i == 0) {
last_type = poller[i].stream->type;
} else if (last_type != poller[i].stream->type) {
errno = EINVAL;
goto CLEANUP;
}
}
if (!poller[0].stream->poll) {
errno = EINVAL;
goto CLEANUP;
}
rval = poller[0].stream->poll (poller, nstreams, timeout);
if (rval > 0) {
for (i = 0; i < nstreams; i++) {
streams[i].revents = poller[i].revents;
}
}
CLEANUP:
bson_free (poller);
return rval;
}
bool
mongoc_stream_check_closed (mongoc_stream_t *stream)
{
int ret;
ENTRY;
if (!stream) {
return true;
}
ret = stream->check_closed (stream);
RETURN (ret);
}
bool
mongoc_stream_timed_out (mongoc_stream_t *stream)
{
ENTRY;
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
/* for e.g. a file stream there is no timed_out function */
RETURN (stream->timed_out && stream->timed_out (stream));
}
bool
mongoc_stream_should_retry (mongoc_stream_t *stream)
{
ENTRY;
- BSON_ASSERT (stream);
+ BSON_ASSERT_PARAM (stream);
/* for e.g. a file stream there is no should_retry function */
RETURN (stream->should_retry && stream->should_retry (stream));
}
bool
_mongoc_stream_writev_full (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
int32_t timeout_msec,
bson_error_t *error)
{
size_t total_bytes = 0;
int i;
ssize_t r;
ENTRY;
for (i = 0; i < iovcnt; i++) {
total_bytes += iov[i].iov_len;
}
r = mongoc_stream_writev (stream, iov, iovcnt, timeout_msec);
TRACE ("writev returned: %ld", r);
if (r < 0) {
if (error) {
char buf[128];
char *errstr;
errstr = bson_strerror_r (errno, buf, sizeof (buf));
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failure during socket delivery: %s (%d)",
errstr,
errno);
}
RETURN (false);
}
if (r != total_bytes) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failure to send all requested bytes (only sent: %" PRIu64
"/%" PRId64 " in %dms) during socket delivery",
(uint64_t) r,
(int64_t) total_bytes,
timeout_msec);
RETURN (false);
}
RETURN (true);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h
similarity index 92%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h
index ec382f4b..379e4eb5 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h
@@ -1,86 +1,94 @@
/*
* Copyright 2013-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
*
* 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_THREAD_PRIVATE_H
#define MONGOC_THREAD_PRIVATE_H
#include <bson/bson.h>
#include "common-thread-private.h"
#include "mongoc-config.h"
#include "mongoc-log.h"
#if defined(BSON_OS_UNIX)
#define mongoc_cond_t pthread_cond_t
#define mongoc_cond_broadcast pthread_cond_broadcast
#define mongoc_cond_init(_n) pthread_cond_init ((_n), NULL)
#define mongoc_cond_wait pthread_cond_wait
#define mongoc_cond_signal pthread_cond_signal
static BSON_INLINE int
mongoc_cond_timedwait (pthread_cond_t *cond,
pthread_mutex_t *mutex,
int64_t timeout_msec)
{
struct timespec to;
struct timeval tv;
int64_t msec;
bson_gettimeofday (&tv);
msec = ((int64_t) tv.tv_sec * 1000) + (tv.tv_usec / 1000) + timeout_msec;
to.tv_sec = msec / 1000;
to.tv_nsec = (msec % 1000) * 1000 * 1000;
return pthread_cond_timedwait (cond, mutex, &to);
}
+static BSON_INLINE bool
+mongo_cond_ret_is_timedout (int ret) {
+ return ret == ETIMEDOUT;
+}
#define mongoc_cond_destroy pthread_cond_destroy
#else
#define mongoc_cond_t CONDITION_VARIABLE
#define mongoc_cond_init InitializeConditionVariable
#define mongoc_cond_wait(_c, _m) mongoc_cond_timedwait ((_c), (_m), INFINITE)
static BSON_INLINE int
mongoc_cond_timedwait (mongoc_cond_t *cond,
bson_mutex_t *mutex,
int64_t timeout_msec)
{
int r;
if (SleepConditionVariableCS (cond, mutex, (DWORD) timeout_msec)) {
return 0;
} else {
r = GetLastError ();
if (r == WAIT_TIMEOUT || r == ERROR_TIMEOUT) {
return WSAETIMEDOUT;
} else {
return EINVAL;
}
}
}
+static BSON_INLINE bool
+mongo_cond_ret_is_timedout (int ret) {
+ return ret == WSAETIMEDOUT;
+}
#define mongoc_cond_signal WakeConditionVariable
#define mongoc_cond_broadcast WakeAllConditionVariable
static BSON_INLINE int
mongoc_cond_destroy (mongoc_cond_t *_ignored)
{
return 0;
}
#endif
#endif /* MONGOC_THREAD_PRIVATE_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h
new file mode 100644
index 00000000..948f5a6b
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h
@@ -0,0 +1,45 @@
+
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "mongoc-prelude.h"
+
+#ifndef MONGOC_TOPOLOGY_BACKGROUND_MONITORING_PRIVATE_H
+#define MONGOC_TOPOLOGY_BACKGROUND_MONITORING_PRIVATE_H
+
+#include "mongoc.h"
+#include "mongoc-topology-private.h"
+
+/* Methods of mongoc_topology_t for managing background monitoring. */
+
+void
+_mongoc_topology_background_monitoring_start (mongoc_topology_t *topology);
+
+void
+_mongoc_topology_background_monitoring_reconcile (mongoc_topology_t *topology);
+
+void
+_mongoc_topology_background_monitoring_request_scan (
+ mongoc_topology_t *topology);
+
+void
+_mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology);
+
+void
+_mongoc_topology_background_monitoring_cancel_check (
+ mongoc_topology_t *topology, uint32_t server_id);
+
+#endif /* MONGOC_TOPOLOGY_BACKGROUND_MONITORING_PRIVATE_H */
diff --git a/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c
new file mode 100644
index 00000000..43fdc2b0
--- /dev/null
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2020-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
+ *
+ * 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.
+ */
+
+#include "mongoc-topology-background-monitoring-private.h"
+
+#include "mongoc-client-private.h"
+#include "mongoc-log-private.h"
+#include "mongoc-server-monitor-private.h"
+#ifdef MONGOC_ENABLE_SSL
+#include "mongoc-ssl-private.h"
+#endif
+#include "mongoc-stream-private.h"
+#include "mongoc-topology-description-apm-private.h"
+#include "mongoc-topology-private.h"
+#include "mongoc-trace-private.h"
+#include "mongoc-util-private.h"
+
+#undef MONGOC_LOG_DOMAIN
+#define MONGOC_LOG_DOMAIN "monitor"
+
+static BSON_THREAD_FUN (srv_polling_run, topology_void)
+{
+ mongoc_topology_t *topology;
+
+ topology = topology_void;
+ bson_mutex_lock (&topology->mutex);
+ while (true) {
+ int64_t now_ms;
+ int64_t scan_due_ms;
+ int64_t sleep_duration_ms;
+
+ if (topology->scanner_state != MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
+ bson_mutex_unlock (&topology->mutex);
+ break;
+ }
+
+ /* This will check if a scan is due. */
+ mongoc_topology_rescan_srv (topology);
+
+ /* Unlock and sleep until next scan is due, or until shutdown signalled.
+ */
+ now_ms = bson_get_monotonic_time () / 1000;
+ scan_due_ms = topology->srv_polling_last_scan_ms +
+ topology->srv_polling_rescan_interval_ms;
+ sleep_duration_ms = scan_due_ms - now_ms;
+
+ if (sleep_duration_ms > 0) {
+ TRACE ("srv polling thread sleeping for %" PRId64 "ms",
+ sleep_duration_ms);
+ }
+
+ /* Check for shutdown again here. mongoc_topology_rescan_srv unlocks the
+ * topology mutex for the scan. The topology may have shut down in that
+ * time. */
+ if (topology->scanner_state != MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
+ bson_mutex_unlock (&topology->mutex);
+ break;
+ }
+
+ /* If shutting down, stop. */
+ mongoc_cond_timedwait (
+ &topology->srv_polling_cond, &topology->mutex, sleep_duration_ms);
+ }
+ BSON_THREAD_RETURN;
+}
+
+/* Create a server monitor if necessary.
+ *
+ * Called by monitor threads and application threads when reconciling the
+ * topology description. Caller must have topology mutex locked.
+ */
+static void
+_background_monitor_reconcile_server_monitor (mongoc_topology_t *topology,
+ mongoc_server_description_t *sd)
+{
+ mongoc_set_t *server_monitors;
+ mongoc_server_monitor_t *server_monitor;
+
+ server_monitors = topology->server_monitors;
+ server_monitor = mongoc_set_get (server_monitors, sd->id);
+
+ if (!server_monitor) {
+ /* Add a new server monitor. */
+ server_monitor = mongoc_server_monitor_new (topology, sd);
+ mongoc_server_monitor_run (server_monitor);
+ mongoc_set_add (server_monitors, sd->id, server_monitor);
+ }
+
+ /* Check if an RTT monitor is needed. */
+ if (!bson_empty (&sd->topology_version)) {
+ mongoc_set_t *rtt_monitors;
+ mongoc_server_monitor_t *rtt_monitor;
+
+ rtt_monitors = topology->rtt_monitors;
+ rtt_monitor = mongoc_set_get (rtt_monitors, sd->id);
+ if (!rtt_monitor) {
+ rtt_monitor = mongoc_server_monitor_new (topology, sd);
+ mongoc_server_monitor_run_as_rtt (rtt_monitor);
+ mongoc_set_add (rtt_monitors, sd->id, rtt_monitor);
+ }
+ }
+ return;
+}
+
+/* Start background monitoring.
+ *
+ * Called by an application thread popping a client from a pool. Safe to
+ * call repeatedly.
+ * Caller must have topology mutex locked.
+ */
+void
+_mongoc_topology_background_monitoring_start (mongoc_topology_t *topology)
+{
+ BSON_ASSERT (!topology->single_threaded);
+
+ if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
+ return;
+ }
+
+ TRACE ("%s", "background monitoring starting");
+
+ BSON_ASSERT (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF);
+
+ topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_BG_RUNNING;
+
+ _mongoc_handshake_freeze ();
+ _mongoc_topology_description_monitor_opening (&topology->description);
+
+ /* Reconcile to create the first server monitors. */
+ _mongoc_topology_background_monitoring_reconcile (topology);
+ /* Start SRV polling thread. */
+ if (mongoc_uri_get_service (topology->uri)) {
+ COMMON_PREFIX (thread_create)
+ (&topology->srv_polling_thread, srv_polling_run, topology);
+ }
+}
+
+/* Remove server monitors that are no longer in the set of server descriptions.
+ *
+ * Called by monitor threads and application threads when reconciling the
+ * topology description. Caller must have topology mutex locked.
+ */
+static void
+_remove_orphaned_server_monitors (mongoc_set_t *server_monitors,
+ mongoc_set_t *server_descriptions)
+{
+ uint32_t *server_monitor_ids_to_remove;
+ uint32_t n_server_monitor_ids_to_remove = 0;
+ int i;
+
+ /* Signal shutdown to server monitors no longer in the topology description.
+ */
+ server_monitor_ids_to_remove =
+ bson_malloc0 (sizeof (uint32_t) * server_monitors->items_len);
+ for (i = 0; i < server_monitors->items_len; i++) {
+ mongoc_server_monitor_t *server_monitor;
+ uint32_t id;
+
+ server_monitor = mongoc_set_get_item_and_id (server_monitors, i, &id);
+ if (!mongoc_set_get (server_descriptions, id)) {
+ if (mongoc_server_monitor_request_shutdown (server_monitor)) {
+ mongoc_server_monitor_wait_for_shutdown (server_monitor);
+ mongoc_server_monitor_destroy (server_monitor);
+ server_monitor_ids_to_remove[n_server_monitor_ids_to_remove] = id;
+ n_server_monitor_ids_to_remove++;
+ }
+ }
+ }
+
+ /* Remove freed server monitors that have completed shutdown. */
+ for (i = 0; i < n_server_monitor_ids_to_remove; i++) {
+ mongoc_set_rm (server_monitors, server_monitor_ids_to_remove[i]);
+ }
+ bson_free (server_monitor_ids_to_remove);
+}
+
+/* Reconcile the topology description with the set of server monitors.
+ *
+ * Called when the topology description is updated (via handshake, monitoring,
+ * or invalidation). May be called by server monitor thread or an application
+ * thread.
+ * Caller must have topology mutex locked.
+ * Locks server monitor mutexes. May join / remove server monitors that have
+ * completed shutdown.
+ */
+void
+_mongoc_topology_background_monitoring_reconcile (mongoc_topology_t *topology)
+{
+ mongoc_topology_description_t *td;
+ mongoc_set_t *server_descriptions;
+ int i;
+
+ td = &topology->description;
+ server_descriptions = td->servers;
+
+ BSON_ASSERT (!topology->single_threaded);
+
+ if (topology->scanner_state != MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
+ return;
+ }
+
+ /* Add newly discovered server monitors, and update existing ones. */
+ for (i = 0; i < server_descriptions->items_len; i++) {
+ mongoc_server_description_t *sd;
+
+ sd = mongoc_set_get_item (server_descriptions, i);
+ _background_monitor_reconcile_server_monitor (topology, sd);
+ }
+
+ _remove_orphaned_server_monitors (topology->server_monitors,
+ server_descriptions);
+ _remove_orphaned_server_monitors (topology->rtt_monitors,
+ server_descriptions);
+}
+
+/* Request all server monitors to scan.
+ *
+ * Called from application threads (during server selection or "not master"
+ * errors). Caller must have topology mutex locked. Locks server monitor mutexes
+ * to deliver scan_requested.
+ */
+void
+_mongoc_topology_background_monitoring_request_scan (
+ mongoc_topology_t *topology)
+{
+ mongoc_set_t *server_monitors;
+ int i;
+
+ BSON_ASSERT (!topology->single_threaded);
+
+ if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN) {
+ return;
+ }
+
+ server_monitors = topology->server_monitors;
+
+ for (i = 0; i < server_monitors->items_len; i++) {
+ mongoc_server_monitor_t *server_monitor;
+ uint32_t id;
+
+ server_monitor = mongoc_set_get_item_and_id (server_monitors, i, &id);
+ mongoc_server_monitor_request_scan (server_monitor);
+ }
+}
+
+/* Stop, join, and destroy all server monitors.
+ *
+ * Called by application threads when destroying a client pool.
+ * Caller must have topology mutex locked.
+ * Locks server monitor mutexes to deliver shutdown. Releases topology mutex to
+ * join server monitor threads. Leaves topology mutex locked on exit. This
+ * function is thread-safe. But in practice, it is only ever called by one
+ * application thread (because mongoc_client_pool_destroy is not thread-safe).
+ */
+void
+_mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology)
+{
+ mongoc_server_monitor_t *server_monitor;
+ int i;
+ bool is_srv_polling;
+
+ BSON_ASSERT (!topology->single_threaded);
+
+ if (topology->scanner_state != MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
+ return;
+ }
+
+ topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN;
+ TRACE ("%s", "background monitoring stopping");
+
+ is_srv_polling = NULL != mongoc_uri_get_service (topology->uri);
+ /* Signal SRV polling to shut down (if it is started). */
+ if (is_srv_polling) {
+ mongoc_cond_signal (&topology->srv_polling_cond);
+ }
+
+ /* Signal all server monitors to shut down. */
+ for (i = 0; i < topology->server_monitors->items_len; i++) {
+ server_monitor = mongoc_set_get_item (topology->server_monitors, i);
+ mongoc_server_monitor_request_shutdown (server_monitor);
+ }
+
+ /* Signal all RTT monitors to shut down. */
+ for (i = 0; i < topology->rtt_monitors->items_len; i++) {
+ server_monitor = mongoc_set_get_item (topology->rtt_monitors, i);
+ mongoc_server_monitor_request_shutdown (server_monitor);
+ }
+
+ /* Some mongoc_server_monitor_t may be waiting for topology mutex. Unlock so
+ * they can proceed to terminate. It is safe to unlock topology mutex. Since
+ * scanner_state has transitioned to shutting down, no thread can modify
+ * server_monitors. */
+ bson_mutex_unlock (&topology->mutex);
+
+ for (i = 0; i < topology->server_monitors->items_len; i++) {
+ /* Wait for the thread to shutdown. */
+ server_monitor = mongoc_set_get_item (topology->server_monitors, i);
+ mongoc_server_monitor_wait_for_shutdown (server_monitor);
+ mongoc_server_monitor_destroy (server_monitor);
+ }
+
+ for (i = 0; i < topology->rtt_monitors->items_len; i++) {
+ /* Wait for the thread to shutdown. */
+ server_monitor = mongoc_set_get_item (topology->rtt_monitors, i);
+ mongoc_server_monitor_wait_for_shutdown (server_monitor);
+ mongoc_server_monitor_destroy (server_monitor);
+ }
+
+ /* Wait for SRV polling thread. */
+ if (is_srv_polling) {
+ COMMON_PREFIX (thread_join) (topology->srv_polling_thread);
+ }
+
+ bson_mutex_lock (&topology->mutex);
+ mongoc_set_destroy (topology->server_monitors);
+ mongoc_set_destroy (topology->rtt_monitors);
+ topology->server_monitors = mongoc_set_new (1, NULL, NULL);
+ topology->rtt_monitors = mongoc_set_new (1, NULL, NULL);
+ topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_OFF;
+ mongoc_cond_broadcast (&topology->cond_client);
+}
+
+/* Cancel an in-progress streaming ismaster for a specific server (if
+ * applicable).
+ *
+ * Called from application threads on network errors.
+ * Caller must have topology mutex locked.
+ */
+void
+_mongoc_topology_background_monitoring_cancel_check (
+ mongoc_topology_t *topology, uint32_t server_id)
+{
+ mongoc_server_monitor_t *server_monitor;
+
+ server_monitor = mongoc_set_get (topology->server_monitors, server_id);
+ if (!server_monitor) {
+ /* Already removed. */
+ return;
+ }
+ mongoc_server_monitor_request_cancel (server_monitor);
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h
index db4a9f1a..10071702 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h
@@ -1,138 +1,142 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H
#define MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H
#include "mongoc-set-private.h"
#include "mongoc-server-description.h"
#include "mongoc-array-private.h"
#include "mongoc-topology-description.h"
#include "mongoc-apm-private.h"
typedef enum {
MONGOC_TOPOLOGY_UNKNOWN,
MONGOC_TOPOLOGY_SHARDED,
MONGOC_TOPOLOGY_RS_NO_PRIMARY,
MONGOC_TOPOLOGY_RS_WITH_PRIMARY,
MONGOC_TOPOLOGY_SINGLE,
MONGOC_TOPOLOGY_DESCRIPTION_TYPES
} mongoc_topology_description_type_t;
struct _mongoc_topology_description_t {
bson_oid_t topology_id;
bool opened;
mongoc_topology_description_type_t type;
int64_t heartbeat_msec;
mongoc_set_t *servers;
char *set_name;
int64_t max_set_version;
bson_oid_t max_election_id;
bson_error_t compatibility_error;
uint32_t max_server_id;
bool stale;
unsigned int rand_seed;
/* the greatest seen cluster time, for a MongoDB 3.6+ sharded cluster.
* see Driver Sessions Spec. */
bson_t cluster_time;
/* smallest seen logicalSessionTimeoutMinutes, or -1 if any server has no
* logicalSessionTimeoutMinutes. see Server Discovery and Monitoring Spec */
int64_t session_timeout_minutes;
mongoc_apm_callbacks_t apm_callbacks;
void *apm_context;
};
typedef enum { MONGOC_SS_READ, MONGOC_SS_WRITE } mongoc_ss_optype_t;
void
mongoc_topology_description_init (mongoc_topology_description_t *description,
int64_t heartbeat_msec);
void
_mongoc_topology_description_copy_to (const mongoc_topology_description_t *src,
mongoc_topology_description_t *dst);
void
mongoc_topology_description_destroy (
mongoc_topology_description_t *description);
void
mongoc_topology_description_handle_ismaster (
mongoc_topology_description_t *topology,
uint32_t server_id,
const bson_t *reply,
int64_t rtt_msec,
const bson_error_t *error /* IN */);
mongoc_server_description_t *
mongoc_topology_description_select (mongoc_topology_description_t *description,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_pref,
int64_t local_threshold_ms);
mongoc_server_description_t *
mongoc_topology_description_server_by_id (
mongoc_topology_description_t *description,
uint32_t id,
bson_error_t *error);
int32_t
mongoc_topology_description_lowest_max_wire_version (
const mongoc_topology_description_t *td);
bool
mongoc_topology_description_all_sds_have_write_date (
const mongoc_topology_description_t *td);
bool
_mongoc_topology_description_validate_max_staleness (
const mongoc_topology_description_t *td,
int64_t max_staleness_seconds,
bson_error_t *error);
void
mongoc_topology_description_suitable_servers (
mongoc_array_t *set, /* OUT */
mongoc_ss_optype_t optype,
mongoc_topology_description_t *topology,
const mongoc_read_prefs_t *read_pref,
size_t local_threshold_ms);
bool
mongoc_topology_description_has_data_node (mongoc_topology_description_t *td);
void
mongoc_topology_description_invalidate_server (
mongoc_topology_description_t *topology,
uint32_t id,
const bson_error_t *error /* IN */);
bool
mongoc_topology_description_add_server (mongoc_topology_description_t *topology,
const char *server,
uint32_t *id /* OUT */);
void
mongoc_topology_description_update_cluster_time (
mongoc_topology_description_t *td, const bson_t *reply);
+void
+mongoc_topology_description_reconcile (mongoc_topology_description_t *td,
+ mongoc_host_list_t *host_list);
+
#endif /* MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c
similarity index 93%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c
index 4fb39eed..9c785376 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c
@@ -1,2121 +1,2238 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-array-private.h"
#include "mongoc-error.h"
#include "mongoc-server-description-private.h"
#include "mongoc-topology-description-apm-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-set-private.h"
#include "mongoc-client-private.h"
#include "mongoc-thread-private.h"
+#include "mongoc-host-list-private.h"
+#include "utlist.h"
static bool
_is_data_node (mongoc_server_description_t *sd)
{
switch (sd->type) {
case MONGOC_SERVER_MONGOS:
case MONGOC_SERVER_STANDALONE:
case MONGOC_SERVER_RS_SECONDARY:
case MONGOC_SERVER_RS_PRIMARY:
return true;
case MONGOC_SERVER_RS_OTHER:
case MONGOC_SERVER_RS_ARBITER:
case MONGOC_SERVER_UNKNOWN:
case MONGOC_SERVER_POSSIBLE_PRIMARY:
case MONGOC_SERVER_RS_GHOST:
case MONGOC_SERVER_DESCRIPTION_TYPES:
default:
return false;
}
}
static void
_mongoc_topology_server_dtor (void *server_, void *ctx_)
{
mongoc_server_description_destroy ((mongoc_server_description_t *) server_);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_init --
*
* Initialize the given topology description
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_description_init (mongoc_topology_description_t *description,
int64_t heartbeat_msec)
{
ENTRY;
BSON_ASSERT (description);
memset (description, 0, sizeof (*description));
bson_oid_init (&description->topology_id, NULL);
description->opened = false;
description->type = MONGOC_TOPOLOGY_UNKNOWN;
description->heartbeat_msec = heartbeat_msec;
description->servers =
mongoc_set_new (8, _mongoc_topology_server_dtor, NULL);
description->set_name = NULL;
description->max_set_version = MONGOC_NO_SET_VERSION;
description->stale = true;
description->rand_seed = (unsigned int) bson_get_monotonic_time ();
bson_init (&description->cluster_time);
description->session_timeout_minutes = MONGOC_NO_SESSIONS;
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_copy_to --
*
* Deep-copy @src to an uninitialized topology description @dst.
* @dst must not already point to any allocated resources. Clean
* up with mongoc_topology_description_destroy.
*
* WARNING: @dst's rand_seed is not initialized.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_description_copy_to (const mongoc_topology_description_t *src,
mongoc_topology_description_t *dst)
{
size_t nitems;
size_t i;
mongoc_server_description_t *sd;
uint32_t id;
ENTRY;
BSON_ASSERT (src);
BSON_ASSERT (dst);
bson_oid_copy (&src->topology_id, &dst->topology_id);
dst->opened = src->opened;
dst->type = src->type;
dst->heartbeat_msec = src->heartbeat_msec;
nitems = bson_next_power_of_two (src->servers->items_len);
dst->servers = mongoc_set_new (nitems, _mongoc_topology_server_dtor, NULL);
for (i = 0; i < src->servers->items_len; i++) {
sd = mongoc_set_get_item_and_id (src->servers, (int) i, &id);
mongoc_set_add (
dst->servers, id, mongoc_server_description_new_copy (sd));
}
dst->set_name = bson_strdup (src->set_name);
dst->max_set_version = src->max_set_version;
memcpy (&dst->compatibility_error,
&src->compatibility_error,
sizeof (bson_error_t));
dst->max_server_id = src->max_server_id;
dst->stale = src->stale;
memcpy (&dst->apm_callbacks,
&src->apm_callbacks,
sizeof (mongoc_apm_callbacks_t));
dst->apm_context = src->apm_context;
bson_copy_to (&src->cluster_time, &dst->cluster_time);
dst->session_timeout_minutes = src->session_timeout_minutes;
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_destroy --
*
* Destroy allocated resources within @description
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_description_destroy (mongoc_topology_description_t *description)
{
ENTRY;
BSON_ASSERT (description);
if (description->servers) {
mongoc_set_destroy (description->servers);
}
if (description->set_name) {
bson_free (description->set_name);
}
bson_destroy (&description->cluster_time);
EXIT;
}
/* find the primary, then stop iterating */
static bool
_mongoc_topology_description_has_primary_cb (void *item, void *ctx /* OUT */)
{
mongoc_server_description_t *server = (mongoc_server_description_t *) item;
mongoc_server_description_t **primary = (mongoc_server_description_t **) ctx;
/* TODO should this include MONGOS? */
if (server->type == MONGOC_SERVER_RS_PRIMARY ||
server->type == MONGOC_SERVER_STANDALONE) {
*primary = (mongoc_server_description_t *) item;
return false;
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_has_primary --
*
* If topology has a primary, return it.
*
* Returns:
* A pointer to the primary, or NULL.
*
* Side effects:
* None
*
*--------------------------------------------------------------------------
*/
static mongoc_server_description_t *
_mongoc_topology_description_has_primary (
mongoc_topology_description_t *description)
{
mongoc_server_description_t *primary = NULL;
mongoc_set_for_each (description->servers,
_mongoc_topology_description_has_primary_cb,
&primary);
return primary;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_later_election --
*
* Check if we've seen a more recent election in the replica set
* than this server has.
*
* Returns:
* True if the topology description's max replica set version plus
* election id is later than the server description's.
*
* Side effects:
* None
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_topology_description_later_election (mongoc_topology_description_t *td,
mongoc_server_description_t *sd)
{
/* initially max_set_version is -1 and max_election_id is zeroed */
return td->max_set_version > sd->set_version ||
(td->max_set_version == sd->set_version &&
bson_oid_compare (&td->max_election_id, &sd->election_id) > 0);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_set_max_set_version --
*
* Remember that we've seen a new replica set version. Unconditionally
* sets td->set_version to sd->set_version.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_set_max_set_version (
mongoc_topology_description_t *td, mongoc_server_description_t *sd)
{
td->max_set_version = sd->set_version;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_set_max_election_id --
*
* Remember that we've seen a new election id. Unconditionally sets
* td->max_election_id to sd->election_id.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_set_max_election_id (
mongoc_topology_description_t *td, mongoc_server_description_t *sd)
{
bson_oid_copy (&sd->election_id, &td->max_election_id);
}
static bool
_mongoc_topology_description_server_is_candidate (
mongoc_server_description_type_t desc_type,
mongoc_read_mode_t read_mode,
mongoc_topology_description_type_t topology_type)
{
switch ((int) topology_type) {
case MONGOC_TOPOLOGY_SINGLE:
switch ((int) desc_type) {
case MONGOC_SERVER_STANDALONE:
return true;
default:
return false;
}
case MONGOC_TOPOLOGY_RS_NO_PRIMARY:
case MONGOC_TOPOLOGY_RS_WITH_PRIMARY:
switch ((int) read_mode) {
case MONGOC_READ_PRIMARY:
switch ((int) desc_type) {
case MONGOC_SERVER_RS_PRIMARY:
return true;
default:
return false;
}
case MONGOC_READ_SECONDARY:
switch ((int) desc_type) {
case MONGOC_SERVER_RS_SECONDARY:
return true;
default:
return false;
}
default:
switch ((int) desc_type) {
case MONGOC_SERVER_RS_PRIMARY:
case MONGOC_SERVER_RS_SECONDARY:
return true;
default:
return false;
}
}
case MONGOC_TOPOLOGY_SHARDED:
switch ((int) desc_type) {
case MONGOC_SERVER_MONGOS:
return true;
default:
return false;
}
default:
return false;
}
}
typedef struct _mongoc_suitable_data_t {
mongoc_read_mode_t read_mode;
mongoc_topology_description_type_t topology_type;
mongoc_server_description_t *primary; /* OUT */
mongoc_server_description_t **candidates; /* OUT */
size_t candidates_len; /* OUT */
bool has_secondary; /* OUT */
} mongoc_suitable_data_t;
static bool
_mongoc_replica_set_read_suitable_cb (void *item, void *ctx)
{
mongoc_server_description_t *server = (mongoc_server_description_t *) item;
mongoc_suitable_data_t *data = (mongoc_suitable_data_t *) ctx;
/* primary's used in staleness calculation, even with mode SECONDARY */
if (server->type == MONGOC_SERVER_RS_PRIMARY) {
data->primary = server;
}
if (_mongoc_topology_description_server_is_candidate (
server->type, data->read_mode, data->topology_type)) {
if (server->type == MONGOC_SERVER_RS_PRIMARY) {
if (data->read_mode == MONGOC_READ_PRIMARY ||
data->read_mode == MONGOC_READ_PRIMARY_PREFERRED) {
/* we want a primary and we have one, done! */
return false;
}
}
if (server->type == MONGOC_SERVER_RS_SECONDARY) {
data->has_secondary = true;
}
/* add to our candidates */
data->candidates[data->candidates_len++] = server;
} else {
TRACE ("Rejected [%s] [%s] for mode [%s]",
mongoc_server_description_type (server),
server->host.host_and_port,
_mongoc_read_mode_as_str (data->read_mode));
}
return true;
}
/* if any mongos are candidates, add them to the candidates array */
static void
_mongoc_try_mode_secondary (mongoc_array_t *set, /* OUT */
mongoc_topology_description_t *topology,
const mongoc_read_prefs_t *read_pref,
size_t local_threshold_ms)
{
mongoc_read_prefs_t *secondary;
secondary = mongoc_read_prefs_copy (read_pref);
mongoc_read_prefs_set_mode (secondary, MONGOC_READ_SECONDARY);
mongoc_topology_description_suitable_servers (
set, MONGOC_SS_READ, topology, secondary, local_threshold_ms);
mongoc_read_prefs_destroy (secondary);
}
/* if any mongos are candidates, add them to the candidates array */
static bool
_mongoc_find_suitable_mongos_cb (void *item, void *ctx)
{
mongoc_server_description_t *server = (mongoc_server_description_t *) item;
mongoc_suitable_data_t *data = (mongoc_suitable_data_t *) ctx;
if (_mongoc_topology_description_server_is_candidate (
server->type, data->read_mode, data->topology_type)) {
data->candidates[data->candidates_len++] = server;
}
return true;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_description_lowest_max_wire_version --
*
* The topology's max wire version.
*
* NOTE: this method should only be called while holding the mutex on
* the owning topology object.
*
* Returns:
* The minimum of all known servers' max wire versions, or INT32_MAX
* if there are no known servers.
*
* Side effects:
* None.
*
*-------------------------------------------------------------------------
*/
int32_t
mongoc_topology_description_lowest_max_wire_version (
const mongoc_topology_description_t *td)
{
int i;
int32_t ret = INT32_MAX;
mongoc_server_description_t *sd;
for (i = 0; (size_t) i < td->servers->items_len; i++) {
sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i);
if (sd->type != MONGOC_SERVER_UNKNOWN && sd->max_wire_version < ret) {
ret = sd->max_wire_version;
}
}
return ret;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_description_all_sds_have_write_date --
*
* Whether the primary and all secondaries' server descriptions have
* last_write_date_ms.
*
* Side effects:
* None.
*
*-------------------------------------------------------------------------
*/
bool
mongoc_topology_description_all_sds_have_write_date (
const mongoc_topology_description_t *td)
{
int i;
mongoc_server_description_t *sd;
for (i = 0; (size_t) i < td->servers->items_len; i++) {
sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i);
if (sd->last_write_date_ms <= 0 &&
(sd->type == MONGOC_SERVER_RS_PRIMARY ||
sd->type == MONGOC_SERVER_RS_SECONDARY)) {
return false;
}
}
return true;
}
/*
*-------------------------------------------------------------------------
*
* _mongoc_topology_description_validate_max_staleness --
*
* If the provided "maxStalenessSeconds" component of the read
* preference is not valid for this topology, fill out @error and
* return false.
*
* Side effects:
* None.
*
*-------------------------------------------------------------------------
*/
bool
_mongoc_topology_description_validate_max_staleness (
const mongoc_topology_description_t *td,
int64_t max_staleness_seconds,
bson_error_t *error)
{
mongoc_topology_description_type_t td_type;
/* Server Selection Spec: A driver MUST raise an error if the TopologyType
* is ReplicaSetWithPrimary or ReplicaSetNoPrimary and either of these
* conditions is false:
*
* maxStalenessSeconds * 1000 >= heartbeatFrequencyMS + idleWritePeriodMS
* maxStalenessSeconds >= smallestMaxStalenessSeconds
*/
td_type = td->type;
if (td_type != MONGOC_TOPOLOGY_RS_WITH_PRIMARY &&
td_type != MONGOC_TOPOLOGY_RS_NO_PRIMARY) {
return true;
}
if (max_staleness_seconds * 1000 <
td->heartbeat_msec + MONGOC_IDLE_WRITE_PERIOD_MS) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"maxStalenessSeconds is set to %" PRId64
", it must be at least heartbeatFrequencyMS (%" PRId64
") + server's idle write period (%d seconds)",
max_staleness_seconds,
td->heartbeat_msec,
MONGOC_IDLE_WRITE_PERIOD_MS / 1000);
return false;
}
if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"maxStalenessSeconds is set to %" PRId64
", it must be at least %d seconds",
max_staleness_seconds,
MONGOC_SMALLEST_MAX_STALENESS_SECONDS);
return false;
}
return true;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_description_suitable_servers --
*
* Fill out an array of servers matching the read preference and
* localThresholdMS.
*
* NOTE: this method should only be called while holding the mutex on
* the owning topology object.
*
* Side effects:
* None.
*
*-------------------------------------------------------------------------
*/
void
mongoc_topology_description_suitable_servers (
mongoc_array_t *set, /* OUT */
mongoc_ss_optype_t optype,
mongoc_topology_description_t *topology,
const mongoc_read_prefs_t *read_pref,
size_t local_threshold_ms)
{
mongoc_suitable_data_t data;
mongoc_server_description_t **candidates;
mongoc_server_description_t *server;
int64_t nearest = -1;
int i;
mongoc_read_mode_t read_mode = mongoc_read_prefs_get_mode (read_pref);
candidates = (mongoc_server_description_t **) bson_malloc0 (
sizeof (*candidates) * topology->servers->items_len);
data.read_mode = read_mode;
data.topology_type = topology->type;
data.primary = NULL;
data.candidates = candidates;
data.candidates_len = 0;
data.has_secondary = false;
/* Single server --
* Either it is suitable or it isn't */
if (topology->type == MONGOC_TOPOLOGY_SINGLE) {
server = (mongoc_server_description_t *) mongoc_set_get_item (
topology->servers, 0);
if (_mongoc_topology_description_server_is_candidate (
server->type, read_mode, topology->type)) {
_mongoc_array_append_val (set, server);
} else {
TRACE (
"Rejected [%s] [%s] for read mode [%s] with topology type Single",
mongoc_server_description_type (server),
server->host.host_and_port,
_mongoc_read_mode_as_str (read_mode));
}
goto DONE;
}
/* Replica sets --
* Find suitable servers based on read mode */
if (topology->type == MONGOC_TOPOLOGY_RS_NO_PRIMARY ||
topology->type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY) {
if (optype == MONGOC_SS_READ) {
mongoc_set_for_each (
topology->servers, _mongoc_replica_set_read_suitable_cb, &data);
if (read_mode == MONGOC_READ_PRIMARY) {
if (data.primary) {
_mongoc_array_append_val (set, data.primary);
}
goto DONE;
}
if (read_mode == MONGOC_READ_PRIMARY_PREFERRED && data.primary) {
_mongoc_array_append_val (set, data.primary);
goto DONE;
}
if (read_mode == MONGOC_READ_SECONDARY_PREFERRED) {
/* try read_mode SECONDARY */
_mongoc_try_mode_secondary (
set, topology, read_pref, local_threshold_ms);
/* otherwise fall back to primary */
if (!set->len && data.primary) {
_mongoc_array_append_val (set, data.primary);
}
goto DONE;
}
if (read_mode == MONGOC_READ_SECONDARY) {
for (i = 0; i < data.candidates_len; i++) {
if (candidates[i] &&
candidates[i]->type != MONGOC_SERVER_RS_SECONDARY) {
TRACE ("Rejected [%s] [%s] for mode [%s] with RS topology",
mongoc_server_description_type (candidates[i]),
candidates[i]->host.host_and_port,
_mongoc_read_mode_as_str (read_mode));
candidates[i] = NULL;
}
}
}
/* mode is SECONDARY or NEAREST, filter by staleness and tags */
mongoc_server_description_filter_stale (data.candidates,
data.candidates_len,
data.primary,
topology->heartbeat_msec,
read_pref);
mongoc_server_description_filter_tags (
data.candidates, data.candidates_len, read_pref);
} else if (topology->type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY) {
/* includes optype == MONGOC_SS_WRITE as the exclusion of the above if
*/
mongoc_set_for_each (topology->servers,
_mongoc_topology_description_has_primary_cb,
&data.primary);
if (data.primary) {
_mongoc_array_append_val (set, data.primary);
goto DONE;
}
}
}
/* Sharded clusters --
* All candidates in the latency window are suitable */
if (topology->type == MONGOC_TOPOLOGY_SHARDED) {
mongoc_set_for_each (
topology->servers, _mongoc_find_suitable_mongos_cb, &data);
}
/* Ways to get here:
* - secondary read
* - secondary preferred read
* - primary_preferred and no primary read
* - sharded anything
* Find the nearest, then select within the window */
for (i = 0; i < data.candidates_len; i++) {
if (candidates[i] &&
(nearest == -1 || nearest > candidates[i]->round_trip_time_msec)) {
nearest = candidates[i]->round_trip_time_msec;
}
}
for (i = 0; i < data.candidates_len; i++) {
if (candidates[i] && (candidates[i]->round_trip_time_msec <=
nearest + local_threshold_ms)) {
_mongoc_array_append_val (set, candidates[i]);
}
}
DONE:
bson_free (candidates);
return;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_has_data_node --
*
* Internal method: are any servers not Arbiter, Ghost, or Unknown?
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_description_has_data_node (mongoc_topology_description_t *td)
{
int i;
mongoc_server_description_t *sd;
for (i = 0; i < (int) td->servers->items_len; i++) {
sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i);
if (_is_data_node (sd)) {
return true;
}
}
return false;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_description_select --
*
* Return a server description of a node that is appropriate for
* the given read preference and operation type.
*
* NOTE: this method simply attempts to select a server from the
* current topology, it does not retry or trigger topology checks.
*
* NOTE: this method should only be called while holding the mutex on
* the owning topology object.
*
* Returns:
* Selected server description, or NULL upon failure.
*
* Side effects:
* None.
*
*-------------------------------------------------------------------------
*/
mongoc_server_description_t *
mongoc_topology_description_select (mongoc_topology_description_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_pref,
int64_t local_threshold_ms)
{
mongoc_array_t suitable_servers;
mongoc_server_description_t *sd = NULL;
int rand_n;
ENTRY;
if (topology->type == MONGOC_TOPOLOGY_SINGLE) {
sd = (mongoc_server_description_t *) mongoc_set_get_item (
topology->servers, 0);
if (sd->has_is_master) {
RETURN (sd);
} else {
TRACE ("Topology type single, [%s] is down", sd->host.host_and_port);
RETURN (NULL);
}
}
_mongoc_array_init (&suitable_servers,
sizeof (mongoc_server_description_t *));
mongoc_topology_description_suitable_servers (
&suitable_servers, optype, topology, read_pref, local_threshold_ms);
if (suitable_servers.len != 0) {
rand_n = _mongoc_rand_simple (&topology->rand_seed);
sd = _mongoc_array_index (&suitable_servers,
mongoc_server_description_t *,
rand_n % suitable_servers.len);
}
_mongoc_array_destroy (&suitable_servers);
if (sd) {
TRACE ("Topology type [%s], selected [%s] [%s]",
mongoc_topology_description_type (topology),
mongoc_server_description_type (sd),
sd->host.host_and_port);
}
RETURN (sd);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_server_by_id --
*
* Get the server description for @id, if that server is present
* in @description. Otherwise, return NULL and fill out optional
* @error.
*
* NOTE: In most cases, caller should create a duplicate of the
* returned server description. Caller should hold the mutex on the
* owning topology object while calling this method and while using
* the returned reference.
*
* Returns:
* A mongoc_server_description_t *, or NULL.
*
* Side effects:
* Fills out optional @error if server not found.
*
*--------------------------------------------------------------------------
*/
mongoc_server_description_t *
mongoc_topology_description_server_by_id (
mongoc_topology_description_t *description, uint32_t id, bson_error_t *error)
{
mongoc_server_description_t *sd;
BSON_ASSERT (description);
sd =
(mongoc_server_description_t *) mongoc_set_get (description->servers, id);
if (!sd) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"Could not find description for node %u",
id);
}
return sd;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_remove_server --
*
* If present, remove this server from this topology description.
*
* Returns:
* None.
*
* Side effects:
* Removes the server description from topology and destroys it.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_remove_server (
mongoc_topology_description_t *description,
mongoc_server_description_t *server)
{
BSON_ASSERT (description);
BSON_ASSERT (server);
_mongoc_topology_description_monitor_server_closed (description, server);
mongoc_set_rm (description->servers, server->id);
/* Check if removing server resulted in an empty set of servers */
if (description->servers->items_len == 0) {
MONGOC_WARNING ("Last server removed from topology");
}
}
typedef struct _mongoc_address_and_id_t {
const char *address; /* IN */
bool found; /* OUT */
uint32_t id; /* OUT */
} mongoc_address_and_id_t;
/* find the given server and stop iterating */
static bool
_mongoc_topology_description_has_server_cb (void *item,
void *ctx /* IN - OUT */)
{
mongoc_server_description_t *server = (mongoc_server_description_t *) item;
mongoc_address_and_id_t *data = (mongoc_address_and_id_t *) ctx;
if (strcasecmp (data->address, server->connection_address) == 0) {
data->found = true;
data->id = server->id;
return false;
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_has_set_version --
*
* Whether @topology's max replica set version has been set.
*
* Returns:
* True if the max setVersion was ever set.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_topology_description_has_set_version (mongoc_topology_description_t *td)
{
return td->max_set_version != MONGOC_NO_SET_VERSION;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_topology_has_server --
*
* Return true if @server is in @topology. If so, place its id in
* @id if given.
*
* Returns:
* True if server is in topology, false otherwise.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_topology_description_has_server (
mongoc_topology_description_t *description,
const char *address,
uint32_t *id /* OUT */)
{
mongoc_address_and_id_t data;
BSON_ASSERT (description);
BSON_ASSERT (address);
data.address = address;
data.found = false;
mongoc_set_for_each (
description->servers, _mongoc_topology_description_has_server_cb, &data);
if (data.found && id) {
*id = data.id;
}
return data.found;
}
typedef struct _mongoc_address_and_type_t {
const char *address;
mongoc_server_description_type_t type;
} mongoc_address_and_type_t;
static bool
_mongoc_label_unknown_member_cb (void *item, void *ctx)
{
mongoc_server_description_t *server = (mongoc_server_description_t *) item;
mongoc_address_and_type_t *data = (mongoc_address_and_type_t *) ctx;
if (strcasecmp (server->connection_address, data->address) == 0 &&
server->type == MONGOC_SERVER_UNKNOWN) {
mongoc_server_description_set_state (server, data->type);
return false;
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_label_unknown_member --
*
* Find the server description with the given @address and if its
* type is UNKNOWN, set its type to @type.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_label_unknown_member (
mongoc_topology_description_t *description,
const char *address,
mongoc_server_description_type_t type)
{
mongoc_address_and_type_t data;
BSON_ASSERT (description);
BSON_ASSERT (address);
data.type = type;
data.address = address;
mongoc_set_for_each (
description->servers, _mongoc_label_unknown_member_cb, &data);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_set_state --
*
* Change the state of this cluster and unblock things waiting
* on a change of topology type.
*
* Returns:
* None.
*
* Side effects:
* Unblocks anything waiting on this description to change states.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_set_state (
mongoc_topology_description_t *description,
mongoc_topology_description_type_t type)
{
description->type = type;
}
static void
_update_rs_type (mongoc_topology_description_t *topology)
{
if (_mongoc_topology_description_has_primary (topology)) {
_mongoc_topology_description_set_state (topology,
MONGOC_TOPOLOGY_RS_WITH_PRIMARY);
} else {
_mongoc_topology_description_set_state (topology,
MONGOC_TOPOLOGY_RS_NO_PRIMARY);
}
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_check_if_has_primary --
*
* If there is a primary in topology, set topology
* type to RS_WITH_PRIMARY, otherwise set it to
* RS_NO_PRIMARY.
*
* Returns:
* None.
*
* Side effects:
* Changes the topology type.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_check_if_has_primary (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
_update_rs_type (topology);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_invalidate_server --
*
* Invalidate a server if a network error occurred while using it in
* another part of the client. Server description is set to type
* UNKNOWN, the error is recorded, and other parameters are reset to
* defaults. Pass in the reason for invalidation in @error.
*
* NOTE: this method should only be called while holding the mutex on
* the owning topology object.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_description_invalidate_server (
mongoc_topology_description_t *topology,
uint32_t id,
const bson_error_t *error /* IN */)
{
BSON_ASSERT (error);
/* send NULL ismaster reply */
- mongoc_topology_description_handle_ismaster (topology, id, NULL, 0, error);
+ mongoc_topology_description_handle_ismaster (topology, id, NULL, MONGOC_RTT_UNSET, error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_add_server --
*
* Add the specified server to the cluster topology if it is not
* already a member. If @id, place its id in @id.
*
* NOTE: this method should only be called while holding the mutex on
* the owning topology object.
*
* Return:
* True if the server was added or already existed in the topology,
* false if an error occurred.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_description_add_server (mongoc_topology_description_t *topology,
const char *server,
uint32_t *id /* OUT */)
{
uint32_t server_id;
mongoc_server_description_t *description;
BSON_ASSERT (topology);
BSON_ASSERT (server);
if (!_mongoc_topology_description_has_server (
topology, server, &server_id)) {
/* TODO this might not be an accurate count in all cases */
server_id = ++topology->max_server_id;
description =
(mongoc_server_description_t *) bson_malloc0 (sizeof *description);
mongoc_server_description_init (description, server, server_id);
mongoc_set_add (topology->servers, server_id, description);
/* if we're in topology_new then no callbacks are registered and this is
* a no-op. later, if we discover a new RS member this sends an event. */
_mongoc_topology_description_monitor_server_opening (topology,
description);
}
if (id) {
*id = server_id;
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_update_cluster_time --
*
* Drivers Session Spec: Drivers MUST examine responses to server commands to
* see if they contain a top level field named $clusterTime formatted as
* follows:
*
* {
* ...
* $clusterTime : {
* clusterTime : <BsonTimestamp>,
* signature : {
* hash : <BsonBinaryData>,
* keyId : <BsonInt64>
* }
* },
* ...
* }
*
* Whenever a driver receives a clusterTime from a server it MUST compare it
* to the current highest seen clusterTime for the cluster. If the new
* clusterTime is higher than the highest seen clusterTime it MUST become
* the new highest seen clusterTime. Two clusterTimes are compared using
* only the BsonTimestamp value of the clusterTime embedded field (be sure to
* include both the timestamp and the increment of the BsonTimestamp in the
* comparison). The signature field does not participate in the comparison.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_description_update_cluster_time (
mongoc_topology_description_t *td, const bson_t *reply)
{
bson_iter_t iter;
bson_iter_t child;
const uint8_t *data;
uint32_t size;
bson_t cluster_time;
if (!reply || !bson_iter_init_find (&iter, reply, "$clusterTime")) {
return;
}
if (!BSON_ITER_HOLDS_DOCUMENT (&iter) ||
!bson_iter_recurse (&iter, &child)) {
MONGOC_ERROR ("Can't parse $clusterTime");
return;
}
bson_iter_document (&iter, &size, &data);
BSON_ASSERT (bson_init_static (&cluster_time, data, (size_t) size));
if (bson_empty (&td->cluster_time) ||
_mongoc_cluster_time_greater (&cluster_time, &td->cluster_time)) {
bson_destroy (&td->cluster_time);
bson_copy_to (&cluster_time, &td->cluster_time);
}
}
static void
_mongoc_topology_description_add_new_servers (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
bson_iter_t member_iter;
const bson_t *rs_members[3];
int i;
rs_members[0] = &server->hosts;
rs_members[1] = &server->arbiters;
rs_members[2] = &server->passives;
for (i = 0; i < 3; i++) {
BSON_ASSERT (bson_iter_init (&member_iter, rs_members[i]));
while (bson_iter_next (&member_iter)) {
mongoc_topology_description_add_server (
topology, bson_iter_utf8 (&member_iter, NULL), NULL);
}
}
}
typedef struct _mongoc_primary_and_topology_t {
mongoc_topology_description_t *topology;
mongoc_server_description_t *primary;
} mongoc_primary_and_topology_t;
/* invalidate old primaries */
static bool
_mongoc_topology_description_invalidate_primaries_cb (void *item, void *ctx)
{
mongoc_server_description_t *server = (mongoc_server_description_t *) item;
mongoc_primary_and_topology_t *data = (mongoc_primary_and_topology_t *) ctx;
if (server->id != data->primary->id &&
server->type == MONGOC_SERVER_RS_PRIMARY) {
mongoc_server_description_set_state (server, MONGOC_SERVER_UNKNOWN);
mongoc_server_description_set_set_version (server, MONGOC_NO_SET_VERSION);
mongoc_server_description_set_election_id (server, NULL);
}
return true;
}
/* Remove and destroy all replica set members not in primary's hosts lists */
static void
_mongoc_topology_description_remove_unreported_servers (
mongoc_topology_description_t *topology,
mongoc_server_description_t *primary)
{
mongoc_array_t to_remove;
int i;
mongoc_server_description_t *member;
const char *address;
_mongoc_array_init (&to_remove, sizeof (mongoc_server_description_t *));
/* Accumulate servers to be removed - do this before calling
* _mongoc_topology_description_remove_server, which could call
* mongoc_server_description_cleanup on the primary itself if it
* doesn't report its own connection_address in its hosts list.
* See hosts_differ_from_seeds.json */
for (i = 0; i < topology->servers->items_len; i++) {
member = (mongoc_server_description_t *) mongoc_set_get_item (
topology->servers, i);
address = member->connection_address;
if (!mongoc_server_description_has_rs_member (primary, address)) {
_mongoc_array_append_val (&to_remove, member);
}
}
/* now it's safe to call _mongoc_topology_description_remove_server,
* even on the primary */
for (i = 0; i < to_remove.len; i++) {
member =
_mongoc_array_index (&to_remove, mongoc_server_description_t *, i);
_mongoc_topology_description_remove_server (topology, member);
}
_mongoc_array_destroy (&to_remove);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_matches_me --
*
* Server Discovery And Monitoring Spec: "Removal from the topology of
* seed list members where the "me" property does not match the address
* used to connect prevents clients from being able to select a server,
* only to fail to re-select that server once the primary has responded.
*
* Returns:
* True if "me" matches "connection_address".
*
* Side Effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_topology_description_matches_me (mongoc_server_description_t *server)
{
BSON_ASSERT (server->connection_address);
if (!server->me) {
/* "me" is unknown: consider it a match */
return true;
}
return strcasecmp (server->connection_address, server->me) == 0;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_update_rs_from_primary --
*
* First, determine that this is really the primary:
* -If this node isn't in the cluster, do nothing.
* -If the cluster's set name is null, set it to node's set name.
* Otherwise if the cluster's set name is different from node's,
* we found a rogue primary, so remove it from the cluster and
* check the cluster for a primary, then return.
* -If any of the members of cluster reports an address different
* from node's, node cannot be the primary.
* Now that we know this is the primary:
* -If any hosts, passives, or arbiters in node's description aren't
* in the cluster, add them as UNKNOWN servers.
* -If the cluster has any servers that aren't in node's description,
* remove and destroy them.
* Finally, check the cluster for the new primary.
*
* Returns:
* None.
*
* Side effects:
* Changes to the cluster, possible removal of cluster nodes.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_update_rs_from_primary (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
mongoc_primary_and_topology_t data;
bson_error_t error;
BSON_ASSERT (topology);
BSON_ASSERT (server);
if (!_mongoc_topology_description_has_server (
topology, server->connection_address, NULL))
return;
/* If server->set_name was null this function wouldn't be called from
* mongoc_server_description_handle_ismaster(). static code analyzers however
* don't know that so we check for it explicitly. */
if (server->set_name) {
/* 'Server' can only be the primary if it has the right rs name */
if (!topology->set_name) {
topology->set_name = bson_strdup (server->set_name);
} else if (strcmp (topology->set_name, server->set_name) != 0) {
_mongoc_topology_description_remove_server (topology, server);
_update_rs_type (topology);
return;
}
}
if (mongoc_server_description_has_set_version (server) &&
mongoc_server_description_has_election_id (server)) {
/* Server Discovery And Monitoring Spec: "The client remembers the
* greatest electionId reported by a primary, and distrusts primaries
* with lesser electionIds. This prevents the client from oscillating
* between the old and new primary during a split-brain period."
*/
if (_mongoc_topology_description_later_election (topology, server)) {
bson_set_error (&error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"member's setVersion or electionId is stale");
mongoc_topology_description_invalidate_server (
topology, server->id, &error);
_update_rs_type (topology);
return;
}
/* server's electionId >= topology's max electionId */
_mongoc_topology_description_set_max_election_id (topology, server);
}
if (mongoc_server_description_has_set_version (server) &&
(!_mongoc_topology_description_has_set_version (topology) ||
server->set_version > topology->max_set_version)) {
_mongoc_topology_description_set_max_set_version (topology, server);
}
/* 'Server' is the primary! Invalidate other primaries if found */
data.primary = server;
data.topology = topology;
mongoc_set_for_each (topology->servers,
_mongoc_topology_description_invalidate_primaries_cb,
&data);
/* Add to topology description any new servers primary knows about */
_mongoc_topology_description_add_new_servers (topology, server);
/* Remove from topology description any servers primary doesn't know about */
_mongoc_topology_description_remove_unreported_servers (topology, server);
/* Finally, set topology type */
_update_rs_type (topology);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_update_rs_without_primary --
*
* Update cluster's information when there is no primary.
*
* Returns:
* None.
*
* Side Effects:
* Alters cluster state, may remove node from cluster.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_update_rs_without_primary (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
BSON_ASSERT (topology);
BSON_ASSERT (server);
if (!_mongoc_topology_description_has_server (
topology, server->connection_address, NULL)) {
return;
}
/* make sure we're talking about the same replica set */
if (server->set_name) {
if (!topology->set_name) {
topology->set_name = bson_strdup (server->set_name);
} else if (strcmp (topology->set_name, server->set_name) != 0) {
_mongoc_topology_description_remove_server (topology, server);
return;
}
}
/* Add new servers that this replica set member knows about */
_mongoc_topology_description_add_new_servers (topology, server);
/* If this server thinks there is a primary, label it POSSIBLE_PRIMARY */
if (server->current_primary) {
_mongoc_topology_description_label_unknown_member (
topology, server->current_primary, MONGOC_SERVER_POSSIBLE_PRIMARY);
}
if (!_mongoc_topology_description_matches_me (server)) {
_mongoc_topology_description_remove_server (topology, server);
return;
}
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_update_rs_with_primary_from_member --
*
* Update cluster's information when there is a primary, but the
* update is coming from another replica set member.
*
* Returns:
* None.
*
* Side Effects:
* Alters cluster state.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_update_rs_with_primary_from_member (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
BSON_ASSERT (topology);
BSON_ASSERT (server);
if (!_mongoc_topology_description_has_server (
topology, server->connection_address, NULL)) {
return;
}
/* set_name should never be null here */
if (strcmp (topology->set_name, server->set_name) != 0) {
_mongoc_topology_description_remove_server (topology, server);
_update_rs_type (topology);
return;
}
if (!_mongoc_topology_description_matches_me (server)) {
_mongoc_topology_description_remove_server (topology, server);
return;
}
/* If there is no primary, label server's current_primary as the
* POSSIBLE_PRIMARY */
if (!_mongoc_topology_description_has_primary (topology) &&
server->current_primary) {
_mongoc_topology_description_set_state (topology,
MONGOC_TOPOLOGY_RS_NO_PRIMARY);
_mongoc_topology_description_label_unknown_member (
topology, server->current_primary, MONGOC_SERVER_POSSIBLE_PRIMARY);
}
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_set_topology_type_to_sharded --
*
* Sets topology's type to SHARDED.
*
* Returns:
* None
*
* Side effects:
* Alter's topology's type
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_set_topology_type_to_sharded (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
_mongoc_topology_description_set_state (topology, MONGOC_TOPOLOGY_SHARDED);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_transition_unknown_to_rs_no_primary --
*
* Encapsulates transition from cluster state UNKNOWN to
* RS_NO_PRIMARY. Sets the type to RS_NO_PRIMARY,
* then updates the replica set accordingly.
*
* Returns:
* None.
*
* Side effects:
* Changes topology state.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_transition_unknown_to_rs_no_primary (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
_mongoc_topology_description_set_state (topology,
MONGOC_TOPOLOGY_RS_NO_PRIMARY);
_mongoc_topology_description_update_rs_without_primary (topology, server);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_remove_and_check_primary --
*
* Remove the server and check if the topology still has a primary.
*
* Returns:
* None.
*
* Side effects:
* Removes server from topology and destroys it.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_remove_and_check_primary (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
_mongoc_topology_description_remove_server (topology, server);
_update_rs_type (topology);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_update_unknown_with_standalone --
*
* If the cluster doesn't contain this server, do nothing.
* Otherwise, if the topology only has one seed, change its
* type to SINGLE. If the topology has multiple seeds, it does not
* include us, so remove this server and destroy it.
*
* Returns:
* None.
*
* Side effects:
* Changes the topology type, might remove server from topology.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_update_unknown_with_standalone (
mongoc_topology_description_t *topology, mongoc_server_description_t *server)
{
BSON_ASSERT (topology);
BSON_ASSERT (server);
if (!_mongoc_topology_description_has_server (
topology, server->connection_address, NULL))
return;
if (topology->servers->items_len > 1) {
/* This cluster contains other servers, it cannot be a standalone. */
_mongoc_topology_description_remove_server (topology, server);
} else {
_mongoc_topology_description_set_state (topology, MONGOC_TOPOLOGY_SINGLE);
}
}
/*
*--------------------------------------------------------------------------
*
* This table implements the 'ToplogyType' table outlined in the Server
* Discovery and Monitoring spec. Each row represents a server type,
* and each column represents the topology type. Given a current topology
* type T and a newly-observed server type S, use the function at
* state_transions[S][T] to transition to a new state.
*
* Rows should be read like so:
* { server type for this row
* UNKNOWN,
* SHARDED,
* RS_NO_PRIMARY,
* RS_WITH_PRIMARY
* }
*
*--------------------------------------------------------------------------
*/
typedef void (*transition_t) (mongoc_topology_description_t *topology,
mongoc_server_description_t *server);
transition_t gSDAMTransitionTable
[MONGOC_SERVER_DESCRIPTION_TYPES][MONGOC_TOPOLOGY_DESCRIPTION_TYPES] = {
{
/* UNKNOWN */
NULL, /* MONGOC_TOPOLOGY_UNKNOWN */
NULL, /* MONGOC_TOPOLOGY_SHARDED */
NULL, /* MONGOC_TOPOLOGY_RS_NO_PRIMARY */
_mongoc_topology_description_check_if_has_primary /* MONGOC_TOPOLOGY_RS_WITH_PRIMARY
*/
},
{/* STANDALONE */
_mongoc_topology_description_update_unknown_with_standalone,
_mongoc_topology_description_remove_server,
_mongoc_topology_description_remove_server,
_mongoc_topology_description_remove_and_check_primary},
{/* MONGOS */
_mongoc_topology_description_set_topology_type_to_sharded,
NULL,
_mongoc_topology_description_remove_server,
_mongoc_topology_description_remove_and_check_primary},
{/* POSSIBLE_PRIMARY */
NULL,
NULL,
NULL,
NULL},
{/* PRIMARY */
_mongoc_topology_description_update_rs_from_primary,
_mongoc_topology_description_remove_server,
_mongoc_topology_description_update_rs_from_primary,
_mongoc_topology_description_update_rs_from_primary},
{/* SECONDARY */
_mongoc_topology_description_transition_unknown_to_rs_no_primary,
_mongoc_topology_description_remove_server,
_mongoc_topology_description_update_rs_without_primary,
_mongoc_topology_description_update_rs_with_primary_from_member},
{/* ARBITER */
_mongoc_topology_description_transition_unknown_to_rs_no_primary,
_mongoc_topology_description_remove_server,
_mongoc_topology_description_update_rs_without_primary,
_mongoc_topology_description_update_rs_with_primary_from_member},
{/* RS_OTHER */
_mongoc_topology_description_transition_unknown_to_rs_no_primary,
_mongoc_topology_description_remove_server,
_mongoc_topology_description_update_rs_without_primary,
_mongoc_topology_description_update_rs_with_primary_from_member},
{/* RS_GHOST */
NULL,
_mongoc_topology_description_remove_server,
NULL,
_mongoc_topology_description_check_if_has_primary}};
#ifdef MONGOC_TRACE
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_type --
*
* Get this topology's type, one of the types defined in the Server
* Discovery And Monitoring Spec.
*
* NOTE: this method should only be called while holding the mutex on
* the owning topology object.
*
* Returns:
* A string.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static const char *
_mongoc_topology_description_type (mongoc_topology_description_t *topology)
{
switch (topology->type) {
case MONGOC_TOPOLOGY_UNKNOWN:
return "Unknown";
case MONGOC_TOPOLOGY_SHARDED:
return "Sharded";
case MONGOC_TOPOLOGY_RS_NO_PRIMARY:
return "RSNoPrimary";
case MONGOC_TOPOLOGY_RS_WITH_PRIMARY:
return "RSWithPrimary";
case MONGOC_TOPOLOGY_SINGLE:
return "Single";
case MONGOC_TOPOLOGY_DESCRIPTION_TYPES:
default:
MONGOC_ERROR ("Invalid mongoc_topology_description_type_t type");
return "Invalid";
}
}
#endif
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_update_session_timeout --
*
* Fill out td.session_timeout_minutes.
*
* Server Discovery and Monitoring Spec: "set logicalSessionTimeoutMinutes
* to the smallest logicalSessionTimeoutMinutes value among all
* ServerDescriptions of known ServerType. If any ServerDescription of
* known ServerType has a null logicalSessionTimeoutMinutes, then
* logicalSessionTimeoutMinutes MUST be set to null."
*
* --------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_update_session_timeout (
mongoc_topology_description_t *td)
{
mongoc_set_t *set;
size_t i;
mongoc_server_description_t *sd;
set = td->servers;
td->session_timeout_minutes = MONGOC_NO_SESSIONS;
for (i = 0; i < set->items_len; i++) {
sd = (mongoc_server_description_t *) mongoc_set_get_item (set, (int) i);
if (!_is_data_node (sd)) {
continue;
}
if (sd->session_timeout_minutes == MONGOC_NO_SESSIONS) {
td->session_timeout_minutes = MONGOC_NO_SESSIONS;
return;
} else if (td->session_timeout_minutes == MONGOC_NO_SESSIONS) {
td->session_timeout_minutes = sd->session_timeout_minutes;
} else if (td->session_timeout_minutes > sd->session_timeout_minutes) {
td->session_timeout_minutes = sd->session_timeout_minutes;
}
}
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_description_check_compatible --
*
* Fill out td.compatibility_error if any server's wire versions do
* not overlap with ours. Otherwise clear td.compatibility_error.
*
* If any server is incompatible, the topology as a whole is considered
* incompatible.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_topology_description_check_compatible (
mongoc_topology_description_t *td)
{
size_t i;
mongoc_server_description_t *sd;
memset (&td->compatibility_error, 0, sizeof (bson_error_t));
for (i = 0; i < td->servers->items_len; i++) {
sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers,
(int) i);
if (sd->type == MONGOC_SERVER_UNKNOWN ||
sd->type == MONGOC_SERVER_POSSIBLE_PRIMARY) {
continue;
}
if (sd->min_wire_version > WIRE_VERSION_MAX) {
bson_set_error (
&td->compatibility_error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Server at %s requires wire version %d,"
" but this version of libmongoc only supports up to %d",
sd->host.host_and_port,
sd->min_wire_version,
WIRE_VERSION_MAX);
} else if (sd->max_wire_version < WIRE_VERSION_MIN) {
bson_set_error (
&td->compatibility_error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Server at %s reports wire version %d, but this"
" version of libmongoc requires at least 3 (MongoDB 3.0)",
sd->host.host_and_port,
sd->max_wire_version);
}
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_handle_ismaster --
*
* Handle an ismaster. This is called by the background SDAM process,
- * and by client when invalidating servers. If there was an error
- * calling ismaster, pass it in as @error.
+ * and by client when performing a handshake or invalidating servers.
+ * If there was an error calling ismaster, pass it in as @error.
*
* NOTE: this method should only be called while holding the mutex on
* the owning topology object.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_description_handle_ismaster (
mongoc_topology_description_t *topology,
uint32_t server_id,
const bson_t *ismaster_response,
int64_t rtt_msec,
const bson_error_t *error /* IN */)
{
mongoc_topology_description_t *prev_td = NULL;
mongoc_server_description_t *prev_sd = NULL;
mongoc_server_description_t *sd;
+ bson_iter_t iter;
+ /* sd_changed is set if the server description meaningfully changed AND
+ * callbacks are registered. */
+ bool sd_changed = false;
BSON_ASSERT (topology);
BSON_ASSERT (server_id != 0);
sd = mongoc_topology_description_server_by_id (topology, server_id, NULL);
if (!sd) {
return; /* server already removed from topology */
}
if (topology->apm_callbacks.topology_changed) {
prev_td = bson_malloc0 (sizeof (mongoc_topology_description_t));
_mongoc_topology_description_copy_to (topology, prev_td);
}
- if (topology->apm_callbacks.server_changed) {
+ if (ismaster_response &&
+ bson_iter_init_find (&iter, ismaster_response, "topologyVersion") &&
+ BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ bson_t incoming_topology_version;
+ const uint8_t *bytes;
+ uint32_t len;
+
+ bson_iter_document (&iter, &len, &bytes);
+ bson_init_static (&incoming_topology_version, bytes, len);
+
+ if (mongoc_server_description_topology_version_cmp (
+ &sd->topology_version, &incoming_topology_version) == 1) {
+ TRACE ("%s", "topology version is strictly less. Skipping.");
+ if (prev_td) {
+ mongoc_topology_description_destroy (prev_td);
+ bson_free (prev_td);
+ }
+ return;
+ }
+ }
+
+ if (topology->apm_callbacks.topology_changed ||
+ topology->apm_callbacks.server_changed) {
+ /* Only copy the previous server description if a monitoring callback is
+ * registered. */
prev_sd = mongoc_server_description_new_copy (sd);
}
+ DUMP_BSON (ismaster_response);
/* pass the current error in */
+
mongoc_server_description_handle_ismaster (
sd, ismaster_response, rtt_msec, error);
+ /* if the user specified a set_name in the connection string
+ * and they are in topology type single, check that the set name
+ * matches. */
+ if (topology->set_name && topology->type == MONGOC_TOPOLOGY_SINGLE) {
+ bool wrong_set_name = false;
+ bson_error_t set_name_err = {0};
+
+ if (!sd->set_name) {
+ wrong_set_name = true;
+ bson_set_error (&set_name_err,
+ MONGOC_ERROR_SERVER_SELECTION,
+ MONGOC_ERROR_SERVER_SELECTION_FAILURE,
+ "no reported set name, but expected '%s'",
+ topology->set_name);
+ } else if (0 != strcmp (sd->set_name, topology->set_name)) {
+ wrong_set_name = true;
+ bson_set_error (&set_name_err,
+ MONGOC_ERROR_SERVER_SELECTION,
+ MONGOC_ERROR_SERVER_SELECTION_FAILURE,
+ "reported set name '%s' does not match '%s'",
+ sd->set_name,
+ topology->set_name);
+ }
+
+ if (wrong_set_name) {
+ /* Replace with unknown. */
+ TRACE ("%s", "wrong set name");
+ mongoc_server_description_handle_ismaster (
+ sd, NULL, MONGOC_RTT_UNSET, &set_name_err);
+ }
+ }
+
mongoc_topology_description_update_cluster_time (topology,
ismaster_response);
- _mongoc_topology_description_monitor_server_changed (topology, prev_sd, sd);
+
+ if (prev_sd) {
+ sd_changed = !_mongoc_server_description_equal (prev_sd, sd);
+ }
+ if (sd_changed) {
+ _mongoc_topology_description_monitor_server_changed (
+ topology, prev_sd, sd);
+ }
if (gSDAMTransitionTable[sd->type][topology->type]) {
- TRACE ("Transitioning to %s for %s",
+ TRACE ("Topology description %s handling server description %s",
_mongoc_topology_description_type (topology),
mongoc_server_description_type (sd));
gSDAMTransitionTable[sd->type][topology->type](topology, sd);
} else {
- TRACE ("No transition entry to %s for %s",
+ TRACE ("Topology description %s ignoring server description %s",
_mongoc_topology_description_type (topology),
mongoc_server_description_type (sd));
}
_mongoc_topology_description_update_session_timeout (topology);
/* Don't bother checking wire version compatibility if we already errored */
if (ismaster_response && (!error || !error->code)) {
_mongoc_topology_description_check_compatible (topology);
}
- _mongoc_topology_description_monitor_changed (prev_td, topology);
+
+ /* If server description did not change, then neither did topology
+ * description */
+ if (sd_changed) {
+ _mongoc_topology_description_monitor_changed (prev_td, topology);
+ }
if (prev_td) {
mongoc_topology_description_destroy (prev_td);
bson_free (prev_td);
}
- if (prev_sd) {
- mongoc_server_description_destroy (prev_sd);
- }
+ mongoc_server_description_destroy (prev_sd);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_has_readable_server --
*
* SDAM Monitoring Spec:
* "Determines if the topology has a readable server available."
*
* NOTE: this method should only be called by user code in an SDAM
* Monitoring callback, while the monitoring framework holds the mutex
* on the owning topology object.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_description_has_readable_server (
mongoc_topology_description_t *td, const mongoc_read_prefs_t *prefs)
{
bson_error_t error;
if (!mongoc_topology_compatible (td, NULL, &error)) {
return false;
}
/* local threshold argument doesn't matter */
return mongoc_topology_description_select (td, MONGOC_SS_READ, prefs, 0) !=
NULL;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_has_writable_server --
*
* SDAM Monitoring Spec:
* "Determines if the topology has a writable server available."
*
* NOTE: this method should only be called by user code in an SDAM
* Monitoring callback, while the monitoring framework holds the mutex
* on the owning topology object.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_description_has_writable_server (
mongoc_topology_description_t *td)
{
bson_error_t error;
if (!mongoc_topology_compatible (td, NULL, &error)) {
return false;
}
return mongoc_topology_description_select (td, MONGOC_SS_WRITE, NULL, 0) !=
NULL;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_type --
*
* Get this topology's type, one of the types defined in the Server
* Discovery And Monitoring Spec.
*
* NOTE: this method should only be called by user code in an SDAM
* Monitoring callback, while the monitoring framework holds the mutex
* on the owning topology object.
*
* Returns:
* A string.
*
*--------------------------------------------------------------------------
*/
const char *
mongoc_topology_description_type (const mongoc_topology_description_t *td)
{
switch (td->type) {
case MONGOC_TOPOLOGY_UNKNOWN:
return "Unknown";
case MONGOC_TOPOLOGY_SHARDED:
return "Sharded";
case MONGOC_TOPOLOGY_RS_NO_PRIMARY:
return "ReplicaSetNoPrimary";
case MONGOC_TOPOLOGY_RS_WITH_PRIMARY:
return "ReplicaSetWithPrimary";
case MONGOC_TOPOLOGY_SINGLE:
return "Single";
case MONGOC_TOPOLOGY_DESCRIPTION_TYPES:
default:
fprintf (stderr, "ERROR: Unknown topology type %d\n", td->type);
BSON_ASSERT (0);
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_description_get_servers --
*
* Fetch an array of server descriptions for all known servers in the
* topology.
*
* Returns:
* An array you must free with mongoc_server_descriptions_destroy_all.
*
*--------------------------------------------------------------------------
*/
mongoc_server_description_t **
mongoc_topology_description_get_servers (
const mongoc_topology_description_t *td, size_t *n /* OUT */)
{
size_t i;
mongoc_set_t *set;
mongoc_server_description_t **sds;
mongoc_server_description_t *sd;
BSON_ASSERT (td);
BSON_ASSERT (n);
set = td->servers;
/* enough room for all descriptions, even if some are unknown */
sds = (mongoc_server_description_t **) bson_malloc0 (
sizeof (mongoc_server_description_t *) * set->items_len);
*n = 0;
for (i = 0; i < set->items_len; ++i) {
sd = (mongoc_server_description_t *) mongoc_set_get_item (set, (int) i);
if (sd->type != MONGOC_SERVER_UNKNOWN) {
sds[*n] = mongoc_server_description_new_copy (sd);
++(*n);
}
}
return sds;
}
+
+typedef struct {
+ mongoc_host_list_t *host_list;
+ mongoc_topology_description_t *td;
+} _remove_if_not_in_host_list_ctx_t;
+
+bool
+_remove_if_not_in_host_list_cb (void *sd_void, void *ctx_void)
+{
+ _remove_if_not_in_host_list_ctx_t *ctx;
+ mongoc_topology_description_t *td;
+ mongoc_server_description_t *sd;
+ mongoc_host_list_t *host_list;
+
+ ctx = ctx_void;
+ sd = sd_void;
+ host_list = ctx->host_list;
+ td = ctx->td;
+
+ if (_mongoc_host_list_contains_one (host_list, &sd->host)) {
+ return true;
+ }
+ _mongoc_topology_description_remove_server (td, sd);
+ return true;
+}
+
+void
+mongoc_topology_description_reconcile (mongoc_topology_description_t *td,
+ mongoc_host_list_t *host_list)
+{
+ mongoc_host_list_t *host;
+ _remove_if_not_in_host_list_ctx_t ctx;
+
+ LL_FOREACH (host_list, host)
+ {
+ /* "add" is really an "upsert" */
+ mongoc_topology_description_add_server (td, host->host_and_port, NULL);
+ }
+
+ ctx.host_list = host_list;
+ ctx.td = td;
+ mongoc_set_for_each (td->servers, _remove_if_not_in_host_list_cb, &ctx);
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
similarity index 76%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
index ea81e148..7292ebc9 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
@@ -1,194 +1,228 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_TOPOLOGY_PRIVATE_H
#define MONGOC_TOPOLOGY_PRIVATE_H
#include "mongoc-config.h"
#include "mongoc-topology-scanner-private.h"
#include "mongoc-server-description-private.h"
#include "mongoc-topology-description-private.h"
#include "mongoc-thread-private.h"
#include "mongoc-uri.h"
#include "mongoc-client-session-private.h"
#include "mongoc-crypt-private.h"
#define MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS 500
#define MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS 5000
#define MONGOC_TOPOLOGY_COOLDOWN_MS 5000
#define MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS 15
#define MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS 30000
#define MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED 10000
#define MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED 60000
#define MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS 60000
typedef enum {
MONGOC_TOPOLOGY_SCANNER_OFF,
MONGOC_TOPOLOGY_SCANNER_BG_RUNNING,
- MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN,
- MONGOC_TOPOLOGY_SCANNER_SINGLE_THREADED,
+ MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN
} mongoc_topology_scanner_state_t;
+struct _mongoc_background_monitor_t;
struct _mongoc_client_pool_t;
typedef struct _mongoc_topology_t {
mongoc_topology_description_t description;
+ /* topology->uri is initialized as a copy of the client/pool's URI.
+ * For a "mongodb+srv://" URI, topology->uri is then updated in
+ * mongoc_topology_new() after initial seedlist discovery.
+ * Afterwards, it remains read-only and may be read outside of the topology
+ * mutex.
+ */
mongoc_uri_t *uri;
mongoc_topology_scanner_t *scanner;
bool server_selection_try_once;
int64_t last_scan;
int64_t local_threshold_msec;
int64_t connect_timeout_msec;
int64_t server_selection_timeout_msec;
/* defaults to 500ms, configurable by tests */
int64_t min_heartbeat_frequency_msec;
/* Minimum of SRV record TTLs, but no lower than 60 seconds.
* May be zero for non-SRV/non-MongoS topology. */
- int64_t rescanSRVIntervalMS;
- int64_t last_srv_scan;
+ int64_t srv_polling_rescan_interval_ms;
+ int64_t srv_polling_last_scan_ms;
+ /* For multi-threaded, srv polling occurs in a separate thread. */
+ bson_thread_t srv_polling_thread;
+ mongoc_cond_t srv_polling_cond;
bson_mutex_t mutex;
mongoc_cond_t cond_client;
- mongoc_cond_t cond_server;
- bson_thread_t thread;
-
mongoc_topology_scanner_state_t scanner_state;
- bool scan_requested;
+
bool single_threaded;
bool stale;
mongoc_server_session_t *session_pool;
/* Is client side encryption enabled? */
bool cse_enabled;
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
_mongoc_crypt_t *crypt;
struct _mongoc_client_t *mongocryptd_client; /* single threaded */
struct _mongoc_client_t *keyvault_client; /* single threaded */
struct _mongoc_client_pool_t *mongocryptd_client_pool; /* multi threaded */
struct _mongoc_client_pool_t *keyvault_client_pool; /* multi threaded */
char *keyvault_db;
char *keyvault_coll;
bool bypass_auto_encryption;
bool mongocryptd_bypass_spawn;
char *mongocryptd_spawn_path;
bson_t *mongocryptd_spawn_args;
#endif
+
+ /* For background monitoring. */
+ mongoc_set_t *server_monitors;
+ mongoc_set_t *rtt_monitors;
+ bson_mutex_t apm_mutex;
} mongoc_topology_t;
mongoc_topology_t *
mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded);
void
mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology,
mongoc_apm_callbacks_t *callbacks,
void *context);
void
mongoc_topology_destroy (mongoc_topology_t *topology);
void
mongoc_topology_reconcile (mongoc_topology_t *topology);
bool
mongoc_topology_compatible (const mongoc_topology_description_t *td,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error);
mongoc_server_description_t *
mongoc_topology_select (mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error);
uint32_t
mongoc_topology_select_server_id (mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error);
mongoc_server_description_t *
mongoc_topology_server_by_id (mongoc_topology_t *topology,
uint32_t id,
bson_error_t *error);
mongoc_host_list_t *
_mongoc_topology_host_by_id (mongoc_topology_t *topology,
uint32_t id,
bson_error_t *error);
+/* TODO: Try to remove this function when CDRIVER-3654 is complete.
+ * It is only called when an application thread needs to mark a server Unknown.
+ * But an application error is also tied to other behavior, and should also
+ * consider the connection generation. This logic is captured in
+ * _mongoc_topology_handle_app_error. This should not be called directly
+ */
void
mongoc_topology_invalidate_server (mongoc_topology_t *topology,
uint32_t id,
const bson_error_t *error);
bool
_mongoc_topology_update_from_handshake (mongoc_topology_t *topology,
const mongoc_server_description_t *sd);
void
_mongoc_topology_update_last_used (mongoc_topology_t *topology,
uint32_t server_id);
int64_t
mongoc_topology_server_timestamp (mongoc_topology_t *topology, uint32_t id);
mongoc_topology_description_type_t
_mongoc_topology_get_type (mongoc_topology_t *topology);
-bool
-_mongoc_topology_start_background_scanner (mongoc_topology_t *topology);
-
-void
-_mongoc_topology_background_thread_stop (mongoc_topology_t *topology);
-
bool
_mongoc_topology_set_appname (mongoc_topology_t *topology, const char *appname);
void
_mongoc_topology_update_cluster_time (mongoc_topology_t *topology,
const bson_t *reply);
mongoc_server_session_t *
_mongoc_topology_pop_server_session (mongoc_topology_t *topology,
bson_error_t *error);
void
_mongoc_topology_push_server_session (mongoc_topology_t *topology,
mongoc_server_session_t *server_session);
bool
_mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd);
void
_mongoc_topology_clear_session_pool (mongoc_topology_t *topology);
void
_mongoc_topology_do_blocking_scan (mongoc_topology_t *topology,
bson_error_t *error);
const bson_t *
_mongoc_topology_get_ismaster (mongoc_topology_t *topology);
void
_mongoc_topology_request_scan (mongoc_topology_t *topology);
void
_mongoc_topology_bypass_cooldown (mongoc_topology_t *topology);
+
+typedef enum {
+ MONGOC_SDAM_APP_ERROR_COMMAND,
+ MONGOC_SDAM_APP_ERROR_NETWORK,
+ MONGOC_SDAM_APP_ERROR_TIMEOUT
+} _mongoc_sdam_app_error_type_t;
+
+bool
+_mongoc_topology_handle_app_error (mongoc_topology_t *topology,
+ uint32_t server_id,
+ bool handshake_complete,
+ _mongoc_sdam_app_error_type_t type,
+ const bson_t *reply,
+ const bson_error_t *why,
+ uint32_t max_wire_version,
+ uint32_t generation);
+
+void
+_mongoc_topology_clear_connection_pool (mongoc_topology_t *topology,
+ uint32_t server_id);
+
+void
+mongoc_topology_rescan_srv (mongoc_topology_t *topology);
#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
similarity index 91%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
index 993655dc..ed2be12d 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
@@ -1,215 +1,232 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_TOPOLOGY_SCANNER_PRIVATE_H
#define MONGOC_TOPOLOGY_SCANNER_PRIVATE_H
/* TODO: rename to TOPOLOGY scanner */
#include <bson/bson.h>
#include "mongoc-async-private.h"
#include "mongoc-async-cmd-private.h"
#include "mongoc-handshake-private.h"
#include "mongoc-host-list.h"
#include "mongoc-apm-private.h"
-
-#ifdef MONGOC_ENABLE_SSL
+#include "mongoc-scram-private.h"
#include "mongoc-ssl.h"
-#endif
+#include "mongoc-crypto-private.h"
BSON_BEGIN_DECLS
typedef void (*mongoc_topology_scanner_setup_err_cb_t) (
uint32_t id, void *data, const bson_error_t *error /* IN */);
typedef void (*mongoc_topology_scanner_cb_t) (
uint32_t id,
const bson_t *bson,
int64_t rtt,
void *data,
const bson_error_t *error /* IN */);
struct mongoc_topology_scanner;
struct mongoc_topology_scanner_node;
typedef struct mongoc_topology_scanner_node {
uint32_t id;
/* after scanning, this is set to the successful stream if one exists. */
mongoc_stream_t *stream;
- int64_t timestamp;
int64_t last_used;
int64_t last_failed;
bool has_auth;
mongoc_host_list_t host;
struct mongoc_topology_scanner *ts;
struct mongoc_topology_scanner_node *next;
struct mongoc_topology_scanner_node *prev;
bool retired;
bson_error_t last_error;
/* the hostname for a node may resolve to multiple DNS results.
* dns_results has the full list of DNS results, ordered by host preference.
* successful_dns_result is the most recent successful DNS result.
*/
struct addrinfo *dns_results;
struct addrinfo *successful_dns_result;
int64_t last_dns_cache;
/* used by single-threaded clients to store negotiated sasl mechanisms on a
* node. */
mongoc_handshake_sasl_supported_mechs_t sasl_supported_mechs;
bool negotiated_sasl_supported_mechs;
+ bson_t speculative_auth_response;
+ mongoc_scram_t scram;
} mongoc_topology_scanner_node_t;
typedef struct mongoc_topology_scanner {
mongoc_async_t *async;
int64_t connect_timeout_msec;
mongoc_topology_scanner_node_t *nodes;
bson_t ismaster_cmd;
bson_t ismaster_cmd_with_handshake;
bson_t cluster_time;
bool handshake_ok_to_send;
const char *appname;
mongoc_topology_scanner_setup_err_cb_t setup_err_cb;
mongoc_topology_scanner_cb_t cb;
void *cb_data;
const mongoc_uri_t *uri;
mongoc_async_cmd_setup_t setup;
mongoc_stream_initiator_t initiator;
void *initiator_context;
bson_error_t error;
#ifdef MONGOC_ENABLE_SSL
mongoc_ssl_opt_t *ssl_opts;
#endif
mongoc_apm_callbacks_t apm_callbacks;
void *apm_context;
int64_t dns_cache_timeout_ms;
/* only used by single-threaded clients to negotiate auth mechanisms. */
bool negotiate_sasl_supported_mechs;
bool bypass_cooldown;
+ bool speculative_authentication;
} mongoc_topology_scanner_t;
mongoc_topology_scanner_t *
mongoc_topology_scanner_new (
const mongoc_uri_t *uri,
mongoc_topology_scanner_setup_err_cb_t setup_err_cb,
mongoc_topology_scanner_cb_t cb,
void *data,
int64_t connect_timeout_msec);
void
mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts);
bool
mongoc_topology_scanner_valid (mongoc_topology_scanner_t *ts);
void
mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
uint32_t id);
void
mongoc_topology_scanner_scan (mongoc_topology_scanner_t *ts, uint32_t id);
void
mongoc_topology_scanner_disconnect (mongoc_topology_scanner_t *scanner);
void
mongoc_topology_scanner_node_retire (mongoc_topology_scanner_node_t *node);
void
mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node,
bool failed);
void
mongoc_topology_scanner_node_destroy (mongoc_topology_scanner_node_t *node,
bool failed);
bool
mongoc_topology_scanner_in_cooldown (mongoc_topology_scanner_t *ts,
int64_t when);
void
mongoc_topology_scanner_start (mongoc_topology_scanner_t *ts,
bool obey_cooldown);
void
mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts);
void
_mongoc_topology_scanner_finish (mongoc_topology_scanner_t *ts);
void
mongoc_topology_scanner_get_error (mongoc_topology_scanner_t *ts,
bson_error_t *error);
void
mongoc_topology_scanner_reset (mongoc_topology_scanner_t *ts);
void
mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node,
bson_error_t *error);
mongoc_topology_scanner_node_t *
mongoc_topology_scanner_get_node (mongoc_topology_scanner_t *ts, uint32_t id);
+void
+_mongoc_topology_scanner_add_speculative_authentication (
+ bson_t *cmd,
+ const mongoc_uri_t *uri,
+ const mongoc_ssl_opt_t *ssl_opts,
+ mongoc_scram_cache_t *scram_cache,
+ mongoc_scram_t *scram /* OUT */);
+
+void
+_mongoc_topology_scanner_parse_speculative_authentication (
+ const bson_t *ismaster, bson_t *speculative_authenticate);
+
+const char *
+_mongoc_topology_scanner_get_speculative_auth_mechanism (
+ const mongoc_uri_t *uri);
+
const bson_t *
_mongoc_topology_scanner_get_ismaster (mongoc_topology_scanner_t *ts);
bool
mongoc_topology_scanner_has_node_for_host (mongoc_topology_scanner_t *ts,
mongoc_host_list_t *host);
void
mongoc_topology_scanner_set_stream_initiator (mongoc_topology_scanner_t *ts,
mongoc_stream_initiator_t si,
void *ctx);
bool
_mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts,
const char *name);
void
_mongoc_topology_scanner_set_cluster_time (mongoc_topology_scanner_t *ts,
const bson_t *cluster_time);
void
_mongoc_topology_scanner_set_dns_cache_timeout (mongoc_topology_scanner_t *ts,
int64_t timeout_ms);
#ifdef MONGOC_ENABLE_SSL
void
mongoc_topology_scanner_set_ssl_opts (mongoc_topology_scanner_t *ts,
mongoc_ssl_opt_t *opts);
#endif
bool
mongoc_topology_scanner_node_in_cooldown (mongoc_topology_scanner_node_t *node,
int64_t when);
/* for testing. */
mongoc_stream_t *
_mongoc_topology_scanner_tcp_initiate (mongoc_async_cmd_t *acmd);
BSON_END_DECLS
#endif /* MONGOC_TOPOLOGY_SCANNER_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
similarity index 88%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
index 93632e85..2b21ab7f 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
@@ -1,1179 +1,1326 @@
/*
* Copyright 2014 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.
*/
#include <bson/bson.h>
#include "mongoc-config.h"
#include "mongoc-error.h"
#include "mongoc-trace-private.h"
#include "mongoc-topology-scanner-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-socket.h"
#include "mongoc-handshake.h"
#include "mongoc-handshake-private.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-stream-tls.h"
#endif
#include "mongoc-counters-private.h"
#include "utlist.h"
#include "mongoc-topology-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-uri-private.h"
+#include "mongoc-cluster-private.h"
+#include "mongoc-client-private.h"
+#include "mongoc-util-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "topology_scanner"
#define DNS_CACHE_TIMEOUT_MS 10 * 60 * 1000
#define HAPPY_EYEBALLS_DELAY_MS 250
/* forward declarations */
static void
_async_connected (mongoc_async_cmd_t *acmd);
static void
_async_success (mongoc_async_cmd_t *acmd,
const bson_t *ismaster_response,
int64_t duration_usec);
static void
_async_error_or_timeout (mongoc_async_cmd_t *acmd,
int64_t duration_usec,
const char *default_err_msg);
static void
_async_handler (mongoc_async_cmd_t *acmd,
mongoc_async_cmd_result_t async_status,
const bson_t *ismaster_response,
int64_t duration_usec);
static void
_mongoc_topology_scanner_monitor_heartbeat_started (
const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host);
static void
_mongoc_topology_scanner_monitor_heartbeat_succeeded (
const mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
const bson_t *reply,
int64_t duration_usec);
static void
_mongoc_topology_scanner_monitor_heartbeat_failed (
const mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
const bson_error_t *error,
int64_t duration_usec);
/* reset "retired" nodes that failed or were removed in the previous scan */
static void
_delete_retired_nodes (mongoc_topology_scanner_t *ts);
/* cancel any pending async commands for a specific node excluding acmd.
* If acmd is NULL, cancel all async commands on the node. */
static void
_cancel_commands_excluding (mongoc_topology_scanner_node_t *node,
mongoc_async_cmd_t *acmd);
/* return the number of pending async commands for a node. */
static int
_count_acmds (mongoc_topology_scanner_node_t *node);
/* if acmd fails, schedule the sibling commands sooner. */
static void
_jumpstart_other_acmds (mongoc_topology_scanner_node_t *node,
mongoc_async_cmd_t *acmd);
static void
_add_ismaster (bson_t *cmd)
{
BSON_APPEND_INT32 (cmd, "isMaster", 1);
}
+const char *
+_mongoc_topology_scanner_get_speculative_auth_mechanism (
+ const mongoc_uri_t *uri)
+{
+ const char *mechanism = mongoc_uri_get_auth_mechanism (uri);
+ bool requires_auth = mechanism || mongoc_uri_get_username (uri);
+
+ if (!requires_auth) {
+ return NULL;
+ }
+
+ if (!mechanism) {
+ return "SCRAM-SHA-256";
+ }
+
+ return mechanism;
+}
+
+void
+_mongoc_topology_scanner_add_speculative_authentication (
+ bson_t *cmd,
+ const mongoc_uri_t *uri,
+ const mongoc_ssl_opt_t *ssl_opts,
+ mongoc_scram_cache_t *scram_cache,
+ mongoc_scram_t *scram /* OUT */)
+{
+ bson_t auth_cmd;
+ bson_error_t error;
+ bool has_auth = false;
+ const char *mechanism =
+ _mongoc_topology_scanner_get_speculative_auth_mechanism (uri);
+
+ if (!mechanism) {
+ return;
+ }
+
+ if (strcasecmp (mechanism, "MONGODB-X509") == 0) {
+ /* Ignore errors while building authentication document: we proceed with
+ * the handshake as usual and let the subsequent authenticate command
+ * fail. */
+ if (_mongoc_cluster_get_auth_cmd_x509 (
+ uri, ssl_opts, &auth_cmd, &error)) {
+ has_auth = true;
+ BSON_APPEND_UTF8 (&auth_cmd, "db", "$external");
+ }
+ }
+
+#ifdef MONGOC_ENABLE_CRYPTO
+ if (strcasecmp (mechanism, "SCRAM-SHA-1") == 0 ||
+ strcasecmp (mechanism, "SCRAM-SHA-256") == 0) {
+ mongoc_crypto_hash_algorithm_t algo =
+ strcasecmp (mechanism, "SCRAM-SHA-1") == 0
+ ? MONGOC_CRYPTO_ALGORITHM_SHA_1
+ : MONGOC_CRYPTO_ALGORITHM_SHA_256;
+
+ _mongoc_uri_init_scram (uri, scram, algo);
+
+ if (scram_cache) {
+ _mongoc_scram_set_cache (scram, scram_cache);
+ }
+
+ if (_mongoc_cluster_get_auth_cmd_scram (algo, scram, &auth_cmd, &error)) {
+ const char *auth_source;
+
+ if (!(auth_source = mongoc_uri_get_auth_source (uri)) ||
+ (*auth_source == '\0')) {
+ auth_source = "admin";
+ }
+
+ has_auth = true;
+ BSON_APPEND_UTF8 (&auth_cmd, "db", auth_source);
+ }
+ }
+#endif
+
+ if (has_auth) {
+ BSON_APPEND_DOCUMENT (cmd, "speculativeAuthenticate", &auth_cmd);
+ bson_destroy (&auth_cmd);
+ }
+}
+
+void
+_mongoc_topology_scanner_parse_speculative_authentication (
+ const bson_t *ismaster, bson_t *speculative_authenticate)
+{
+ bson_iter_t iter;
+ uint32_t data_len;
+ const uint8_t *data;
+ bson_t auth_response;
+
+ BSON_ASSERT (ismaster);
+ BSON_ASSERT (speculative_authenticate);
+
+ if (!bson_iter_init_find (&iter, ismaster, "speculativeAuthenticate")) {
+ return;
+ }
+
+ bson_iter_document (&iter, &data_len, &data);
+ BSON_ASSERT (bson_init_static (&auth_response, data, data_len));
+
+ bson_destroy (speculative_authenticate);
+ bson_copy_to (&auth_response, speculative_authenticate);
+}
+
static bool
_build_ismaster_with_handshake (mongoc_topology_scanner_t *ts)
{
bson_t *doc = &ts->ismaster_cmd_with_handshake;
bson_t subdoc;
bson_iter_t iter;
const char *key;
int keylen;
bool res;
const bson_t *compressors;
int count = 0;
char buf[16];
_add_ismaster (doc);
BSON_APPEND_DOCUMENT_BEGIN (doc, HANDSHAKE_FIELD, &subdoc);
res = _mongoc_handshake_build_doc_with_application (&subdoc, ts->appname);
bson_append_document_end (doc, &subdoc);
BSON_APPEND_ARRAY_BEGIN (doc, "compression", &subdoc);
if (ts->uri) {
compressors = mongoc_uri_get_compressors (ts->uri);
if (bson_iter_init (&iter, compressors)) {
while (bson_iter_next (&iter)) {
keylen = bson_uint32_to_string (count++, &key, buf, sizeof buf);
bson_append_utf8 (
&subdoc, key, (int) keylen, bson_iter_key (&iter), -1);
}
}
}
bson_append_array_end (doc, &subdoc);
/* Return whether the handshake doc fit the size limit */
return res;
}
/* Caller must lock topology->mutex to protect ismaster_cmd_with_handshake. This
* is called at the start of the scan in _mongoc_topology_run_background, when a
* node is added in _mongoc_topology_reconcile_add_nodes, or when running an
* ismaster directly on a node in _mongoc_stream_run_ismaster. */
const bson_t *
_mongoc_topology_scanner_get_ismaster (mongoc_topology_scanner_t *ts)
{
/* If this is the first time using the node or if it's the first time
* using it after a failure, build handshake doc */
if (bson_empty (&ts->ismaster_cmd_with_handshake)) {
ts->handshake_ok_to_send = _build_ismaster_with_handshake (ts);
if (!ts->handshake_ok_to_send) {
MONGOC_WARNING ("Handshake doc too big, not including in isMaster");
}
}
/* If the doc turned out to be too big */
if (!ts->handshake_ok_to_send) {
return &ts->ismaster_cmd;
}
return &ts->ismaster_cmd_with_handshake;
}
static void
_begin_ismaster_cmd (mongoc_topology_scanner_node_t *node,
mongoc_stream_t *stream,
bool is_setup_done,
struct addrinfo *dns_result,
int64_t initiate_delay_ms)
{
mongoc_topology_scanner_t *ts = node->ts;
bson_t cmd;
if (node->last_used != -1 && node->last_failed == -1) {
/* The node's been used before and not failed recently */
bson_copy_to (&ts->ismaster_cmd, &cmd);
} else {
bson_copy_to (_mongoc_topology_scanner_get_ismaster (ts), &cmd);
}
if (node->ts->negotiate_sasl_supported_mechs &&
!node->negotiated_sasl_supported_mechs) {
_mongoc_handshake_append_sasl_supported_mechs (ts->uri, &cmd);
}
+ if (node->ts->speculative_authentication && !node->has_auth &&
+ bson_empty (&node->speculative_auth_response) && node->scram.step == 0) {
+ mongoc_ssl_opt_t *ssl_opts = NULL;
+
+#ifdef MONGOC_ENABLE_SSL
+ ssl_opts = ts->ssl_opts;
+#endif
+
+ _mongoc_topology_scanner_add_speculative_authentication (
+ &cmd, ts->uri, ssl_opts, NULL, &node->scram);
+ }
+
if (!bson_empty (&ts->cluster_time)) {
bson_append_document (&cmd, "$clusterTime", 12, &ts->cluster_time);
}
/* if the node should connect with a TCP socket, stream will be null, and
* dns_result will be set. The async loop is responsible for calling the
* _tcp_initiator to construct TCP sockets. */
mongoc_async_cmd_new (ts->async,
stream,
is_setup_done,
dns_result,
_mongoc_topology_scanner_tcp_initiate,
initiate_delay_ms,
ts->setup,
node->host.host,
"admin",
&cmd,
&_async_handler,
node,
ts->connect_timeout_msec);
bson_destroy (&cmd);
}
mongoc_topology_scanner_t *
mongoc_topology_scanner_new (
const mongoc_uri_t *uri,
mongoc_topology_scanner_setup_err_cb_t setup_err_cb,
mongoc_topology_scanner_cb_t cb,
void *data,
int64_t connect_timeout_msec)
{
mongoc_topology_scanner_t *ts =
(mongoc_topology_scanner_t *) bson_malloc0 (sizeof (*ts));
ts->async = mongoc_async_new ();
bson_init (&ts->ismaster_cmd);
_add_ismaster (&ts->ismaster_cmd);
bson_init (&ts->ismaster_cmd_with_handshake);
bson_init (&ts->cluster_time);
ts->setup_err_cb = setup_err_cb;
ts->cb = cb;
ts->cb_data = data;
ts->uri = uri;
ts->appname = NULL;
ts->handshake_ok_to_send = false;
ts->connect_timeout_msec = connect_timeout_msec;
/* may be overridden for testing. */
ts->dns_cache_timeout_ms = DNS_CACHE_TIMEOUT_MS;
return ts;
}
#ifdef MONGOC_ENABLE_SSL
void
mongoc_topology_scanner_set_ssl_opts (mongoc_topology_scanner_t *ts,
mongoc_ssl_opt_t *opts)
{
ts->ssl_opts = opts;
ts->setup = mongoc_async_cmd_tls_setup;
}
#endif
void
mongoc_topology_scanner_set_stream_initiator (mongoc_topology_scanner_t *ts,
mongoc_stream_initiator_t si,
void *ctx)
{
ts->initiator = si;
ts->initiator_context = ctx;
ts->setup = NULL;
}
void
mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts)
{
mongoc_topology_scanner_node_t *ele, *tmp;
DL_FOREACH_SAFE (ts->nodes, ele, tmp)
{
mongoc_topology_scanner_node_destroy (ele, false);
}
mongoc_async_destroy (ts->async);
bson_destroy (&ts->ismaster_cmd);
bson_destroy (&ts->ismaster_cmd_with_handshake);
bson_destroy (&ts->cluster_time);
/* This field can be set by a mongoc_client */
bson_free ((char *) ts->appname);
bson_free (ts);
}
/* whether the scanner was successfully initialized - false if a mongodb+srv
* URI failed to resolve to any hosts */
bool
mongoc_topology_scanner_valid (mongoc_topology_scanner_t *ts)
{
return ts->nodes != NULL;
}
void
mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
uint32_t id)
{
mongoc_topology_scanner_node_t *node;
node = (mongoc_topology_scanner_node_t *) bson_malloc0 (sizeof (*node));
memcpy (&node->host, host, sizeof (*host));
node->id = id;
node->ts = ts;
node->last_failed = -1;
node->last_used = -1;
+ bson_init (&node->speculative_auth_response);
DL_APPEND (ts->nodes, node);
}
void
mongoc_topology_scanner_scan (mongoc_topology_scanner_t *ts, uint32_t id)
{
mongoc_topology_scanner_node_t *node;
node = mongoc_topology_scanner_get_node (ts, id);
/* begin non-blocking connection, don't wait for success */
if (node) {
mongoc_topology_scanner_node_setup (node, &node->last_error);
}
/* if setup fails the node stays in the scanner. destroyed after the scan. */
}
void
mongoc_topology_scanner_disconnect (mongoc_topology_scanner_t *scanner)
{
mongoc_topology_scanner_node_t *node;
BSON_ASSERT (scanner);
node = scanner->nodes;
while (node) {
mongoc_topology_scanner_node_disconnect (node, false);
node = node->next;
}
}
void
mongoc_topology_scanner_node_retire (mongoc_topology_scanner_node_t *node)
{
/* cancel any pending commands. */
_cancel_commands_excluding (node, NULL);
node->retired = true;
}
void
mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node,
bool failed)
{
/* the node may or may not have succeeded in finding a working stream. */
if (node->stream) {
if (failed) {
mongoc_stream_failed (node->stream);
} else {
mongoc_stream_destroy (node->stream);
}
node->stream = NULL;
memset (
&node->sasl_supported_mechs, 0, sizeof (node->sasl_supported_mechs));
node->negotiated_sasl_supported_mechs = false;
+ bson_reinit (&node->speculative_auth_response);
}
}
void
mongoc_topology_scanner_node_destroy (mongoc_topology_scanner_node_t *node,
bool failed)
{
DL_DELETE (node->ts->nodes, node);
mongoc_topology_scanner_node_disconnect (node, failed);
if (node->dns_results) {
freeaddrinfo (node->dns_results);
}
+
+ bson_destroy (&node->speculative_auth_response);
+
+#ifdef MONGOC_ENABLE_CRYPTO
+ _mongoc_scram_destroy (&node->scram);
+#endif
+
bson_free (node);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_get_node --
*
* Return the scanner node with the given id.
*
*--------------------------------------------------------------------------
*/
mongoc_topology_scanner_node_t *
mongoc_topology_scanner_get_node (mongoc_topology_scanner_t *ts, uint32_t id)
{
mongoc_topology_scanner_node_t *ele, *tmp;
DL_FOREACH_SAFE (ts->nodes, ele, tmp)
{
if (ele->id == id) {
return ele;
}
if (ele->id > id) {
break;
}
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_has_node_for_host --
*
* Whether the scanner has a node for the given host and port.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_scanner_has_node_for_host (mongoc_topology_scanner_t *ts,
mongoc_host_list_t *host)
{
mongoc_topology_scanner_node_t *ele, *tmp;
DL_FOREACH_SAFE (ts->nodes, ele, tmp)
{
- if (_mongoc_host_list_equal (&ele->host, host)) {
+ if (_mongoc_host_list_compare_one (&ele->host, host)) {
return true;
}
}
return false;
}
static void
_async_connected (mongoc_async_cmd_t *acmd)
{
mongoc_topology_scanner_node_t *node =
(mongoc_topology_scanner_node_t *) acmd->data;
/* this cmd connected successfully, cancel other cmds on this node. */
_cancel_commands_excluding (node, acmd);
node->successful_dns_result = acmd->dns_result;
}
static void
_async_success (mongoc_async_cmd_t *acmd,
const bson_t *ismaster_response,
int64_t duration_usec)
{
void *data = acmd->data;
mongoc_topology_scanner_node_t *node =
(mongoc_topology_scanner_node_t *) data;
mongoc_stream_t *stream = acmd->stream;
mongoc_topology_scanner_t *ts = node->ts;
if (node->retired) {
if (stream) {
mongoc_stream_failed (stream);
}
return;
}
node->last_used = bson_get_monotonic_time ();
node->last_failed = -1;
_mongoc_topology_scanner_monitor_heartbeat_succeeded (
ts, &node->host, ismaster_response, duration_usec);
/* set our successful stream. */
BSON_ASSERT (!node->stream);
node->stream = stream;
if (ts->negotiate_sasl_supported_mechs &&
!node->negotiated_sasl_supported_mechs) {
_mongoc_handshake_parse_sasl_supported_mechs (
ismaster_response, &node->sasl_supported_mechs);
}
+ if (ts->speculative_authentication) {
+ _mongoc_topology_scanner_parse_speculative_authentication (
+ ismaster_response, &node->speculative_auth_response);
+ }
+
/* mongoc_topology_scanner_cb_t takes rtt_msec, not usec */
ts->cb (node->id,
ismaster_response,
duration_usec / 1000,
ts->cb_data,
&acmd->error);
}
static void
_async_error_or_timeout (mongoc_async_cmd_t *acmd,
int64_t duration_usec,
const char *default_err_msg)
{
void *data = acmd->data;
mongoc_topology_scanner_node_t *node =
(mongoc_topology_scanner_node_t *) data;
mongoc_stream_t *stream = acmd->stream;
mongoc_topology_scanner_t *ts = node->ts;
bson_error_t *error = &acmd->error;
int64_t now = bson_get_monotonic_time ();
const char *message;
/* the stream may have failed on initiation. */
if (stream) {
mongoc_stream_failed (stream);
}
if (node->retired) {
return;
}
node->last_used = now;
if (!node->stream && _count_acmds (node) == 1) {
/* there are no remaining streams, connecting has failed. */
node->last_failed = now;
if (error->code) {
message = error->message;
} else {
message = default_err_msg;
}
/* invalidate any cached DNS results. */
if (node->dns_results) {
freeaddrinfo (node->dns_results);
node->dns_results = NULL;
node->successful_dns_result = NULL;
}
bson_set_error (&node->last_error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_STREAM_CONNECT,
"%s calling ismaster on \'%s\'",
message,
node->host.host_and_port);
_mongoc_topology_scanner_monitor_heartbeat_failed (
ts, &node->host, &node->last_error, duration_usec);
/* call the topology scanner callback. cannot connect to this node.
* callback takes rtt_msec, not usec. */
ts->cb (node->id, NULL, duration_usec / 1000, ts->cb_data, error);
} else {
/* there are still more commands left for this node or it succeeded
* with another stream. skip the topology scanner callback. */
_jumpstart_other_acmds (node, acmd);
}
}
/*
*-----------------------------------------------------------------------
*
* This is the callback passed to async_cmd when we're running
* ismasters from within the topology monitor.
*
*-----------------------------------------------------------------------
*/
static void
_async_handler (mongoc_async_cmd_t *acmd,
mongoc_async_cmd_result_t async_status,
const bson_t *ismaster_response,
int64_t duration_usec)
{
BSON_ASSERT (acmd->data);
switch (async_status) {
case MONGOC_ASYNC_CMD_CONNECTED:
_async_connected (acmd);
return;
case MONGOC_ASYNC_CMD_SUCCESS:
_async_success (acmd, ismaster_response, duration_usec);
return;
case MONGOC_ASYNC_CMD_TIMEOUT:
_async_error_or_timeout (acmd, duration_usec, "connection timeout");
return;
case MONGOC_ASYNC_CMD_ERROR:
_async_error_or_timeout (acmd, duration_usec, "connection error");
return;
case MONGOC_ASYNC_CMD_IN_PROGRESS:
default:
fprintf (stderr, "unexpected async status: %d\n", async_status);
BSON_ASSERT (false);
return;
}
}
mongoc_stream_t *
_mongoc_topology_scanner_node_setup_stream_for_tls (
mongoc_topology_scanner_node_t *node, mongoc_stream_t *stream)
{
#ifdef MONGOC_ENABLE_SSL
mongoc_stream_t *tls_stream;
#endif
if (!stream) {
return NULL;
}
#ifdef MONGOC_ENABLE_SSL
if (node->ts->ssl_opts) {
tls_stream = mongoc_stream_tls_new_with_hostname (
stream, node->host.host, node->ts->ssl_opts, 1);
if (!tls_stream) {
mongoc_stream_destroy (stream);
return NULL;
} else {
return tls_stream;
}
}
#endif
return stream;
}
/* attempt to create a new socket stream using this dns result. */
mongoc_stream_t *
_mongoc_topology_scanner_tcp_initiate (mongoc_async_cmd_t *acmd)
{
mongoc_topology_scanner_node_t *node =
(mongoc_topology_scanner_node_t *) acmd->data;
struct addrinfo *res = acmd->dns_result;
mongoc_socket_t *sock = NULL;
BSON_ASSERT (acmd->dns_result);
/* create a new non-blocking socket. */
if (!(sock = mongoc_socket_new (
res->ai_family, res->ai_socktype, res->ai_protocol))) {
return NULL;
}
(void) mongoc_socket_connect (
sock, res->ai_addr, (mongoc_socklen_t) res->ai_addrlen, 0);
return _mongoc_topology_scanner_node_setup_stream_for_tls (
node, mongoc_stream_socket_new (sock));
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_node_setup_tcp --
*
* Create an async command for each DNS record found for this node.
*
* Returns:
* A bool. On failure error is set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_scanner_node_setup_tcp (mongoc_topology_scanner_node_t *node,
bson_error_t *error)
{
struct addrinfo hints;
struct addrinfo *iter;
char portstr[8];
mongoc_host_list_t *host;
int s;
int64_t delay = 0;
int64_t now = bson_get_monotonic_time ();
ENTRY;
host = &node->host;
/* if cached dns results are expired, flush. */
if (node->dns_results &&
(now - node->last_dns_cache) > node->ts->dns_cache_timeout_ms * 1000) {
freeaddrinfo (node->dns_results);
node->dns_results = NULL;
node->successful_dns_result = NULL;
}
if (!node->dns_results) {
bson_snprintf (portstr, sizeof portstr, "%hu", host->port);
memset (&hints, 0, sizeof hints);
hints.ai_family = host->family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
s = getaddrinfo (host->host, portstr, &hints, &node->dns_results);
if (s != 0) {
mongoc_counter_dns_failure_inc ();
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"Failed to resolve '%s'",
host->host);
RETURN (false);
}
mongoc_counter_dns_success_inc ();
node->last_dns_cache = now;
}
if (node->successful_dns_result) {
_begin_ismaster_cmd (node, NULL, false, node->successful_dns_result, 0);
} else {
LL_FOREACH2 (node->dns_results, iter, ai_next)
{
_begin_ismaster_cmd (node, NULL, false, iter, delay);
/* each subsequent DNS result will have an additional 250ms delay. */
delay += HAPPY_EYEBALLS_DELAY_MS;
}
}
RETURN (true);
}
bool
mongoc_topology_scanner_node_connect_unix (mongoc_topology_scanner_node_t *node,
bson_error_t *error)
{
#ifdef _WIN32
ENTRY;
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"UNIX domain sockets not supported on win32.");
RETURN (false);
#else
struct sockaddr_un saddr;
mongoc_socket_t *sock;
mongoc_stream_t *stream;
mongoc_host_list_t *host;
ENTRY;
host = &node->host;
memset (&saddr, 0, sizeof saddr);
saddr.sun_family = AF_UNIX;
bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host);
sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0);
if (sock == NULL) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to create socket.");
RETURN (false);
}
if (-1 == mongoc_socket_connect (
sock, (struct sockaddr *) &saddr, sizeof saddr, -1)) {
char buf[128];
char *errstr;
errstr = bson_strerror_r (mongoc_socket_errno (sock), buf, sizeof (buf));
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"Failed to connect to UNIX domain socket: %s",
errstr);
mongoc_socket_destroy (sock);
RETURN (false);
}
stream = _mongoc_topology_scanner_node_setup_stream_for_tls (
node, mongoc_stream_socket_new (sock));
if (stream) {
_begin_ismaster_cmd (node,
stream,
false /* is_setup_done */,
NULL /* dns result */,
0 /* delay */);
RETURN (true);
}
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_CONNECT,
+ "Failed to create TLS stream");
RETURN (false);
#endif
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_node_setup --
*
* Create a stream and begin a non-blocking connect.
*
* Returns:
* true on success, or false and error is set.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node,
bson_error_t *error)
{
bool success = false;
mongoc_stream_t *stream;
int64_t start;
_mongoc_topology_scanner_monitor_heartbeat_started (node->ts, &node->host);
start = bson_get_monotonic_time ();
/* if there is already a working stream, push it back to be re-scanned. */
if (node->stream) {
_begin_ismaster_cmd (
node, node->stream, true /* is_setup_done */, NULL, 0);
node->stream = NULL;
return;
}
BSON_ASSERT (!node->retired);
if (node->ts->initiator) {
stream = node->ts->initiator (
node->ts->uri, &node->host, node->ts->initiator_context, error);
if (stream) {
success = true;
_begin_ismaster_cmd (node, stream, false, NULL, 0);
}
} else {
if (node->host.family == AF_UNIX) {
success = mongoc_topology_scanner_node_connect_unix (node, error);
} else {
success = mongoc_topology_scanner_node_setup_tcp (node, error);
}
}
if (!success) {
_mongoc_topology_scanner_monitor_heartbeat_failed (
node->ts,
&node->host,
error,
(bson_get_monotonic_time () - start) / 1000);
node->ts->setup_err_cb (node->id, node->ts->cb_data, error);
return;
}
node->has_auth = false;
- node->timestamp = bson_get_monotonic_time ();
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_node_in_cooldown --
*
* Return true if @node has experienced a network error attempting
* to call "ismaster" less than 5 seconds before @when, a timestamp in
* microseconds.
*
* Server Discovery and Monitoring Spec: "After a single-threaded client
* gets a network error trying to check a server, the client skips
* re-checking the server until cooldownMS has passed. This avoids
* spending connectTimeoutMS on each unavailable server during each scan.
* This value MUST be 5000 ms, and it MUST NOT be configurable."
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_scanner_node_in_cooldown (mongoc_topology_scanner_node_t *node,
int64_t when)
{
if (node->last_failed == -1 || node->ts->bypass_cooldown) {
return false; /* node is new, or connected */
}
return node->last_failed + 1000 * MONGOC_TOPOLOGY_COOLDOWN_MS >= when;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_in_cooldown --
*
* Return true if all nodes will be in cooldown at time @when, a
* timestamp in microseconds.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_scanner_in_cooldown (mongoc_topology_scanner_t *ts,
int64_t when)
{
mongoc_topology_scanner_node_t *node;
if (ts->bypass_cooldown) {
return false;
}
DL_FOREACH (ts->nodes, node)
{
if (!mongoc_topology_scanner_node_in_cooldown (node, when)) {
return false;
}
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_start --
*
* Initializes the scanner and begins a full topology check. This
* should be called once before calling mongoc_topology_scanner_work()
* to complete the scan.
*
* The topology mutex must be held by the caller.
*
* If "obey_cooldown" is true, this is a single-threaded blocking scan
* that must obey the Server Discovery And Monitoring Spec's cooldownMS:
*
* "After a single-threaded client gets a network error trying to check
* a server, the client skips re-checking the server until cooldownMS has
* passed.
*
* "This avoids spending connectTimeoutMS on each unavailable server
* during each scan.
*
* "This value MUST be 5000 ms, and it MUST NOT be configurable."
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_scanner_start (mongoc_topology_scanner_t *ts,
bool obey_cooldown)
{
mongoc_topology_scanner_node_t *node, *tmp;
bool skip;
int64_t now;
BSON_ASSERT (ts);
_delete_retired_nodes (ts);
now = bson_get_monotonic_time ();
DL_FOREACH_SAFE (ts->nodes, node, tmp)
{
skip =
obey_cooldown && mongoc_topology_scanner_node_in_cooldown (node, now);
if (!skip) {
mongoc_topology_scanner_node_setup (node, &node->last_error);
}
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_finish_scan --
*
* Summarizes all scanner node errors into one error message,
* deletes retired nodes.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_scanner_finish (mongoc_topology_scanner_t *ts)
{
mongoc_topology_scanner_node_t *node, *tmp;
bson_error_t *error = &ts->error;
bson_string_t *msg;
memset (&ts->error, 0, sizeof (bson_error_t));
msg = bson_string_new (NULL);
DL_FOREACH_SAFE (ts->nodes, node, tmp)
{
if (node->last_error.code) {
if (msg->len) {
bson_string_append_c (msg, ' ');
}
bson_string_append_printf (msg, "[%s]", node->last_error.message);
/* last error domain and code win */
error->domain = node->last_error.domain;
error->code = node->last_error.code;
}
}
bson_strncpy ((char *) &error->message, msg->str, sizeof (error->message));
bson_string_free (msg, true);
_delete_retired_nodes (ts);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_work --
*
* Crank the knob on the topology scanner state machine. This should
* be called only after mongoc_topology_scanner_start() has been used
* to begin the scan.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts)
{
mongoc_async_run (ts->async);
BSON_ASSERT (ts->async->ncmds == 0);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_get_error --
*
* Copy the scanner's current error; which may no-error (code 0).
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_scanner_get_error (mongoc_topology_scanner_t *ts,
bson_error_t *error)
{
BSON_ASSERT (ts);
BSON_ASSERT (error);
memcpy (error, &ts->error, sizeof (bson_error_t));
}
/*
* Set a field in the topology scanner.
*/
bool
_mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts,
const char *appname)
{
if (!_mongoc_handshake_appname_is_valid (appname)) {
MONGOC_ERROR ("Cannot set appname: %s is invalid", appname);
return false;
}
if (ts->appname != NULL) {
MONGOC_ERROR ("Cannot set appname more than once");
return false;
}
ts->appname = bson_strdup (appname);
return true;
}
/*
* Set the scanner's clusterTime unconditionally: don't compare with prior
* @cluster_time is like {clusterTime: <timestamp>}
*/
void
_mongoc_topology_scanner_set_cluster_time (mongoc_topology_scanner_t *ts,
const bson_t *cluster_time)
{
bson_destroy (&ts->cluster_time);
bson_copy_to (cluster_time, &ts->cluster_time);
}
/* SDAM Monitoring Spec: send HeartbeatStartedEvent */
static void
_mongoc_topology_scanner_monitor_heartbeat_started (
const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host)
{
if (ts->apm_callbacks.server_heartbeat_started) {
mongoc_apm_server_heartbeat_started_t event;
event.host = host;
event.context = ts->apm_context;
+ event.awaited = false;
ts->apm_callbacks.server_heartbeat_started (&event);
}
}
/* SDAM Monitoring Spec: send HeartbeatSucceededEvent */
static void
_mongoc_topology_scanner_monitor_heartbeat_succeeded (
const mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
const bson_t *reply,
int64_t duration_usec)
{
if (ts->apm_callbacks.server_heartbeat_succeeded) {
mongoc_apm_server_heartbeat_succeeded_t event;
+ bson_t ismaster_redacted;
+
+ bson_init (&ismaster_redacted);
+ bson_copy_to_excluding_noinit (
+ reply, &ismaster_redacted, "speculativeAuthenticate", NULL);
+
event.host = host;
event.context = ts->apm_context;
event.reply = reply;
event.duration_usec = duration_usec;
+ event.awaited = false;
ts->apm_callbacks.server_heartbeat_succeeded (&event);
+
+ bson_destroy (&ismaster_redacted);
}
}
/* SDAM Monitoring Spec: send HeartbeatFailedEvent */
static void
_mongoc_topology_scanner_monitor_heartbeat_failed (
const mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
const bson_error_t *error,
int64_t duration_usec)
{
if (ts->apm_callbacks.server_heartbeat_failed) {
mongoc_apm_server_heartbeat_failed_t event;
event.host = host;
event.context = ts->apm_context;
event.error = error;
event.duration_usec = duration_usec;
+ event.awaited = false;
ts->apm_callbacks.server_heartbeat_failed (&event);
}
}
/* this is for testing the dns cache timeout. */
void
_mongoc_topology_scanner_set_dns_cache_timeout (mongoc_topology_scanner_t *ts,
int64_t timeout_ms)
{
ts->dns_cache_timeout_ms = timeout_ms;
}
/* reset "retired" nodes that failed or were removed in the previous scan */
static void
_delete_retired_nodes (mongoc_topology_scanner_t *ts)
{
mongoc_topology_scanner_node_t *node, *tmp;
DL_FOREACH_SAFE (ts->nodes, node, tmp)
{
if (node->retired) {
mongoc_topology_scanner_node_destroy (node, true);
}
}
}
static void
_cancel_commands_excluding (mongoc_topology_scanner_node_t *node,
mongoc_async_cmd_t *acmd)
{
mongoc_async_cmd_t *iter;
DL_FOREACH (node->ts->async->cmds, iter)
{
if ((mongoc_topology_scanner_node_t *) iter->data == node &&
iter != acmd) {
iter->state = MONGOC_ASYNC_CMD_CANCELED_STATE;
}
}
}
static int
_count_acmds (mongoc_topology_scanner_node_t *node)
{
mongoc_async_cmd_t *iter;
int count = 0;
DL_FOREACH (node->ts->async->cmds, iter)
{
if ((mongoc_topology_scanner_node_t *) iter->data == node) {
++count;
}
}
return count;
}
static void
_jumpstart_other_acmds (mongoc_topology_scanner_node_t *node,
mongoc_async_cmd_t *acmd)
{
mongoc_async_cmd_t *iter;
DL_FOREACH (node->ts->async->cmds, iter)
{
if ((mongoc_topology_scanner_node_t *) iter->data == node &&
iter != acmd && acmd->initiate_delay_ms < iter->initiate_delay_ms) {
iter->initiate_delay_ms =
BSON_MAX (iter->initiate_delay_ms - HAPPY_EYEBALLS_DELAY_MS, 0);
}
}
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
similarity index 71%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
index 987f98e4..0ca6608c 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
@@ -1,1659 +1,1771 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-config.h"
#include "mongoc-handshake.h"
#include "mongoc-handshake-private.h"
#include "mongoc-error.h"
#include "mongoc-host-list-private.h"
#include "mongoc-log.h"
#include "mongoc-topology-private.h"
#include "mongoc-topology-description-apm-private.h"
#include "mongoc-client-private.h"
#include "mongoc-cmd-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-util-private.h"
#include "mongoc-trace-private.h"
+#include "mongoc-error-private.h"
+#include "mongoc-topology-background-monitoring-private.h"
+#include "mongoc-read-prefs-private.h"
#include "utlist.h"
+static void
+_topology_collect_errors (mongoc_topology_t *topology, bson_error_t *error_out);
+
static bool
_mongoc_topology_reconcile_add_nodes (mongoc_server_description_t *sd,
mongoc_topology_t *topology)
{
mongoc_topology_scanner_t *scanner = topology->scanner;
/* quickly search by id, then check if a node for this host was retired in
* this scan. */
if (!mongoc_topology_scanner_get_node (scanner, sd->id) &&
!mongoc_topology_scanner_has_node_for_host (scanner, &sd->host)) {
mongoc_topology_scanner_add (scanner, &sd->host, sd->id);
mongoc_topology_scanner_scan (scanner, sd->id);
}
return true;
}
+/* Called from:
+ * - the topology scanner callback (when an ismaster was just received)
+ * - at the start of a single-threaded scan (mongoc_topology_scan_once)
+ * Not called for multi threaded monitoring.
+ */
void
mongoc_topology_reconcile (mongoc_topology_t *topology)
{
mongoc_topology_description_t *description;
mongoc_set_t *servers;
mongoc_server_description_t *sd;
int i;
mongoc_topology_scanner_node_t *ele, *tmp;
description = &topology->description;
servers = description->servers;
/* Add newly discovered nodes */
for (i = 0; i < (int) servers->items_len; i++) {
sd = (mongoc_server_description_t *) mongoc_set_get_item (servers, i);
_mongoc_topology_reconcile_add_nodes (sd, topology);
}
/* Remove removed nodes */
DL_FOREACH_SAFE (topology->scanner->nodes, ele, tmp)
{
if (!mongoc_topology_description_server_by_id (
description, ele->id, NULL)) {
mongoc_topology_scanner_node_retire (ele);
}
}
}
/* call this while already holding the lock */
static bool
_mongoc_topology_update_no_lock (uint32_t id,
const bson_t *ismaster_response,
int64_t rtt_msec,
mongoc_topology_t *topology,
const bson_error_t *error /* IN */)
{
mongoc_topology_description_handle_ismaster (
&topology->description, id, ismaster_response, rtt_msec, error);
/* return false if server removed from topology */
return mongoc_topology_description_server_by_id (
&topology->description, id, NULL) != NULL;
}
/*
*-------------------------------------------------------------------------
*
* _mongoc_topology_scanner_setup_err_cb --
*
* Callback method to handle errors during topology scanner node
* setup, typically DNS or SSL errors.
*
*-------------------------------------------------------------------------
*/
void
_mongoc_topology_scanner_setup_err_cb (uint32_t id,
void *data,
const bson_error_t *error /* IN */)
{
mongoc_topology_t *topology;
BSON_ASSERT (data);
topology = (mongoc_topology_t *) data;
mongoc_topology_description_handle_ismaster (&topology->description,
id,
NULL /* ismaster reply */,
-1 /* rtt_msec */,
error);
}
/*
*-------------------------------------------------------------------------
*
* _mongoc_topology_scanner_cb --
*
* Callback method to handle ismaster responses received by async
* command objects.
*
* NOTE: This method locks the given topology's mutex.
+ * Only called for single-threaded monitoring.
*
*-------------------------------------------------------------------------
*/
void
_mongoc_topology_scanner_cb (uint32_t id,
const bson_t *ismaster_response,
int64_t rtt_msec,
void *data,
const bson_error_t *error /* IN */)
{
mongoc_topology_t *topology;
mongoc_server_description_t *sd;
BSON_ASSERT (data);
topology = (mongoc_topology_t *) data;
bson_mutex_lock (&topology->mutex);
sd = mongoc_topology_description_server_by_id (
&topology->description, id, NULL);
+ if (!ismaster_response) {
+ /* Server monitoring: When a server check fails due to a network error
+ * (including a network timeout), the client MUST clear its connection
+ * pool for the server */
+ _mongoc_topology_clear_connection_pool (topology, id);
+ }
+
/* Server Discovery and Monitoring Spec: "Once a server is connected, the
* client MUST change its type to Unknown only after it has retried the
* server once." */
if (!ismaster_response && sd && sd->type != MONGOC_SERVER_UNKNOWN) {
_mongoc_topology_update_no_lock (
id, ismaster_response, rtt_msec, topology, error);
/* add another ismaster call to the current scan - the scan continues
* until all commands are done */
mongoc_topology_scanner_scan (topology->scanner, sd->id);
} else {
_mongoc_topology_update_no_lock (
id, ismaster_response, rtt_msec, topology, error);
/* The processing of the ismaster results above may have added/removed
* server descriptions. We need to reconcile that with our monitoring
* agents
*/
mongoc_topology_reconcile (topology);
mongoc_cond_broadcast (&topology->cond_client);
}
bson_mutex_unlock (&topology->mutex);
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_new --
*
* Creates and returns a new topology object.
*
* Returns:
* A new topology object.
*
* Side effects:
* None.
*
*-------------------------------------------------------------------------
*/
mongoc_topology_t *
mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
{
int64_t heartbeat_default;
int64_t heartbeat;
mongoc_topology_t *topology;
bool topology_valid;
mongoc_topology_description_type_t init_type;
const char *service;
char *prefixed_service;
uint32_t id;
const mongoc_host_list_t *hl;
mongoc_rr_data_t rr_data;
+ bool has_directconnection;
+ bool directconnection;
BSON_ASSERT (uri);
+ topology_valid = false;
#ifndef MONGOC_ENABLE_CRYPTO
if (mongoc_uri_get_option_as_bool (
uri, MONGOC_URI_RETRYWRITES, MONGOC_DEFAULT_RETRYWRITES)) {
/* retryWrites requires sessions, which require crypto - just warn */
MONGOC_WARNING (
"retryWrites not supported without an SSL crypto library");
}
#endif
topology = (mongoc_topology_t *) bson_malloc0 (sizeof *topology);
topology->session_pool = NULL;
heartbeat_default =
single_threaded ? MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED
: MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED;
heartbeat = mongoc_uri_get_option_as_int32 (
uri, MONGOC_URI_HEARTBEATFREQUENCYMS, heartbeat_default);
mongoc_topology_description_init (&topology->description, heartbeat);
topology->description.set_name =
bson_strdup (mongoc_uri_get_replica_set (uri));
topology->uri = mongoc_uri_copy (uri);
topology->single_threaded = single_threaded;
if (single_threaded) {
/* Server Selection Spec:
*
* "Single-threaded drivers MUST provide a "serverSelectionTryOnce"
* mode, in which the driver scans the topology exactly once after
* server selection fails, then either selects a server or raises an
* error.
*
* "The serverSelectionTryOnce option MUST be true by default."
*/
topology->server_selection_try_once = mongoc_uri_get_option_as_bool (
uri, MONGOC_URI_SERVERSELECTIONTRYONCE, true);
} else {
topology->server_selection_try_once = false;
}
topology->server_selection_timeout_msec = mongoc_uri_get_option_as_int32 (
topology->uri,
MONGOC_URI_SERVERSELECTIONTIMEOUTMS,
MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS);
/* tests can override this */
topology->min_heartbeat_frequency_msec =
MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS;
topology->local_threshold_msec =
mongoc_uri_get_local_threshold_option (topology->uri);
/* Total time allowed to check a server is connectTimeoutMS.
* Server Discovery And Monitoring Spec:
*
* "The socket used to check a server MUST use the same connectTimeoutMS as
* regular sockets. Multi-threaded clients SHOULD set monitoring sockets'
* socketTimeoutMS to the connectTimeoutMS."
*/
topology->connect_timeout_msec =
mongoc_uri_get_option_as_int32 (topology->uri,
MONGOC_URI_CONNECTTIMEOUTMS,
MONGOC_DEFAULT_CONNECTTIMEOUTMS);
topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_OFF;
topology->scanner =
mongoc_topology_scanner_new (topology->uri,
_mongoc_topology_scanner_setup_err_cb,
_mongoc_topology_scanner_cb,
topology,
topology->connect_timeout_msec);
bson_mutex_init (&topology->mutex);
mongoc_cond_init (&topology->cond_client);
- mongoc_cond_init (&topology->cond_server);
if (single_threaded) {
+ /* single threaded drivers attempt speculative authentication during a
+ * topology scan */
+ topology->scanner->speculative_authentication = true;
+
/* single threaded clients negotiate sasl supported mechanisms during
* a topology scan. */
if (_mongoc_uri_requires_auth_negotiation (uri)) {
topology->scanner->negotiate_sasl_supported_mechs = true;
}
}
- topology_valid = true;
service = mongoc_uri_get_service (uri);
if (service) {
memset (&rr_data, 0, sizeof (mongoc_rr_data_t));
+ /* Initialize the last scan time and interval. Even if the initial DNS
+ * lookup fails, SRV polling will still start when background monitoring
+ * starts. */
+ topology->srv_polling_last_scan_ms = bson_get_monotonic_time () / 1000;
+ topology->srv_polling_rescan_interval_ms =
+ MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS;
+
/* a mongodb+srv URI. try SRV lookup, if no error then also try TXT */
prefixed_service = bson_strdup_printf ("_mongodb._tcp.%s", service);
if (!_mongoc_client_get_rr (prefixed_service,
MONGOC_RR_SRV,
- topology->uri,
&rr_data,
- &topology->scanner->error) ||
- !_mongoc_client_get_rr (service,
- MONGOC_RR_TXT,
- topology->uri,
- NULL,
&topology->scanner->error)) {
- topology_valid = false;
- } else {
- topology->last_srv_scan = bson_get_monotonic_time ();
- topology->rescanSRVIntervalMS = BSON_MAX (
- rr_data.min_ttl * 1000, MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS);
+ GOTO (srv_fail);
+ }
+
+ /* Failure to find TXT records will not return an error (since it is only
+ * for options). But _mongoc_client_get_rr may return an error if
+ * there is more than one TXT record returned. */
+ if (!_mongoc_client_get_rr (
+ service, MONGOC_RR_TXT, &rr_data, &topology->scanner->error)) {
+ GOTO (srv_fail);
+ }
+
+ /* Use rr_data to update the topology's URI. */
+ if (rr_data.txt_record_opts &&
+ !mongoc_uri_parse_options (topology->uri,
+ rr_data.txt_record_opts,
+ true /* from_dns */,
+ &topology->scanner->error)) {
+ GOTO (srv_fail);
+ }
+
+ if (!mongoc_uri_init_with_srv_host_list (
+ topology->uri, rr_data.hosts, &topology->scanner->error)) {
+ GOTO (srv_fail);
}
+ topology->srv_polling_last_scan_ms = bson_get_monotonic_time () / 1000;
+ topology->srv_polling_rescan_interval_ms = BSON_MAX (
+ rr_data.min_ttl * 1000, MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS);
+
+ topology_valid = true;
+ srv_fail:
+ bson_free (rr_data.txt_record_opts);
bson_free (prefixed_service);
+ _mongoc_host_list_destroy_all (rr_data.hosts);
+ } else {
+ topology_valid = true;
}
/*
* Set topology type from URI:
- * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
- * - otherwise, if the seed list has a single host, initialize to SINGLE
+ * + if directConnection=true
+ * - whether or not we have a replicaSet name, initialize to SINGLE
+ * (directConnect with SRV or multiple hosts triggers a URI parse error)
+ * + if directConnection=false
+ * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
+ * - otherwise, initialize to UNKNOWN
+ * + if directConnection was not specified in the URI (old behavior)
+ * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
+ * - otherwise, if the seed list has a single host, initialize to SINGLE
* - everything else gets initialized to UNKNOWN
*/
+ has_directconnection =
+ mongoc_uri_has_option (uri, MONGOC_URI_DIRECTCONNECTION);
+ directconnection =
+ has_directconnection &&
+ mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
hl = mongoc_uri_get_hosts (topology->uri);
- if (mongoc_uri_get_replica_set (topology->uri)) {
+ if (service && !has_directconnection) {
+ init_type = MONGOC_TOPOLOGY_UNKNOWN;
+ } else if (has_directconnection) {
+ if (directconnection) {
+ init_type = MONGOC_TOPOLOGY_SINGLE;
+ } else {
+ if (mongoc_uri_get_replica_set (topology->uri)) {
+ init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
+ } else {
+ init_type = MONGOC_TOPOLOGY_UNKNOWN;
+ }
+ }
+ } else if (mongoc_uri_get_replica_set (topology->uri)) {
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
} else {
if (hl && hl->next) {
init_type = MONGOC_TOPOLOGY_UNKNOWN;
} else {
init_type = MONGOC_TOPOLOGY_SINGLE;
}
}
topology->description.type = init_type;
+ if (!topology->single_threaded) {
+ topology->server_monitors = mongoc_set_new (1, NULL, NULL);
+ topology->rtt_monitors = mongoc_set_new (1, NULL, NULL);
+ bson_mutex_init (&topology->apm_mutex);
+ mongoc_cond_init (&topology->srv_polling_cond);
+ }
+
if (!topology_valid) {
+ TRACE ("%s", "topology invalid");
/* add no nodes */
return topology;
}
while (hl) {
mongoc_topology_description_add_server (
&topology->description, hl->host_and_port, &id);
mongoc_topology_scanner_add (topology->scanner, hl, id);
hl = hl->next;
}
return topology;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_set_apm_callbacks --
*
* Set Application Performance Monitoring callbacks.
*
+ * Caller must hold topology->mutex.
+ *
*-------------------------------------------------------------------------
*/
void
mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology,
mongoc_apm_callbacks_t *callbacks,
void *context)
{
if (callbacks) {
memcpy (&topology->description.apm_callbacks,
callbacks,
sizeof (mongoc_apm_callbacks_t));
memcpy (&topology->scanner->apm_callbacks,
callbacks,
sizeof (mongoc_apm_callbacks_t));
} else {
memset (&topology->description.apm_callbacks,
0,
sizeof (mongoc_apm_callbacks_t));
memset (
&topology->scanner->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t));
}
topology->description.apm_context = context;
topology->scanner->apm_context = context;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_destroy --
*
* Free the memory associated with this topology object.
*
* Returns:
* None.
*
* Side effects:
* @topology will be cleaned up.
*
*-------------------------------------------------------------------------
*/
void
mongoc_topology_destroy (mongoc_topology_t *topology)
{
if (!topology) {
return;
}
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
bson_free (topology->keyvault_db);
bson_free (topology->keyvault_coll);
mongoc_client_destroy (topology->mongocryptd_client);
mongoc_client_pool_destroy (topology->mongocryptd_client_pool);
_mongoc_crypt_destroy (topology->crypt);
bson_destroy (topology->mongocryptd_spawn_args);
bson_free (topology->mongocryptd_spawn_path);
#endif
- _mongoc_topology_background_thread_stop (topology);
+ if (!topology->single_threaded) {
+ bson_mutex_lock (&topology->mutex);
+ _mongoc_topology_background_monitoring_stop (topology);
+ bson_mutex_unlock (&topology->mutex);
+ BSON_ASSERT (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF);
+ mongoc_set_destroy (topology->server_monitors);
+ mongoc_set_destroy (topology->rtt_monitors);
+ bson_mutex_destroy (&topology->apm_mutex);
+ mongoc_cond_destroy (&topology->srv_polling_cond);
+ }
_mongoc_topology_description_monitor_closed (&topology->description);
mongoc_uri_destroy (topology->uri);
mongoc_topology_description_destroy (&topology->description);
mongoc_topology_scanner_destroy (topology->scanner);
/* If we are single-threaded, the client will try to call
_mongoc_topology_end_sessions_cmd when it dies. This removes
sessions from the pool as it calls endSessions on them. In
case this does not succeed, we clear the pool again here. */
_mongoc_topology_clear_session_pool (topology);
mongoc_cond_destroy (&topology->cond_client);
- mongoc_cond_destroy (&topology->cond_server);
bson_mutex_destroy (&topology->mutex);
bson_free (topology);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_clear_session_pool --
*
* Clears the pool of server sessions without sending endSessions.
*
* Returns:
* Nothing.
*
* Side effects:
* Server session pool will be emptied.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_clear_session_pool (mongoc_topology_t *topology)
{
mongoc_server_session_t *ss, *tmp1, *tmp2;
CDL_FOREACH_SAFE (topology->session_pool, ss, tmp1, tmp2)
{
_mongoc_server_session_destroy (ss);
}
topology->session_pool = NULL;
}
+/* Returns false if none of the hosts were valid. */
+bool
+mongoc_topology_apply_scanned_srv_hosts (mongoc_uri_t *uri,
+ mongoc_topology_description_t *td,
+ mongoc_host_list_t *hosts,
+ bson_error_t *error)
+{
+ mongoc_host_list_t *host;
+ mongoc_host_list_t *valid_hosts = NULL;
+ bool had_valid_hosts = false;
+
+ /* Validate that the hosts have a matching domain.
+ * If validation fails, log it.
+ * If no valid hosts remain, do not update the topology description.
+ */
+ LL_FOREACH (hosts, host)
+ {
+ if (mongoc_uri_validate_srv_result (uri, host->host, error)) {
+ _mongoc_host_list_upsert (&valid_hosts, host);
+ } else {
+ MONGOC_ERROR ("Invalid host returned by SRV: %s", host->host_and_port);
+ /* Continue on, there may still be valid hosts returned. */
+ }
+ }
+
+ if (valid_hosts) {
+ /* Reconcile with the topology description. Newly found servers will start
+ * getting monitored and are eligible to be used by clients. */
+ mongoc_topology_description_reconcile (td, valid_hosts);
+ had_valid_hosts = true;
+ } else {
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_NAME_RESOLUTION,
+ "SRV response did not contain any valid hosts");
+ }
+
+ _mongoc_host_list_destroy_all (valid_hosts);
+ return had_valid_hosts;
+}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_rescan_srv --
*
* Queries SRV records for new hosts in a mongos cluster.
*
* NOTE: this method expects @topology's mutex to be locked on entry.
*
* --------------------------------------------------------------------------
*/
-static void
+void
mongoc_topology_rescan_srv (mongoc_topology_t *topology)
{
mongoc_rr_data_t rr_data = {0};
- mongoc_host_list_t *h = NULL;
const char *service;
char *prefixed_service = NULL;
- int64_t scan_time;
+ int64_t scan_time_ms;
+ bool ret;
if ((topology->description.type != MONGOC_TOPOLOGY_SHARDED) &&
(topology->description.type != MONGOC_TOPOLOGY_UNKNOWN)) {
/* Only perform rescan for sharded topology. */
return;
}
service = mongoc_uri_get_service (topology->uri);
if (!service) {
/* Only rescan if we have a mongodb+srv:// URI. */
return;
}
- scan_time = topology->last_srv_scan + (topology->rescanSRVIntervalMS * 1000);
- if (bson_get_monotonic_time () < scan_time) {
- /* Query SRV no more frequently than rescanSRVIntervalMS. */
+ scan_time_ms = topology->srv_polling_last_scan_ms +
+ topology->srv_polling_rescan_interval_ms;
+ if (bson_get_monotonic_time () / 1000 < scan_time_ms) {
+ /* Query SRV no more frequently than srv_polling_rescan_interval_ms. */
return;
}
- /* Go forth and query... */
- rr_data.hosts =
- _mongoc_host_list_copy (mongoc_uri_get_hosts (topology->uri), NULL);
+ TRACE ("%s", "Polling for SRV records");
+ /* Go forth and query... */
prefixed_service = bson_strdup_printf ("_mongodb._tcp.%s", service);
- if (!_mongoc_client_get_rr (prefixed_service,
- MONGOC_RR_SRV,
- topology->uri,
- &rr_data,
- &topology->scanner->error)) {
+
+ /* Unlock topology mutex during scan so it does not hold up other operations.
+ */
+ bson_mutex_unlock (&topology->mutex);
+ ret = _mongoc_client_get_rr (
+ prefixed_service, MONGOC_RR_SRV, &rr_data, &topology->scanner->error);
+ bson_mutex_lock (&topology->mutex);
+
+ topology->srv_polling_last_scan_ms = bson_get_monotonic_time () / 1000;
+ if (!ret) {
/* Failed querying, soldier on and try again next time. */
- topology->rescanSRVIntervalMS = topology->description.heartbeat_msec;
+ topology->srv_polling_rescan_interval_ms =
+ topology->description.heartbeat_msec;
+ MONGOC_ERROR ("SRV polling error: %s", topology->scanner->error.message);
GOTO (done);
}
- topology->last_srv_scan = bson_get_monotonic_time ();
- topology->rescanSRVIntervalMS = BSON_MAX (
+ topology->srv_polling_rescan_interval_ms = BSON_MAX (
rr_data.min_ttl * 1000, MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS);
- if (rr_data.count == 0) {
- /* Special case when DNS returns zero records successfully.
+ if (!mongoc_topology_apply_scanned_srv_hosts (topology->uri,
+ &topology->description,
+ rr_data.hosts,
+ &topology->scanner->error)) {
+ MONGOC_ERROR ("%s", topology->scanner->error.message);
+ /* Special case when DNS returns zero records successfully or no valid
+ * hosts exist.
* Leave the toplogy alone and perform another scan at the next interval
* rather than removing all records and having nothing to connect to.
- * For no verified hosts drivers "MUST temporarily set rescanSRVIntervalMS
+ * For no verified hosts drivers "MUST temporarily set
+ * srv_polling_rescan_interval_ms
* to heartbeatFrequencyMS until at least one verified SRV record is
* obtained."
*/
- topology->rescanSRVIntervalMS = topology->description.heartbeat_msec;
+ topology->srv_polling_rescan_interval_ms =
+ topology->description.heartbeat_msec;
GOTO (done);
}
- /* rr_data.hosts was initialized to the current set of known hosts
- * on entry, and mongoc_client_get_rr will have stripped it down to
- * only include hosts which were NOT included in the most recent query.
- * Remove those hosts and we're left with only active servers.
- */
- for (h = rr_data.hosts; h; h = rr_data.hosts) {
- rr_data.hosts = h->next;
- mongoc_uri_remove_host (topology->uri, h->host, h->port);
- bson_free (h);
- }
-
done:
bson_free (prefixed_service);
_mongoc_host_list_destroy_all (rr_data.hosts);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scan_once --
*
* Runs a single complete scan.
*
* NOTE: this method expects @topology's mutex to be locked on entry.
*
* NOTE: this method unlocks and re-locks @topology's mutex.
*
+ * Only runs for single threaded monitoring. (obey_cooldown is always
+ * true).
+ *
*--------------------------------------------------------------------------
*/
static void
mongoc_topology_scan_once (mongoc_topology_t *topology, bool obey_cooldown)
{
/* Prior to scanning hosts, update the list of SRV hosts, if applicable. */
mongoc_topology_rescan_srv (topology);
/* since the last scan, members may be added or removed from the topology
* description based on ismaster responses in connection handshakes, see
* _mongoc_topology_update_from_handshake. retire scanner nodes for removed
* members and create scanner nodes for new ones. */
mongoc_topology_reconcile (topology);
mongoc_topology_scanner_start (topology->scanner, obey_cooldown);
/* scanning locks and unlocks the mutex itself until the scan is done */
bson_mutex_unlock (&topology->mutex);
mongoc_topology_scanner_work (topology->scanner);
bson_mutex_lock (&topology->mutex);
_mongoc_topology_scanner_finish (topology->scanner);
topology->last_scan = bson_get_monotonic_time ();
topology->stale = false;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_do_blocking_scan --
*
* Monitoring entry for single-threaded use case. Assumes the caller
* has checked that it's the right time to scan.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_do_blocking_scan (mongoc_topology_t *topology,
bson_error_t *error)
{
- topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_SINGLE_THREADED;
-
_mongoc_handshake_freeze ();
bson_mutex_lock (&topology->mutex);
mongoc_topology_scan_once (topology, true /* obey cooldown */);
bson_mutex_unlock (&topology->mutex);
mongoc_topology_scanner_get_error (topology->scanner, error);
}
bool
mongoc_topology_compatible (const mongoc_topology_description_t *td,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error)
{
int64_t max_staleness_seconds;
int32_t max_wire_version;
if (td->compatibility_error.code) {
if (error) {
memcpy (error, &td->compatibility_error, sizeof (bson_error_t));
}
return false;
}
if (!read_prefs) {
/* NULL means read preference Primary */
return true;
}
max_staleness_seconds =
mongoc_read_prefs_get_max_staleness_seconds (read_prefs);
if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) {
max_wire_version =
mongoc_topology_description_lowest_max_wire_version (td);
if (max_wire_version < WIRE_VERSION_MAX_STALENESS) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Not all servers support maxStalenessSeconds");
return false;
}
/* shouldn't happen if we've properly enforced wire version */
if (!mongoc_topology_description_all_sds_have_write_date (td)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Not all servers have lastWriteDate");
return false;
}
if (!_mongoc_topology_description_validate_max_staleness (
td, max_staleness_seconds, error)) {
return false;
}
}
return true;
}
static void
_mongoc_server_selection_error (const char *msg,
const bson_error_t *scanner_error,
bson_error_t *error)
{
if (scanner_error && scanner_error->code) {
bson_set_error (error,
MONGOC_ERROR_SERVER_SELECTION,
MONGOC_ERROR_SERVER_SELECTION_FAILURE,
"%s: %s",
msg,
scanner_error->message);
} else {
bson_set_error (error,
MONGOC_ERROR_SERVER_SELECTION,
MONGOC_ERROR_SERVER_SELECTION_FAILURE,
"%s",
msg);
}
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_select --
*
* Selects a server description for an operation based on @optype
* and @read_prefs.
*
* NOTE: this method returns a copy of the original server
* description. Callers must own and clean up this copy.
*
* NOTE: this method locks and unlocks @topology's mutex.
*
* Parameters:
* @topology: The topology.
* @optype: Whether we are selecting for a read or write operation.
* @read_prefs: Required, the read preferences for the command.
* @error: Required, out pointer for error info.
*
* Returns:
* A mongoc_server_description_t, or NULL on failure, in which case
* @error will be set.
*
* Side effects:
* @error may be set.
*
*-------------------------------------------------------------------------
*/
mongoc_server_description_t *
mongoc_topology_select (mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error)
{
uint32_t server_id =
mongoc_topology_select_server_id (topology, optype, read_prefs, error);
if (server_id) {
/* new copy of the server description */
return mongoc_topology_server_by_id (topology, server_id, error);
} else {
return NULL;
}
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_select_server_id --
*
* Alternative to mongoc_topology_select when you only need the id.
*
* Returns:
* A server id, or 0 on failure, in which case @error will be set.
*
*-------------------------------------------------------------------------
*/
uint32_t
mongoc_topology_select_server_id (mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error)
{
static const char *timeout_msg =
"No suitable servers found: `serverSelectionTimeoutMS` expired";
mongoc_topology_scanner_t *ts;
int r;
int64_t local_threshold_ms;
mongoc_server_description_t *selected_server = NULL;
bool try_once;
int64_t sleep_usec;
bool tried_once;
bson_error_t scanner_error = {0};
int64_t heartbeat_msec;
uint32_t server_id;
/* These names come from the Server Selection Spec pseudocode */
int64_t loop_start; /* when we entered this function */
int64_t loop_end; /* when we last completed a loop (single-threaded) */
int64_t scan_ready; /* the soonest we can do a blocking scan */
int64_t next_update; /* the latest we must do a blocking scan */
int64_t expire_at; /* when server selection timeout expires */
BSON_ASSERT (topology);
ts = topology->scanner;
bson_mutex_lock (&topology->mutex);
/* It isn't strictly necessary to lock here, because if the topology
* is invalid, it will never become valid. Lock anyway for consistency. */
if (!mongoc_topology_scanner_valid (ts)) {
if (error) {
mongoc_topology_scanner_get_error (ts, error);
error->domain = MONGOC_ERROR_SERVER_SELECTION;
error->code = MONGOC_ERROR_SERVER_SELECTION_FAILURE;
}
bson_mutex_unlock (&topology->mutex);
return 0;
}
bson_mutex_unlock (&topology->mutex);
heartbeat_msec = topology->description.heartbeat_msec;
local_threshold_ms = topology->local_threshold_msec;
try_once = topology->server_selection_try_once;
loop_start = loop_end = bson_get_monotonic_time ();
expire_at =
loop_start + ((int64_t) topology->server_selection_timeout_msec * 1000);
if (topology->single_threaded) {
_mongoc_topology_description_monitor_opening (&topology->description);
tried_once = false;
next_update = topology->last_scan + heartbeat_msec * 1000;
if (next_update < loop_start) {
/* we must scan now */
topology->stale = true;
}
/* until we find a server or time out */
for (;;) {
if (topology->stale) {
/* how soon are we allowed to scan? */
scan_ready = topology->last_scan +
topology->min_heartbeat_frequency_msec * 1000;
if (scan_ready > expire_at && !try_once) {
/* selection timeout will expire before min heartbeat passes */
_mongoc_server_selection_error (
"No suitable servers found: "
"`serverselectiontimeoutms` timed out",
&scanner_error,
error);
return 0;
}
sleep_usec = scan_ready - loop_end;
if (sleep_usec > 0) {
if (try_once &&
mongoc_topology_scanner_in_cooldown (ts, scan_ready)) {
_mongoc_server_selection_error (
"No servers yet eligible for rescan",
&scanner_error,
error);
return 0;
}
_mongoc_usleep (sleep_usec);
}
/* takes up to connectTimeoutMS. sets "last_scan", clears "stale" */
_mongoc_topology_do_blocking_scan (topology, &scanner_error);
loop_end = topology->last_scan;
tried_once = true;
}
if (!mongoc_topology_compatible (
&topology->description, read_prefs, error)) {
return 0;
}
selected_server = mongoc_topology_description_select (
&topology->description, optype, read_prefs, local_threshold_ms);
if (selected_server) {
return selected_server->id;
}
topology->stale = true;
if (try_once) {
if (tried_once) {
_mongoc_server_selection_error (
"No suitable servers found (`serverSelectionTryOnce` set)",
&scanner_error,
error);
return 0;
}
} else {
loop_end = bson_get_monotonic_time ();
if (loop_end > expire_at) {
/* no time left in server_selection_timeout_msec */
_mongoc_server_selection_error (
timeout_msg, &scanner_error, error);
return 0;
}
}
}
}
/* With background thread */
/* we break out when we've found a server or timed out */
for (;;) {
bson_mutex_lock (&topology->mutex);
if (!mongoc_topology_compatible (
&topology->description, read_prefs, error)) {
bson_mutex_unlock (&topology->mutex);
return 0;
}
selected_server = mongoc_topology_description_select (
&topology->description, optype, read_prefs, local_threshold_ms);
if (!selected_server) {
+ TRACE (
+ "server selection requesting an immediate scan, want %s",
+ _mongoc_read_mode_as_str (mongoc_read_prefs_get_mode (read_prefs)));
_mongoc_topology_request_scan (topology);
+ TRACE ("server selection about to wait for %" PRId64 "ms",
+ (expire_at - loop_start) / 1000);
r = mongoc_cond_timedwait (&topology->cond_client,
&topology->mutex,
(expire_at - loop_start) / 1000);
+ TRACE ("%s", "server selection awake");
+ _topology_collect_errors (topology, &scanner_error);
- mongoc_topology_scanner_get_error (ts, &scanner_error);
bson_mutex_unlock (&topology->mutex);
#ifdef _WIN32
if (r == WSAETIMEDOUT) {
#else
if (r == ETIMEDOUT) {
#endif
/* handle timeouts */
_mongoc_server_selection_error (timeout_msg, &scanner_error, error);
return 0;
} else if (r) {
bson_set_error (error,
MONGOC_ERROR_SERVER_SELECTION,
MONGOC_ERROR_SERVER_SELECTION_FAILURE,
"Unknown error '%d' received while waiting on "
"thread condition",
r);
return 0;
}
loop_start = bson_get_monotonic_time ();
if (loop_start > expire_at) {
_mongoc_server_selection_error (timeout_msg, &scanner_error, error);
return 0;
}
} else {
server_id = selected_server->id;
bson_mutex_unlock (&topology->mutex);
return server_id;
}
}
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_server_by_id --
*
* Get the server description for @id, if that server is present
* in @description. Otherwise, return NULL and fill out the optional
* @error.
*
* NOTE: this method returns a copy of the original server
* description. Callers must own and clean up this copy.
*
* NOTE: this method locks and unlocks @topology's mutex.
*
* Returns:
* A mongoc_server_description_t, or NULL.
*
* Side effects:
* Fills out optional @error if server not found.
*
*-------------------------------------------------------------------------
*/
mongoc_server_description_t *
mongoc_topology_server_by_id (mongoc_topology_t *topology,
uint32_t id,
bson_error_t *error)
{
mongoc_server_description_t *sd;
bson_mutex_lock (&topology->mutex);
sd = mongoc_server_description_new_copy (
mongoc_topology_description_server_by_id (
&topology->description, id, error));
bson_mutex_unlock (&topology->mutex);
return sd;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_host_by_id --
*
* Copy the mongoc_host_list_t for @id, if that server is present
* in @description. Otherwise, return NULL and fill out the optional
* @error.
*
* NOTE: this method returns a copy of the original mongoc_host_list_t.
* Callers must own and clean up this copy.
*
* NOTE: this method locks and unlocks @topology's mutex.
*
* Returns:
* A mongoc_host_list_t, or NULL.
*
* Side effects:
* Fills out optional @error if server not found.
*
*-------------------------------------------------------------------------
*/
mongoc_host_list_t *
_mongoc_topology_host_by_id (mongoc_topology_t *topology,
uint32_t id,
bson_error_t *error)
{
mongoc_server_description_t *sd;
mongoc_host_list_t *host = NULL;
bson_mutex_lock (&topology->mutex);
/* not a copy - direct pointer into topology description data */
sd = mongoc_topology_description_server_by_id (
&topology->description, id, error);
if (sd) {
host = bson_malloc0 (sizeof (mongoc_host_list_t));
memcpy (host, &sd->host, sizeof (mongoc_host_list_t));
}
bson_mutex_unlock (&topology->mutex);
return host;
}
/*
- *--------------------------------------------------------------------------
- *
- * _mongoc_topology_request_scan --
- *
- * Non-locking variant
+
+ * Caller must have topology->mutex locked.
*
- *--------------------------------------------------------------------------
*/
void
_mongoc_topology_request_scan (mongoc_topology_t *topology)
{
- topology->scan_requested = true;
-
- mongoc_cond_signal (&topology->cond_server);
+ _mongoc_topology_background_monitoring_request_scan (topology);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_invalidate_server --
*
* Invalidate the given server after receiving a network error in
* another part of the client.
*
* NOTE: this method uses @topology's mutex.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_invalidate_server (mongoc_topology_t *topology,
uint32_t id,
const bson_error_t *error)
{
BSON_ASSERT (error);
bson_mutex_lock (&topology->mutex);
mongoc_topology_description_invalidate_server (
&topology->description, id, error);
bson_mutex_unlock (&topology->mutex);
}
/*
- *--------------------------------------------------------------------------
- *
- * _mongoc_topology_update_from_handshake --
- *
- * A client opens a new connection and calls ismaster on it when it
- * detects a closed connection in _mongoc_cluster_check_interval, or if
- * mongoc_client_pool_pop creates a new client. Update the topology
- * description from the ismaster response.
- *
- * NOTE: this method uses @topology's mutex.
- *
- * Returns:
- * false if the server was removed from the topology
- *--------------------------------------------------------------------------
+ * Update the topology from the response to a handshake on a new application
+ * connection.
+ * Only applicable to a client pool (single-threaded clients reuse monitoring
+ * connections).
+ * Caller must not have the topology->mutex locked.
+ * Locks topology->mutex.
+ * Called only from app threads (not server monitor threads).
+ * Returns false if the server was removed from the topology
*/
bool
_mongoc_topology_update_from_handshake (mongoc_topology_t *topology,
const mongoc_server_description_t *sd)
{
bool has_server;
BSON_ASSERT (topology);
BSON_ASSERT (sd);
+ BSON_ASSERT (!topology->single_threaded);
bson_mutex_lock (&topology->mutex);
/* return false if server was removed from topology */
has_server = _mongoc_topology_update_no_lock (
sd->id, &sd->last_is_master, sd->round_trip_time_msec, topology, NULL);
/* if pooled, wake threads waiting in mongoc_topology_server_by_id */
mongoc_cond_broadcast (&topology->cond_client);
+ /* Update background monitoring. */
+ _mongoc_topology_background_monitoring_reconcile (topology);
bson_mutex_unlock (&topology->mutex);
return has_server;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_update_last_used --
*
* Internal function. In single-threaded mode only, track when the socket
* to a particular server was last used. This is required for
* mongoc_cluster_check_interval to know when a socket has been idle.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_update_last_used (mongoc_topology_t *topology,
uint32_t server_id)
{
mongoc_topology_scanner_node_t *node;
if (!topology->single_threaded) {
return;
}
node = mongoc_topology_scanner_get_node (topology->scanner, server_id);
if (node) {
node->last_used = bson_get_monotonic_time ();
}
}
-/*
- *--------------------------------------------------------------------------
- *
- * mongoc_topology_server_timestamp --
- *
- * Return the topology's scanner's timestamp for the given server,
- * or -1 if there is no scanner node for the given server.
- *
- * NOTE: this method uses @topology's mutex.
- *
- * Returns:
- * Timestamp, or -1
- *
- *--------------------------------------------------------------------------
- */
-int64_t
-mongoc_topology_server_timestamp (mongoc_topology_t *topology, uint32_t id)
-{
- mongoc_topology_scanner_node_t *node;
- int64_t timestamp = -1;
-
- bson_mutex_lock (&topology->mutex);
-
- node = mongoc_topology_scanner_get_node (topology->scanner, id);
- if (node) {
- timestamp = node->timestamp;
- }
-
- bson_mutex_unlock (&topology->mutex);
-
- return timestamp;
-}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_get_type --
*
* Return the topology's description's type.
*
* NOTE: this method uses @topology's mutex.
*
* Returns:
* The topology description type.
*
*--------------------------------------------------------------------------
*/
mongoc_topology_description_type_t
_mongoc_topology_get_type (mongoc_topology_t *topology)
{
mongoc_topology_description_type_t td_type;
bson_mutex_lock (&topology->mutex);
td_type = topology->description.type;
bson_mutex_unlock (&topology->mutex);
return td_type;
}
-/*
- *--------------------------------------------------------------------------
- *
- * _mongoc_topology_run_background --
- *
- * The background topology monitoring thread runs in this loop.
- *
- * NOTE: this method uses @topology's mutex.
- *
- *--------------------------------------------------------------------------
- */
-static void *
-_mongoc_topology_run_background (void *data)
-{
- mongoc_topology_t *topology;
- int64_t now;
- int64_t last_scan;
- int64_t timeout;
- int64_t force_timeout;
- int64_t heartbeat_msec;
- int r;
-
- BSON_ASSERT (data);
-
- last_scan = 0;
- topology = (mongoc_topology_t *) data;
- heartbeat_msec = topology->description.heartbeat_msec;
-
- /* we exit this loop when shutting down, or on error */
- for (;;) {
- /* unlocked after starting a scan or after breaking out of the loop */
- bson_mutex_lock (&topology->mutex);
- if (!mongoc_topology_scanner_valid (topology->scanner)) {
- bson_mutex_unlock (&topology->mutex);
- goto DONE;
- }
-
- /* we exit this loop on error, or when we should scan immediately */
- for (;;) {
- if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN) {
- bson_mutex_unlock (&topology->mutex);
- goto DONE;
- }
-
- now = bson_get_monotonic_time ();
-
- if (last_scan == 0) {
- /* set up the "last scan" as exactly long enough to force an
- * immediate scan on the first pass */
- last_scan = now - (heartbeat_msec * 1000);
- }
-
- timeout = heartbeat_msec - ((now - last_scan) / 1000);
-
- /* if someone's specifically asked for a scan, use a shorter interval
- */
- if (topology->scan_requested) {
- force_timeout = topology->min_heartbeat_frequency_msec -
- ((now - last_scan) / 1000);
-
- timeout = BSON_MIN (timeout, force_timeout);
- }
-
- /* if we can start scanning, do so immediately */
- if (timeout <= 0) {
- break;
- } else {
- /* otherwise wait until someone:
- * o requests a scan
- * o we time out
- * o requests a shutdown
- */
- r = mongoc_cond_timedwait (
- &topology->cond_server, &topology->mutex, timeout);
-
-#ifdef _WIN32
- if (!(r == 0 || r == WSAETIMEDOUT)) {
-#else
- if (!(r == 0 || r == ETIMEDOUT)) {
-#endif
- bson_mutex_unlock (&topology->mutex);
- /* handle errors */
- goto DONE;
- }
-
- /* if we timed out, or were woken up, check if it's time to scan
- * again, or bail out */
- }
- }
-
- topology->scan_requested = false;
- mongoc_topology_scan_once (topology, false /* obey cooldown */);
- bson_mutex_unlock (&topology->mutex);
-
- last_scan = bson_get_monotonic_time ();
- }
-
-DONE:
- return NULL;
-}
-
-/*
- *--------------------------------------------------------------------------
- *
- * mongoc_topology_start_background_scanner
- *
- * Start the topology background thread running. This should only be
- * called once per pool. If clients are created separately (not
- * through a pool) the SDAM logic will not be run in a background
- * thread. Returns whether or not the scanner is running on termination
- * of the function.
- *
- * NOTE: this method uses @topology's mutex.
- *
- *--------------------------------------------------------------------------
- */
-
-bool
-_mongoc_topology_start_background_scanner (mongoc_topology_t *topology)
-{
- int r;
-
- if (topology->single_threaded) {
- return false;
- }
-
- bson_mutex_lock (&topology->mutex);
-
- if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
- bson_mutex_unlock (&topology->mutex);
- return true;
- }
-
- BSON_ASSERT (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF);
-
- topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_BG_RUNNING;
-
- _mongoc_handshake_freeze ();
- _mongoc_topology_description_monitor_opening (&topology->description);
-
- r = bson_thread_create (
- &topology->thread, _mongoc_topology_run_background, topology);
-
- if (r != 0) {
- MONGOC_ERROR ("could not start topology scanner thread: %s",
- strerror (r));
- abort ();
- }
-
- bson_mutex_unlock (&topology->mutex);
-
- return true;
-}
-
-/*
- *--------------------------------------------------------------------------
- *
- * mongoc_topology_background_thread_stop --
- *
- * Stop the topology background thread. Called by the owning pool at
- * its destruction.
- *
- * NOTE: this method uses @topology's mutex.
- *
- *--------------------------------------------------------------------------
- */
-
-void
-_mongoc_topology_background_thread_stop (mongoc_topology_t *topology)
-{
- bool join_thread = false;
-
- if (topology->single_threaded) {
- return;
- }
-
- bson_mutex_lock (&topology->mutex);
-
- BSON_ASSERT (topology->scanner_state !=
- MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN);
-
- if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
- /* if the background thread is running, request a shutdown and signal the
- * thread */
- topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN;
- mongoc_cond_signal (&topology->cond_server);
- join_thread = true;
- } else {
- /* nothing to do if it's already off */
- }
-
- bson_mutex_unlock (&topology->mutex);
-
- if (join_thread) {
- /* if we're joining the thread, wait for it to come back and broadcast
- * all listeners */
- bson_thread_join (topology->thread);
-
- bson_mutex_lock (&topology->mutex);
- topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_OFF;
- bson_mutex_unlock (&topology->mutex);
-
- mongoc_cond_broadcast (&topology->cond_client);
- }
-}
-
bool
_mongoc_topology_set_appname (mongoc_topology_t *topology, const char *appname)
{
bool ret = false;
bson_mutex_lock (&topology->mutex);
if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF) {
ret = _mongoc_topology_scanner_set_appname (topology->scanner, appname);
} else {
MONGOC_ERROR ("Cannot set appname after handshake initiated");
}
bson_mutex_unlock (&topology->mutex);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_update_cluster_time --
*
* Internal function. If the server reply has a later $clusterTime than
* any seen before, update the topology's clusterTime. See the Driver
* Sessions Spec.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_update_cluster_time (mongoc_topology_t *topology,
const bson_t *reply)
{
bson_mutex_lock (&topology->mutex);
mongoc_topology_description_update_cluster_time (&topology->description,
reply);
_mongoc_topology_scanner_set_cluster_time (
topology->scanner, &topology->description.cluster_time);
bson_mutex_unlock (&topology->mutex);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_pop_server_session --
*
* Internal function. Get a server session from the pool or create
* one. On error, return NULL and fill out @error.
*
*--------------------------------------------------------------------------
*/
mongoc_server_session_t *
_mongoc_topology_pop_server_session (mongoc_topology_t *topology,
bson_error_t *error)
{
int64_t timeout;
mongoc_server_session_t *ss = NULL;
mongoc_topology_description_t *td;
ENTRY;
bson_mutex_lock (&topology->mutex);
td = &topology->description;
timeout = td->session_timeout_minutes;
if (timeout == MONGOC_NO_SESSIONS) {
/* if needed, connect and check for session timeout again */
if (!mongoc_topology_description_has_data_node (td)) {
bson_mutex_unlock (&topology->mutex);
if (!mongoc_topology_select_server_id (
topology, MONGOC_SS_READ, NULL, error)) {
RETURN (NULL);
}
bson_mutex_lock (&topology->mutex);
timeout = td->session_timeout_minutes;
}
if (timeout == MONGOC_NO_SESSIONS) {
bson_mutex_unlock (&topology->mutex);
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_SESSION_FAILURE,
"Server does not support sessions");
RETURN (NULL);
}
}
while (topology->session_pool) {
ss = topology->session_pool;
CDL_DELETE (topology->session_pool, ss);
if (_mongoc_server_session_timed_out (ss, timeout)) {
_mongoc_server_session_destroy (ss);
ss = NULL;
} else {
break;
}
}
bson_mutex_unlock (&topology->mutex);
if (!ss) {
ss = _mongoc_server_session_new (error);
}
RETURN (ss);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_push_server_session --
*
* Internal function. Return a server session to the pool.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_push_server_session (mongoc_topology_t *topology,
mongoc_server_session_t *server_session)
{
int64_t timeout;
mongoc_server_session_t *ss;
ENTRY;
bson_mutex_lock (&topology->mutex);
timeout = topology->description.session_timeout_minutes;
/* start at back of queue and reap timed-out sessions */
while (topology->session_pool && topology->session_pool->prev) {
ss = topology->session_pool->prev;
if (_mongoc_server_session_timed_out (ss, timeout)) {
BSON_ASSERT (ss->next); /* silences clang scan-build */
CDL_DELETE (topology->session_pool, ss);
_mongoc_server_session_destroy (ss);
} else {
/* if ss is not timed out, sessions in front of it are ok too */
break;
}
}
/* If session is expiring or "dirty" (a network error occurred on it), do not
* return it to the pool. */
if (_mongoc_server_session_timed_out (server_session, timeout) ||
server_session->dirty) {
_mongoc_server_session_destroy (server_session);
} else {
/* silences clang scan-build */
BSON_ASSERT (!topology->session_pool || (topology->session_pool->next &&
topology->session_pool->prev));
- CDL_PREPEND (topology->session_pool, server_session);
+
+ /* add server session (lsid) to session pool to be reused only if the
+ * server session has been used (the server is aware of the session) */
+ if (server_session->last_used_usec == SESSION_NEVER_USED) {
+ _mongoc_server_session_destroy (server_session);
+ } else {
+ CDL_PREPEND (topology->session_pool, server_session);
+ }
}
bson_mutex_unlock (&topology->mutex);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_end_sessions_cmd --
*
* Internal function. End up to 10,000 server sessions. @cmd is an
* uninitialized document. Sessions are destroyed as their ids are
* appended to @cmd.
*
* Driver Sessions Spec: "If the number of sessions is very large the
* endSessions command SHOULD be run multiple times to end 10,000
* sessions at a time (in order to avoid creating excessively large
* commands)."
*
* Returns:
* true if any session ids were appended to @cmd.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd)
{
mongoc_server_session_t *ss, *tmp1, *tmp2;
char buf[16];
const char *key;
uint32_t i;
bson_t ar;
bson_init (cmd);
BSON_APPEND_ARRAY_BEGIN (cmd, "endSessions", &ar);
i = 0;
CDL_FOREACH_SAFE (topology->session_pool, ss, tmp1, tmp2)
{
bson_uint32_to_string (i, &key, buf, sizeof buf);
BSON_APPEND_DOCUMENT (&ar, key, &ss->lsid);
CDL_DELETE (topology->session_pool, ss);
_mongoc_server_session_destroy (ss);
if (++i == 10000) {
break;
}
}
bson_append_array_end (cmd, &ar);
return i > 0;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_get_ismaster --
*
* Locks topology->mutex and retrieves (possibly constructing) the
* handshake on the topology scanner.
*
* Returns:
* A bson_t representing an ismaster command.
*
*--------------------------------------------------------------------------
*/
const bson_t *
_mongoc_topology_get_ismaster (mongoc_topology_t *topology)
{
const bson_t *cmd;
bson_mutex_lock (&topology->mutex);
cmd = _mongoc_topology_scanner_get_ismaster (topology->scanner);
bson_mutex_unlock (&topology->mutex);
return cmd;
}
void
_mongoc_topology_bypass_cooldown (mongoc_topology_t *topology)
{
BSON_ASSERT (topology->single_threaded);
topology->scanner->bypass_cooldown = true;
-}
\ No newline at end of file
+}
+
+static void
+_find_topology_version (const bson_t *reply, bson_t *topology_version)
+{
+ bson_iter_t iter;
+ const uint8_t *bytes;
+ uint32_t len;
+
+ if (!bson_iter_init_find (&iter, reply, "topologyVersion") ||
+ !BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ bson_init (topology_version);
+ return;
+ }
+ bson_iter_document (&iter, &len, &bytes);
+ bson_init_static (topology_version, bytes, len);
+}
+
+
+/* "Clears" the connection pool by incrementing the generation.
+ *
+ * Pooled clients with open connections will discover the invalidation
+ * the next time they fetch a stream to the server.
+ *
+ * Caller must lock topology->mutex. */
+void
+_mongoc_topology_clear_connection_pool (mongoc_topology_t *topology,
+ uint32_t server_id)
+{
+ mongoc_server_description_t *sd;
+ bson_error_t error;
+
+ sd = mongoc_topology_description_server_by_id (
+ &topology->description, server_id, &error);
+ if (!sd) {
+ /* Server removed, ignore and ignore error. */
+ return;
+ }
+ TRACE ("clearing pool for server: %s", sd->host.host_and_port);
+ sd->generation++;
+}
+
+
+/* Handle an error from an app connection.
+ *
+ * This can be a network error or "not master" / "node is recovering" error.
+ * Caller must lock topology->mutex.
+ * Returns true if pool was cleared.
+ */
+bool
+_mongoc_topology_handle_app_error (mongoc_topology_t *topology,
+ uint32_t server_id,
+ bool handshake_complete,
+ _mongoc_sdam_app_error_type_t type,
+ const bson_t *reply,
+ const bson_error_t *why,
+ uint32_t max_wire_version,
+ uint32_t generation)
+{
+ bson_error_t server_selection_error;
+ mongoc_server_description_t *sd;
+ bool pool_cleared;
+
+ pool_cleared = false;
+ sd = mongoc_topology_description_server_by_id (
+ &topology->description, server_id, &server_selection_error);
+ if (!sd) {
+ /* The server was already removed from the topology. Ignore error. */
+ return false;
+ }
+
+ if (generation < sd->generation) {
+ /* This is a stale connection. Ignore. */
+ return false;
+ }
+
+ if (type == MONGOC_SDAM_APP_ERROR_NETWORK) {
+ /* Mark server as unknown. */
+ mongoc_topology_description_invalidate_server (
+ &topology->description, server_id, why);
+ _mongoc_topology_clear_connection_pool (topology, server_id);
+ pool_cleared = true;
+ if (!topology->single_threaded) {
+ _mongoc_topology_background_monitoring_cancel_check (topology,
+ server_id);
+ }
+ } else if (type == MONGOC_SDAM_APP_ERROR_TIMEOUT) {
+ if (handshake_complete) {
+ /* Timeout errors after handshake are ok, do nothing. */
+ return false;
+ }
+ /* Mark server as unknown. */
+ mongoc_topology_description_invalidate_server (
+ &topology->description, server_id, why);
+ _mongoc_topology_clear_connection_pool (topology, server_id);
+ pool_cleared = true;
+ if (!topology->single_threaded) {
+ _mongoc_topology_background_monitoring_cancel_check (topology,
+ server_id);
+ }
+ } else if (type == MONGOC_SDAM_APP_ERROR_COMMAND) {
+ bson_error_t cmd_error;
+ bson_t incoming_topology_version;
+
+ if (_mongoc_cmd_check_ok_no_wce (
+ reply, MONGOC_ERROR_API_VERSION_2, &cmd_error)) {
+ /* No error. */
+ return false;
+ }
+
+ if (!_mongoc_error_is_state_change (&cmd_error)) {
+ /* Not a "not master" or "node is recovering" error. */
+ return false;
+ }
+
+ /* Check if the error is "stale", i.e. the topologyVersion refers to an
+ * older
+ * version of the server than we have stored in the topology description.
+ */
+ _find_topology_version (reply, &incoming_topology_version);
+ if (mongoc_server_description_topology_version_cmp (
+ &sd->topology_version, &incoming_topology_version) >= 0) {
+ /* The server description is greater or equal, ignore the error. */
+ bson_destroy (&incoming_topology_version);
+ return false;
+ }
+ /* Overwrite the topology version. */
+ mongoc_server_description_set_topology_version (
+ sd, &incoming_topology_version);
+ bson_destroy (&incoming_topology_version);
+
+ /* SDAM: When handling a "not master" or "node is recovering" error, the
+ * client MUST clear the server's connection pool if and only if the error
+ * is "node is shutting down" or the error originated from server version
+ * < 4.2.
+ */
+ if (max_wire_version <= WIRE_VERSION_4_0 ||
+ _mongoc_error_is_shutdown (&cmd_error)) {
+ _mongoc_topology_clear_connection_pool (topology, server_id);
+ pool_cleared = true;
+ }
+
+ /* SDAM: When the client sees a "not master" or "node is recovering" error
+ * and the error's topologyVersion is strictly greater than the current
+ * ServerDescription's topologyVersion it MUST replace the server's
+ * description with a ServerDescription of type Unknown. */
+ mongoc_topology_description_invalidate_server (
+ &topology->description, server_id, &cmd_error);
+
+ if (topology->single_threaded) {
+ /* SDAM: For single-threaded clients, in the case of a "not master" or
+ * "node is shutting down" error, the client MUST mark the topology as
+ * "stale"
+ */
+ if (_mongoc_error_is_not_master (&cmd_error)) {
+ topology->stale = true;
+ }
+ } else {
+ /* SDAM Spec: "Multi-threaded and asynchronous clients MUST request an
+ * immediate check of the server."
+ * Instead of requesting a check of the one server, request a scan
+ * to all servers (to find the new primary).
+ */
+ _mongoc_topology_request_scan (topology);
+ }
+ }
+ return pool_cleared;
+}
+
+/* Called from application threads
+ * Caller must hold topology lock.
+ * Locks topology description mutex to copy out server description errors.
+ * For single-threaded monitoring, the topology scanner may include errors for
+ * servers that were removed from the topology.
+ */
+static void
+_topology_collect_errors (mongoc_topology_t *topology, bson_error_t *error_out)
+{
+ mongoc_topology_description_t *topology_description;
+ mongoc_server_description_t *server_description;
+ bson_string_t *error_message;
+ int i;
+
+ topology_description = &topology->description;
+ memset (error_out, 0, sizeof (bson_error_t));
+ error_message = bson_string_new ("");
+
+ for (i = 0; i < topology_description->servers->items_len; i++) {
+ bson_error_t *error;
+
+ server_description = topology_description->servers->items[i].item;
+ error = &server_description->error;
+ if (error->code) {
+ if (error_message->len > 0) {
+ bson_string_append_c (error_message, ' ');
+ }
+ bson_string_append_printf (
+ error_message, "[%s]", server_description->error.message);
+ /* The last error's code and domain wins. */
+ error_out->code = error->code;
+ error_out->domain = error->domain;
+ }
+ }
+
+ bson_strncpy ((char *) &error_out->message,
+ error_message->str,
+ sizeof (error_out->message));
+ bson_string_free (error_message, true);
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h
similarity index 77%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h
index 8fb5a38f..6774b934 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h
@@ -1,118 +1,136 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_TRACE_PRIVATE_H
#define MONGOC_TRACE_PRIVATE_H
#include <bson/bson.h>
#include <ctype.h>
#include "mongoc-log.h"
#include "mongoc-log-private.h"
BSON_BEGIN_DECLS
#ifdef MONGOC_TRACE
#define TRACE(msg, ...) \
do { \
mongoc_log (MONGOC_LOG_LEVEL_TRACE, \
MONGOC_LOG_DOMAIN, \
"TRACE: %s():%d " msg, \
BSON_FUNC, \
__LINE__, \
__VA_ARGS__); \
} while (0)
#define ENTRY \
do { \
mongoc_log (MONGOC_LOG_LEVEL_TRACE, \
MONGOC_LOG_DOMAIN, \
"ENTRY: %s():%d", \
BSON_FUNC, \
__LINE__); \
} while (0)
#define EXIT \
do { \
mongoc_log (MONGOC_LOG_LEVEL_TRACE, \
MONGOC_LOG_DOMAIN, \
" EXIT: %s():%d", \
BSON_FUNC, \
__LINE__); \
return; \
} while (0)
#define RETURN(ret) \
do { \
mongoc_log (MONGOC_LOG_LEVEL_TRACE, \
MONGOC_LOG_DOMAIN, \
" EXIT: %s():%d", \
BSON_FUNC, \
__LINE__); \
return ret; \
} while (0)
#define GOTO(label) \
do { \
mongoc_log (MONGOC_LOG_LEVEL_TRACE, \
MONGOC_LOG_DOMAIN, \
" GOTO: %s():%d %s", \
BSON_FUNC, \
__LINE__, \
#label); \
goto label; \
} while (0)
#define DUMP_BYTES(_n, _b, _l) \
do { \
mongoc_log (MONGOC_LOG_LEVEL_TRACE, \
MONGOC_LOG_DOMAIN, \
"TRACE: %s():%d %s = %p [%d]", \
BSON_FUNC, \
__LINE__, \
#_n, \
_b, \
(int) _l); \
mongoc_log_trace_bytes (MONGOC_LOG_DOMAIN, _b, _l); \
} while (0)
+#define DUMP_BSON(_bson) \
+ do { \
+ char *_bson_str; \
+ if (_bson) { \
+ _bson_str = bson_as_canonical_extended_json (_bson, NULL); \
+ } else { \
+ _bson_str = bson_strdup ("<NULL>"); \
+ } \
+ mongoc_log (MONGOC_LOG_LEVEL_TRACE, \
+ MONGOC_LOG_DOMAIN, \
+ "TRACE: %s():%d %s = %s", \
+ BSON_FUNC, \
+ __LINE__, \
+ #_bson, \
+ _bson_str); \
+ bson_free (_bson_str); \
+ } while (0)
#define DUMP_IOVEC(_n, _iov, _iovcnt) \
do { \
mongoc_log (MONGOC_LOG_LEVEL_TRACE, \
MONGOC_LOG_DOMAIN, \
"TRACE: %s():%d %s = %p [%d]", \
BSON_FUNC, \
__LINE__, \
#_n, \
- _iov, \
+ (void *) _iov, \
(int) _iovcnt); \
mongoc_log_trace_iovec (MONGOC_LOG_DOMAIN, _iov, _iovcnt); \
} while (0)
#else
-#define TRACE(msg, ...)
+#define TRACE(msg, ...) (void) 0
#define ENTRY
#define EXIT return
#define RETURN(ret) return ret
#define GOTO(label) goto label
#define DUMP_BYTES(_n, _b, _l)
#define DUMP_IOVEC(_n, _iov, _iovcnt)
+#define DUMP_BSON(_bson)
#endif
BSON_END_DECLS
#endif /* MONGOC_TRACE_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h
similarity index 74%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h
index beda21b3..e00f6edf 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h
@@ -1,63 +1,82 @@
/*
* Copyright 2015 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_URI_PRIVATE_H
#define MONGOC_URI_PRIVATE_H
#include "mongoc-uri.h"
+#include "mongoc-scram-private.h"
+#include "mongoc-crypto-private.h"
BSON_BEGIN_DECLS
bool
mongoc_uri_upsert_host_and_port (mongoc_uri_t *uri,
const char *host_and_port,
bson_error_t *error);
bool
mongoc_uri_upsert_host (mongoc_uri_t *uri,
const char *host,
uint16_t port,
bson_error_t *error);
void
mongoc_uri_remove_host (mongoc_uri_t *uri, const char *host, uint16_t port);
bool
mongoc_uri_parse_host (mongoc_uri_t *uri, const char *str);
bool
mongoc_uri_parse_options (mongoc_uri_t *uri,
const char *str,
bool from_dns,
bson_error_t *error);
int32_t
mongoc_uri_get_local_threshold_option (const mongoc_uri_t *uri);
bool
_mongoc_uri_requires_auth_negotiation (const mongoc_uri_t *uri);
const char *
mongoc_uri_canonicalize_option (const char *key);
mongoc_uri_t *
_mongoc_uri_copy_and_replace_host_list (const mongoc_uri_t *original,
const char *host);
+bool
+mongoc_uri_init_with_srv_host_list (mongoc_uri_t *uri,
+ mongoc_host_list_t *hosts,
+ bson_error_t *error);
+
+bool
+mongoc_uri_validate_srv_result (const mongoc_uri_t *uri,
+ const char *host,
+ bson_error_t *error);
+
+#ifdef MONGOC_ENABLE_CRYPTO
+void
+_mongoc_uri_init_scram (const mongoc_uri_t *uri,
+ mongoc_scram_t *scram,
+ mongoc_crypto_hash_algorithm_t algo);
+#endif
+
BSON_END_DECLS
#endif /* MONGOC_URI_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c
similarity index 89%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c
index 8617e513..8b5402d0 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c
@@ -1,2934 +1,3110 @@
/*
* Copyright 2013 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.
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <math.h>
/* strcasecmp on windows */
#include "mongoc-util-private.h"
#include "mongoc-config.h"
#include "mongoc-host-list.h"
#include "mongoc-host-list-private.h"
#include "mongoc-log.h"
#include "mongoc-handshake-private.h"
#include "mongoc-socket.h"
#include "mongoc-topology-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-compression-private.h"
#include "utlist.h"
struct _mongoc_uri_t {
char *str;
bool is_srv;
char srv[BSON_HOST_NAME_MAX + 1];
mongoc_host_list_t *hosts;
char *username;
char *password;
char *database;
bson_t raw; /* Unparsed options, see mongoc_uri_parse_options */
bson_t options; /* Type-coerced and canonicalized options */
bson_t credentials;
bson_t compressors;
mongoc_read_prefs_t *read_prefs;
mongoc_read_concern_t *read_concern;
mongoc_write_concern_t *write_concern;
};
#define MONGOC_URI_ERROR(error, format, ...) \
bson_set_error (error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
format, \
__VA_ARGS__);
static const char *escape_instructions = "Percent-encode username and password"
" according to RFC 3986";
static bool
_mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri,
const char *option,
int32_t value);
static bool
_mongoc_uri_set_option_as_int32_with_error (mongoc_uri_t *uri,
const char *option,
int32_t value,
bson_error_t *error);
static bool
_mongoc_uri_set_option_as_int64_with_error (mongoc_uri_t *uri,
const char *option,
int64_t value,
bson_error_t *error);
static bool
ends_with (const char *str, const char *suffix);
static void
mongoc_uri_do_unescape (char **str)
{
char *tmp;
if ((tmp = *str)) {
*str = mongoc_uri_unescape (tmp);
bson_free (tmp);
}
}
#define VALIDATE_SRV_ERR() \
do { \
bson_set_error (error, \
MONGOC_ERROR_STREAM, \
MONGOC_ERROR_STREAM_NAME_RESOLUTION, \
"Invalid host \"%s\" returned for service \"%s\": " \
"host must be subdomain of service name", \
host, \
service); \
return false; \
} while (0)
static int
count_dots (const char *s)
{
int n = 0;
const char *dot = s;
while ((dot = strchr (dot + 1, '.'))) {
n++;
}
return n;
}
+static char *
+lowercase_str_new (const char *key)
+{
+ char *ret = bson_strdup (key);
+ mongoc_lowercase (key, ret);
+ return ret;
+}
/* at least one character, and does not start with dot */
static bool
valid_hostname (const char *s)
{
size_t len = strlen (s);
return len > 1 && s[0] != '.';
}
-static bool
-validate_srv_result (mongoc_uri_t *uri, const char *host, bson_error_t *error)
+bool
+mongoc_uri_validate_srv_result (const mongoc_uri_t *uri,
+ const char *host,
+ bson_error_t *error)
{
const char *service;
const char *service_root;
service = mongoc_uri_get_service (uri);
BSON_ASSERT (service);
if (!valid_hostname (host)) {
VALIDATE_SRV_ERR ();
}
service_root = strchr (service, '.');
BSON_ASSERT (service_root);
/* host must be descendent of service root: if service is
* "a.foo.co" host can be like "a.foo.co", "b.foo.co", "a.b.foo.co", etc.
*/
if (strlen (host) < strlen (service_root)) {
VALIDATE_SRV_ERR ();
}
if (!ends_with (host, service_root)) {
VALIDATE_SRV_ERR ();
}
return true;
}
-/* upsert @host into @uri's host list. Side effect: modifies host->next when
- * inserting. */
+/* copy and upsert @host into @uri's host list. */
static bool
_upsert_into_host_list (mongoc_uri_t *uri,
mongoc_host_list_t *host,
bson_error_t *error)
{
- if (uri->is_srv && !validate_srv_result (uri, host->host, error)) {
+ if (uri->is_srv &&
+ !mongoc_uri_validate_srv_result (uri, host->host, error)) {
return false;
}
_mongoc_host_list_upsert (&uri->hosts, host);
return true;
}
bool
mongoc_uri_upsert_host_and_port (mongoc_uri_t *uri,
const char *host_and_port,
bson_error_t *error)
{
mongoc_host_list_t temp;
memset (&temp, 0, sizeof (mongoc_host_list_t));
if (!_mongoc_host_list_from_string_with_err (&temp, host_and_port, error)) {
return false;
}
return _upsert_into_host_list (uri, &temp, error);
}
bool
mongoc_uri_upsert_host (mongoc_uri_t *uri,
const char *host,
uint16_t port,
bson_error_t *error)
{
mongoc_host_list_t temp;
memset (&temp, 0, sizeof (mongoc_host_list_t));
if (!_mongoc_host_list_from_hostport_with_err (&temp, host, port, error)) {
return false;
}
return _upsert_into_host_list (uri, &temp, error);
}
void
mongoc_uri_remove_host (mongoc_uri_t *uri, const char *host, uint16_t port)
{
_mongoc_host_list_remove_host (&(uri->hosts), host, port);
}
/*
*--------------------------------------------------------------------------
*
* scan_to_unichar --
*
* Scans 'str' until either a character matching 'match' is found,
* until one of the characters in 'terminators' is encountered, or
* until we reach the end of 'str'.
*
* NOTE: 'terminators' may not include multibyte UTF-8 characters.
*
* Returns:
* If 'match' is found, returns a copy of the section of 'str' before
* that character. Otherwise, returns NULL.
*
* Side Effects:
* If 'match' is found, sets 'end' to begin at the matching character
* in 'str'.
*
*--------------------------------------------------------------------------
*/
static char *
scan_to_unichar (const char *str,
bson_unichar_t match,
const char *terminators,
const char **end)
{
bson_unichar_t c;
const char *iter;
for (iter = str; iter && *iter && (c = bson_utf8_get_char (iter));
iter = bson_utf8_next_char (iter)) {
if (c == match) {
*end = iter;
return bson_strndup (str, iter - str);
} else if (c == '\\') {
iter = bson_utf8_next_char (iter);
if (!bson_utf8_get_char (iter)) {
break;
}
} else {
const char *term_iter;
for (term_iter = terminators; *term_iter; term_iter++) {
if (c == *term_iter) {
return NULL;
}
}
}
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* ends_with --
*
* Return true if str ends with suffix.
*
*--------------------------------------------------------------------------
*/
static bool
ends_with (const char *str, const char *suffix)
{
size_t str_len = strlen (str);
size_t suffix_len = strlen (suffix);
const char *s1, *s2;
if (str_len < suffix_len) {
return false;
}
/* start at the ends of both strings */
s1 = str + str_len;
s2 = suffix + suffix_len;
/* until either pointer reaches start of its string, compare the pointers */
for (; s1 >= str && s2 >= suffix; s1--, s2--) {
if (*s1 != *s2) {
return false;
}
}
return true;
}
static bool
mongoc_uri_parse_scheme (mongoc_uri_t *uri, const char *str, const char **end)
{
if (!strncmp (str, "mongodb+srv://", 14)) {
uri->is_srv = true;
*end = str + 14;
return true;
}
if (!strncmp (str, "mongodb://", 10)) {
uri->is_srv = false;
*end = str + 10;
return true;
}
return false;
}
static bool
mongoc_uri_has_unescaped_chars (const char *str, const char *chars)
{
const char *c;
const char *tmp;
char *s;
for (c = chars; *c; c++) {
s = scan_to_unichar (str, (bson_unichar_t) *c, "", &tmp);
if (s) {
bson_free (s);
return true;
}
}
return false;
}
/* "str" is non-NULL, the part of URI between "mongodb://" and first "@" */
static bool
mongoc_uri_parse_userpass (mongoc_uri_t *uri,
const char *str,
bson_error_t *error)
{
const char *prohibited = "@:/";
const char *end_user;
BSON_ASSERT (str);
BSON_ASSERT (uri);
if ((uri->username = scan_to_unichar (str, ':', "", &end_user))) {
uri->password = bson_strdup (end_user + 1);
} else {
uri->username = bson_strdup (str);
uri->password = NULL;
}
if (mongoc_uri_has_unescaped_chars (uri->username, prohibited)) {
MONGOC_URI_ERROR (error,
"Username \"%s\" must not have unescaped chars. %s",
uri->username,
escape_instructions);
return false;
}
mongoc_uri_do_unescape (&uri->username);
if (!uri->username) {
MONGOC_URI_ERROR (
error, "Incorrect URI escapes in username. %s", escape_instructions);
return false;
}
/* Providing password at all is optional */
if (uri->password) {
if (mongoc_uri_has_unescaped_chars (uri->password, prohibited)) {
MONGOC_URI_ERROR (error,
"Password \"%s\" must not have unescaped chars. %s",
uri->password,
escape_instructions);
return false;
}
mongoc_uri_do_unescape (&uri->password);
if (!uri->password) {
MONGOC_URI_ERROR (error, "%s", "Incorrect URI escapes in password");
return false;
}
}
return true;
}
bool
mongoc_uri_parse_host (mongoc_uri_t *uri, const char *host_and_port_in)
{
char *host_and_port = bson_strdup (host_and_port_in);
bson_error_t err = {0};
bool r;
/* unescape host. It doesn't hurt including port. */
if (mongoc_uri_has_unescaped_chars (host_and_port, "/")) {
MONGOC_WARNING ("Unix Domain Sockets must be escaped (e.g. / = %%2F)");
bson_free (host_and_port);
return false;
}
mongoc_uri_do_unescape (&host_and_port);
if (!host_and_port) {
/* invalid */
bson_free (host_and_port);
return false;
}
r = mongoc_uri_upsert_host_and_port (uri, host_and_port, &err);
if (!r) {
MONGOC_ERROR ("%s", err.message);
bson_free (host_and_port);
return false;
}
bson_free (host_and_port);
return true;
}
bool
mongoc_uri_parse_srv (mongoc_uri_t *uri, const char *str)
{
char *service;
if (*str == '\0') {
return false;
}
service = bson_strdup (str);
mongoc_uri_do_unescape (&service);
if (!service) {
/* invalid */
return false;
}
if (!valid_hostname (service) || count_dots (service) < 2) {
bson_free (service);
return false;
}
bson_strncpy (uri->srv, service, sizeof uri->srv);
bson_free (service);
if (strchr (uri->srv, ',') || strchr (uri->srv, ':')) {
/* prohibit port number or multiple service names */
return false;
}
return true;
}
/* "hosts" is non-NULL, the part between "mongodb://" or "@" and last "/" */
static bool
mongoc_uri_parse_hosts (mongoc_uri_t *uri, const char *hosts)
{
const char *next;
const char *end_hostport;
char *s;
BSON_ASSERT (hosts);
/*
* Parsing the series of hosts is a lot more complicated than you might
* imagine. This is due to some characters being both separators as well as
* valid characters within the "hostname". In particularly, we can have file
* paths to specify paths to UNIX domain sockets. We impose the restriction
* that they must be suffixed with ".sock" to simplify the parsing.
*
* You can separate hosts and file system paths to UNIX domain sockets with
* ",".
*/
s = scan_to_unichar (hosts, '?', "", &end_hostport);
if (s) {
MONGOC_WARNING (
"%s", "A '/' is required between the host list and any options.");
goto error;
}
next = hosts;
do {
/* makes a copy of the section of the string */
s = scan_to_unichar (next, ',', "", &end_hostport);
if (s) {
next = (char *) end_hostport + 1;
} else {
s = bson_strdup (next);
next = NULL;
}
if (!mongoc_uri_parse_host (uri, s)) {
goto error;
}
bson_free (s);
} while (next);
return true;
error:
bson_free (s);
return false;
}
/* -----------------------------------------------------------------------------
*
* mongoc_uri_parse_database --
*
* Parse the database after @str. @str is expected to point after the
* host list to the character immediately after the / in the uri string.
* If no database is specified in the uri, e.g. the uri has a form like:
* mongodb://localhost/?option=X then uri->database remains NULL after
* parsing.
*
* Return:
* True if the parsed database is valid. An empty database is considered
* valid.
* -----------------------------------------------------------------------------
*/
static bool
mongoc_uri_parse_database (mongoc_uri_t *uri, const char *str, const char **end)
{
const char *end_database;
const char *c;
char *invalid_c;
const char *tmp;
if ((uri->database = scan_to_unichar (str, '?', "", &end_database))) {
if (strcmp (uri->database, "") == 0) {
/* no database is found, don't store the empty string. */
bson_free (uri->database);
uri->database = NULL;
/* but it is valid to have an empty database. */
return true;
}
*end = end_database;
} else if (*str) {
uri->database = bson_strdup (str);
*end = str + strlen (str);
}
mongoc_uri_do_unescape (&uri->database);
if (!uri->database) {
/* invalid */
return false;
}
/* invalid characters in database name */
for (c = "/\\. \"$"; *c; c++) {
invalid_c =
scan_to_unichar (uri->database, (bson_unichar_t) *c, "", &tmp);
if (invalid_c) {
bson_free (invalid_c);
return false;
}
}
return true;
}
static bool
mongoc_uri_parse_auth_mechanism_properties (mongoc_uri_t *uri, const char *str)
{
char *field;
char *value;
const char *end_scan;
bson_t properties;
bson_init (&properties);
/* build up the properties document */
while ((field = scan_to_unichar (str, ':', "&", &end_scan))) {
str = end_scan + 1;
if (!(value = scan_to_unichar (str, ',', ":&", &end_scan))) {
value = bson_strdup (str);
str = "";
} else {
str = end_scan + 1;
}
bson_append_utf8 (&properties, field, -1, value, -1);
bson_free (field);
bson_free (value);
}
/* append our auth properties to our credentials */
if (!mongoc_uri_set_mechanism_properties (uri, &properties)) {
bson_destroy (&properties);
return false;
}
bson_destroy (&properties);
return true;
}
static bool
mongoc_uri_parse_tags (mongoc_uri_t *uri, /* IN */
const char *str) /* IN */
{
const char *end_keyval;
const char *end_key;
bson_t b;
char *keyval;
char *key;
bson_init (&b);
again:
if ((keyval = scan_to_unichar (str, ',', "", &end_keyval))) {
if (!(key = scan_to_unichar (keyval, ':', "", &end_key))) {
bson_free (keyval);
goto fail;
}
bson_append_utf8 (&b, key, -1, end_key + 1, -1);
bson_free (key);
bson_free (keyval);
str = end_keyval + 1;
goto again;
} else if ((key = scan_to_unichar (str, ':', "", &end_key))) {
bson_append_utf8 (&b, key, -1, end_key + 1, -1);
bson_free (key);
} else if (strlen (str)) {
/* we're not finished but we couldn't parse the string */
goto fail;
}
mongoc_read_prefs_add_tag (uri->read_prefs, &b);
bson_destroy (&b);
return true;
fail:
MONGOC_WARNING ("Unsupported value for \"" MONGOC_URI_READPREFERENCETAGS
"\": \"%s\"",
str);
bson_destroy (&b);
return false;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_bson_append_or_replace_key --
*
*
* Appends 'option' to the end of 'options' if not already set.
*
* Since we cannot grow utf8 strings inline, we have to allocate a
* temporary bson variable and splice in the new value if the key
* is already set.
*
* NOTE: This function keeps the order of the BSON keys.
*
* NOTE: 'option' is case*in*sensitive.
*
*
*--------------------------------------------------------------------------
*/
static void
mongoc_uri_bson_append_or_replace_key (bson_t *options,
const char *option,
const char *value)
{
bson_iter_t iter;
bool found = false;
if (bson_iter_init (&iter, options)) {
bson_t tmp = BSON_INITIALIZER;
while (bson_iter_next (&iter)) {
const bson_value_t *bvalue;
if (!strcasecmp (bson_iter_key (&iter), option)) {
bson_append_utf8 (&tmp, option, -1, value, -1);
found = true;
continue;
}
bvalue = bson_iter_value (&iter);
BSON_APPEND_VALUE (&tmp, bson_iter_key (&iter), bvalue);
}
if (!found) {
bson_append_utf8 (&tmp, option, -1, value, -1);
}
bson_destroy (options);
bson_copy_to (&tmp, options);
bson_destroy (&tmp);
}
}
+bool
+mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key)
+{
+ bson_iter_t iter;
+
+ return bson_iter_init_find_case (&iter, &uri->options, key);
+}
+
bool
mongoc_uri_option_is_int32 (const char *key)
{
return mongoc_uri_option_is_int64 (key) ||
!strcasecmp (key, MONGOC_URI_CONNECTTIMEOUTMS) ||
!strcasecmp (key, MONGOC_URI_HEARTBEATFREQUENCYMS) ||
!strcasecmp (key, MONGOC_URI_SERVERSELECTIONTIMEOUTMS) ||
!strcasecmp (key, MONGOC_URI_SOCKETCHECKINTERVALMS) ||
!strcasecmp (key, MONGOC_URI_SOCKETTIMEOUTMS) ||
!strcasecmp (key, MONGOC_URI_LOCALTHRESHOLDMS) ||
!strcasecmp (key, MONGOC_URI_MAXPOOLSIZE) ||
!strcasecmp (key, MONGOC_URI_MAXSTALENESSSECONDS) ||
!strcasecmp (key, MONGOC_URI_MINPOOLSIZE) ||
!strcasecmp (key, MONGOC_URI_MAXIDLETIMEMS) ||
!strcasecmp (key, MONGOC_URI_WAITQUEUEMULTIPLE) ||
!strcasecmp (key, MONGOC_URI_WAITQUEUETIMEOUTMS) ||
!strcasecmp (key, MONGOC_URI_ZLIBCOMPRESSIONLEVEL);
}
bool
mongoc_uri_option_is_int64 (const char *key)
{
return !strcasecmp (key, MONGOC_URI_WTIMEOUTMS);
}
bool
mongoc_uri_option_is_bool (const char *key)
{
return !strcasecmp (key, MONGOC_URI_CANONICALIZEHOSTNAME) ||
+ !strcasecmp (key, MONGOC_URI_DIRECTCONNECTION) ||
!strcasecmp (key, MONGOC_URI_JOURNAL) ||
!strcasecmp (key, MONGOC_URI_RETRYREADS) ||
!strcasecmp (key, MONGOC_URI_RETRYWRITES) ||
!strcasecmp (key, MONGOC_URI_SAFE) ||
!strcasecmp (key, MONGOC_URI_SERVERSELECTIONTRYONCE) ||
!strcasecmp (key, MONGOC_URI_SLAVEOK) ||
!strcasecmp (key, MONGOC_URI_TLS) ||
!strcasecmp (key, MONGOC_URI_TLSINSECURE) ||
!strcasecmp (key, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) ||
!strcasecmp (key, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES) ||
+ !strcasecmp (key, MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK) ||
+ !strcasecmp (key, MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK) ||
/* deprecated options */
!strcasecmp (key, MONGOC_URI_SSL) ||
!strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES) ||
!strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES);
}
bool
mongoc_uri_option_is_utf8 (const char *key)
{
return !strcasecmp (key, MONGOC_URI_APPNAME) ||
!strcasecmp (key, MONGOC_URI_REPLICASET) ||
!strcasecmp (key, MONGOC_URI_READPREFERENCE) ||
!strcasecmp (key, MONGOC_URI_TLSCERTIFICATEKEYFILE) ||
!strcasecmp (key, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD) ||
!strcasecmp (key, MONGOC_URI_TLSCAFILE) ||
/* deprecated options */
!strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE) ||
!strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD) ||
!strcasecmp (key, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE);
}
const char *
mongoc_uri_canonicalize_option (const char *key)
{
if (!strcasecmp (key, MONGOC_URI_SSL)) {
return MONGOC_URI_TLS;
} else if (!strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE)) {
return MONGOC_URI_TLSCERTIFICATEKEYFILE;
} else if (!strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD)) {
return MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD;
} else if (!strcasecmp (key, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE)) {
return MONGOC_URI_TLSCAFILE;
} else if (!strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES)) {
return MONGOC_URI_TLSALLOWINVALIDCERTIFICATES;
} else if (!strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES)) {
return MONGOC_URI_TLSALLOWINVALIDHOSTNAMES;
} else {
return key;
}
}
static bool
_mongoc_uri_parse_int64 (const char *key, const char *value, int64_t *result)
{
char *endptr;
int64_t i;
errno = 0;
i = bson_ascii_strtoll (value, &endptr, 10);
if (errno || endptr < value + strlen (value)) {
MONGOC_WARNING ("Invalid %s: cannot parse integer\n", key);
return false;
}
*result = i;
return true;
}
static bool
mongoc_uri_parse_int32 (const char *key, const char *value, int32_t *result)
{
int64_t i;
if (!_mongoc_uri_parse_int64 (key, value, &i)) {
/* _mongoc_uri_parse_int64 emits a warning if it could not parse the
* given value, so we don't have to add one here.
*/
return false;
}
if (i > INT32_MAX || i < INT32_MIN) {
MONGOC_WARNING ("Invalid %s: cannot fit in int32\n", key);
return false;
}
*result = (int32_t) i;
return true;
}
static bool
dns_option_allowed (const char *lkey)
{
/* Initial DNS Seedlist Discovery Spec: "A Client MUST only support the
* authSource and replicaSet options through a TXT record, and MUST raise an
* error if any other option is encountered."
*/
return !strcmp (lkey, MONGOC_URI_AUTHSOURCE) ||
!strcmp (lkey, MONGOC_URI_REPLICASET);
}
/* Decompose a key=val pair and place them into a document.
* Includes case-folding for key portion.
*/
static bool
mongoc_uri_split_option (mongoc_uri_t *uri,
bson_t *options,
const char *str,
bool from_dns,
bson_error_t *error)
{
bson_iter_t iter;
const char *end_key;
char *key = NULL;
char *lkey = NULL;
char *value = NULL;
const char *opt;
char *opt_end;
size_t opt_len;
bool ret = false;
if (!(key = scan_to_unichar (str, '=', "", &end_key))) {
MONGOC_URI_ERROR (error, "URI option \"%s\" contains no \"=\" sign", str);
goto CLEANUP;
}
value = bson_strdup (end_key + 1);
mongoc_uri_do_unescape (&value);
if (!value) {
/* do_unescape detected invalid UTF-8 and freed value */
MONGOC_URI_ERROR (
error, "Value for URI option \"%s\" contains invalid UTF-8", key);
goto CLEANUP;
}
lkey = bson_strdup (key);
mongoc_lowercase (key, lkey);
/* Initial DNS Seedlist Discovery Spec: "A Client MUST only support the
* authSource and replicaSet options through a TXT record, and MUST raise an
* error if any other option is encountered."*/
if (from_dns && !dns_option_allowed (lkey)) {
MONGOC_URI_ERROR (
error, "URI option \"%s\" prohibited in TXT record", key);
goto CLEANUP;
}
/* Special case: READPREFERENCETAGS is a composing option.
* Multiple instances should append, not overwrite.
* Encode them directly to the options field,
* bypassing canonicalization and duplicate checks.
*/
if (!strcmp (lkey, MONGOC_URI_READPREFERENCETAGS)) {
if (!mongoc_uri_parse_tags (uri, value)) {
MONGOC_URI_ERROR (
error, "Unsupported value for \"%s\": \"%s\"", key, value);
goto CLEANUP;
}
} else if (bson_iter_init_find (&iter, &uri->raw, lkey) ||
bson_iter_init_find (&iter, options, lkey)) {
/* Special case, MONGOC_URI_W == "any non-int" is not overridden
* by later values.
*/
if (!strcmp (lkey, MONGOC_URI_W) &&
(opt = bson_iter_utf8_unsafe (&iter, &opt_len))) {
strtol (opt, &opt_end, 10);
if (*opt_end != '\0') {
ret = true;
goto CLEANUP;
}
}
/* Initial DNS Seedlist Discovery Spec: "Client MUST use options
* specified in the Connection String to override options provided
* through TXT records." So, do NOT override existing options with TXT
* options. */
if (from_dns) {
MONGOC_WARNING (
"Cannot override URI option \"%s\" from TXT record \"%s\"",
key,
str);
ret = true;
goto CLEANUP;
}
MONGOC_WARNING ("Overwriting previously provided value for '%s'", key);
}
if (!(strcmp (lkey, MONGOC_URI_REPLICASET)) && *value == '\0') {
MONGOC_URI_ERROR (
error, "Value for URI option \"%s\" cannot be empty string", lkey);
goto CLEANUP;
}
mongoc_uri_bson_append_or_replace_key (options, lkey, value);
ret = true;
CLEANUP:
bson_free (key);
bson_free (lkey);
bson_free (value);
return ret;
}
/* Check for canonical/deprecated conflicts
* between the option list a, and b.
* If both names exist either way with differing values, error.
*/
static bool
mongoc_uri_options_validate_names (const bson_t *a,
const bson_t *b,
bson_error_t *error)
{
bson_iter_t key_iter, canon_iter;
const char *key = NULL;
const char *canon = NULL;
const char *value = NULL;
const char *cval = NULL;
size_t value_len = 0;
size_t cval_len = 0;
/* Scan `a` looking for deprecated names
* where the canonical name was also used in `a`,
* or was used in `b`. */
bson_iter_init (&key_iter, a);
while (bson_iter_next (&key_iter)) {
key = bson_iter_key (&key_iter);
value = bson_iter_utf8_unsafe (&key_iter, &value_len);
canon = mongoc_uri_canonicalize_option (key);
if (key == canon) {
/* Canonical form, no point checking `b`. */
continue;
}
/* Check for a conflict in `a`. */
if (bson_iter_init_find (&canon_iter, a, canon)) {
cval = bson_iter_utf8_unsafe (&canon_iter, &cval_len);
if ((value_len != cval_len) || strcmp (value, cval)) {
goto HANDLE_CONFLICT;
}
}
/* Check for a conflict in `b`. */
if (bson_iter_init_find (&canon_iter, b, canon)) {
cval = bson_iter_utf8_unsafe (&canon_iter, &cval_len);
if ((value_len != cval_len) || strcmp (value, cval)) {
goto HANDLE_CONFLICT;
}
}
}
return true;
HANDLE_CONFLICT:
MONGOC_URI_ERROR (error,
"Deprecated option '%s=%s' conflicts with "
"canonical name '%s=%s'",
key,
value,
canon,
cval);
return false;
}
#define HANDLE_DUPE() \
if (from_dns) { \
MONGOC_WARNING ("Cannot override URI option \"%s\" from TXT record", \
key); \
continue; \
} else { \
MONGOC_WARNING ("Overwriting previously provided value for '%s'", key); \
}
static bool
mongoc_uri_apply_options (mongoc_uri_t *uri,
const bson_t *options,
bool from_dns,
bson_error_t *error)
{
bson_iter_t iter;
int32_t v_int;
int64_t v_int64;
const char *key = NULL;
const char *canon = NULL;
const char *value = NULL;
size_t value_len;
bool bval;
bson_iter_init (&iter, options);
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
canon = mongoc_uri_canonicalize_option (key);
value = bson_iter_utf8_unsafe (&iter, &value_len);
/* Keep a record of how the option was originally presented. */
mongoc_uri_bson_append_or_replace_key (&uri->raw, key, value);
/* This check precedes mongoc_uri_option_is_int32 as all 64-bit values are
* also recognised as 32-bit ints.
*/
if (mongoc_uri_option_is_int64 (key)) {
- if (!_mongoc_uri_parse_int64 (key, value, &v_int64)) {
- goto UNSUPPORTED_VALUE;
- }
+ if (0 < strlen (value)) {
+ if (!_mongoc_uri_parse_int64 (key, value, &v_int64)) {
+ goto UNSUPPORTED_VALUE;
+ }
- if (!_mongoc_uri_set_option_as_int64_with_error (
- uri, canon, v_int64, error)) {
- return false;
+ if (!_mongoc_uri_set_option_as_int64_with_error (
+ uri, canon, v_int64, error)) {
+ return false;
+ }
+ } else {
+ MONGOC_WARNING ("Empty value provided for \"%s\"", key);
}
} else if (mongoc_uri_option_is_int32 (key)) {
- if (!mongoc_uri_parse_int32 (key, value, &v_int)) {
- goto UNSUPPORTED_VALUE;
- }
+ if (0 < strlen (value)) {
+ if (!mongoc_uri_parse_int32 (key, value, &v_int)) {
+ goto UNSUPPORTED_VALUE;
+ }
- if (!_mongoc_uri_set_option_as_int32_with_error (
- uri, canon, v_int, error)) {
- return false;
+ if (!_mongoc_uri_set_option_as_int32_with_error (
+ uri, canon, v_int, error)) {
+ return false;
+ }
+ } else {
+ MONGOC_WARNING ("Empty value provided for \"%s\"", key);
}
} else if (!strcmp (key, MONGOC_URI_W)) {
if (*value == '-' || isdigit (*value)) {
v_int = (int) strtol (value, NULL, 10);
_mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_W, v_int);
} else if (0 == strcasecmp (value, "majority")) {
mongoc_uri_bson_append_or_replace_key (
&uri->options, MONGOC_URI_W, "majority");
} else if (*value) {
mongoc_uri_bson_append_or_replace_key (
&uri->options, MONGOC_URI_W, value);
}
} else if (mongoc_uri_option_is_bool (key)) {
- if (0 == strcasecmp (value, "true")) {
- bval = true;
- } else if (0 == strcasecmp (value, "false")) {
- bval = false;
- } else if ((0 == strcmp (value, "1")) ||
- (0 == strcasecmp (value, "yes")) ||
- (0 == strcasecmp (value, "y")) ||
- (0 == strcasecmp (value, "t"))) {
- MONGOC_WARNING ("Deprecated boolean value for \"%s\": \"%s\", "
- "please update to \"%s=true\"",
- key,
- value,
- key);
- bval = true;
- } else if ((0 == strcasecmp (value, "0")) ||
- (0 == strcasecmp (value, "-1")) ||
- (0 == strcmp (value, "no")) || (0 == strcmp (value, "n")) ||
- (0 == strcmp (value, "f"))) {
- MONGOC_WARNING ("Deprecated boolean value for \"%s\": \"%s\", "
- "please update to \"%s=false\"",
- key,
- value,
- key);
- bval = false;
- } else {
- goto UNSUPPORTED_VALUE;
- }
+ if (0 < strlen (value)) {
+ if (0 == strcasecmp (value, "true")) {
+ bval = true;
+ } else if (0 == strcasecmp (value, "false")) {
+ bval = false;
+ } else if ((0 == strcmp (value, "1")) ||
+ (0 == strcasecmp (value, "yes")) ||
+ (0 == strcasecmp (value, "y")) ||
+ (0 == strcasecmp (value, "t"))) {
+ MONGOC_WARNING ("Deprecated boolean value for \"%s\": \"%s\", "
+ "please update to \"%s=true\"",
+ key,
+ value,
+ key);
+ bval = true;
+ } else if ((0 == strcasecmp (value, "0")) ||
+ (0 == strcasecmp (value, "-1")) ||
+ (0 == strcmp (value, "no")) ||
+ (0 == strcmp (value, "n")) ||
+ (0 == strcmp (value, "f"))) {
+ MONGOC_WARNING ("Deprecated boolean value for \"%s\": \"%s\", "
+ "please update to \"%s=false\"",
+ key,
+ value,
+ key);
+ bval = false;
+ } else {
+ goto UNSUPPORTED_VALUE;
+ }
- if (!mongoc_uri_set_option_as_bool (uri, canon, bval)) {
- return false;
+ if (!mongoc_uri_set_option_as_bool (uri, canon, bval)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "Failed to set %s to %d",
+ canon, bval);
+ return false;
+ }
+ } else {
+ MONGOC_WARNING ("Empty value provided for \"%s\"", key);
}
} else if (!strcmp (key, MONGOC_URI_READPREFERENCETAGS)) {
/* Skip this option here.
* It was marshalled during mongoc_uri_split_option()
* as a special case composing option.
*/
} else if (!strcmp (key, MONGOC_URI_AUTHMECHANISM) ||
!strcmp (key, MONGOC_URI_AUTHSOURCE)) {
if (bson_has_field (&uri->credentials, key)) {
HANDLE_DUPE ();
}
mongoc_uri_bson_append_or_replace_key (
&uri->credentials, canon, value);
} else if (!strcmp (key, MONGOC_URI_READCONCERNLEVEL)) {
if (!mongoc_read_concern_is_default (uri->read_concern)) {
HANDLE_DUPE ();
}
mongoc_read_concern_set_level (uri->read_concern, value);
} else if (!strcmp (key, MONGOC_URI_GSSAPISERVICENAME)) {
char *tmp = bson_strdup_printf ("SERVICE_NAME:%s", value);
if (bson_has_field (&uri->credentials,
MONGOC_URI_AUTHMECHANISMPROPERTIES)) {
MONGOC_WARNING ("authMechanismProperties SERVICE_NAME already set, "
"ignoring '%s'",
key);
} else if (!mongoc_uri_parse_auth_mechanism_properties (uri, tmp)) {
bson_free (tmp);
goto UNSUPPORTED_VALUE;
}
bson_free (tmp);
} else if (!strcmp (key, MONGOC_URI_AUTHMECHANISMPROPERTIES)) {
if (bson_has_field (&uri->credentials, key)) {
HANDLE_DUPE ();
}
if (!mongoc_uri_parse_auth_mechanism_properties (uri, value)) {
goto UNSUPPORTED_VALUE;
}
} else if (!strcmp (key, MONGOC_URI_APPNAME)) {
/* Part of uri->options */
if (!mongoc_uri_set_appname (uri, value)) {
goto UNSUPPORTED_VALUE;
}
} else if (!strcmp (key, MONGOC_URI_COMPRESSORS)) {
if (!bson_empty (mongoc_uri_get_compressors (uri))) {
HANDLE_DUPE ();
}
if (!mongoc_uri_set_compressors (uri, value)) {
goto UNSUPPORTED_VALUE;
}
} else if (mongoc_uri_option_is_utf8 (key)) {
mongoc_uri_bson_append_or_replace_key (&uri->options, canon, value);
} else {
/*
* Keys that aren't supported by a driver MUST be ignored.
*
* A WARN level logging message MUST be issued
* https://github.com/mongodb/specifications/blob/master/source/connection-string/connection-string-spec.rst#keys
*/
MONGOC_WARNING ("Unsupported URI option \"%s\"", key);
}
}
return true;
UNSUPPORTED_VALUE:
MONGOC_URI_ERROR (error, "Unsupported value for \"%s\": \"%s\"", key, value);
return false;
}
/* Processes a query string formatted set of driver options
* (i.e. tls=true&connectTimeoutMS=250 ) into a BSON dict of values.
* uri->raw is initially populated with the raw split of key/value pairs,
* then the keys are canonicalized and the values coerced
* to their appropriate type and stored in uri->options.
*/
bool
mongoc_uri_parse_options (mongoc_uri_t *uri,
const char *str,
bool from_dns,
bson_error_t *error)
{
bson_t options;
const char *end_option;
char *option;
bson_init (&options);
while ((option = scan_to_unichar (str, '&', "", &end_option))) {
if (!mongoc_uri_split_option (uri, &options, option, from_dns, error)) {
bson_free (option);
bson_destroy (&options);
return false;
}
bson_free (option);
str = end_option + 1;
}
if (*str && !mongoc_uri_split_option (uri, &options, str, from_dns, error)) {
bson_destroy (&options);
return false;
}
/* Walk both sides of this map to handle each ordering:
* deprecated first canonical later, and vice-versa.
* Then finalize parse by writing final values to uri->options.
*/
if (!mongoc_uri_options_validate_names (&uri->options, &options, error) ||
!mongoc_uri_options_validate_names (&options, &uri->options, error) ||
!mongoc_uri_apply_options (uri, &options, from_dns, error)) {
bson_destroy (&options);
return false;
}
bson_destroy (&options);
return true;
}
static bool
mongoc_uri_finalize_tls (mongoc_uri_t *uri, bson_error_t *error)
{
/* Initial DNS Seedlist Discovery Spec: "If mongodb+srv is used, a driver
* MUST implicitly also enable TLS." */
if (uri->is_srv && !bson_has_field (&uri->options, MONGOC_URI_TLS)) {
mongoc_uri_set_option_as_bool (uri, MONGOC_URI_TLS, true);
}
+ /* tlsInsecure implies tlsAllowInvalidCertificates, tlsAllowInvalidHostnames,
+ * tlsDisableOCSPEndpointCheck, and tlsDisableCertificateRevocationCheck, so
+ * consider it an error to have both. The user might have the wrong idea. */
if (bson_has_field (&uri->options, MONGOC_URI_TLSINSECURE) &&
(bson_has_field (&uri->options,
MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) ||
- bson_has_field (&uri->options, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES))) {
+ bson_has_field (&uri->options, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES) ||
+ bson_has_field (&uri->options,
+ MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK) ||
+ bson_has_field (&uri->options,
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK))) {
MONGOC_URI_ERROR (error,
- "%s may not be specified with %s or %s",
+ "%s may not be specified with %s, %s, %s, or %s",
MONGOC_URI_TLSINSECURE,
MONGOC_URI_TLSALLOWINVALIDCERTIFICATES,
- MONGOC_URI_TLSALLOWINVALIDHOSTNAMES);
+ MONGOC_URI_TLSALLOWINVALIDHOSTNAMES,
+ MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK,
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK);
+ return false;
+ }
+
+ /* tlsAllowInvalidCertificates implies tlsDisableOCSPEndpointCheck and
+ * tlsDisableCertificateRevocationCheck, so consider it an error to have
+ * both. The user might have the wrong idea. */
+ if (bson_has_field (&uri->options, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) &&
+ (bson_has_field (&uri->options,
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK) ||
+ bson_has_field (&uri->options,
+ MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK))) {
+ MONGOC_URI_ERROR (error,
+ "%s may not be specified with %s or %s",
+ MONGOC_URI_TLSALLOWINVALIDCERTIFICATES,
+ MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK,
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK);
+ return false;
+ }
+
+ /* tlsDisableCertificateRevocationCheck implies tlsDisableOCSPEndpointCheck,
+ * so consider it an error to have both. The user might have the wrong idea.
+ */
+ if (bson_has_field (&uri->options,
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK) &&
+ bson_has_field (&uri->options, MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK)) {
+ MONGOC_URI_ERROR (error,
+ "%s may not be specified with %s",
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK,
+ MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK);
return false;
}
return true;
}
static bool
mongoc_uri_finalize_auth (mongoc_uri_t *uri,
bson_error_t *error,
bool require_auth)
{
bson_iter_t iter;
const char *source = NULL;
if (bson_iter_init_find_case (
&iter, &uri->credentials, MONGOC_URI_AUTHSOURCE)) {
source = bson_iter_utf8 (&iter, NULL);
require_auth = true;
}
if (mongoc_uri_get_auth_mechanism (uri)) {
/* authSource with GSSAPI or X509 should always be external */
if (!strcasecmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI") ||
!strcasecmp (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509")) {
if (source) {
if (strcasecmp (source, "$external")) {
MONGOC_URI_ERROR (
error,
"%s",
"GSSAPI and X509 require \"$external\" authSource");
return false;
}
} else {
bson_append_utf8 (
&uri->credentials, MONGOC_URI_AUTHSOURCE, -1, "$external", -1);
}
}
- /* MONGODB-X509 is the only mechanism that doesn't require username */
- if (strcasecmp (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509") !=
- 0) {
+ /* MONGODB-X509 and MONGODB-AWS are the only mechanisms that don't require
+ * username */
+ if (!(strcasecmp (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509") ==
+ 0 ||
+ strcasecmp (mongoc_uri_get_auth_mechanism (uri), "MONGODB-AWS") ==
+ 0)) {
if (!mongoc_uri_get_username (uri) ||
strcmp (mongoc_uri_get_username (uri), "") == 0) {
MONGOC_URI_ERROR (error,
"'%s' authentication mechanism requires username",
mongoc_uri_get_auth_mechanism (uri));
return false;
}
}
/* MONGODB-X509 errors if a password is supplied. */
if (strcasecmp (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509") ==
0) {
if (mongoc_uri_get_password (uri)) {
MONGOC_URI_ERROR (
error,
"'%s' authentication mechanism does not accept a password",
mongoc_uri_get_auth_mechanism (uri));
return false;
}
}
/* GSSAPI uses 'mongodb' as the default service name */
if (strcasecmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI") == 0 &&
!(bson_iter_init_find (
&iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES) &&
BSON_ITER_HOLDS_DOCUMENT (&iter) &&
bson_iter_recurse (&iter, &iter) &&
bson_iter_find_case (&iter, "SERVICE_NAME"))) {
bson_t tmp;
bson_t *props = NULL;
props = mongoc_uri_get_mechanism_properties (uri, &tmp)
? bson_copy (&tmp)
: bson_new ();
BSON_APPEND_UTF8 (props, "SERVICE_NAME", "mongodb");
mongoc_uri_set_mechanism_properties (uri, props);
bson_destroy (props);
}
} else if (require_auth) /* Default auth mechanism is used */ {
if (!mongoc_uri_get_username (uri) ||
strcmp (mongoc_uri_get_username (uri), "") == 0) {
MONGOC_URI_ERROR (
error, "%s", "Default authentication mechanism requires username");
return false;
}
}
return true;
}
+static bool
+mongoc_uri_finalize_directconnection (mongoc_uri_t *uri, bson_error_t *error)
+{
+ bool directconnection = false;
+
+ directconnection =
+ mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
+ if (!directconnection) {
+ return true;
+ }
+
+ /* URI options spec: "The driver MUST report an error if the
+ * directConnection=true URI option is specified with an SRV URI, because
+ * the URI may resolve to multiple hosts. The driver MUST allow specifying
+ * directConnection=false URI option with an SRV URI." */
+ if (uri->is_srv) {
+ MONGOC_URI_ERROR (
+ error, "%s", "SRV URI not allowed with directConnection option");
+ return false;
+ }
+
+ /* URI options spec: "The driver MUST report an error if the
+ * directConnection=true URI option is specified with multiple seeds." */
+ if (uri->hosts && uri->hosts->next) {
+ MONGOC_URI_ERROR (
+ error,
+ "%s",
+ "Multiple seeds not allowed with directConnection option");
+ return false;
+ }
+
+ return true;
+}
+
static bool
mongoc_uri_parse_before_slash (mongoc_uri_t *uri,
const char *before_slash,
bson_error_t *error)
{
char *userpass;
const char *hosts;
userpass = scan_to_unichar (before_slash, '@', "", &hosts);
if (userpass) {
if (!mongoc_uri_parse_userpass (uri, userpass, error)) {
goto error;
}
hosts++; /* advance past "@" */
if (*hosts == '@') {
/* special case: "mongodb://alice@@localhost" */
MONGOC_URI_ERROR (
error, "Invalid username or password. %s", escape_instructions);
goto error;
}
} else {
hosts = before_slash;
}
if (uri->is_srv) {
if (!mongoc_uri_parse_srv (uri, hosts)) {
MONGOC_URI_ERROR (error, "%s", "Invalid service name in URI");
goto error;
}
} else {
if (!mongoc_uri_parse_hosts (uri, hosts)) {
MONGOC_URI_ERROR (error, "%s", "Invalid host string in URI");
goto error;
}
}
bson_free (userpass);
return true;
error:
bson_free (userpass);
return false;
}
static bool
mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error)
{
char *before_slash = NULL;
const char *tmp;
bool require_auth = false;
if (!bson_utf8_validate (str, strlen (str), false /* allow_null */)) {
MONGOC_URI_ERROR (error, "%s", "Invalid UTF-8 in URI");
goto error;
}
if (!mongoc_uri_parse_scheme (uri, str, &str)) {
MONGOC_URI_ERROR (
error,
"%s",
"Invalid URI Schema, expecting 'mongodb://' or 'mongodb+srv://'");
goto error;
}
before_slash = scan_to_unichar (str, '/', "", &tmp);
if (!before_slash) {
before_slash = bson_strdup (str);
str += strlen (before_slash);
} else {
str = tmp;
}
if (!mongoc_uri_parse_before_slash (uri, before_slash, error)) {
goto error;
}
if (*str) {
if (*str == '/') {
str++;
if (*str) {
if (!mongoc_uri_parse_database (uri, str, &str)) {
MONGOC_URI_ERROR (error, "%s", "Invalid database name in URI");
goto error;
}
}
if (*str == '?') {
str++;
if (*str) {
if (!mongoc_uri_parse_options (
uri, str, false /* from DNS */, error)) {
goto error;
}
}
}
} else {
MONGOC_URI_ERROR (error, "%s", "Expected end of hostname delimiter");
goto error;
}
}
if (!mongoc_uri_finalize_tls (uri, error)) {
goto error;
}
require_auth = uri->username != NULL;
if (!mongoc_uri_finalize_auth (uri, error, require_auth)) {
goto error;
}
+ if (!mongoc_uri_finalize_directconnection (uri, error)) {
+ goto error;
+ }
+
bson_free (before_slash);
return true;
error:
bson_free (before_slash);
return false;
}
const mongoc_host_list_t *
mongoc_uri_get_hosts (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return uri->hosts;
}
const char *
mongoc_uri_get_replica_set (const mongoc_uri_t *uri)
{
bson_iter_t iter;
BSON_ASSERT (uri);
if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_REPLICASET) &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
return bson_iter_utf8 (&iter, NULL);
}
return NULL;
}
const bson_t *
mongoc_uri_get_credentials (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return &uri->credentials;
}
const char *
mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri)
{
bson_iter_t iter;
BSON_ASSERT (uri);
if (bson_iter_init_find_case (
&iter, &uri->credentials, MONGOC_URI_AUTHMECHANISM) &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
return bson_iter_utf8 (&iter, NULL);
}
return NULL;
}
bool
mongoc_uri_set_auth_mechanism (mongoc_uri_t *uri, const char *value)
{
size_t len;
BSON_ASSERT (value);
len = strlen (value);
if (!bson_utf8_validate (value, len, false)) {
return false;
}
mongoc_uri_bson_append_or_replace_key (
&uri->credentials, MONGOC_URI_AUTHMECHANISM, value);
return true;
}
bool
mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri,
bson_t *properties /* OUT */)
{
bson_iter_t iter;
BSON_ASSERT (uri);
BSON_ASSERT (properties);
if (bson_iter_init_find_case (
&iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES) &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
uint32_t len = 0;
const uint8_t *data = NULL;
bson_iter_document (&iter, &len, &data);
BSON_ASSERT (bson_init_static (properties, data, len));
return true;
}
return false;
}
bool
mongoc_uri_set_mechanism_properties (mongoc_uri_t *uri,
const bson_t *properties)
{
bson_iter_t iter;
bson_t tmp = BSON_INITIALIZER;
bool r;
BSON_ASSERT (uri);
BSON_ASSERT (properties);
if (bson_iter_init_find (
&iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES)) {
/* copy all elements to tmp besides authMechanismProperties */
bson_copy_to_excluding_noinit (&uri->credentials,
&tmp,
MONGOC_URI_AUTHMECHANISMPROPERTIES,
(char *) NULL);
r = BSON_APPEND_DOCUMENT (
&tmp, MONGOC_URI_AUTHMECHANISMPROPERTIES, properties);
if (!r) {
bson_destroy (&tmp);
return false;
}
bson_destroy (&uri->credentials);
bson_copy_to (&tmp, &uri->credentials);
bson_destroy (&tmp);
return true;
} else {
bson_destroy (&tmp);
return BSON_APPEND_DOCUMENT (
&uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES, properties);
}
}
static bool
_mongoc_uri_assign_read_prefs_mode (mongoc_uri_t *uri, bson_error_t *error)
{
const char *str;
bson_iter_t iter;
BSON_ASSERT (uri);
if (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_SLAVEOK, false)) {
mongoc_read_prefs_set_mode (uri->read_prefs,
MONGOC_READ_SECONDARY_PREFERRED);
}
if (bson_iter_init_find_case (
&iter, &uri->options, MONGOC_URI_READPREFERENCE) &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
str = bson_iter_utf8 (&iter, NULL);
if (0 == strcasecmp ("primary", str)) {
mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_PRIMARY);
} else if (0 == strcasecmp ("primarypreferred", str)) {
mongoc_read_prefs_set_mode (uri->read_prefs,
MONGOC_READ_PRIMARY_PREFERRED);
} else if (0 == strcasecmp ("secondary", str)) {
mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_SECONDARY);
} else if (0 == strcasecmp ("secondarypreferred", str)) {
mongoc_read_prefs_set_mode (uri->read_prefs,
MONGOC_READ_SECONDARY_PREFERRED);
} else if (0 == strcasecmp ("nearest", str)) {
mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_NEAREST);
} else {
MONGOC_URI_ERROR (
error, "Unsupported readPreference value [readPreference=%s]", str);
return false;
}
}
return true;
}
static bool
_mongoc_uri_build_write_concern (mongoc_uri_t *uri, bson_error_t *error)
{
mongoc_write_concern_t *write_concern;
const char *str;
bson_iter_t iter;
int64_t wtimeoutms;
int value;
BSON_ASSERT (uri);
write_concern = mongoc_write_concern_new ();
uri->write_concern = write_concern;
if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_SAFE) &&
BSON_ITER_HOLDS_BOOL (&iter)) {
mongoc_write_concern_set_w (
write_concern,
bson_iter_bool (&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
}
wtimeoutms = mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 0);
if (wtimeoutms < 0) {
MONGOC_URI_ERROR (
error, "Unsupported wtimeoutMS value [w=%" PRId64 "]", wtimeoutms);
return false;
} else if (wtimeoutms > 0) {
mongoc_write_concern_set_wtimeout_int64 (write_concern, wtimeoutms);
}
if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_JOURNAL) &&
BSON_ITER_HOLDS_BOOL (&iter)) {
mongoc_write_concern_set_journal (write_concern, bson_iter_bool (&iter));
}
if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_W)) {
if (BSON_ITER_HOLDS_INT32 (&iter)) {
value = bson_iter_int32 (&iter);
switch (value) {
case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED:
case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED:
if (mongoc_write_concern_get_journal (write_concern)) {
MONGOC_URI_ERROR (
error, "Journal conflicts with w value [w=%d]", value);
return false;
}
mongoc_write_concern_set_w (write_concern, value);
break;
default:
if (value > 0) {
mongoc_write_concern_set_w (write_concern, value);
break;
}
MONGOC_URI_ERROR (error, "Unsupported w value [w=%d]", value);
return false;
}
} else if (BSON_ITER_HOLDS_UTF8 (&iter)) {
str = bson_iter_utf8 (&iter, NULL);
if (0 == strcasecmp ("majority", str)) {
mongoc_write_concern_set_w (write_concern,
MONGOC_WRITE_CONCERN_W_MAJORITY);
} else {
mongoc_write_concern_set_wtag (write_concern, str);
}
} else {
BSON_ASSERT (false);
return false;
}
}
return true;
}
/* can't use mongoc_uri_get_option_as_int32, it treats 0 specially */
static int32_t
_mongoc_uri_get_max_staleness_option (const mongoc_uri_t *uri)
{
const bson_t *options;
bson_iter_t iter;
int32_t retval = MONGOC_NO_MAX_STALENESS;
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (
&iter, options, MONGOC_URI_MAXSTALENESSSECONDS) &&
BSON_ITER_HOLDS_INT32 (&iter)) {
retval = bson_iter_int32 (&iter);
if (retval == 0) {
MONGOC_WARNING (
"Unsupported value for \"" MONGOC_URI_MAXSTALENESSSECONDS
"\": \"%d\"",
retval);
retval = -1;
} else if (retval < 0 && retval != -1) {
MONGOC_WARNING (
"Unsupported value for \"" MONGOC_URI_MAXSTALENESSSECONDS
"\": \"%d\"",
retval);
retval = MONGOC_NO_MAX_STALENESS;
}
}
return retval;
}
mongoc_uri_t *
mongoc_uri_new_with_error (const char *uri_string, bson_error_t *error)
{
mongoc_uri_t *uri;
int32_t max_staleness_seconds;
uri = (mongoc_uri_t *) bson_malloc0 (sizeof *uri);
bson_init (&uri->raw);
bson_init (&uri->options);
bson_init (&uri->credentials);
bson_init (&uri->compressors);
/* Initialize read_prefs, since parsing may add to it */
uri->read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
/* Initialize empty read_concern */
uri->read_concern = mongoc_read_concern_new ();
if (!uri_string) {
uri_string = "mongodb://127.0.0.1/";
}
if (!mongoc_uri_parse (uri, uri_string, error)) {
mongoc_uri_destroy (uri);
return NULL;
}
uri->str = bson_strdup (uri_string);
if (!_mongoc_uri_assign_read_prefs_mode (uri, error)) {
mongoc_uri_destroy (uri);
return NULL;
}
max_staleness_seconds = _mongoc_uri_get_max_staleness_option (uri);
mongoc_read_prefs_set_max_staleness_seconds (uri->read_prefs,
max_staleness_seconds);
if (!mongoc_read_prefs_is_valid (uri->read_prefs)) {
mongoc_uri_destroy (uri);
MONGOC_URI_ERROR (error, "%s", "Invalid readPreferences");
return NULL;
}
if (!_mongoc_uri_build_write_concern (uri, error)) {
mongoc_uri_destroy (uri);
return NULL;
}
if (!mongoc_write_concern_is_valid (uri->write_concern)) {
mongoc_uri_destroy (uri);
MONGOC_URI_ERROR (error, "%s", "Invalid writeConcern");
return NULL;
}
return uri;
}
mongoc_uri_t *
mongoc_uri_new (const char *uri_string)
{
bson_error_t error = {0};
mongoc_uri_t *uri;
uri = mongoc_uri_new_with_error (uri_string, &error);
if (error.domain) {
MONGOC_WARNING ("Error parsing URI: '%s'", error.message);
}
return uri;
}
mongoc_uri_t *
mongoc_uri_new_for_host_port (const char *hostname, uint16_t port)
{
mongoc_uri_t *uri;
char *str;
BSON_ASSERT (hostname);
BSON_ASSERT (port);
str = bson_strdup_printf ("mongodb://%s:%hu/", hostname, port);
uri = mongoc_uri_new (str);
bson_free (str);
return uri;
}
const char *
mongoc_uri_get_username (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return uri->username;
}
bool
mongoc_uri_set_username (mongoc_uri_t *uri, const char *username)
{
size_t len;
BSON_ASSERT (username);
len = strlen (username);
if (!bson_utf8_validate (username, len, false)) {
return false;
}
if (uri->username) {
bson_free (uri->username);
}
uri->username = bson_strdup (username);
return true;
}
const char *
mongoc_uri_get_password (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return uri->password;
}
bool
mongoc_uri_set_password (mongoc_uri_t *uri, const char *password)
{
size_t len;
BSON_ASSERT (password);
len = strlen (password);
if (!bson_utf8_validate (password, len, false)) {
return false;
}
if (uri->password) {
bson_free (uri->password);
}
uri->password = bson_strdup (password);
return true;
}
const char *
mongoc_uri_get_database (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return uri->database;
}
bool
mongoc_uri_set_database (mongoc_uri_t *uri, const char *database)
{
size_t len;
BSON_ASSERT (database);
len = strlen (database);
if (!bson_utf8_validate (database, len, false)) {
return false;
}
if (uri->database) {
bson_free (uri->database);
}
uri->database = bson_strdup (database);
return true;
}
const char *
mongoc_uri_get_auth_source (const mongoc_uri_t *uri)
{
bson_iter_t iter;
const char *mechanism;
BSON_ASSERT (uri);
if (bson_iter_init_find_case (
&iter, &uri->credentials, MONGOC_URI_AUTHSOURCE)) {
return bson_iter_utf8 (&iter, NULL);
}
/* Auth spec:
* "For GSSAPI and MONGODB-X509 authMechanisms the authSource defaults to
* $external. For PLAIN the authSource defaults to the database name if
* supplied on the connection string or $external. For MONGODB-CR,
* SCRAM-SHA-1 and SCRAM-SHA-256 authMechanisms, the authSource defaults to
* the database name if supplied on the connection string or admin."
*/
mechanism = mongoc_uri_get_auth_mechanism (uri);
if (mechanism) {
if (!strcasecmp (mechanism, "GSSAPI") ||
!strcasecmp (mechanism, "MONGODB-X509")) {
return "$external";
}
if (!strcasecmp (mechanism, "PLAIN")) {
return uri->database ? uri->database : "$external";
}
}
return uri->database ? uri->database : "admin";
}
bool
mongoc_uri_set_auth_source (mongoc_uri_t *uri, const char *value)
{
size_t len;
BSON_ASSERT (value);
len = strlen (value);
if (!bson_utf8_validate (value, len, false)) {
return false;
}
mongoc_uri_bson_append_or_replace_key (
&uri->credentials, MONGOC_URI_AUTHSOURCE, value);
return true;
}
const char *
mongoc_uri_get_appname (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_APPNAME, NULL);
}
bool
mongoc_uri_set_appname (mongoc_uri_t *uri, const char *value)
{
BSON_ASSERT (value);
if (!bson_utf8_validate (value, strlen (value), false)) {
return false;
}
if (!_mongoc_handshake_appname_is_valid (value)) {
return false;
}
mongoc_uri_bson_append_or_replace_key (
&uri->options, MONGOC_URI_APPNAME, value);
return true;
}
bool
mongoc_uri_set_compressors (mongoc_uri_t *uri, const char *value)
{
const char *end_compressor;
char *entry;
bson_destroy (&uri->compressors);
bson_init (&uri->compressors);
if (value && !bson_utf8_validate (value, strlen (value), false)) {
return false;
}
while ((entry = scan_to_unichar (value, ',', "", &end_compressor))) {
if (mongoc_compressor_supported (entry)) {
mongoc_uri_bson_append_or_replace_key (
&uri->compressors, entry, "yes");
} else {
MONGOC_WARNING ("Unsupported compressor: '%s'", entry);
}
value = end_compressor + 1;
bson_free (entry);
}
if (value) {
if (mongoc_compressor_supported (value)) {
mongoc_uri_bson_append_or_replace_key (
&uri->compressors, value, "yes");
} else {
MONGOC_WARNING ("Unsupported compressor: '%s'", value);
}
}
return true;
}
const bson_t *
mongoc_uri_get_compressors (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return &uri->compressors;
}
/* can't use mongoc_uri_get_option_as_int32, it treats 0 specially */
int32_t
mongoc_uri_get_local_threshold_option (const mongoc_uri_t *uri)
{
const bson_t *options;
bson_iter_t iter;
int32_t retval = MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS;
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, "localthresholdms") &&
BSON_ITER_HOLDS_INT32 (&iter)) {
retval = bson_iter_int32 (&iter);
if (retval < 0) {
MONGOC_WARNING ("Invalid localThresholdMS: %d", retval);
retval = MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS;
}
}
return retval;
}
const char *
mongoc_uri_get_service (const mongoc_uri_t *uri)
{
if (uri->is_srv) {
return uri->srv;
}
return NULL;
}
const bson_t *
mongoc_uri_get_options (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return &uri->options;
}
void
mongoc_uri_destroy (mongoc_uri_t *uri)
{
if (uri) {
_mongoc_host_list_destroy_all (uri->hosts);
bson_free (uri->str);
bson_free (uri->database);
bson_free (uri->username);
bson_destroy (&uri->raw);
bson_destroy (&uri->options);
bson_destroy (&uri->credentials);
bson_destroy (&uri->compressors);
mongoc_read_prefs_destroy (uri->read_prefs);
mongoc_read_concern_destroy (uri->read_concern);
mongoc_write_concern_destroy (uri->write_concern);
if (uri->password) {
bson_zero_free (uri->password, strlen (uri->password));
}
bson_free (uri);
}
}
mongoc_uri_t *
mongoc_uri_copy (const mongoc_uri_t *uri)
{
mongoc_uri_t *copy;
mongoc_host_list_t *iter;
bson_error_t error;
BSON_ASSERT (uri);
copy = (mongoc_uri_t *) bson_malloc0 (sizeof (*copy));
copy->str = bson_strdup (uri->str);
copy->is_srv = uri->is_srv;
bson_strncpy (copy->srv, uri->srv, sizeof uri->srv);
copy->username = bson_strdup (uri->username);
copy->password = bson_strdup (uri->password);
copy->database = bson_strdup (uri->database);
copy->read_prefs = mongoc_read_prefs_copy (uri->read_prefs);
copy->read_concern = mongoc_read_concern_copy (uri->read_concern);
copy->write_concern = mongoc_write_concern_copy (uri->write_concern);
LL_FOREACH (uri->hosts, iter)
{
if (!mongoc_uri_upsert_host (copy, iter->host, iter->port, &error)) {
MONGOC_ERROR ("%s", error.message);
mongoc_uri_destroy (copy);
return NULL;
}
}
bson_copy_to (&uri->raw, &copy->raw);
bson_copy_to (&uri->options, &copy->options);
bson_copy_to (&uri->credentials, &copy->credentials);
bson_copy_to (&uri->compressors, &copy->compressors);
return copy;
}
const char *
mongoc_uri_get_string (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return uri->str;
}
const bson_t *
mongoc_uri_get_read_prefs (const mongoc_uri_t *uri)
{
BSON_ASSERT (uri);
return mongoc_read_prefs_get_tags (uri->read_prefs);
}
char *
mongoc_uri_unescape (const char *escaped_string)
{
bson_unichar_t c;
bson_string_t *str;
unsigned int hex = 0;
const char *ptr;
const char *end;
size_t len;
bool unescape_occurred = false;
BSON_ASSERT (escaped_string);
len = strlen (escaped_string);
/*
* Double check that this is a UTF-8 valid string. Bail out if necessary.
*/
if (!bson_utf8_validate (escaped_string, len, false)) {
MONGOC_WARNING ("%s(): escaped_string contains invalid UTF-8", BSON_FUNC);
return NULL;
}
ptr = escaped_string;
end = ptr + len;
str = bson_string_new (NULL);
for (; *ptr; ptr = bson_utf8_next_char (ptr)) {
c = bson_utf8_get_char (ptr);
switch (c) {
case '%':
if (((end - ptr) < 2) || !isxdigit (ptr[1]) || !isxdigit (ptr[2]) ||
#ifdef _MSC_VER
(1 != sscanf_s (&ptr[1], "%02x", &hex))
#else
(1 != sscanf (&ptr[1], "%02x", &hex))
#endif
- || 0 == hex) {
+ ||
+ 0 == hex) {
bson_string_free (str, true);
MONGOC_WARNING ("Invalid %% escape sequence");
return NULL;
}
bson_string_append_c (str, hex);
ptr += 2;
unescape_occurred = true;
break;
default:
bson_string_append_unichar (str, c);
break;
}
}
/* Check that after unescaping, it is still valid UTF-8 */
if (unescape_occurred && !bson_utf8_validate (str->str, str->len, false)) {
- MONGOC_WARNING ("Invalid %% escape sequence: unescaped string contains invalid UTF-8");
+ MONGOC_WARNING (
+ "Invalid %% escape sequence: unescaped string contains invalid UTF-8");
bson_string_free (str, true);
return NULL;
}
return bson_string_free (str, false);
}
const mongoc_read_prefs_t *
mongoc_uri_get_read_prefs_t (const mongoc_uri_t *uri) /* IN */
{
BSON_ASSERT (uri);
return uri->read_prefs;
}
void
mongoc_uri_set_read_prefs_t (mongoc_uri_t *uri,
const mongoc_read_prefs_t *prefs)
{
BSON_ASSERT (uri);
BSON_ASSERT (prefs);
mongoc_read_prefs_destroy (uri->read_prefs);
uri->read_prefs = mongoc_read_prefs_copy (prefs);
}
const mongoc_read_concern_t *
mongoc_uri_get_read_concern (const mongoc_uri_t *uri) /* IN */
{
BSON_ASSERT (uri);
return uri->read_concern;
}
void
mongoc_uri_set_read_concern (mongoc_uri_t *uri, const mongoc_read_concern_t *rc)
{
BSON_ASSERT (uri);
BSON_ASSERT (rc);
mongoc_read_concern_destroy (uri->read_concern);
uri->read_concern = mongoc_read_concern_copy (rc);
}
const mongoc_write_concern_t *
mongoc_uri_get_write_concern (const mongoc_uri_t *uri) /* IN */
{
BSON_ASSERT (uri);
return uri->write_concern;
}
void
mongoc_uri_set_write_concern (mongoc_uri_t *uri,
const mongoc_write_concern_t *wc)
{
BSON_ASSERT (uri);
BSON_ASSERT (wc);
mongoc_write_concern_destroy (uri->write_concern);
uri->write_concern = mongoc_write_concern_copy (wc);
}
bool
mongoc_uri_get_tls (const mongoc_uri_t *uri) /* IN */
{
bson_iter_t iter;
BSON_ASSERT (uri);
if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_TLS) &&
BSON_ITER_HOLDS_BOOL (&iter)) {
return bson_iter_bool (&iter);
}
if (bson_iter_init_find_case (
&iter, &uri->options, MONGOC_URI_TLSCERTIFICATEKEYFILE) ||
bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_TLSCAFILE) ||
bson_iter_init_find_case (
&iter, &uri->options, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) ||
bson_iter_init_find_case (
&iter, &uri->options, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES) ||
bson_iter_init_find_case (
&iter, &uri->options, MONGOC_URI_TLSINSECURE) ||
bson_iter_init_find_case (
- &iter, &uri->options, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD)) {
+ &iter, &uri->options, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD) ||
+ bson_iter_init_find_case (
+ &iter, &uri->options, MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK) ||
+ bson_iter_init_find_case (
+ &iter,
+ &uri->options,
+ MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK)) {
return true;
}
return false;
}
bool
mongoc_uri_get_ssl (const mongoc_uri_t *uri) /* IN */
{
return mongoc_uri_get_tls (uri);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_get_option_as_int32 --
*
* Checks if the URI 'option' is set and of correct type (int32).
* The special value '0' is considered as "unset".
* This is so users can provide
* sprintf("mongodb://localhost/?option=%d", myvalue) style connection
* strings, and still apply default values.
*
* If not set, or set to invalid type, 'fallback' is returned.
*
* NOTE: 'option' is case*in*sensitive.
*
* Returns:
* The value of 'option' if available as int32 (and not 0), or
* 'fallback'.
*
*--------------------------------------------------------------------------
*/
int32_t
mongoc_uri_get_option_as_int32 (const mongoc_uri_t *uri,
const char *option_orig,
int32_t fallback)
{
const char *option;
const bson_t *options;
bson_iter_t iter;
int64_t retval = 0;
option = mongoc_uri_canonicalize_option (option_orig);
/* BC layer to allow retrieving 32-bit values stored in 64-bit options */
if (mongoc_uri_option_is_int64 (option_orig)) {
retval = mongoc_uri_get_option_as_int64 (uri, option_orig, 0);
if (retval > INT32_MAX || retval < INT32_MIN) {
MONGOC_WARNING ("Cannot read 64-bit value for \"%s\": %" PRId64,
option_orig,
retval);
retval = 0;
}
} else if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, option) &&
BSON_ITER_HOLDS_INT32 (&iter)) {
retval = bson_iter_int32 (&iter);
}
if (!retval) {
retval = fallback;
}
return (int32_t) retval;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_set_option_as_int32 --
*
* Sets a URI option 'after the fact'. Allows users to set individual
* URI options without passing them as a connection string.
*
* Only allows a set of known options to be set.
* @see mongoc_uri_option_is_int32 ().
*
* Does in-place-update of the option BSON if 'option' is already set.
* Appends the option to the end otherwise.
*
* NOTE: If 'option' is already set, and is of invalid type, this
* function will return false.
*
* NOTE: 'option' is case*in*sensitive.
*
* Returns:
* true on successfully setting the option, false on failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri,
const char *option_orig,
int32_t value)
{
const char *option;
bson_error_t error;
bool r;
if (mongoc_uri_option_is_int64 (option_orig)) {
return mongoc_uri_set_option_as_int64 (uri, option_orig, value);
}
option = mongoc_uri_canonicalize_option (option_orig);
if (!mongoc_uri_option_is_int32 (option)) {
MONGOC_WARNING (
"Unsupported value for \"%s\": %d, \"%s\" is not an int32 option",
option_orig,
value,
option);
return false;
}
r = _mongoc_uri_set_option_as_int32_with_error (uri, option, value, &error);
if (!r) {
MONGOC_WARNING ("%s", error.message);
}
return r;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_uri_set_option_as_int32_with_error --
*
* Same as mongoc_uri_set_option_as_int32, with error reporting.
*
* Precondition:
* mongoc_uri_option_is_int32(option) must be true.
*
* Returns:
* true on successfully setting the option, false on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_uri_set_option_as_int32_with_error (mongoc_uri_t *uri,
const char *option_orig,
int32_t value,
bson_error_t *error)
{
const char *option;
const bson_t *options;
bson_iter_t iter;
+ char *option_lowercase = NULL;
option = mongoc_uri_canonicalize_option (option_orig);
/* Server Discovery and Monitoring Spec: "the driver MUST NOT permit users
* to configure it less than minHeartbeatFrequencyMS (500ms)." */
if (!bson_strcasecmp (option, MONGOC_URI_HEARTBEATFREQUENCYMS) &&
value < MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS) {
MONGOC_URI_ERROR (error,
"Invalid \"%s\" of %d: must be at least %d",
option_orig,
value,
MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS);
return false;
}
/* zlib levels are from -1 (default) through 9 (best compression) */
if (!bson_strcasecmp (option, MONGOC_URI_ZLIBCOMPRESSIONLEVEL) &&
(value < -1 || value > 9)) {
MONGOC_URI_ERROR (error,
"Invalid \"%s\" of %d: must be between -1 and 9",
option_orig,
value);
return false;
}
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, option)) {
if (BSON_ITER_HOLDS_INT32 (&iter)) {
bson_iter_overwrite_int32 (&iter, value);
return true;
} else {
MONGOC_URI_ERROR (error,
"Cannot set URI option \"%s\" to %d, it already has "
"a non-32-bit integer value",
option,
value);
return false;
}
}
-
- if (!bson_append_int32 (&uri->options, option, -1, value)) {
+ option_lowercase = lowercase_str_new (option);
+ if (!bson_append_int32 (&uri->options, option_lowercase, -1, value)) {
+ bson_free (option_lowercase);
MONGOC_URI_ERROR (
error, "Failed to set URI option \"%s\" to %d", option_orig, value);
return false;
}
+ bson_free (option_lowercase);
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_uri_set_option_as_int32 --
*
* Same as mongoc_uri_set_option_as_int32, except the option is not
* validated against valid int32 options
*
* Returns:
* true on successfully setting the option, false on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri,
const char *option_orig,
int32_t value)
{
const char *option;
const bson_t *options;
bson_iter_t iter;
+ char *option_lowercase = NULL;
option = mongoc_uri_canonicalize_option (option_orig);
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, option)) {
if (BSON_ITER_HOLDS_INT32 (&iter)) {
bson_iter_overwrite_int32 (&iter, value);
return true;
} else {
return false;
}
}
- bson_append_int32 (&uri->options, option, -1, value);
+ option_lowercase = lowercase_str_new (option);
+ bson_append_int32 (&uri->options, option_lowercase, -1, value);
+ bson_free (option_lowercase);
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_get_option_as_int64 --
*
* Checks if the URI 'option' is set and of correct type (int32 or
* int64).
* The special value '0' is considered as "unset".
* This is so users can provide
* sprintf("mongodb://localhost/?option=%" PRId64, myvalue) style
* connection strings, and still apply default values.
*
* If not set, or set to invalid type, 'fallback' is returned.
*
* NOTE: 'option' is case*in*sensitive.
*
* Returns:
* The value of 'option' if available as int64 or int32 (and not 0), or
* 'fallback'.
*
*--------------------------------------------------------------------------
*/
int64_t
mongoc_uri_get_option_as_int64 (const mongoc_uri_t *uri,
const char *option_orig,
int64_t fallback)
{
const char *option;
const bson_t *options;
bson_iter_t iter;
int64_t retval = fallback;
option = mongoc_uri_canonicalize_option (option_orig);
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, option)) {
if (BSON_ITER_HOLDS_INT (&iter)) {
if (!(retval = bson_iter_as_int64 (&iter))) {
retval = fallback;
}
}
}
return retval;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_set_option_as_int64 --
*
* Sets a URI option 'after the fact'. Allows users to set individual
* URI options without passing them as a connection string.
*
* Only allows a set of known options to be set.
* @see mongoc_uri_option_is_int64 ().
*
* Does in-place-update of the option BSON if 'option' is already set.
* Appends the option to the end otherwise.
*
* NOTE: If 'option' is already set, and is of invalid type, this
* function will return false.
*
* NOTE: 'option' is case*in*sensitive.
*
* Returns:
* true on successfully setting the option, false on failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_uri_set_option_as_int64 (mongoc_uri_t *uri,
const char *option_orig,
int64_t value)
{
const char *option;
bson_error_t error;
bool r;
option = mongoc_uri_canonicalize_option (option_orig);
if (!mongoc_uri_option_is_int64 (option)) {
if (mongoc_uri_option_is_int32 (option_orig)) {
if (value >= INT32_MIN && value <= INT32_MAX) {
MONGOC_WARNING (
"Setting value for 32-bit option \"%s\" through 64-bit method",
option_orig);
return mongoc_uri_set_option_as_int32 (
uri, option_orig, (int32_t) value);
}
MONGOC_WARNING ("Unsupported value for \"%s\": %" PRId64
", \"%s\" is not an int64 option",
option_orig,
value,
option);
return false;
}
}
r = _mongoc_uri_set_option_as_int64_with_error (uri, option, value, &error);
if (!r) {
MONGOC_WARNING ("%s", error.message);
}
return r;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_uri_set_option_as_int64_with_error --
*
* Same as mongoc_uri_set_option_as_int64, with error reporting.
*
* Precondition:
* mongoc_uri_option_is_int64(option) must be true.
*
* Returns:
* true on successfully setting the option, false on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_uri_set_option_as_int64_with_error (mongoc_uri_t *uri,
const char *option_orig,
int64_t value,
bson_error_t *error)
{
const char *option;
const bson_t *options;
bson_iter_t iter;
+ char *option_lowercase = NULL;
option = mongoc_uri_canonicalize_option (option_orig);
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, option)) {
if (BSON_ITER_HOLDS_INT64 (&iter)) {
bson_iter_overwrite_int64 (&iter, value);
return true;
} else {
MONGOC_URI_ERROR (error,
"Cannot set URI option \"%s\" to %" PRId64
", it already has "
"a non-64-bit integer value",
option,
value);
return false;
}
}
- if (!bson_append_int64 (&uri->options, option, -1, value)) {
+ option_lowercase = lowercase_str_new (option);
+ if (!bson_append_int64 (&uri->options, option_lowercase, -1, value)) {
+ bson_free (option_lowercase);
MONGOC_URI_ERROR (error,
"Failed to set URI option \"%s\" to %" PRId64,
option_orig,
value);
return false;
}
-
+ bson_free (option_lowercase);
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_get_option_as_bool --
*
* Checks if the URI 'option' is set and of correct type (bool).
*
* If not set, or set to invalid type, 'fallback' is returned.
*
* NOTE: 'option' is case*in*sensitive.
*
* Returns:
* The value of 'option' if available as bool, or 'fallback'.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri,
const char *option_orig,
bool fallback)
{
const char *option;
const bson_t *options;
bson_iter_t iter;
option = mongoc_uri_canonicalize_option (option_orig);
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, option) &&
BSON_ITER_HOLDS_BOOL (&iter)) {
return bson_iter_bool (&iter);
}
return fallback;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_set_option_as_bool --
*
* Sets a URI option 'after the fact'. Allows users to set individual
* URI options without passing them as a connection string.
*
* Only allows a set of known options to be set.
* @see mongoc_uri_option_is_bool ().
*
* Does in-place-update of the option BSON if 'option' is already set.
* Appends the option to the end otherwise.
*
* NOTE: If 'option' is already set, and is of invalid type, this
* function will return false.
*
* NOTE: 'option' is case*in*sensitive.
*
* Returns:
* true on successfully setting the option, false on failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_uri_set_option_as_bool (mongoc_uri_t *uri,
const char *option_orig,
bool value)
{
const char *option;
+ char *option_lowercase;
const bson_t *options;
bson_iter_t iter;
option = mongoc_uri_canonicalize_option (option_orig);
BSON_ASSERT (option);
if (!mongoc_uri_option_is_bool (option)) {
return false;
}
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, option)) {
if (BSON_ITER_HOLDS_BOOL (&iter)) {
bson_iter_overwrite_bool (&iter, value);
return true;
} else {
return false;
}
}
-
- bson_append_bool (&uri->options, option, -1, value);
+ option_lowercase = lowercase_str_new (option);
+ bson_append_bool (&uri->options, option_lowercase, -1, value);
+ bson_free (option_lowercase);
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_get_option_as_utf8 --
*
* Checks if the URI 'option' is set and of correct type (utf8).
*
* If not set, or set to invalid type, 'fallback' is returned.
*
* NOTE: 'option' is case*in*sensitive.
*
* Returns:
* The value of 'option' if available as utf8, or 'fallback'.
*
*--------------------------------------------------------------------------
*/
const char *
mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri,
const char *option_orig,
const char *fallback)
{
const char *option;
const bson_t *options;
bson_iter_t iter;
option = mongoc_uri_canonicalize_option (option_orig);
if ((options = mongoc_uri_get_options (uri)) &&
bson_iter_init_find_case (&iter, options, option) &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
return bson_iter_utf8 (&iter, NULL);
}
return fallback;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_uri_set_option_as_utf8 --
*
* Sets a URI option 'after the fact'. Allows users to set individual
* URI options without passing them as a connection string.
*
* Only allows a set of known options to be set.
* @see mongoc_uri_option_is_utf8 ().
*
* If the option is not already set, this function will append it to
*the end of the options bson. NOTE: If the option is already set the entire
*options bson will be overwritten, containing the new option=value
*(at the same position).
*
* NOTE: If 'option' is already set, and is of invalid type, this
* function will return false.
*
* NOTE: 'option' must be valid utf8.
*
* NOTE: 'option' is case*in*sensitive.
*
* Returns:
* true on successfully setting the option, false on failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_uri_set_option_as_utf8 (mongoc_uri_t *uri,
const char *option_orig,
const char *value)
{
const char *option;
size_t len;
+ char *option_lowercase = NULL;
option = mongoc_uri_canonicalize_option (option_orig);
BSON_ASSERT (option);
len = strlen (value);
if (!bson_utf8_validate (value, len, false)) {
return false;
}
if (!mongoc_uri_option_is_utf8 (option)) {
return false;
}
if (!bson_strcasecmp (option, MONGOC_URI_APPNAME)) {
return mongoc_uri_set_appname (uri, value);
} else {
- mongoc_uri_bson_append_or_replace_key (&uri->options, option, value);
+ option_lowercase = lowercase_str_new (option);
+ mongoc_uri_bson_append_or_replace_key (
+ &uri->options, option_lowercase, value);
+ bson_free (option_lowercase);
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_uri_requires_auth_negotiation --
*
* Returns true if auth mechanism is necessary for this uri. According
* to the auth spec: "If an application provides a username but does
* not provide an authentication mechanism, drivers MUST negotiate a
* mechanism".
*
* Returns:
* true if the driver should negotiate the auth mechanism for the uri
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_uri_requires_auth_negotiation (const mongoc_uri_t *uri)
{
return mongoc_uri_get_username (uri) && !mongoc_uri_get_auth_mechanism (uri);
}
/* A bit of a hack. Needed for multi mongos tests to create a URI with the same
* auth, SSL, and compressors settings but with only one specific host. */
mongoc_uri_t *
_mongoc_uri_copy_and_replace_host_list (const mongoc_uri_t *original,
const char *host)
{
mongoc_uri_t *uri = mongoc_uri_copy (original);
_mongoc_host_list_destroy_all (uri->hosts);
uri->hosts = bson_malloc0 (sizeof (mongoc_host_list_t));
_mongoc_host_list_from_string (uri->hosts, host);
return uri;
}
+
+bool
+mongoc_uri_init_with_srv_host_list (mongoc_uri_t *uri,
+ mongoc_host_list_t *host_list,
+ bson_error_t *error)
+{
+ mongoc_host_list_t *host;
+
+ BSON_ASSERT (uri->is_srv);
+ BSON_ASSERT (!uri->hosts);
+
+ LL_FOREACH (host_list, host)
+ {
+ if (!mongoc_uri_upsert_host_and_port (uri, host->host_and_port, error)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#ifdef MONGOC_ENABLE_CRYPTO
+void
+_mongoc_uri_init_scram (const mongoc_uri_t *uri,
+ mongoc_scram_t *scram,
+ mongoc_crypto_hash_algorithm_t algo)
+{
+ BSON_ASSERT (uri);
+ BSON_ASSERT (scram);
+
+ _mongoc_scram_init (scram, algo);
+
+ _mongoc_scram_set_pass (scram, mongoc_uri_get_password (uri));
+ _mongoc_scram_set_user (scram, mongoc_uri_get_username (uri));
+}
+#endif
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h
index 4cdd4033..e08b7d43 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h
@@ -1,218 +1,224 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_URI_H
#define MONGOC_URI_H
#include <bson/bson.h>
#include "mongoc-macros.h"
#include "mongoc-host-list.h"
#include "mongoc-read-prefs.h"
#include "mongoc-read-concern.h"
#include "mongoc-write-concern.h"
#include "mongoc-config.h"
#ifndef MONGOC_DEFAULT_PORT
#define MONGOC_DEFAULT_PORT 27017
#endif
#define MONGOC_URI_APPNAME "appname"
#define MONGOC_URI_AUTHMECHANISM "authmechanism"
#define MONGOC_URI_AUTHMECHANISMPROPERTIES "authmechanismproperties"
#define MONGOC_URI_AUTHSOURCE "authsource"
#define MONGOC_URI_CANONICALIZEHOSTNAME "canonicalizehostname"
#define MONGOC_URI_CONNECTTIMEOUTMS "connecttimeoutms"
#define MONGOC_URI_COMPRESSORS "compressors"
+#define MONGOC_URI_DIRECTCONNECTION "directconnection"
#define MONGOC_URI_GSSAPISERVICENAME "gssapiservicename"
#define MONGOC_URI_HEARTBEATFREQUENCYMS "heartbeatfrequencyms"
#define MONGOC_URI_JOURNAL "journal"
#define MONGOC_URI_LOCALTHRESHOLDMS "localthresholdms"
#define MONGOC_URI_MAXIDLETIMEMS "maxidletimems"
#define MONGOC_URI_MAXPOOLSIZE "maxpoolsize"
#define MONGOC_URI_MAXSTALENESSSECONDS "maxstalenessseconds"
#define MONGOC_URI_MINPOOLSIZE "minpoolsize"
#define MONGOC_URI_READCONCERNLEVEL "readconcernlevel"
#define MONGOC_URI_READPREFERENCE "readpreference"
#define MONGOC_URI_READPREFERENCETAGS "readpreferencetags"
#define MONGOC_URI_REPLICASET "replicaset"
#define MONGOC_URI_RETRYREADS "retryreads"
#define MONGOC_URI_RETRYWRITES "retrywrites"
#define MONGOC_URI_SAFE "safe"
#define MONGOC_URI_SERVERSELECTIONTIMEOUTMS "serverselectiontimeoutms"
#define MONGOC_URI_SERVERSELECTIONTRYONCE "serverselectiontryonce"
#define MONGOC_URI_SLAVEOK "slaveok"
#define MONGOC_URI_SOCKETCHECKINTERVALMS "socketcheckintervalms"
#define MONGOC_URI_SOCKETTIMEOUTMS "sockettimeoutms"
#define MONGOC_URI_TLS "tls"
#define MONGOC_URI_TLSCERTIFICATEKEYFILE "tlscertificatekeyfile"
#define MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD "tlscertificatekeyfilepassword"
#define MONGOC_URI_TLSCAFILE "tlscafile"
#define MONGOC_URI_TLSALLOWINVALIDCERTIFICATES "tlsallowinvalidcertificates"
#define MONGOC_URI_TLSALLOWINVALIDHOSTNAMES "tlsallowinvalidhostnames"
#define MONGOC_URI_TLSINSECURE "tlsinsecure"
+#define MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK \
+ "tlsdisablecertificaterevocationcheck"
+#define MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK "tlsdisableocspendpointcheck"
#define MONGOC_URI_W "w"
#define MONGOC_URI_WAITQUEUEMULTIPLE "waitqueuemultiple"
#define MONGOC_URI_WAITQUEUETIMEOUTMS "waitqueuetimeoutms"
#define MONGOC_URI_WTIMEOUTMS "wtimeoutms"
#define MONGOC_URI_ZLIBCOMPRESSIONLEVEL "zlibcompressionlevel"
/* Deprecated in MongoDB 4.2, use "tls" variants instead. */
#define MONGOC_URI_SSL "ssl"
#define MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE "sslclientcertificatekeyfile"
#define MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD \
"sslclientcertificatekeypassword"
#define MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE "sslcertificateauthorityfile"
#define MONGOC_URI_SSLALLOWINVALIDCERTIFICATES "sslallowinvalidcertificates"
#define MONGOC_URI_SSLALLOWINVALIDHOSTNAMES "sslallowinvalidhostnames"
BSON_BEGIN_DECLS
typedef struct _mongoc_uri_t mongoc_uri_t;
MONGOC_EXPORT (mongoc_uri_t *)
mongoc_uri_copy (const mongoc_uri_t *uri);
MONGOC_EXPORT (void)
mongoc_uri_destroy (mongoc_uri_t *uri);
MONGOC_EXPORT (mongoc_uri_t *)
mongoc_uri_new (const char *uri_string) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (mongoc_uri_t *)
mongoc_uri_new_with_error (const char *uri_string,
bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (mongoc_uri_t *)
mongoc_uri_new_for_host_port (const char *hostname,
uint16_t port) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_uri_get_hosts (const mongoc_uri_t *uri);
MONGOC_EXPORT (const char *)
mongoc_uri_get_service (const mongoc_uri_t *uri);
MONGOC_EXPORT (const char *)
mongoc_uri_get_database (const mongoc_uri_t *uri);
MONGOC_EXPORT (bool)
mongoc_uri_set_database (mongoc_uri_t *uri, const char *database);
MONGOC_EXPORT (const bson_t *)
mongoc_uri_get_compressors (const mongoc_uri_t *uri);
MONGOC_EXPORT (const bson_t *)
mongoc_uri_get_options (const mongoc_uri_t *uri);
MONGOC_EXPORT (const char *)
mongoc_uri_get_password (const mongoc_uri_t *uri);
MONGOC_EXPORT (bool)
mongoc_uri_set_password (mongoc_uri_t *uri, const char *password);
MONGOC_EXPORT (bool)
+mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key);
+MONGOC_EXPORT (bool)
mongoc_uri_option_is_int32 (const char *key);
MONGOC_EXPORT (bool)
mongoc_uri_option_is_int64 (const char *key);
MONGOC_EXPORT (bool)
mongoc_uri_option_is_bool (const char *key);
MONGOC_EXPORT (bool)
mongoc_uri_option_is_utf8 (const char *key);
MONGOC_EXPORT (int32_t)
mongoc_uri_get_option_as_int32 (const mongoc_uri_t *uri,
const char *option,
int32_t fallback);
MONGOC_EXPORT (int64_t)
mongoc_uri_get_option_as_int64 (const mongoc_uri_t *uri,
const char *option,
int64_t fallback);
MONGOC_EXPORT (bool)
mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri,
const char *option,
bool fallback);
MONGOC_EXPORT (const char *)
mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri,
const char *option,
const char *fallback);
MONGOC_EXPORT (bool)
mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri,
const char *option,
int32_t value);
MONGOC_EXPORT (bool)
mongoc_uri_set_option_as_int64 (mongoc_uri_t *uri,
const char *option,
int64_t value);
MONGOC_EXPORT (bool)
mongoc_uri_set_option_as_bool (mongoc_uri_t *uri,
const char *option,
bool value);
MONGOC_EXPORT (bool)
mongoc_uri_set_option_as_utf8 (mongoc_uri_t *uri,
const char *option,
const char *value);
MONGOC_EXPORT (const bson_t *)
mongoc_uri_get_read_prefs (const mongoc_uri_t *uri)
BSON_GNUC_DEPRECATED_FOR (mongoc_uri_get_read_prefs_t);
MONGOC_EXPORT (const char *)
mongoc_uri_get_replica_set (const mongoc_uri_t *uri);
MONGOC_EXPORT (const char *)
mongoc_uri_get_string (const mongoc_uri_t *uri);
MONGOC_EXPORT (const char *)
mongoc_uri_get_username (const mongoc_uri_t *uri);
MONGOC_EXPORT (bool)
mongoc_uri_set_username (mongoc_uri_t *uri, const char *username);
MONGOC_EXPORT (const bson_t *)
mongoc_uri_get_credentials (const mongoc_uri_t *uri);
MONGOC_EXPORT (const char *)
mongoc_uri_get_auth_source (const mongoc_uri_t *uri);
MONGOC_EXPORT (bool)
mongoc_uri_set_auth_source (mongoc_uri_t *uri, const char *value);
MONGOC_EXPORT (const char *)
mongoc_uri_get_appname (const mongoc_uri_t *uri);
MONGOC_EXPORT (bool)
mongoc_uri_set_appname (mongoc_uri_t *uri, const char *value);
MONGOC_EXPORT (bool)
mongoc_uri_set_compressors (mongoc_uri_t *uri, const char *value);
MONGOC_EXPORT (const char *)
mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri);
MONGOC_EXPORT (bool)
mongoc_uri_set_auth_mechanism (mongoc_uri_t *uri, const char *value);
MONGOC_EXPORT (bool)
mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri,
bson_t *properties);
MONGOC_EXPORT (bool)
mongoc_uri_set_mechanism_properties (mongoc_uri_t *uri,
const bson_t *properties);
MONGOC_EXPORT (bool)
mongoc_uri_get_ssl (const mongoc_uri_t *uri)
BSON_GNUC_DEPRECATED_FOR (mongoc_uri_get_tls);
MONGOC_EXPORT (bool)
mongoc_uri_get_tls (const mongoc_uri_t *uri);
MONGOC_EXPORT (char *)
mongoc_uri_unescape (const char *escaped_string);
MONGOC_EXPORT (const mongoc_read_prefs_t *)
mongoc_uri_get_read_prefs_t (const mongoc_uri_t *uri);
MONGOC_EXPORT (void)
mongoc_uri_set_read_prefs_t (mongoc_uri_t *uri,
const mongoc_read_prefs_t *prefs);
MONGOC_EXPORT (const mongoc_write_concern_t *)
mongoc_uri_get_write_concern (const mongoc_uri_t *uri);
MONGOC_EXPORT (void)
mongoc_uri_set_write_concern (mongoc_uri_t *uri,
const mongoc_write_concern_t *wc);
MONGOC_EXPORT (const mongoc_read_concern_t *)
mongoc_uri_get_read_concern (const mongoc_uri_t *uri);
MONGOC_EXPORT (void)
mongoc_uri_set_read_concern (mongoc_uri_t *uri,
const mongoc_read_concern_t *rc);
BSON_END_DECLS
#endif /* MONGOC_URI_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
similarity index 88%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
index a4d5fcfc..511c1840 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
@@ -1,139 +1,158 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_UTIL_PRIVATE_H
#define MONGOC_UTIL_PRIVATE_H
#include <bson/bson.h>
#include "mongoc.h"
#ifdef BSON_HAVE_STRINGS_H
#include <strings.h>
#endif
/* string comparison functions for Windows */
#ifdef _WIN32
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#endif
#if BSON_GNUC_CHECK_VERSION(4, 6)
#define BEGIN_IGNORE_DEPRECATIONS \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#define END_IGNORE_DEPRECATIONS _Pragma ("GCC diagnostic pop")
#elif defined(__clang__)
#define BEGIN_IGNORE_DEPRECATIONS \
_Pragma ("clang diagnostic push") \
_Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"")
#define END_IGNORE_DEPRECATIONS _Pragma ("clang diagnostic pop")
#else
#define BEGIN_IGNORE_DEPRECATIONS
#define END_IGNORE_DEPRECATIONS
#endif
#ifndef _WIN32
#define MONGOC_PRINTF_FORMAT(a, b) __attribute__ ((format (__printf__, a, b)))
#else
#define MONGOC_PRINTF_FORMAT(a, b) /* no-op */
#endif
#define COALESCE(x, y) ((x == 0) ? (y) : (x))
/* Helper macros for stringifying things */
#define MONGOC_STR(s) #s
#define MONGOC_EVALUATE_STR(s) MONGOC_STR (s)
BSON_BEGIN_DECLS
extern const bson_validate_flags_t _mongoc_default_insert_vflags;
extern const bson_validate_flags_t _mongoc_default_replace_vflags;
extern const bson_validate_flags_t _mongoc_default_update_vflags;
int
_mongoc_rand_simple (unsigned int *seed);
char *
_mongoc_hex_md5 (const char *input);
void
_mongoc_usleep (int64_t usec);
const char *
_mongoc_get_command_name (const bson_t *command);
const char *
_mongoc_get_documents_field_name (const char *command_name);
bool
_mongoc_lookup_bool (const bson_t *bson, const char *key, bool default_value);
-void
-_mongoc_get_db_name (const char *ns, char *db /* OUT */);
+/* Returns a database name that the caller must free. */
+char *
+_mongoc_get_db_name (const char *ns);
void
_mongoc_bson_init_if_set (bson_t *bson);
const char *
_mongoc_bson_type_to_str (bson_type_t t);
bool
_mongoc_get_server_id_from_opts (const bson_t *opts,
mongoc_error_domain_t domain,
mongoc_error_code_t code,
uint32_t *server_id,
bson_error_t *error);
bool
_mongoc_validate_new_document (const bson_t *insert,
bson_validate_flags_t vflags,
bson_error_t *error);
bool
_mongoc_validate_replace (const bson_t *insert,
bson_validate_flags_t vflags,
bson_error_t *error);
bool
_mongoc_validate_update (const bson_t *update,
bson_validate_flags_t vflags,
bson_error_t *error);
void
mongoc_lowercase (const char *src, char *buf /* OUT */);
bool
mongoc_parse_port (uint16_t *port, const char *str);
void
_mongoc_bson_array_add_label (bson_t *bson, const char *label);
void
_mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst);
void
_mongoc_bson_init_with_transient_txn_error (const mongoc_client_session_t *cs,
bson_t *reply);
bool
_mongoc_document_is_pipeline (const bson_t *document);
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _mongoc_getenv --
+ *
+ * Get the value of an environment variable.
+ *
+ * Returns:
+ * A string you must bson_free, or NULL if the variable is not set.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------------------
+ */
+char *
+_mongoc_getenv (const char *name);
+
BSON_END_DECLS
#endif /* MONGOC_UTIL_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
similarity index 94%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
index 99939ffc..0bbee03e 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
@@ -1,572 +1,596 @@
/*
* Copyright 2013 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.
*/
#ifdef _WIN32
#define _CRT_RAND_S
#endif
#include <string.h>
#include "common-md5-private.h"
#include "mongoc-util-private.h"
#include "mongoc-client.h"
#include "mongoc-client-session-private.h"
#include "mongoc-trace-private.h"
const bson_validate_flags_t _mongoc_default_insert_vflags =
BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL |
BSON_VALIDATE_EMPTY_KEYS | BSON_VALIDATE_DOT_KEYS |
BSON_VALIDATE_DOLLAR_KEYS;
const bson_validate_flags_t _mongoc_default_replace_vflags =
BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL |
BSON_VALIDATE_EMPTY_KEYS | BSON_VALIDATE_DOT_KEYS |
BSON_VALIDATE_DOLLAR_KEYS;
const bson_validate_flags_t _mongoc_default_update_vflags =
BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL |
BSON_VALIDATE_EMPTY_KEYS;
int
_mongoc_rand_simple (unsigned int *seed)
{
#ifdef _WIN32
/* ignore the seed */
unsigned int ret = 0;
errno_t err;
err = rand_s (&ret);
if (0 != err) {
- MONGOC_ERROR ("rand_s failed: %");
+ MONGOC_ERROR ("rand_s failed: %s", strerror(err));
}
return (int) ret;
#else
return rand_r (seed);
#endif
}
char *
_mongoc_hex_md5 (const char *input)
{
uint8_t digest[16];
bson_md5_t md5;
char digest_str[33];
int i;
- _bson_md5_init (&md5);
- _bson_md5_append (&md5, (const uint8_t *) input, (uint32_t) strlen (input));
- _bson_md5_finish (&md5, digest);
+ COMMON_PREFIX (_bson_md5_init (&md5));
+ COMMON_PREFIX (_bson_md5_append (
+ &md5, (const uint8_t *) input, (uint32_t) strlen (input)));
+ COMMON_PREFIX (_bson_md5_finish (&md5, digest));
for (i = 0; i < sizeof digest; i++) {
bson_snprintf (&digest_str[i * 2], 3, "%02x", digest[i]);
}
digest_str[sizeof digest_str - 1] = '\0';
return bson_strdup (digest_str);
}
void
_mongoc_usleep (int64_t usec)
{
#ifdef _WIN32
LARGE_INTEGER ft;
HANDLE timer;
BSON_ASSERT (usec >= 0);
ft.QuadPart = -(10 * usec);
timer = CreateWaitableTimer (NULL, true, NULL);
SetWaitableTimer (timer, &ft, 0, NULL, NULL, 0);
WaitForSingleObject (timer, INFINITE);
CloseHandle (timer);
#else
BSON_ASSERT (usec >= 0);
usleep ((useconds_t) usec);
#endif
}
const char *
_mongoc_get_command_name (const bson_t *command)
{
bson_iter_t iter;
const char *name;
bson_iter_t child;
const char *wrapper_name = NULL;
BSON_ASSERT (command);
if (!bson_iter_init (&iter, command) || !bson_iter_next (&iter)) {
return NULL;
}
name = bson_iter_key (&iter);
/* wrapped in "$query" or "query"?
*
* {$query: {count: "collection"}, $readPreference: {...}}
*/
if (name[0] == '$') {
wrapper_name = "$query";
} else if (!strcmp (name, "query")) {
wrapper_name = "query";
}
if (wrapper_name && bson_iter_init_find (&iter, command, wrapper_name) &&
BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child) &&
bson_iter_next (&child)) {
name = bson_iter_key (&child);
}
return name;
}
const char *
_mongoc_get_documents_field_name (const char *command_name)
{
if (!strcmp (command_name, "insert")) {
return "documents";
}
if (!strcmp (command_name, "update")) {
return "updates";
}
if (!strcmp (command_name, "delete")) {
return "deletes";
}
return NULL;
}
bool
_mongoc_lookup_bool (const bson_t *bson, const char *key, bool default_value)
{
bson_iter_t iter;
bson_iter_t child;
if (!bson) {
return default_value;
}
BSON_ASSERT (bson_iter_init (&iter, bson));
if (!bson_iter_find_descendant (&iter, key, &child)) {
return default_value;
}
return bson_iter_as_bool (&child);
}
-void
-_mongoc_get_db_name (const char *ns, char *db /* OUT */)
+char *
+_mongoc_get_db_name (const char *ns)
{
size_t dblen;
const char *dot;
BSON_ASSERT (ns);
dot = strstr (ns, ".");
if (dot) {
- dblen = BSON_MIN (dot - ns + 1, MONGOC_NAMESPACE_MAX);
- bson_strncpy (db, ns, dblen);
+ dblen = dot - ns;
+ return bson_strndup (ns, dblen);
} else {
- bson_strncpy (db, ns, MONGOC_NAMESPACE_MAX);
+ return bson_strdup (ns);
}
}
void
_mongoc_bson_init_if_set (bson_t *bson)
{
if (bson) {
bson_init (bson);
}
}
const char *
_mongoc_bson_type_to_str (bson_type_t t)
{
switch (t) {
case BSON_TYPE_EOD:
return "EOD";
case BSON_TYPE_DOUBLE:
return "DOUBLE";
case BSON_TYPE_UTF8:
return "UTF8";
case BSON_TYPE_DOCUMENT:
return "DOCUMENT";
case BSON_TYPE_ARRAY:
return "ARRAY";
case BSON_TYPE_BINARY:
return "BINARY";
case BSON_TYPE_UNDEFINED:
return "UNDEFINED";
case BSON_TYPE_OID:
return "OID";
case BSON_TYPE_BOOL:
return "BOOL";
case BSON_TYPE_DATE_TIME:
return "DATE_TIME";
case BSON_TYPE_NULL:
return "NULL";
case BSON_TYPE_REGEX:
return "REGEX";
case BSON_TYPE_DBPOINTER:
return "DBPOINTER";
case BSON_TYPE_CODE:
return "CODE";
case BSON_TYPE_SYMBOL:
return "SYMBOL";
case BSON_TYPE_CODEWSCOPE:
return "CODEWSCOPE";
case BSON_TYPE_INT32:
return "INT32";
case BSON_TYPE_TIMESTAMP:
return "TIMESTAMP";
case BSON_TYPE_INT64:
return "INT64";
case BSON_TYPE_MAXKEY:
return "MAXKEY";
case BSON_TYPE_MINKEY:
return "MINKEY";
case BSON_TYPE_DECIMAL128:
return "DECIMAL128";
default:
return "Unknown";
}
}
/* Get "serverId" from opts. Sets *server_id to the serverId from "opts" or 0
* if absent. On error, fills out *error with domain and code and return false.
*/
bool
_mongoc_get_server_id_from_opts (const bson_t *opts,
mongoc_error_domain_t domain,
mongoc_error_code_t code,
uint32_t *server_id,
bson_error_t *error)
{
bson_iter_t iter;
ENTRY;
BSON_ASSERT (server_id);
*server_id = 0;
if (!opts || !bson_iter_init_find (&iter, opts, "serverId")) {
RETURN (true);
}
if (!BSON_ITER_HOLDS_INT (&iter)) {
bson_set_error (
error, domain, code, "The serverId option must be an integer");
RETURN (false);
}
if (bson_iter_as_int64 (&iter) <= 0) {
bson_set_error (error, domain, code, "The serverId option must be >= 1");
RETURN (false);
}
*server_id = (uint32_t) bson_iter_as_int64 (&iter);
RETURN (true);
}
bool
_mongoc_validate_new_document (const bson_t *doc,
bson_validate_flags_t vflags,
bson_error_t *error)
{
bson_error_t validate_err;
if (vflags == BSON_VALIDATE_NONE) {
return true;
}
if (!bson_validate_with_error (doc, vflags, &validate_err)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"invalid document for insert: %s",
validate_err.message);
return false;
}
return true;
}
bool
_mongoc_validate_replace (const bson_t *doc,
bson_validate_flags_t vflags,
bson_error_t *error)
{
bson_error_t validate_err;
if (vflags == BSON_VALIDATE_NONE) {
return true;
}
if (!bson_validate_with_error (doc, vflags, &validate_err)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"invalid argument for replace: %s",
validate_err.message);
return false;
}
return true;
}
bool
_mongoc_validate_update (const bson_t *update,
bson_validate_flags_t vflags,
bson_error_t *error)
{
bson_error_t validate_err;
bson_iter_t iter;
const char *key;
if (vflags == BSON_VALIDATE_NONE) {
return true;
}
if (!bson_validate_with_error (update, vflags, &validate_err)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"invalid argument for update: %s",
validate_err.message);
return false;
}
if (_mongoc_document_is_pipeline (update)) {
return true;
}
if (!bson_iter_init (&iter, update)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"update document is corrupt");
return false;
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (key[0] != '$') {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid key '%s': update only works with $ operators"
" and pipelines",
key);
return false;
}
}
return true;
}
void
mongoc_lowercase (const char *src, char *buf /* OUT */)
{
for (; *src; ++src, ++buf) {
/* UTF8 non-ascii characters have a 1 at the leftmost bit. If this is the
* case, just copy */
if ((*src & (0x1 << 7)) == 0) {
*buf = (char) tolower (*src);
} else {
*buf = *src;
}
}
}
bool
mongoc_parse_port (uint16_t *port, const char *str)
{
unsigned long ul_port;
ul_port = strtoul (str, NULL, 10);
if (ul_port == 0 || ul_port > UINT16_MAX) {
/* Parse error or port number out of range. mongod prohibits port 0. */
return false;
}
*port = (uint16_t) ul_port;
return true;
}
/*--------------------------------------------------------------------------
*
* _mongoc_bson_array_add_label --
*
* Append an error label like "TransientTransactionError" to a BSON
* array iff the array does not already contain it.
*
* Side effects:
* Aborts if the array is invalid or contains non-string elements.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_bson_array_add_label (bson_t *bson, const char *label)
{
bson_iter_t iter;
char buf[16];
uint32_t i = 0;
const char *key;
BSON_ASSERT (bson_iter_init (&iter, bson));
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_utf8 (&iter, NULL), label)) {
/* already included once */
return;
}
i++;
}
bson_uint32_to_string (i, &key, buf, sizeof buf);
BSON_APPEND_UTF8 (bson, key, label);
}
/*--------------------------------------------------------------------------
*
* _mongoc_bson_array_copy_labels_to --
*
* Copy error labels like "TransientTransactionError" from a server
* reply to a BSON array iff the array does not already contain it.
*
* Side effects:
* Aborts if @dst is invalid or contains non-string elements.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst)
{
bson_iter_t iter;
bson_iter_t label;
if (bson_iter_init_find (&iter, reply, "errorLabels")) {
BSON_ASSERT (bson_iter_recurse (&iter, &label));
while (bson_iter_next (&label)) {
if (BSON_ITER_HOLDS_UTF8 (&label)) {
_mongoc_bson_array_add_label (dst, bson_iter_utf8 (&label, NULL));
}
}
}
}
/*--------------------------------------------------------------------------
*
* _mongoc_bson_init_with_transient_txn_error --
*
* If @reply is not NULL, initialize it. If @cs is not NULL and in a
* transaction, add errorLabels: ["TransientTransactionError"] to @cs.
*
* Transactions Spec: TransientTransactionError includes "server
* selection error encountered running any command besides
* commitTransaction in a transaction. ...in the case of network errors
* or server selection errors where the client receives no server reply,
* the client adds the label."
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_bson_init_with_transient_txn_error (const mongoc_client_session_t *cs,
bson_t *reply)
{
bson_t labels;
if (!reply) {
return;
}
bson_init (reply);
if (_mongoc_client_session_in_txn (cs)) {
BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels);
BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR);
bson_append_array_end (reply, &labels);
}
}
bool
_mongoc_document_is_pipeline (const bson_t *document)
{
bson_iter_t iter;
bson_iter_t child;
const char *key;
int i = 0;
char *i_str;
if (!bson_iter_init (&iter, document)) {
return false;
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
i_str = bson_strdup_printf ("%d", i++);
if (strcmp (key, i_str)) {
bson_free (i_str);
return false;
}
bson_free (i_str);
if (BSON_ITER_HOLDS_DOCUMENT (&iter)) {
if (!bson_iter_recurse (&iter, &child)) {
return false;
}
if (!bson_iter_next (&child)) {
return false;
}
key = bson_iter_key (&child);
if (key[0] != '$') {
return false;
}
} else {
return false;
}
}
/* should return false when the document is empty */
return i != 0;
-}
\ No newline at end of file
+}
+
+char *
+_mongoc_getenv (const char *name)
+{
+#ifdef _MSC_VER
+ char buf[1024];
+ size_t buflen;
+
+ if ((0 == getenv_s (&buflen, buf, sizeof buf, name)) && buflen) {
+ return bson_strdup (buf);
+ } else {
+ return NULL;
+ }
+#else
+
+ if (getenv (name) && strlen (getenv (name))) {
+ return bson_strdup (getenv (name));
+ } else {
+ return NULL;
+ }
+
+#endif
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
similarity index 94%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
index 4f5d30bf..1eadae31 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
@@ -1,102 +1,102 @@
/*
* Copyright 2013 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.
*/
#if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION)
#error "Only <mongoc/mongoc.h> can be included directly."
#endif
#ifndef MONGOC_VERSION_H
#define MONGOC_VERSION_H
/**
* MONGOC_MAJOR_VERSION:
*
* MONGOC major version component (e.g. 1 if %MONGOC_VERSION is 1.2.3)
*/
#define MONGOC_MAJOR_VERSION (1)
/**
* MONGOC_MINOR_VERSION:
*
* MONGOC minor version component (e.g. 2 if %MONGOC_VERSION is 1.2.3)
*/
-#define MONGOC_MINOR_VERSION (16)
+#define MONGOC_MINOR_VERSION (17)
/**
* MONGOC_MICRO_VERSION:
*
* MONGOC micro version component (e.g. 3 if %MONGOC_VERSION is 1.2.3)
*/
-#define MONGOC_MICRO_VERSION (2)
+#define MONGOC_MICRO_VERSION (0)
/**
* MONGOC_PRERELEASE_VERSION:
*
* MONGOC prerelease version component (e.g. pre if %MONGOC_VERSION is 1.2.3-pre)
*/
#define MONGOC_PRERELEASE_VERSION ()
/**
* MONGOC_VERSION:
*
* MONGOC version.
*/
-#define MONGOC_VERSION (1.16.2)
+#define MONGOC_VERSION (1.17.0)
/**
* MONGOC_VERSION_S:
*
* MONGOC version, encoded as a string, useful for printing and
* concatenation.
*/
-#define MONGOC_VERSION_S "1.16.2"
+#define MONGOC_VERSION_S "1.17.0"
/**
* MONGOC_VERSION_HEX:
*
* MONGOC version, encoded as an hexadecimal number, useful for
* integer comparisons.
*/
#define MONGOC_VERSION_HEX (MONGOC_MAJOR_VERSION << 24 | \
MONGOC_MINOR_VERSION << 16 | \
MONGOC_MICRO_VERSION << 8)
/**
* MONGOC_CHECK_VERSION:
* @major: required major version
* @minor: required minor version
* @micro: required micro version
*
* Compile-time version checking. Evaluates to %TRUE if the version
* of MONGOC is greater than the required one.
*/
#define MONGOC_CHECK_VERSION(major,minor,micro) \
(MONGOC_MAJOR_VERSION > (major) || \
(MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION > (minor)) || \
(MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION == (minor) && \
MONGOC_MICRO_VERSION >= (micro)))
#endif /* MONGOC_VERSION_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
similarity index 97%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
index 340a97d3..47a3019c 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
@@ -1,515 +1,523 @@
/*
* Copyright 2014-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
*
* 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.
*/
#include <bson/bson.h>
#include "mongoc-write-command-legacy-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
static void
_mongoc_monitor_legacy_write (mongoc_client_t *client,
mongoc_write_command_t *command,
const char *db,
const char *collection,
mongoc_server_stream_t *stream,
int64_t request_id)
{
bson_t doc;
bson_t wc;
mongoc_apm_command_started_t event;
ENTRY;
if (!client->apm_callbacks.started) {
EXIT;
}
bson_init (&doc);
_mongoc_write_command_init (&doc, command, collection);
BSON_APPEND_DOCUMENT_BEGIN (&doc, "writeConcern", &wc);
BSON_APPEND_INT32 (&wc, "w", 0);
bson_append_document_end (&doc, &wc);
_append_array_from_command (command, &doc);
mongoc_apm_command_started_init (
&event,
&doc,
db,
_mongoc_command_type_to_name (command->type),
request_id,
command->operation_id,
&stream->sd->host,
stream->sd->id,
client->apm_context);
client->apm_callbacks.started (&event);
mongoc_apm_command_started_cleanup (&event);
bson_destroy (&doc);
}
/* fire command-succeeded event as if we'd used a modern write command.
* note, cluster.request_id was incremented once for the write, again
* for the getLastError, so cluster.request_id is no longer valid; used the
* passed-in request_id instead.
*/
static void
_mongoc_monitor_legacy_write_succeeded (mongoc_client_t *client,
int64_t duration,
mongoc_write_command_t *command,
mongoc_server_stream_t *stream,
int64_t request_id)
{
bson_t doc;
mongoc_apm_command_succeeded_t event;
ENTRY;
if (!client->apm_callbacks.succeeded) {
EXIT;
}
bson_init (&doc);
/*
* Unacknowledged writes must provide a CommandSucceededEvent with a { ok: 1
* } reply.
* https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#unacknowledged-acknowledged-writes
*/
bson_append_int32 (&doc, "ok", 2, 1);
bson_append_int32 (&doc, "n", 1, (int32_t) command->n_documents);
mongoc_apm_command_succeeded_init (
&event,
duration,
&doc,
_mongoc_command_type_to_name (command->type),
request_id,
command->operation_id,
&stream->sd->host,
stream->sd->id,
client->apm_context);
client->apm_callbacks.succeeded (&event);
mongoc_apm_command_succeeded_cleanup (&event);
bson_destroy (&doc);
EXIT;
}
void
_mongoc_write_command_delete_legacy (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error)
{
int64_t started;
int32_t max_bson_obj_size;
const uint8_t *data;
mongoc_rpc_t rpc;
uint32_t request_id;
bson_iter_t q_iter;
uint32_t len;
int64_t limit = 0;
- char ns[MONGOC_NAMESPACE_MAX + 1];
+ char *ns;
bool r;
bson_reader_t *reader;
const bson_t *bson;
bool eof;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
started = bson_get_monotonic_time ();
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
if (!command->n_documents) {
bson_set_error (error,
MONGOC_ERROR_COLLECTION,
MONGOC_ERROR_COLLECTION_DELETE_FAILED,
"Cannot do an empty delete.");
result->failed = true;
EXIT;
}
- bson_snprintf (ns, sizeof ns, "%s.%s", database, collection);
+ ns = bson_strdup_printf ("%s.%s", database, collection);
reader =
bson_reader_new_from_data (command->payload.data, command->payload.len);
while ((bson = bson_reader_read (reader, &eof))) {
/* the document is like { "q": { <selector> }, limit: <0 or 1> } */
r = (bson_iter_init (&q_iter, bson) && bson_iter_find (&q_iter, "q") &&
BSON_ITER_HOLDS_DOCUMENT (&q_iter));
BSON_ASSERT (r);
bson_iter_document (&q_iter, &len, &data);
BSON_ASSERT (data);
BSON_ASSERT (len >= 5);
if (len > max_bson_obj_size) {
_mongoc_write_command_too_large_error (
error, 0, len, max_bson_obj_size);
result->failed = true;
bson_reader_destroy (reader);
+ bson_free (ns);
EXIT;
}
request_id = ++client->cluster.request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_DELETE;
rpc.delete_.zero = 0;
rpc.delete_.collection = ns;
if (bson_iter_find (&q_iter, "limit") &&
(BSON_ITER_HOLDS_INT (&q_iter))) {
limit = bson_iter_as_int64 (&q_iter);
}
rpc.delete_.flags =
limit ? MONGOC_DELETE_SINGLE_REMOVE : MONGOC_DELETE_NONE;
rpc.delete_.selector = data;
_mongoc_monitor_legacy_write (
client, command, database, collection, server_stream, request_id);
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
&client->cluster, &rpc, server_stream, error)) {
result->failed = true;
+ bson_free (ns);
bson_reader_destroy (reader);
EXIT;
}
_mongoc_monitor_legacy_write_succeeded (client,
bson_get_monotonic_time () -
started,
command,
server_stream,
request_id);
started = bson_get_monotonic_time ();
}
bson_reader_destroy (reader);
+ bson_free (ns);
EXIT;
}
void
_mongoc_write_command_insert_legacy (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error)
{
int64_t started;
mongoc_iovec_t *iov;
mongoc_rpc_t rpc;
uint32_t size = 0;
bool has_more;
- char ns[MONGOC_NAMESPACE_MAX + 1];
+ char *ns;
uint32_t n_docs_in_batch;
uint32_t request_id = 0;
uint32_t idx = 0;
int32_t max_msg_size;
int32_t max_bson_obj_size;
bson_reader_t *reader;
const bson_t *bson;
bool eof;
int data_offset = 0;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT);
started = bson_get_monotonic_time ();
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
max_msg_size = mongoc_server_stream_max_msg_size (server_stream);
if (!command->n_documents) {
bson_set_error (error,
MONGOC_ERROR_COLLECTION,
MONGOC_ERROR_COLLECTION_INSERT_FAILED,
"Cannot do an empty insert.");
result->failed = true;
EXIT;
}
- bson_snprintf (ns, sizeof ns, "%s.%s", database, collection);
+ ns = bson_strdup_printf ("%s.%s", database, collection);
iov = (mongoc_iovec_t *) bson_malloc ((sizeof *iov) * command->n_documents);
again:
has_more = false;
n_docs_in_batch = 0;
size = (uint32_t) (sizeof (mongoc_rpc_header_t) + 4 + strlen (database) + 1 +
strlen (collection) + 1);
reader = bson_reader_new_from_data (command->payload.data + data_offset,
command->payload.len - data_offset);
while ((bson = bson_reader_read (reader, &eof))) {
BSON_ASSERT (n_docs_in_batch <= idx);
BSON_ASSERT (idx <= command->n_documents);
if (bson->len > max_bson_obj_size) {
/* document is too large */
_mongoc_write_command_too_large_error (
error, idx, bson->len, max_bson_obj_size);
data_offset += bson->len;
if (command->flags.ordered) {
/* send the batch so far (if any) and return the error */
break;
}
} else if (size > (max_msg_size - bson->len)) {
/* batch is full, send it and then start the next batch */
has_more = true;
break;
} else {
/* add document to batch and continue building the batch */
iov[n_docs_in_batch].iov_base = (void *) bson_get_data (bson);
iov[n_docs_in_batch].iov_len = bson->len;
size += bson->len;
n_docs_in_batch++;
data_offset += bson->len;
}
idx++;
}
bson_reader_destroy (reader);
if (n_docs_in_batch) {
request_id = ++client->cluster.request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_INSERT;
rpc.insert.flags =
((command->flags.ordered) ? MONGOC_INSERT_NONE
: MONGOC_INSERT_CONTINUE_ON_ERROR);
rpc.insert.collection = ns;
rpc.insert.documents = iov;
rpc.insert.n_documents = n_docs_in_batch;
_mongoc_monitor_legacy_write (
client, command, database, collection, server_stream, request_id);
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
&client->cluster, &rpc, server_stream, error)) {
result->failed = true;
GOTO (cleanup);
}
_mongoc_monitor_legacy_write_succeeded (client,
bson_get_monotonic_time () -
started,
command,
server_stream,
request_id);
started = bson_get_monotonic_time ();
}
cleanup:
if (has_more) {
GOTO (again);
}
+ bson_free (ns);
bson_free (iov);
EXIT;
}
void
_mongoc_write_command_update_legacy (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error)
{
int64_t started;
int32_t max_bson_obj_size;
mongoc_rpc_t rpc;
uint32_t request_id = 0;
bson_iter_t subiter, subsubiter;
bson_t doc;
bson_t update, selector;
const uint8_t *data = NULL;
uint32_t len = 0;
size_t err_offset;
bool val = false;
- char ns[MONGOC_NAMESPACE_MAX + 1];
+ char *ns;
int vflags = (BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL |
BSON_VALIDATE_DOLLAR_KEYS | BSON_VALIDATE_DOT_KEYS);
bson_reader_t *reader;
const bson_t *bson;
bool eof;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
started = bson_get_monotonic_time ();
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
reader =
bson_reader_new_from_data (command->payload.data, command->payload.len);
while ((bson = bson_reader_read (reader, &eof))) {
if (bson_iter_init (&subiter, bson) && bson_iter_find (&subiter, "u") &&
BSON_ITER_HOLDS_DOCUMENT (&subiter)) {
bson_iter_document (&subiter, &len, &data);
BSON_ASSERT (bson_init_static (&doc, data, len));
if (bson_iter_init (&subsubiter, &doc) &&
bson_iter_next (&subsubiter) &&
(bson_iter_key (&subsubiter)[0] != '$') &&
!bson_validate (
&doc, (bson_validate_flags_t) vflags, &err_offset)) {
result->failed = true;
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"update document is corrupt or contains "
"invalid keys including $ or .");
bson_reader_destroy (reader);
EXIT;
}
} else {
result->failed = true;
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"updates is malformed.");
bson_reader_destroy (reader);
EXIT;
}
}
- bson_snprintf (ns, sizeof ns, "%s.%s", database, collection);
+ ns = bson_strdup_printf ("%s.%s", database, collection);
bson_reader_destroy (reader);
reader =
bson_reader_new_from_data (command->payload.data, command->payload.len);
while ((bson = bson_reader_read (reader, &eof))) {
request_id = ++client->cluster.request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_UPDATE;
rpc.update.zero = 0;
rpc.update.collection = ns;
rpc.update.flags = MONGOC_UPDATE_NONE;
BSON_ASSERT (bson_iter_init (&subiter, bson));
while (bson_iter_next (&subiter)) {
if (strcmp (bson_iter_key (&subiter), "u") == 0) {
bson_iter_document (&subiter, &len, &data);
if (len > max_bson_obj_size) {
_mongoc_write_command_too_large_error (
error, 0, len, max_bson_obj_size);
result->failed = true;
bson_reader_destroy (reader);
+ bson_free (ns);
EXIT;
}
rpc.update.update = data;
BSON_ASSERT (bson_init_static (&update, data, len));
} else if (strcmp (bson_iter_key (&subiter), "q") == 0) {
bson_iter_document (&subiter, &len, &data);
if (len > max_bson_obj_size) {
_mongoc_write_command_too_large_error (
error, 0, len, max_bson_obj_size);
result->failed = true;
bson_reader_destroy (reader);
+ bson_free (ns);
EXIT;
}
rpc.update.selector = data;
BSON_ASSERT (bson_init_static (&selector, data, len));
} else if (strcmp (bson_iter_key (&subiter), "multi") == 0) {
val = bson_iter_bool (&subiter);
if (val) {
rpc.update.flags = (mongoc_update_flags_t) (
rpc.update.flags | MONGOC_UPDATE_MULTI_UPDATE);
}
} else if (strcmp (bson_iter_key (&subiter), "upsert") == 0) {
val = bson_iter_bool (&subiter);
if (val) {
rpc.update.flags = (mongoc_update_flags_t) (
rpc.update.flags | MONGOC_UPDATE_UPSERT);
}
}
}
_mongoc_monitor_legacy_write (
client, command, database, collection, server_stream, request_id);
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
&client->cluster, &rpc, server_stream, error)) {
result->failed = true;
bson_reader_destroy (reader);
+ bson_free (ns);
EXIT;
}
_mongoc_monitor_legacy_write_succeeded (client,
bson_get_monotonic_time () -
started,
command,
server_stream,
request_id);
started = bson_get_monotonic_time ();
}
bson_reader_destroy (reader);
+ bson_free (ns);
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
similarity index 98%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
index fb1082b6..89fa3113 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
@@ -1,230 +1,231 @@
/*
* Copyright 2014 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.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_WRITE_COMMAND_PRIVATE_H
#define MONGOC_WRITE_COMMAND_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-error.h"
#include "mongoc-write-concern.h"
#include "mongoc-server-stream-private.h"
#include "mongoc-buffer-private.h"
BSON_BEGIN_DECLS
/* forward decl */
struct _mongoc_crud_opts_t;
#define MONGOC_WRITE_COMMAND_DELETE 0
#define MONGOC_WRITE_COMMAND_INSERT 1
#define MONGOC_WRITE_COMMAND_UPDATE 2
/* MongoDB has a extra allowance to allow updating 16mb document, as the update
* operators would otherwise overflow the 16mb object limit. See SERVER-10643
* for context. */
#define BSON_OBJECT_ALLOWANCE (16 * 1024)
+#define RETRYABLE_WRITE_ERROR "RetryableWriteError"
+
struct _mongoc_bulk_write_flags_t {
bool ordered;
bool bypass_document_validation;
bool has_collation;
bool has_multi_write;
bool has_array_filters;
bool has_update_hint;
+ bool has_delete_hint;
};
typedef struct {
int type;
mongoc_buffer_t payload;
uint32_t n_documents;
mongoc_bulk_write_flags_t flags;
int64_t operation_id;
bson_t cmd_opts;
} mongoc_write_command_t;
typedef struct {
uint32_t nInserted;
uint32_t nMatched;
uint32_t nModified;
uint32_t nRemoved;
uint32_t nUpserted;
/* like [{"index": int, "code": int, "errmsg": str}, ...] */
bson_t writeErrors;
/* like [{"index": int, "_id": value}, ...] */
bson_t upserted;
uint32_t n_writeConcernErrors;
/* like [{"code": 64, "errmsg": "duplicate"}, ...] */
bson_t writeConcernErrors;
/* like ["TransientTransactionError", ...] */
bson_t errorLabels;
bool failed; /* The command failed */
bool must_stop; /* The stream may have been disconnected */
bson_error_t error;
uint32_t upsert_append_count;
/* If the command initially failed with a retryable write, and selected a new
* primary, this contains the server id of the newly selected primary. Only
* applies to OP_MSG. Is left at 0 if no retry occurs. */
uint32_t retry_server_id;
} mongoc_write_result_t;
typedef enum {
MONGOC_WRITE_ERR_NONE,
MONGOC_WRITE_ERR_OTHER,
MONGOC_WRITE_ERR_RETRY,
MONGOC_WRITE_ERR_WRITE_CONCERN,
} mongoc_write_err_type_t;
const char *
_mongoc_command_type_to_field_name (int command_type);
const char *
_mongoc_command_type_to_name (int command_type);
void
_mongoc_write_command_destroy (mongoc_write_command_t *command);
void
_mongoc_write_command_init (bson_t *doc,
mongoc_write_command_t *command,
const char *collection);
void
_mongoc_write_command_init_insert (mongoc_write_command_t *command,
const bson_t *document,
const bson_t *cmd_opts,
mongoc_bulk_write_flags_t flags,
int64_t operation_id);
void
_mongoc_write_command_init_insert_idl (mongoc_write_command_t *command,
const bson_t *document,
const bson_t *cmd_opts,
int64_t operation_id);
void
_mongoc_write_command_init_delete (mongoc_write_command_t *command,
const bson_t *selectors,
const bson_t *cmd_opts,
const bson_t *opts,
mongoc_bulk_write_flags_t flags,
int64_t operation_id);
void
_mongoc_write_command_init_delete_idl (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *cmd_opts,
const bson_t *opts,
int64_t operation_id);
void
_mongoc_write_command_init_update (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
const bson_t *opts,
mongoc_bulk_write_flags_t flags,
int64_t operation_id);
void
_mongoc_write_command_init_update_idl (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
const bson_t *opts,
int64_t operation_id);
void
_mongoc_write_command_insert_append (mongoc_write_command_t *command,
const bson_t *document);
void
_mongoc_write_command_update_append (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
const bson_t *opts);
void
_mongoc_write_command_delete_append (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *opts);
void
_mongoc_write_command_too_large_error (bson_error_t *error,
int32_t idx,
int32_t len,
int32_t max_bson_size);
void
_mongoc_write_command_execute (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
const mongoc_write_concern_t *write_concern,
uint32_t offset,
mongoc_client_session_t *cs,
mongoc_write_result_t *result);
void
_mongoc_write_command_execute_idl (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
const struct _mongoc_crud_opts_t *crud,
mongoc_write_result_t *result);
void
_mongoc_write_result_init (mongoc_write_result_t *result);
void
_mongoc_write_result_append_upsert (mongoc_write_result_t *result,
int32_t idx,
const bson_value_t *value);
int32_t
_mongoc_write_result_merge_arrays (uint32_t offset,
mongoc_write_result_t *result,
bson_t *dest,
bson_iter_t *iter);
void
_mongoc_write_result_merge (mongoc_write_result_t *result,
mongoc_write_command_t *command,
const bson_t *reply,
uint32_t offset);
#define MONGOC_WRITE_RESULT_COMPLETE(_result, ...) \
_mongoc_write_result_complete (_result, __VA_ARGS__, NULL)
bool
_mongoc_write_result_complete (mongoc_write_result_t *result,
int32_t error_api_version,
const mongoc_write_concern_t *wc,
mongoc_error_domain_t err_domain_override,
bson_t *reply,
bson_error_t *error,
...);
void
_mongoc_write_result_destroy (mongoc_write_result_t *result);
void
_append_array_from_command (mongoc_write_command_t *command, bson_t *bson);
mongoc_write_err_type_t
-_mongoc_write_error_get_type (bool cmd_ret,
- const bson_error_t *cmd_err,
- const bson_t *reply);
+_mongoc_write_error_get_type (bson_t *reply);
bool
_mongoc_write_error_update_if_unsupported_storage_engine (bool cmd_ret,
bson_error_t *cmd_err,
bson_t *reply);
BSON_END_DECLS
#endif /* MONGOC_WRITE_COMMAND_PRIVATE_H */
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
similarity index 96%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
index 8b3e8960..d30f24b5 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
@@ -1,1591 +1,1599 @@
/*
* Copyright 2014 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.
*/
#include <bson/bson.h>
#include "mongoc-client-private.h"
#include "mongoc-client-session-private.h"
#include "mongoc-client-side-encryption-private.h"
#include "mongoc-error.h"
+#include "mongoc-error-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-write-command-private.h"
#include "mongoc-write-command-legacy-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-util-private.h"
#include "mongoc-opts-private.h"
/*
* TODO:
*
* - Remove error parameter to ops, favor result->error.
*/
typedef void (*mongoc_write_op_t) (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error);
/* indexed by MONGOC_WRITE_COMMAND_DELETE, INSERT, UPDATE */
static const char *gCommandNames[] = {"delete", "insert", "update"};
static const char *gCommandFields[] = {"deletes", "documents", "updates"};
static const uint32_t gCommandFieldLens[] = {7, 9, 7};
static mongoc_write_op_t gLegacyWriteOps[3] = {
_mongoc_write_command_delete_legacy,
_mongoc_write_command_insert_legacy,
_mongoc_write_command_update_legacy};
const char *
_mongoc_command_type_to_name (int command_type)
{
return gCommandNames[command_type];
}
const char *
_mongoc_command_type_to_field_name (int command_type)
{
return gCommandFields[command_type];
}
void
_mongoc_write_command_insert_append (mongoc_write_command_t *command,
const bson_t *document)
{
bson_iter_t iter;
bson_oid_t oid;
bson_t tmp;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT);
BSON_ASSERT (document);
BSON_ASSERT (document->len >= 5);
/*
* If the document does not contain an "_id" field, we need to generate
* a new oid for "_id".
*/
if (!bson_iter_init_find (&iter, document, "_id")) {
bson_init (&tmp);
bson_oid_init (&oid, NULL);
BSON_APPEND_OID (&tmp, "_id", &oid);
bson_concat (&tmp, document);
_mongoc_buffer_append (&command->payload, bson_get_data (&tmp), tmp.len);
bson_destroy (&tmp);
} else {
_mongoc_buffer_append (
&command->payload, bson_get_data (document), document->len);
}
command->n_documents++;
EXIT;
}
void
_mongoc_write_command_update_append (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
const bson_t *opts)
{
bson_t document;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_UPDATE);
BSON_ASSERT (selector && update);
bson_init (&document);
BSON_APPEND_DOCUMENT (&document, "q", selector);
if (_mongoc_document_is_pipeline (update)) {
BSON_APPEND_ARRAY (&document, "u", update);
} else {
BSON_APPEND_DOCUMENT (&document, "u", update);
}
if (opts) {
bson_concat (&document, opts);
}
_mongoc_buffer_append (
&command->payload, bson_get_data (&document), document.len);
command->n_documents++;
bson_destroy (&document);
EXIT;
}
void
_mongoc_write_command_delete_append (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *opts)
{
bson_t document;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_DELETE);
BSON_ASSERT (selector);
BSON_ASSERT (selector->len >= 5);
bson_init (&document);
BSON_APPEND_DOCUMENT (&document, "q", selector);
if (opts) {
bson_concat (&document, opts);
}
_mongoc_buffer_append (
&command->payload, bson_get_data (&document), document.len);
command->n_documents++;
bson_destroy (&document);
EXIT;
}
void
_mongoc_write_command_init_bulk (mongoc_write_command_t *command,
int type,
mongoc_bulk_write_flags_t flags,
int64_t operation_id,
const bson_t *opts)
{
ENTRY;
BSON_ASSERT (command);
command->type = type;
command->flags = flags;
command->operation_id = operation_id;
if (!bson_empty0 (opts)) {
bson_copy_to (opts, &command->cmd_opts);
} else {
bson_init (&command->cmd_opts);
}
_mongoc_buffer_init (&command->payload, NULL, 0, NULL, NULL);
command->n_documents = 0;
EXIT;
}
void
_mongoc_write_command_init_insert (mongoc_write_command_t *command, /* IN */
const bson_t *document, /* IN */
const bson_t *cmd_opts, /* IN */
mongoc_bulk_write_flags_t flags, /* IN */
int64_t operation_id) /* IN */
{
ENTRY;
BSON_ASSERT (command);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_INSERT, flags, operation_id, cmd_opts);
/* must handle NULL document from mongoc_collection_insert_bulk */
if (document) {
_mongoc_write_command_insert_append (command, document);
}
EXIT;
}
void
_mongoc_write_command_init_insert_idl (mongoc_write_command_t *command,
const bson_t *document,
const bson_t *cmd_opts,
int64_t operation_id)
{
mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT;
ENTRY;
BSON_ASSERT (command);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_INSERT, flags, operation_id, cmd_opts);
/* must handle NULL document from mongoc_collection_insert_bulk */
if (document) {
_mongoc_write_command_insert_append (command, document);
}
EXIT;
}
void
_mongoc_write_command_init_delete (mongoc_write_command_t *command, /* IN */
const bson_t *selector, /* IN */
const bson_t *cmd_opts, /* IN */
const bson_t *opts, /* IN */
mongoc_bulk_write_flags_t flags, /* IN */
int64_t operation_id) /* IN */
{
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (selector);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_DELETE, flags, operation_id, cmd_opts);
_mongoc_write_command_delete_append (command, selector, opts);
EXIT;
}
void
_mongoc_write_command_init_delete_idl (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *cmd_opts,
const bson_t *opts,
int64_t operation_id)
{
mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (selector);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_DELETE, flags, operation_id, cmd_opts);
_mongoc_write_command_delete_append (command, selector, opts);
EXIT;
}
void
_mongoc_write_command_init_update (mongoc_write_command_t *command, /* IN */
const bson_t *selector, /* IN */
const bson_t *update, /* IN */
const bson_t *opts, /* IN */
mongoc_bulk_write_flags_t flags, /* IN */
int64_t operation_id) /* IN */
{
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (selector);
BSON_ASSERT (update);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_UPDATE, flags, operation_id, NULL);
_mongoc_write_command_update_append (command, selector, update, opts);
EXIT;
}
void
_mongoc_write_command_init_update_idl (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
const bson_t *opts,
int64_t operation_id)
{
mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT;
ENTRY;
BSON_ASSERT (command);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_UPDATE, flags, operation_id, NULL);
_mongoc_write_command_update_append (command, selector, update, opts);
EXIT;
}
/* takes initialized bson_t *doc and begins formatting a write command */
void
_mongoc_write_command_init (bson_t *doc,
mongoc_write_command_t *command,
const char *collection)
{
ENTRY;
if (!command->n_documents) {
EXIT;
}
BSON_APPEND_UTF8 (doc, gCommandNames[command->type], collection);
BSON_APPEND_BOOL (doc, "ordered", command->flags.ordered);
if (command->flags.bypass_document_validation) {
BSON_APPEND_BOOL (doc,
"bypassDocumentValidation",
command->flags.bypass_document_validation);
}
EXIT;
}
/*
*-------------------------------------------------------------------------
*
* _mongoc_write_command_too_large_error --
*
* Fill a bson_error_t and optional bson_t with error info after
* receiving a document for bulk insert, update, or remove that is
* larger than max_bson_size.
*
* "err_doc" should be NULL or an empty initialized bson_t.
*
* Returns:
* None.
*
* Side effects:
* "error" and optionally "err_doc" are filled out.
*
*-------------------------------------------------------------------------
*/
void
_mongoc_write_command_too_large_error (bson_error_t *error,
int32_t idx,
int32_t len,
int32_t max_bson_size)
{
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Document %u is too large for the cluster. "
"Document is %u bytes, max is %d.",
idx,
len,
max_bson_size);
}
void
_empty_error (mongoc_write_command_t *command, bson_error_t *error)
{
static const uint32_t codes[] = {MONGOC_ERROR_COLLECTION_DELETE_FAILED,
MONGOC_ERROR_COLLECTION_INSERT_FAILED,
MONGOC_ERROR_COLLECTION_UPDATE_FAILED};
bson_set_error (error,
MONGOC_ERROR_COLLECTION,
codes[command->type],
"Cannot do an empty %s",
gCommandNames[command->type]);
}
bool
_mongoc_write_command_will_overflow (uint32_t len_so_far,
uint32_t document_len,
uint32_t n_documents_written,
int32_t max_bson_size,
int32_t max_write_batch_size)
{
/* max BSON object size + 16k bytes.
* server guarantees there is enough room: SERVER-10643
*/
int32_t max_cmd_size = max_bson_size + BSON_OBJECT_ALLOWANCE;
BSON_ASSERT (max_bson_size);
if (len_so_far + document_len > max_cmd_size) {
return true;
} else if (max_write_batch_size > 0 &&
n_documents_written >= max_write_batch_size) {
return true;
}
return false;
}
static void
_mongoc_write_opmsg (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
const mongoc_write_concern_t *write_concern,
uint32_t index_offset,
mongoc_client_session_t *cs,
mongoc_write_result_t *result,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
bson_iter_t iter;
bson_t cmd;
bson_t reply;
bool ret = false;
int32_t max_msg_size;
int32_t max_bson_obj_size;
int32_t max_document_count;
uint32_t header;
uint32_t payload_batch_size = 0;
uint32_t payload_total_offset = 0;
bool ship_it = false;
int document_count = 0;
int32_t len;
mongoc_server_stream_t *retry_server_stream = NULL;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
max_msg_size = mongoc_server_stream_max_msg_size (server_stream);
if (_mongoc_cse_is_enabled (client)) {
max_msg_size = MONGOC_REDUCED_MAX_MSG_SIZE_FOR_FLE;
}
max_document_count =
mongoc_server_stream_max_write_batch_size (server_stream);
bson_init (&cmd);
_mongoc_write_command_init (&cmd, command, collection);
mongoc_cmd_parts_init (&parts, client, database, MONGOC_QUERY_NONE, &cmd);
parts.assembled.operation_id = command->operation_id;
parts.is_write_command = true;
if (!mongoc_cmd_parts_set_write_concern (
&parts, write_concern, server_stream->sd->max_wire_version, error)) {
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
EXIT;
}
if (parts.assembled.is_acknowledged) {
mongoc_cmd_parts_set_session (&parts, cs);
}
/* Write commands that include multi-document operations are not retryable.
* Set this explicitly so that mongoc_cmd_parts_assemble does not need to
* inspect the command body later. */
parts.allow_txn_number =
(command->flags.has_multi_write || !parts.assembled.is_acknowledged)
? MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_NO
: MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES;
BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts));
if (!mongoc_cmd_parts_append_opts (
&parts, &iter, server_stream->sd->max_wire_version, error)) {
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
EXIT;
}
if (!mongoc_cmd_parts_assemble (&parts, server_stream, error)) {
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
EXIT;
}
/*
* OP_MSG header == 16 byte
* + 4 bytes flagBits
* + 1 byte payload type = 1
* + 1 byte payload type = 2
* + 4 byte size of payload
* == 26 bytes opcode overhead
* + X Full command document {insert: "test", writeConcern: {...}}
* + Y command identifier ("documents", "deletes", "updates") ( + \0)
*/
header =
26 + parts.assembled.command->len + gCommandFieldLens[command->type] + 1;
do {
memcpy (&len,
command->payload.data + payload_batch_size + payload_total_offset,
4);
len = BSON_UINT32_FROM_LE (len);
if (len > max_bson_obj_size + BSON_OBJECT_ALLOWANCE) {
/* Quit if the document is too large */
_mongoc_write_command_too_large_error (
error, index_offset, len, max_bson_obj_size);
result->failed = true;
break;
} else if ((payload_batch_size + header) + len <= max_msg_size ||
document_count == 0) {
/* The current batch is still under max batch size in bytes */
payload_batch_size += len;
/* If this document filled the maximum document count */
if (++document_count == max_document_count) {
ship_it = true;
/* If this document is the last document we have */
} else if (payload_batch_size + payload_total_offset ==
command->payload.len) {
ship_it = true;
} else {
ship_it = false;
}
} else {
ship_it = true;
}
if (ship_it) {
bool is_retryable = parts.is_retryable_write;
mongoc_write_err_type_t error_type;
/* Seek past the document offset we have already sent */
parts.assembled.payload = command->payload.data + payload_total_offset;
/* Only send the documents up to this size */
parts.assembled.payload_size = payload_batch_size;
parts.assembled.payload_identifier = gCommandFields[command->type];
/* increment the transaction number for the first attempt of each
* retryable write command */
if (is_retryable) {
bson_iter_t txn_number_iter;
BSON_ASSERT (bson_iter_init_find (
&txn_number_iter, parts.assembled.command, "txnNumber"));
bson_iter_overwrite_int64 (
&txn_number_iter,
++parts.assembled.session->server_session->txn_number);
}
retry:
ret = mongoc_cluster_run_command_monitored (
&client->cluster, &parts.assembled, &reply, error);
+ if (parts.is_retryable_write) {
+ _mongoc_write_error_handle_labels (
+ ret, error, &reply, server_stream->sd->max_wire_version);
+ }
+
/* Add this batch size so we skip these documents next time */
payload_total_offset += payload_batch_size;
payload_batch_size = 0;
/* If a retryable error is encountered and the write is retryable,
* select a new writable stream and retry. If server selection fails or
* the selected server does not support retryable writes, fall through
* and allow the original error to be reported. */
- error_type = _mongoc_write_error_get_type (ret, error, &reply);
+ error_type = _mongoc_write_error_get_type (&reply);
if (is_retryable) {
_mongoc_write_error_update_if_unsupported_storage_engine (
ret, error, &reply);
}
if (is_retryable && error_type == MONGOC_WRITE_ERR_RETRY) {
bson_error_t ignored_error;
/* each write command may be retried at most once */
is_retryable = false;
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
retry_server_stream = mongoc_cluster_stream_for_writes (
&client->cluster, cs, NULL, &ignored_error);
if (retry_server_stream &&
retry_server_stream->sd->max_wire_version >=
WIRE_VERSION_RETRY_WRITES) {
parts.assembled.server_stream = retry_server_stream;
bson_destroy (&reply);
GOTO (retry);
}
}
if (!ret) {
result->failed = true;
- /* Conservatively set must_stop to true. Per CDRIVER-3305 we
- * shouldn't stop for unordered bulk writes, but also need to check
- * if the server stream was invalidated per CDRIVER-3306. */
- result->must_stop = true;
+ /* Stop for ordered bulk writes or when the server stream has been
+ * properly invalidated (e.g., due to a network error). */
+ if (command->flags.ordered || !mongoc_cluster_stream_valid (
+ &client->cluster, server_stream)) {
+ result->must_stop = true;
+ }
}
/* Result merge needs to know the absolute index for a document
* so it can rewrite the error message which contains the relative
* document index per batch
*/
_mongoc_write_result_merge (result, command, &reply, index_offset);
index_offset += document_count;
document_count = 0;
bson_destroy (&reply);
}
/* While we have more documents to write */
} while (payload_total_offset < command->payload.len && !result->must_stop);
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
if (retry_server_stream) {
if (ret) {
/* if a retry succeeded, report that in the result so bulk write can
* use the newly selected server. */
result->retry_server_id =
mongoc_server_description_id (retry_server_stream->sd);
}
mongoc_server_stream_cleanup (retry_server_stream);
}
if (ret) {
/* if a retry succeeded, clear the initial error */
memset (&result->error, 0, sizeof (bson_error_t));
}
EXIT;
}
void
_append_array_from_command (mongoc_write_command_t *command, bson_t *bson)
{
bson_t ar;
bson_reader_t *reader;
char str[16];
uint32_t i = 0;
const char *key;
bool eof;
const bson_t *current;
reader =
bson_reader_new_from_data (command->payload.data, command->payload.len);
bson_append_array_begin (bson,
gCommandFields[command->type],
gCommandFieldLens[command->type],
&ar);
while ((current = bson_reader_read (reader, &eof))) {
bson_uint32_to_string (i, &key, str, sizeof str);
BSON_APPEND_DOCUMENT (&ar, key, current);
i++;
}
bson_append_array_end (bson, &ar);
bson_reader_destroy (reader);
}
/* Assemble the base @cmd with all of the command options.
* @parts is always initialized, even on error.
* This is called twice in _mongoc_write_opquery.
* Once with no payload documents, to determine the total size. And once with
* payload documents, to send the final command. */
static bool
_assemble_cmd (bson_t *cmd,
mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const mongoc_write_concern_t *write_concern,
mongoc_cmd_parts_t *parts,
bson_error_t *error)
{
bool ret;
bson_iter_t iter;
mongoc_cmd_parts_init (parts, client, database, MONGOC_QUERY_NONE, cmd);
parts->is_write_command = true;
parts->assembled.operation_id = command->operation_id;
ret = mongoc_cmd_parts_set_write_concern (
parts, write_concern, server_stream->sd->max_wire_version, error);
if (ret) {
BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts));
ret = mongoc_cmd_parts_append_opts (
parts, &iter, server_stream->sd->max_wire_version, error);
}
if (ret) {
ret = mongoc_cmd_parts_assemble (parts, server_stream, error);
}
return ret;
}
static void
_mongoc_write_opquery (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
const mongoc_write_concern_t *write_concern,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
const char *key;
uint32_t len = 0;
bson_t ar;
bson_t cmd;
char str[16];
bool has_more;
bool ret = false;
uint32_t i;
int32_t max_bson_obj_size;
int32_t max_write_batch_size;
uint32_t overhead;
uint32_t key_len;
int data_offset = 0;
bson_reader_t *reader;
const bson_t *bson;
bool eof;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
bson_init (&cmd);
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
max_write_batch_size =
mongoc_server_stream_max_write_batch_size (server_stream);
again:
has_more = false;
i = 0;
_mongoc_write_command_init (&cmd, command, collection);
/* If any part of assembling failed, return with failure. */
if (!_assemble_cmd (&cmd,
command,
client,
server_stream,
database,
write_concern,
&parts,
error)) {
result->failed = true;
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
EXIT;
}
/* Use the assembled command to compute the overhead, since it may be a new
* BSON document with options applied. If no options were applied, then
* parts.assembled.command points to cmd. The constant 2 is due to 1 byte to
* specify array type and 1 byte for field name's null terminator. */
overhead =
parts.assembled.command->len + 2 + gCommandFieldLens[command->type];
/* Toss out the assembled command, we'll assemble again after adding all of
* the payload documents. */
mongoc_cmd_parts_cleanup (&parts);
reader = bson_reader_new_from_data (command->payload.data + data_offset,
command->payload.len - data_offset);
bson_append_array_begin (&cmd,
gCommandFields[command->type],
gCommandFieldLens[command->type],
&ar);
while ((bson = bson_reader_read (reader, &eof))) {
key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str);
len = bson->len;
/* 1 byte to specify document type, 1 byte for key's null terminator */
if (_mongoc_write_command_will_overflow (overhead,
key_len + len + 2 + ar.len,
i,
max_bson_obj_size,
max_write_batch_size)) {
has_more = true;
break;
}
BSON_APPEND_DOCUMENT (&ar, key, bson);
data_offset += len;
i++;
}
bson_append_array_end (&cmd, &ar);
if (!i) {
_mongoc_write_command_too_large_error (error, i, len, max_bson_obj_size);
result->failed = true;
result->must_stop = true;
ret = false;
if (bson) {
data_offset += len;
}
} else {
bson_t reply;
ret = _assemble_cmd (&cmd,
command,
client,
server_stream,
database,
write_concern,
&parts,
error);
if (ret) {
ret = mongoc_cluster_run_command_monitored (
&client->cluster, &parts.assembled, &reply, error);
} else {
bson_init (&reply);
}
if (!ret) {
result->failed = true;
- if (bson_empty (&reply)) {
+ if (bson_empty (&reply) ||
+ !mongoc_cluster_stream_valid (&client->cluster, server_stream)) {
/* assembling failed, or a network error running the command */
result->must_stop = true;
}
}
_mongoc_write_result_merge (result, command, &reply, offset);
offset += i;
bson_destroy (&reply);
mongoc_cmd_parts_cleanup (&parts);
}
bson_reader_destroy (reader);
if (has_more && (ret || !command->flags.ordered) && !result->must_stop) {
bson_reinit (&cmd);
GOTO (again);
}
bson_destroy (&cmd);
EXIT;
}
void
_mongoc_write_command_execute (
mongoc_write_command_t *command, /* IN */
mongoc_client_t *client, /* IN */
mongoc_server_stream_t *server_stream, /* IN */
const char *database, /* IN */
const char *collection, /* IN */
const mongoc_write_concern_t *write_concern, /* IN */
uint32_t offset, /* IN */
mongoc_client_session_t *cs, /* IN */
mongoc_write_result_t *result) /* OUT */
{
mongoc_crud_opts_t crud = {0};
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (server_stream);
BSON_ASSERT (database);
BSON_ASSERT (collection);
BSON_ASSERT (result);
if (!write_concern) {
write_concern = client->write_concern;
}
if (!mongoc_write_concern_is_valid (write_concern)) {
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The write concern is invalid.");
result->failed = true;
EXIT;
}
crud.client_session = cs;
crud.writeConcern = (mongoc_write_concern_t *) write_concern;
_mongoc_write_command_execute_idl (command,
client,
server_stream,
database,
collection,
offset,
&crud,
result);
EXIT;
}
void
_mongoc_write_command_execute_idl (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
const mongoc_crud_opts_t *crud,
mongoc_write_result_t *result)
{
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (server_stream);
BSON_ASSERT (database);
BSON_ASSERT (collection);
BSON_ASSERT (result);
if (command->flags.has_collation) {
if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
result->failed = true;
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set collation for unacknowledged writes");
EXIT;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) {
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
result->failed = true;
EXIT;
}
}
if (command->flags.has_array_filters) {
if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
result->failed = true;
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot use array filters with unacknowledged writes");
EXIT;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_ARRAY_FILTERS) {
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support array filters");
result->failed = true;
EXIT;
}
}
if (command->flags.has_update_hint) {
- if (server_stream->sd->max_wire_version < WIRE_VERSION_UPDATE_HINT) {
+ if (server_stream->sd->max_wire_version <
+ WIRE_VERSION_HINT_SERVER_SIDE_ERROR ||
+ (server_stream->sd->max_wire_version < WIRE_VERSION_UPDATE_HINT &&
+ !mongoc_write_concern_is_acknowledged (crud->writeConcern))) {
bson_set_error (
&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support hint for update");
result->failed = true;
EXIT;
}
}
+ if (command->flags.has_delete_hint) {
+ if (server_stream->sd->max_wire_version <
+ WIRE_VERSION_HINT_SERVER_SIDE_ERROR ||
+ (server_stream->sd->max_wire_version < WIRE_VERSION_DELETE_HINT &&
+ !mongoc_write_concern_is_acknowledged (crud->writeConcern))) {
+ bson_set_error (
+ &result->error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "The selected server does not support hint for delete");
+ result->failed = true;
+ EXIT;
+ }
+ }
+
if (command->flags.bypass_document_validation) {
if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
result->failed = true;
bson_set_error (
&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set bypassDocumentValidation for unacknowledged writes");
EXIT;
}
}
if (crud->client_session &&
!mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
result->failed = true;
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot use client session with unacknowledged writes");
EXIT;
}
if (command->payload.len == 0) {
_empty_error (command, &result->error);
EXIT;
}
if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
_mongoc_write_opmsg (command,
client,
server_stream,
database,
collection,
crud->writeConcern,
offset,
crud->client_session,
result,
&result->error);
} else {
if (mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
_mongoc_write_opquery (command,
client,
server_stream,
database,
collection,
crud->writeConcern,
offset,
result,
&result->error);
} else {
gLegacyWriteOps[command->type](command,
client,
server_stream,
database,
collection,
offset,
result,
&result->error);
}
}
EXIT;
}
void
_mongoc_write_command_destroy (mongoc_write_command_t *command)
{
ENTRY;
if (command) {
bson_destroy (&command->cmd_opts);
_mongoc_buffer_destroy (&command->payload);
}
EXIT;
}
void
_mongoc_write_result_init (mongoc_write_result_t *result) /* IN */
{
ENTRY;
BSON_ASSERT (result);
memset (result, 0, sizeof *result);
bson_init (&result->upserted);
bson_init (&result->writeConcernErrors);
bson_init (&result->writeErrors);
bson_init (&result->errorLabels);
EXIT;
}
void
_mongoc_write_result_destroy (mongoc_write_result_t *result)
{
ENTRY;
BSON_ASSERT (result);
bson_destroy (&result->upserted);
bson_destroy (&result->writeConcernErrors);
bson_destroy (&result->writeErrors);
bson_destroy (&result->errorLabels);
EXIT;
}
void
_mongoc_write_result_append_upsert (mongoc_write_result_t *result,
int32_t idx,
const bson_value_t *value)
{
bson_t child;
const char *keyptr = NULL;
char key[12];
int len;
BSON_ASSERT (result);
BSON_ASSERT (value);
len = (int) bson_uint32_to_string (
result->upsert_append_count, &keyptr, key, sizeof key);
bson_append_document_begin (&result->upserted, keyptr, len, &child);
BSON_APPEND_INT32 (&child, "index", idx);
BSON_APPEND_VALUE (&child, "_id", value);
bson_append_document_end (&result->upserted, &child);
result->upsert_append_count++;
}
int32_t
_mongoc_write_result_merge_arrays (uint32_t offset,
mongoc_write_result_t *result, /* IN */
bson_t *dest, /* IN */
bson_iter_t *iter) /* IN */
{
const bson_value_t *value;
bson_iter_t ar;
bson_iter_t citer;
int32_t idx;
int32_t count = 0;
int32_t aridx;
bson_t child;
const char *keyptr = NULL;
char key[12];
int len;
ENTRY;
BSON_ASSERT (result);
BSON_ASSERT (dest);
BSON_ASSERT (iter);
BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (iter));
aridx = bson_count_keys (dest);
if (bson_iter_recurse (iter, &ar)) {
while (bson_iter_next (&ar)) {
if (BSON_ITER_HOLDS_DOCUMENT (&ar) &&
bson_iter_recurse (&ar, &citer)) {
len =
(int) bson_uint32_to_string (aridx++, &keyptr, key, sizeof key);
bson_append_document_begin (dest, keyptr, len, &child);
while (bson_iter_next (&citer)) {
if (BSON_ITER_IS_KEY (&citer, "index")) {
idx = bson_iter_int32 (&citer) + offset;
BSON_APPEND_INT32 (&child, "index", idx);
} else {
value = bson_iter_value (&citer);
BSON_APPEND_VALUE (&child, bson_iter_key (&citer), value);
}
}
bson_append_document_end (dest, &child);
count++;
}
}
}
RETURN (count);
}
void
_mongoc_write_result_merge (mongoc_write_result_t *result, /* IN */
mongoc_write_command_t *command, /* IN */
const bson_t *reply, /* IN */
uint32_t offset)
{
int32_t server_index = 0;
const bson_value_t *value;
bson_iter_t iter;
bson_iter_t citer;
bson_iter_t ar;
int32_t n_upserted = 0;
int32_t affected = 0;
ENTRY;
BSON_ASSERT (result);
BSON_ASSERT (reply);
if (bson_iter_init_find (&iter, reply, "n") &&
BSON_ITER_HOLDS_INT32 (&iter)) {
affected = bson_iter_int32 (&iter);
}
if (bson_iter_init_find (&iter, reply, "writeErrors") &&
BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &citer) &&
bson_iter_next (&citer)) {
result->failed = true;
}
switch (command->type) {
case MONGOC_WRITE_COMMAND_INSERT:
result->nInserted += affected;
break;
case MONGOC_WRITE_COMMAND_DELETE:
result->nRemoved += affected;
break;
case MONGOC_WRITE_COMMAND_UPDATE:
/* server returns each upserted _id with its index into this batch
* look for "upserted": [{"index": 4, "_id": ObjectId()}, ...] */
if (bson_iter_init_find (&iter, reply, "upserted")) {
if (BSON_ITER_HOLDS_ARRAY (&iter) &&
(bson_iter_recurse (&iter, &ar))) {
while (bson_iter_next (&ar)) {
if (BSON_ITER_HOLDS_DOCUMENT (&ar) &&
bson_iter_recurse (&ar, &citer) &&
bson_iter_find (&citer, "index") &&
BSON_ITER_HOLDS_INT32 (&citer)) {
server_index = bson_iter_int32 (&citer);
if (bson_iter_recurse (&ar, &citer) &&
bson_iter_find (&citer, "_id")) {
value = bson_iter_value (&citer);
_mongoc_write_result_append_upsert (
result, offset + server_index, value);
n_upserted++;
}
}
}
}
result->nUpserted += n_upserted;
/*
* XXX: The following addition to nMatched needs some checking.
* I'm highly skeptical of it.
*/
result->nMatched += BSON_MAX (0, (affected - n_upserted));
} else {
result->nMatched += affected;
}
if (bson_iter_init_find (&iter, reply, "nModified") &&
BSON_ITER_HOLDS_INT32 (&iter)) {
result->nModified += bson_iter_int32 (&iter);
}
break;
default:
BSON_ASSERT (false);
break;
}
if (bson_iter_init_find (&iter, reply, "writeErrors") &&
BSON_ITER_HOLDS_ARRAY (&iter)) {
_mongoc_write_result_merge_arrays (
offset, result, &result->writeErrors, &iter);
}
if (bson_iter_init_find (&iter, reply, "writeConcernError") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
uint32_t len;
const uint8_t *data;
bson_t write_concern_error;
char str[16];
const char *key;
/* writeConcernError is a subdocument in the server response
* append it to the result->writeConcernErrors array */
bson_iter_document (&iter, &len, &data);
BSON_ASSERT (bson_init_static (&write_concern_error, data, len));
bson_uint32_to_string (
result->n_writeConcernErrors, &key, str, sizeof str);
if (!bson_append_document (
&result->writeConcernErrors, key, -1, &write_concern_error)) {
MONGOC_ERROR ("Error adding \"%s\" to writeConcernErrors.\n", key);
}
result->n_writeConcernErrors++;
}
/* inefficient if there are ever large numbers: for each label in each err,
* we linear-search result->errorLabels to see if it's included yet */
_mongoc_bson_array_copy_labels_to (reply, &result->errorLabels);
EXIT;
}
/*
* If error is not set, set code from first document in array like
* [{"code": 64, "errmsg": "duplicate"}, ...]. Format the error message
* from all errors in array.
*/
static void
_set_error_from_response (bson_t *bson_array,
mongoc_error_domain_t domain,
const char *error_type,
bson_error_t *error /* OUT */)
{
bson_iter_t array_iter;
bson_iter_t doc_iter;
bson_string_t *compound_err;
const char *errmsg = NULL;
int32_t code = 0;
uint32_t n_keys, i;
compound_err = bson_string_new (NULL);
n_keys = bson_count_keys (bson_array);
if (n_keys > 1) {
bson_string_append_printf (
compound_err, "Multiple %s errors: ", error_type);
}
if (!bson_empty0 (bson_array) && bson_iter_init (&array_iter, bson_array)) {
/* get first code and all error messages */
i = 0;
while (bson_iter_next (&array_iter)) {
if (BSON_ITER_HOLDS_DOCUMENT (&array_iter) &&
bson_iter_recurse (&array_iter, &doc_iter)) {
/* parse doc, which is like {"code": 64, "errmsg": "duplicate"} */
while (bson_iter_next (&doc_iter)) {
/* use the first error code we find */
if (BSON_ITER_IS_KEY (&doc_iter, "code") && code == 0) {
- code = bson_iter_int32 (&doc_iter);
+ code = (uint32_t) bson_iter_as_int64 (&doc_iter);
} else if (BSON_ITER_IS_KEY (&doc_iter, "errmsg")) {
errmsg = bson_iter_utf8 (&doc_iter, NULL);
/* build message like 'Multiple write errors: "foo", "bar"' */
if (n_keys > 1) {
bson_string_append_printf (compound_err, "\"%s\"", errmsg);
if (i < n_keys - 1) {
bson_string_append (compound_err, ", ");
}
} else {
/* single error message */
bson_string_append (compound_err, errmsg);
}
}
}
i++;
}
}
if (code && compound_err->len) {
bson_set_error (
error, domain, (uint32_t) code, "%s", compound_err->str);
}
}
bson_string_free (compound_err, true);
}
/* complete a write result, including only certain fields */
bool
_mongoc_write_result_complete (
mongoc_write_result_t *result, /* IN */
int32_t error_api_version, /* IN */
const mongoc_write_concern_t *wc, /* IN */
mongoc_error_domain_t err_domain_override, /* IN */
bson_t *bson, /* OUT */
bson_error_t *error, /* OUT */
...)
{
mongoc_error_domain_t domain;
va_list args;
const char *field;
int n_args;
bson_iter_t iter;
bson_iter_t child;
ENTRY;
BSON_ASSERT (result);
if (error_api_version >= MONGOC_ERROR_API_VERSION_2) {
domain = MONGOC_ERROR_SERVER;
} else if (err_domain_override) {
domain = err_domain_override;
} else if (result->error.domain) {
domain = (mongoc_error_domain_t) result->error.domain;
} else {
domain = MONGOC_ERROR_COLLECTION;
}
/* produce either old fields like nModified from the deprecated Bulk API Spec
* or new fields like modifiedCount from the CRUD Spec, which we partly obey
*/
if (bson && mongoc_write_concern_is_acknowledged (wc)) {
n_args = 0;
va_start (args, error);
while ((field = va_arg (args, const char *))) {
n_args++;
if (!strcmp (field, "nInserted")) {
BSON_APPEND_INT32 (bson, field, result->nInserted);
} else if (!strcmp (field, "insertedCount")) {
BSON_APPEND_INT32 (bson, field, result->nInserted);
} else if (!strcmp (field, "nMatched")) {
BSON_APPEND_INT32 (bson, field, result->nMatched);
} else if (!strcmp (field, "matchedCount")) {
BSON_APPEND_INT32 (bson, field, result->nMatched);
} else if (!strcmp (field, "nModified")) {
BSON_APPEND_INT32 (bson, field, result->nModified);
} else if (!strcmp (field, "modifiedCount")) {
BSON_APPEND_INT32 (bson, field, result->nModified);
} else if (!strcmp (field, "nRemoved")) {
BSON_APPEND_INT32 (bson, field, result->nRemoved);
} else if (!strcmp (field, "deletedCount")) {
BSON_APPEND_INT32 (bson, field, result->nRemoved);
} else if (!strcmp (field, "nUpserted")) {
BSON_APPEND_INT32 (bson, field, result->nUpserted);
} else if (!strcmp (field, "upsertedCount")) {
BSON_APPEND_INT32 (bson, field, result->nUpserted);
} else if (!strcmp (field, "upserted") &&
!bson_empty0 (&result->upserted)) {
BSON_APPEND_ARRAY (bson, field, &result->upserted);
} else if (!strcmp (field, "upsertedId") &&
!bson_empty0 (&result->upserted) &&
bson_iter_init_find (&iter, &result->upserted, "0") &&
bson_iter_recurse (&iter, &child) &&
bson_iter_find (&child, "_id")) {
/* "upsertedId", singular, for update_one() */
BSON_APPEND_VALUE (bson, "upsertedId", bson_iter_value (&child));
}
}
va_end (args);
/* default: a standard result includes all Bulk API fields */
if (!n_args) {
BSON_APPEND_INT32 (bson, "nInserted", result->nInserted);
BSON_APPEND_INT32 (bson, "nMatched", result->nMatched);
BSON_APPEND_INT32 (bson, "nModified", result->nModified);
BSON_APPEND_INT32 (bson, "nRemoved", result->nRemoved);
BSON_APPEND_INT32 (bson, "nUpserted", result->nUpserted);
if (!bson_empty0 (&result->upserted)) {
BSON_APPEND_ARRAY (bson, "upserted", &result->upserted);
}
}
/* always append errors if there are any */
if (!n_args || !bson_empty (&result->writeErrors)) {
BSON_APPEND_ARRAY (bson, "writeErrors", &result->writeErrors);
}
if (result->n_writeConcernErrors) {
BSON_APPEND_ARRAY (
bson, "writeConcernErrors", &result->writeConcernErrors);
}
}
/* set bson_error_t from first write error or write concern error */
_set_error_from_response (
&result->writeErrors, domain, "write", &result->error);
if (!result->error.code) {
_set_error_from_response (&result->writeConcernErrors,
MONGOC_ERROR_WRITE_CONCERN,
"write concern",
&result->error);
}
if (bson && !bson_empty (&result->errorLabels)) {
BSON_APPEND_ARRAY (bson, "errorLabels", &result->errorLabels);
}
if (error) {
memcpy (error, &result->error, sizeof *error);
}
RETURN (!result->failed && result->error.code == 0);
}
/*--------------------------------------------------------------------------
*
* _mongoc_write_error_get_type --
*
* Checks if the error or reply from a write command is considered
* retryable according to the retryable writes spec. Checks both
* for a client error (a network exception) and a server error in
* the reply. @cmd_ret and @cmd_err come from the result of a
- * write_command function.
+ * write_command function. This function should be called after
+ * error labels are appended in _mongoc_write_error_handle_labels,
+ * which should be called after mongoc_cluster_run_command_monitored.
*
*
* Return:
* A mongoc_write_error_type_t indicating the type of error (if any).
*
*--------------------------------------------------------------------------
*/
mongoc_write_err_type_t
-_mongoc_write_error_get_type (bool cmd_ret,
- const bson_error_t *cmd_err,
- const bson_t *reply)
+_mongoc_write_error_get_type (bson_t *reply)
{
bson_error_t error;
- /* check for a client error. */
- if (!cmd_ret && cmd_err->domain == MONGOC_ERROR_STREAM) {
- /* Retryable writes spec: "considered retryable if [...] any network
- * exception (e.g. socket timeout or error) */
+ if (mongoc_error_has_label (reply, RETRYABLE_WRITE_ERROR)) {
return MONGOC_WRITE_ERR_RETRY;
}
/* check for a server error. */
if (_mongoc_cmd_check_ok_no_wce (
reply, MONGOC_ERROR_API_VERSION_2, &error)) {
return MONGOC_WRITE_ERR_NONE;
}
switch (error.code) {
- case 11600: /* InterruptedAtShutdown */
- case 11602: /* InterruptedDueToReplStateChange */
- case 10107: /* NotMaster */
- case 13435: /* NotMasterNoSlaveOk */
- case 13436: /* NotMasterOrSecondary */
- case 189: /* PrimarySteppedDown */
- case 91: /* ShutdownInProgress */
- case 7: /* HostNotFound */
- case 6: /* HostUnreachable */
- case 89: /* NetworkTimeout */
- case 9001: /* SocketException */
- return MONGOC_WRITE_ERR_RETRY;
case 64: /* WriteConcernFailed */
return MONGOC_WRITE_ERR_WRITE_CONCERN;
default:
- if (strstr (error.message, "not master") ||
- strstr (error.message, "node is recovering")) {
- return MONGOC_WRITE_ERR_RETRY;
- }
return MONGOC_WRITE_ERR_OTHER;
}
}
/* Returns true and modifies reply and cmd_err. */
bool
_mongoc_write_error_update_if_unsupported_storage_engine (bool cmd_ret,
bson_error_t *cmd_err,
bson_t *reply)
{
bson_error_t server_error;
if (cmd_ret) {
return false;
}
if (_mongoc_cmd_check_ok_no_wce (
reply, MONGOC_ERROR_API_VERSION_2, &server_error)) {
return false;
}
if (server_error.code == 20 &&
strstr (server_error.message, "Transaction numbers") ==
server_error.message) {
const char *replacement = "This MongoDB deployment does not support "
"retryable writes. Please add "
"retryWrites=false to your connection string.";
strcpy (cmd_err->message, replacement);
if (reply) {
bson_t *new_reply = bson_new ();
bson_copy_to_excluding_noinit (reply, new_reply, "errmsg", NULL);
BSON_APPEND_UTF8 (new_reply, "errmsg", replacement);
bson_destroy (reply);
bson_steal (reply, new_reply);
}
return true;
}
return false;
-}
\ No newline at end of file
+}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c
index 9cfabb29..130375eb 100644
--- a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c
+++ b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c
@@ -1,595 +1,595 @@
/*
* Copyright 2013 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.
*/
#include "mongoc-error.h"
#include "mongoc-log.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern.h"
#include "mongoc-write-concern-private.h"
static void
_mongoc_write_concern_freeze (mongoc_write_concern_t *write_concern);
/**
* mongoc_write_concern_new:
*
* Create a new mongoc_write_concern_t.
*
* Returns: A newly allocated mongoc_write_concern_t. This should be freed
* with mongoc_write_concern_destroy().
*/
mongoc_write_concern_t *
mongoc_write_concern_new (void)
{
mongoc_write_concern_t *write_concern;
write_concern =
(mongoc_write_concern_t *) bson_malloc0 (sizeof *write_concern);
write_concern->w = MONGOC_WRITE_CONCERN_W_DEFAULT;
write_concern->fsync_ = MONGOC_WRITE_CONCERN_FSYNC_DEFAULT;
write_concern->journal = MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT;
write_concern->is_default = true;
bson_init (&write_concern->compiled);
return write_concern;
}
mongoc_write_concern_t *
mongoc_write_concern_copy (const mongoc_write_concern_t *write_concern)
{
mongoc_write_concern_t *ret = NULL;
if (write_concern) {
ret = mongoc_write_concern_new ();
ret->fsync_ = write_concern->fsync_;
ret->journal = write_concern->journal;
ret->w = write_concern->w;
ret->wtimeout = write_concern->wtimeout;
ret->frozen = false;
ret->wtag = bson_strdup (write_concern->wtag);
ret->is_default = write_concern->is_default;
}
return ret;
}
/**
* mongoc_write_concern_destroy:
* @write_concern: A mongoc_write_concern_t.
*
* Releases a mongoc_write_concern_t and all associated memory.
*/
void
mongoc_write_concern_destroy (mongoc_write_concern_t *write_concern)
{
if (write_concern) {
bson_destroy (&write_concern->compiled);
bson_free (write_concern->wtag);
bson_free (write_concern);
}
}
bool
mongoc_write_concern_get_fsync (const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (write_concern);
return (write_concern->fsync_ == true);
}
/**
* mongoc_write_concern_set_fsync:
* @write_concern: A mongoc_write_concern_t.
* @fsync_: If the write concern requires fsync() by the server.
*
* Set if fsync() should be called on the server before acknowledging a
* write request.
*/
void
mongoc_write_concern_set_fsync (mongoc_write_concern_t *write_concern,
bool fsync_)
{
BSON_ASSERT (write_concern);
write_concern->fsync_ = !!fsync_;
write_concern->is_default = false;
write_concern->frozen = false;
}
bool
mongoc_write_concern_get_journal (const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (write_concern);
return (write_concern->journal == true);
}
bool
mongoc_write_concern_journal_is_set (
const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (write_concern);
return (write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT);
}
/**
* mongoc_write_concern_set_journal:
* @write_concern: A mongoc_write_concern_t.
* @journal: If the write should be journaled.
*
* Set if the write request should be journaled before acknowledging the
* write request.
*/
void
mongoc_write_concern_set_journal (mongoc_write_concern_t *write_concern,
bool journal)
{
BSON_ASSERT (write_concern);
write_concern->journal = !!journal;
write_concern->is_default = false;
write_concern->frozen = false;
}
int32_t
mongoc_write_concern_get_w (const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (write_concern);
return write_concern->w;
}
/**
* mongoc_write_concern_set_w:
* @w: The number of nodes for write or MONGOC_WRITE_CONCERN_W_MAJORITY
* for "majority".
*
* Sets the number of nodes that must acknowledge the write request before
* acknowledging the write request to the client.
*
* You may specify @w as MONGOC_WRITE_CONCERN_W_MAJORITY to request that
* a "majority" of nodes acknowledge the request.
*/
void
mongoc_write_concern_set_w (mongoc_write_concern_t *write_concern, int32_t w)
{
BSON_ASSERT (write_concern);
BSON_ASSERT (w >= -3);
write_concern->w = w;
if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) {
write_concern->is_default = false;
}
write_concern->frozen = false;
}
int32_t
mongoc_write_concern_get_wtimeout (const mongoc_write_concern_t *write_concern)
{
return (int32_t) mongoc_write_concern_get_wtimeout_int64 (write_concern);
}
int64_t
mongoc_write_concern_get_wtimeout_int64 (
const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (write_concern);
return write_concern->wtimeout;
}
void
mongoc_write_concern_set_wtimeout (mongoc_write_concern_t *write_concern,
int32_t wtimeout_msec)
{
mongoc_write_concern_set_wtimeout_int64 (write_concern,
(int64_t) wtimeout_msec);
}
void
mongoc_write_concern_set_wtimeout_int64 (mongoc_write_concern_t *write_concern,
int64_t wtimeout_msec)
{
BSON_ASSERT (write_concern);
if (wtimeout_msec < 0) {
return;
}
write_concern->wtimeout = wtimeout_msec;
write_concern->is_default = false;
write_concern->frozen = false;
}
bool
mongoc_write_concern_get_wmajority (const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (write_concern);
return (write_concern->w == MONGOC_WRITE_CONCERN_W_MAJORITY);
}
/**
* mongoc_write_concern_set_wmajority:
* @write_concern: A mongoc_write_concern_t.
* @wtimeout_msec: Number of milliseconds before timeout.
*
* Sets the "w" of a write concern to "majority". It is suggested that
* you provide a reasonable @wtimeout_msec to wait before considering the
* write request failed. A @wtimeout_msec value of 0 indicates no write timeout.
*
* The @wtimeout_msec parameter must be positive or zero. Negative values will
* be ignored.
*/
void
mongoc_write_concern_set_wmajority (mongoc_write_concern_t *write_concern,
int32_t wtimeout_msec)
{
BSON_ASSERT (write_concern);
write_concern->w = MONGOC_WRITE_CONCERN_W_MAJORITY;
write_concern->is_default = false;
write_concern->frozen = false;
if (wtimeout_msec >= 0) {
write_concern->wtimeout = wtimeout_msec;
}
}
const char *
mongoc_write_concern_get_wtag (const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (write_concern);
if (write_concern->w == MONGOC_WRITE_CONCERN_W_TAG) {
return write_concern->wtag;
}
return NULL;
}
void
mongoc_write_concern_set_wtag (mongoc_write_concern_t *write_concern,
const char *wtag)
{
BSON_ASSERT (write_concern);
bson_free (write_concern->wtag);
write_concern->wtag = bson_strdup (wtag);
write_concern->w = MONGOC_WRITE_CONCERN_W_TAG;
write_concern->is_default = false;
write_concern->frozen = false;
}
/**
* mongoc_write_concern_get_bson:
* @write_concern: A mongoc_write_concern_t.
*
* This is an internal function.
*
* Returns: A bson_t representing the write concern, which is owned by the
* mongoc_write_concern_t instance and should not be modified or freed.
*/
const bson_t *
_mongoc_write_concern_get_bson (mongoc_write_concern_t *write_concern)
{
if (!write_concern->frozen) {
_mongoc_write_concern_freeze (write_concern);
}
return &write_concern->compiled;
}
/**
* mongoc_write_concern_is_default:
* @write_concern: A mongoc_write_concern_t.
*
* Returns is_default, which is true when write_concern has not been modified.
*
*/
bool
mongoc_write_concern_is_default (const mongoc_write_concern_t *write_concern)
{
return !write_concern || write_concern->is_default;
}
/**
* mongoc_write_concern_freeze:
* @write_concern: A mongoc_write_concern_t.
*
* This is an internal function.
*
* Encodes the write concern into a bson_t, which may then be returned by
* _mongoc_write_concern_get_bson().
*/
static void
_mongoc_write_concern_freeze (mongoc_write_concern_t *write_concern)
{
bson_t *compiled;
BSON_ASSERT (write_concern);
compiled = &write_concern->compiled;
write_concern->frozen = true;
bson_reinit (compiled);
if (write_concern->w == MONGOC_WRITE_CONCERN_W_TAG) {
BSON_ASSERT (write_concern->wtag);
BSON_APPEND_UTF8 (compiled, "w", write_concern->wtag);
} else if (write_concern->w == MONGOC_WRITE_CONCERN_W_MAJORITY) {
BSON_APPEND_UTF8 (compiled, "w", "majority");
} else if (write_concern->w == MONGOC_WRITE_CONCERN_W_DEFAULT) {
/* Do Nothing */
} else {
BSON_APPEND_INT32 (compiled, "w", write_concern->w);
}
if (write_concern->fsync_ != MONGOC_WRITE_CONCERN_FSYNC_DEFAULT) {
bson_append_bool (compiled, "fsync", 5, !!write_concern->fsync_);
}
if (write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT) {
bson_append_bool (compiled, "j", 1, !!write_concern->journal);
}
if (write_concern->wtimeout) {
bson_append_int64 (compiled, "wtimeout", 8, write_concern->wtimeout);
}
}
/**
* mongoc_write_concern_is_acknowledged:
* @concern: (in): A mongoc_write_concern_t.
*
* Checks to see if @write_concern requests that a getlasterror command is to
* be delivered to the MongoDB server.
*
* Returns: true if a getlasterror command should be sent.
*/
bool
mongoc_write_concern_is_acknowledged (
const mongoc_write_concern_t *write_concern)
{
if (write_concern) {
return (((write_concern->w != MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED) &&
(write_concern->w != MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED)) ||
write_concern->fsync_ == true ||
mongoc_write_concern_get_journal (write_concern));
}
return true;
}
/**
* mongoc_write_concern_is_valid:
* @write_concern: (in): A mongoc_write_concern_t.
*
* Checks to see if @write_concern is valid and does not contain conflicting
* options.
*
* Returns: true if the write concern is valid; otherwise false.
*/
bool
mongoc_write_concern_is_valid (const mongoc_write_concern_t *write_concern)
{
if (!write_concern) {
return false;
}
/* Journal or fsync should require acknowledgement. */
if ((write_concern->fsync_ == true ||
mongoc_write_concern_get_journal (write_concern)) &&
(write_concern->w == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED ||
write_concern->w == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED)) {
return false;
}
if (write_concern->wtimeout < 0) {
return false;
}
return true;
}
static bool
_mongoc_write_concern_validate (const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
if (write_concern && !mongoc_write_concern_is_valid (write_concern)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid writeConcern");
return false;
}
return true;
}
/**
* _mongoc_parse_wc_err:
* @doc: (in): A bson document.
* @error: (out): A bson_error_t.
*
* Parses a document, usually a server reply,
* looking for a writeConcernError. Returns true if
* there is a writeConcernError, false otherwise.
*/
bool
_mongoc_parse_wc_err (const bson_t *doc, bson_error_t *error)
{
bson_iter_t iter;
bson_iter_t inner;
if (bson_iter_init_find (&iter, doc, "writeConcernError") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
const char *errmsg = NULL;
int32_t code = 0;
BSON_ASSERT (bson_iter_recurse (&iter, &inner));
while (bson_iter_next (&inner)) {
if (BSON_ITER_IS_KEY (&inner, "code")) {
- code = bson_iter_int32 (&inner);
+ code = (uint32_t) bson_iter_as_int64 (&inner);
} else if (BSON_ITER_IS_KEY (&inner, "errmsg")) {
errmsg = bson_iter_utf8 (&inner, NULL);
}
}
bson_set_error (error,
MONGOC_ERROR_WRITE_CONCERN,
code,
"Write Concern error: %s",
errmsg);
return true;
}
return false;
}
/**
* mongoc_write_concern_append:
* @write_concern: (in): A mongoc_write_concern_t.
* @command: (out): A pointer to a bson document.
*
* Appends a write_concern document to a command, to send to
* a server.
*
* Returns true on success, false on failure.
*
*/
bool
mongoc_write_concern_append (mongoc_write_concern_t *write_concern,
bson_t *command)
{
if (!mongoc_write_concern_is_valid (write_concern)) {
MONGOC_ERROR ("Invalid writeConcern passed into "
"mongoc_write_concern_append.");
return false;
}
if (!bson_append_document (command,
"writeConcern",
12,
_mongoc_write_concern_get_bson (write_concern))) {
MONGOC_ERROR ("Could not append writeConcern to command.");
return false;
}
return true;
}
/**
* _mongoc_write_concern_new_from_iter:
*
* Create a new mongoc_write_concern_t from an iterator positioned on
* a "writeConcern" document.
*
* Returns: A newly allocated mongoc_write_concern_t. This should be freed
* with mongoc_write_concern_destroy().
*/
mongoc_write_concern_t *
_mongoc_write_concern_new_from_iter (const bson_iter_t *iter,
bson_error_t *error)
{
bson_iter_t inner;
mongoc_write_concern_t *write_concern;
int32_t w;
BSON_ASSERT (iter);
write_concern = mongoc_write_concern_new ();
if (!BSON_ITER_HOLDS_DOCUMENT (iter)) {
goto fail;
}
BSON_ASSERT (bson_iter_recurse (iter, &inner));
while (bson_iter_next (&inner)) {
if (BSON_ITER_IS_KEY (&inner, "w")) {
if (BSON_ITER_HOLDS_INT32 (&inner)) {
w = bson_iter_int32 (&inner);
if (w < MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED) {
goto fail;
}
mongoc_write_concern_set_w (write_concern, w);
} else if (BSON_ITER_HOLDS_UTF8 (&inner)) {
if (!strcmp (bson_iter_utf8 (&inner, NULL), "majority")) {
/* mongoc_write_concern_set_wmajority() only assigns wtimeout if
* it is >= 0. Since we set wtimeout below, pass -1 here. */
mongoc_write_concern_set_wmajority (write_concern, -1);
} else {
mongoc_write_concern_set_wtag (write_concern,
bson_iter_utf8 (&inner, NULL));
}
} else {
/* wrong type for "w" */
goto fail;
}
} else if (BSON_ITER_IS_KEY (&inner, "fsync")) {
if (!BSON_ITER_HOLDS_BOOL (&inner)) {
goto fail;
}
BEGIN_IGNORE_DEPRECATIONS;
mongoc_write_concern_set_fsync (write_concern,
bson_iter_bool (&inner));
END_IGNORE_DEPRECATIONS;
} else if (BSON_ITER_IS_KEY (&inner, "j")) {
if (!BSON_ITER_HOLDS_BOOL (&inner)) {
goto fail;
}
mongoc_write_concern_set_journal (write_concern,
bson_iter_bool (&inner));
} else if (BSON_ITER_IS_KEY (&inner, "wtimeout")) {
if (!BSON_ITER_HOLDS_INT (&inner) || bson_iter_as_int64 (&inner) < 0) {
goto fail;
}
mongoc_write_concern_set_wtimeout_int64 (write_concern,
bson_iter_as_int64 (&inner));
}
}
if (!_mongoc_write_concern_validate (write_concern, error)) {
mongoc_write_concern_destroy (write_concern);
return NULL;
}
return write_concern;
fail:
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid writeConcern");
mongoc_write_concern_destroy (write_concern);
return NULL;
}
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/mongoc.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/mongoc.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-delete.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-delete.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-delete.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-delete.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-header.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-header.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-header.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-header.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-insert.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-insert.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-insert.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-insert.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-msg.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-msg.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-msg.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-msg.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-query.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-query.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-query.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-query.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-reply.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-reply.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-reply.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-reply.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-update.def b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-update.def
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/op-update.def
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/op-update.def
diff --git a/mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/utlist.h b/mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/utlist.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/libmongoc/src/mongoc/utlist.h
rename to mongodb-1.8.1/src/libmongoc/src/libmongoc/src/mongoc/utlist.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/adler32.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/adler32.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/adler32.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/adler32.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/compress.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/compress.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/compress.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/compress.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/crc32.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/crc32.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/crc32.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/crc32.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/crc32.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/crc32.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/crc32.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/crc32.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/deflate.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/deflate.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/deflate.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/deflate.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/deflate.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/deflate.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/deflate.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/deflate.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzclose.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzclose.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzclose.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzclose.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzguts.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzguts.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzguts.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzguts.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzlib.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzlib.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzlib.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzlib.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzread.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzread.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzread.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzread.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzwrite.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzwrite.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/gzwrite.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/gzwrite.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/infback.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/infback.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/infback.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/infback.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inffast.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inffast.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inffast.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inffast.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inffast.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inffast.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inffast.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inffast.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inffixed.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inffixed.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inffixed.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inffixed.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inflate.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inflate.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inflate.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inflate.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inflate.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inflate.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inflate.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inflate.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inftrees.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inftrees.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inftrees.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inftrees.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inftrees.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inftrees.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/inftrees.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/inftrees.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/trees.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/trees.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/trees.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/trees.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/trees.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/trees.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/trees.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/trees.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/uncompr.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/uncompr.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/uncompr.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/uncompr.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zconf.h.in b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zconf.h
similarity index 100%
copy from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zconf.h.in
copy to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zconf.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zconf.h.in b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zconf.h.in
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zconf.h.in
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zconf.h.in
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zlib.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zlib.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zlib.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zlib.h
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zutil.c b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zutil.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zutil.c
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zutil.c
diff --git a/mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zutil.h b/mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zutil.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongoc/src/zlib-1.2.11/zutil.h
rename to mongodb-1.8.1/src/libmongoc/src/zlib-1.2.11/zutil.h
diff --git a/mongodb-1.7.4/src/libmongocrypt-compat/mongocrypt-export.h b/mongodb-1.8.1/src/libmongocrypt-compat/mongocrypt-export.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt-compat/mongocrypt-export.h
rename to mongodb-1.8.1/src/libmongocrypt-compat/mongocrypt-export.h
diff --git a/mongodb-1.7.4/src/libmongocrypt-compat/mongocrypt/mongocrypt.h b/mongodb-1.8.1/src/libmongocrypt-compat/mongocrypt/mongocrypt.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt-compat/mongocrypt/mongocrypt.h
rename to mongodb-1.8.1/src/libmongocrypt-compat/mongocrypt/mongocrypt.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/hexlify.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/hexlify.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/hexlify.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/hexlify.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/hexlify.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/hexlify.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/hexlify.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/hexlify.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_b64.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_b64.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_b64.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_b64.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_apple.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto_apple.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_apple.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto_apple.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_none.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto_none.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_none.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto_none.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_windows.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto_windows.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_crypto_windows.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_crypto_windows.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_decrypt_request.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_decrypt_request.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_decrypt_request.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_decrypt_request.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_encrypt_request.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_encrypt_request.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_encrypt_request.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_encrypt_request.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_kv_list.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_kv_list.c
index 3678900a..0cff3dc2 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.c
+++ b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_kv_list.c
@@ -1,149 +1,149 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "kms_kv_list.h"
#include "kms_message/kms_message.h"
#include "kms_message_private.h"
#include "kms_request_str.h"
#include "kms_port.h"
#include "sort.h"
static void
kv_init (kms_kv_t *kv, kms_request_str_t *key, kms_request_str_t *value)
{
kv->key = kms_request_str_dup (key);
kv->value = kms_request_str_dup (value);
}
static void
kv_cleanup (kms_kv_t *kv)
{
kms_request_str_destroy (kv->key);
kms_request_str_destroy (kv->value);
}
kms_kv_list_t *
kms_kv_list_new (void)
{
kms_kv_list_t *lst = malloc (sizeof (kms_kv_list_t));
KMS_ASSERT (lst);
lst->size = 16;
lst->kvs = malloc (lst->size * sizeof (kms_kv_t));
KMS_ASSERT (lst->kvs);
lst->len = 0;
return lst;
}
void
kms_kv_list_destroy (kms_kv_list_t *lst)
{
size_t i;
if (!lst) {
return;
}
for (i = 0; i < lst->len; i++) {
kv_cleanup (&lst->kvs[i]);
}
free (lst->kvs);
free (lst);
}
void
kms_kv_list_add (kms_kv_list_t *lst,
kms_request_str_t *key,
kms_request_str_t *value)
{
if (lst->len == lst->size) {
lst->size *= 2;
lst->kvs = realloc (lst->kvs, lst->size * sizeof (kms_kv_t));
KMS_ASSERT (lst->kvs);
}
kv_init (&lst->kvs[lst->len], key, value);
++lst->len;
}
const kms_kv_t *
kms_kv_list_find (const kms_kv_list_t *lst, const char *key)
{
size_t i;
for (i = 0; i < lst->len; i++) {
- if (0 == strcasecmp (lst->kvs[i].key->str, key)) {
+ if (0 == kms_strcasecmp (lst->kvs[i].key->str, key)) {
return &lst->kvs[i];
}
}
return NULL;
}
void
kms_kv_list_del (kms_kv_list_t *lst, const char *key)
{
size_t i;
for (i = 0; i < lst->len; i++) {
if (0 == strcmp (lst->kvs[i].key->str, key)) {
kv_cleanup (&lst->kvs[i]);
memmove (&lst->kvs[i],
&lst->kvs[i + 1],
sizeof (kms_kv_t) * (lst->len - i - 1));
lst->len--;
}
}
}
kms_kv_list_t *
kms_kv_list_dup (const kms_kv_list_t *lst)
{
kms_kv_list_t *dup;
size_t i;
if (lst->len == 0) {
return kms_kv_list_new ();
}
dup = malloc (sizeof (kms_kv_list_t));
KMS_ASSERT (dup);
dup->size = dup->len = lst->len;
dup->kvs = malloc (lst->len * sizeof (kms_kv_t));
KMS_ASSERT (dup->kvs);
for (i = 0; i < lst->len; i++) {
kv_init (&dup->kvs[i], lst->kvs[i].key, lst->kvs[i].value);
}
return dup;
}
void
kms_kv_list_sort (kms_kv_list_t *lst, int (*cmp) (const void *, const void *))
{
/* A stable sort is required to sort headers when creating canonical
* requests. qsort is not stable. */
insertionsort (
(unsigned char *) (lst->kvs), lst->len, sizeof (kms_kv_t), cmp);
}
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_kv_list.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_kv_list.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_kv_list.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_message.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_message.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_message.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_message.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_request.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_request.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_request.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_request.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_response.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_response.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_response.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_response.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message_private.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message_private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_message_private.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_message_private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_port.c
similarity index 81%
copy from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h
copy to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_port.c
index c3cbbac3..ee9e6ed9 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h
+++ b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_port.c
@@ -1,35 +1,33 @@
/*
- * Copyright 2018-present MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"){}
+ * Copyright 2020-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
*
* 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.
*/
+#include "kms_port.h"
#if defined(_WIN32)
-#define strcasecmp _stricmp
-
-inline char *
-strndup (const char *src, size_t len)
+#include <stdlib.h>
+#include <string.h>
+char * kms_strndup (const char *src, size_t len)
{
char *dst = (char *) malloc (len + 1);
if (!dst) {
return 0;
}
memcpy (dst, src, len);
dst[len] = '\0';
return dst;
}
-
-#endif
+#endif
\ No newline at end of file
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_port.h
similarity index 73%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_port.h
index c3cbbac3..2123a99d 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_port.h
+++ b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_port.h
@@ -1,35 +1,32 @@
/*
* Copyright 2018-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
*
* 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.
*/
-#if defined(_WIN32)
-#define strcasecmp _stricmp
-
-inline char *
-strndup (const char *src, size_t len)
-{
- char *dst = (char *) malloc (len + 1);
- if (!dst) {
- return 0;
- }
-
- memcpy (dst, src, len);
- dst[len] = '\0';
+#ifndef KMS_PORT_H
+#define KMS_PORT_H
- return dst;
-}
+#include <stddef.h>
+#if defined(_WIN32)
+#define kms_strcasecmp _stricmp
+char *
+kms_strndup (const char *src, size_t len);
+#else
+#define kms_strndup strndup
+#define kms_strcasecmp strcasecmp
#endif
+
+#endif /* KMS_PORT_H */
\ No newline at end of file
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request.c
index 7f273b7e..ac2b07ea 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request.c
+++ b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request.c
@@ -1,760 +1,763 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "kms_crypto.h"
#include "kms_message/kms_message.h"
#include "kms_message_private.h"
#include "kms_request_opt_private.h"
#include "kms_port.h"
static kms_kv_list_t *
parse_query_params (kms_request_str_t *q)
{
kms_kv_list_t *lst = kms_kv_list_new ();
char *p = q->str;
char *end = q->str + q->len;
char *amp, *equals;
kms_request_str_t *k, *v;
do {
equals = strchr ((const char *) p, '=');
if (!equals) {
kms_kv_list_destroy (lst);
return NULL;
}
amp = strchr ((const char *) equals, '&');
if (!amp) {
amp = end;
}
k = kms_request_str_new_from_chars (p, equals - p);
v = kms_request_str_new_from_chars (equals + 1, amp - equals - 1);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
p = amp + 1;
} while (p < end);
return lst;
}
kms_request_t *
kms_request_new (const char *method,
const char *path_and_query,
const kms_request_opt_t *opt)
{
kms_request_t *request = calloc (1, sizeof (kms_request_t));
const char *question_mark;
KMS_ASSERT (request);
/* parsing may set failed to true */
request->failed = false;
request->finalized = false;
request->region = kms_request_str_new ();
request->service = kms_request_str_new ();
request->access_key_id = kms_request_str_new ();
request->secret_key = kms_request_str_new ();
question_mark = strchr (path_and_query, '?');
if (question_mark) {
request->path = kms_request_str_new_from_chars (
path_and_query, question_mark - path_and_query);
request->query = kms_request_str_new_from_chars (question_mark + 1, -1);
request->query_params = parse_query_params (request->query);
if (!request->query_params) {
KMS_ERROR (request, "Cannot parse query: %s", request->query->str);
}
} else {
request->path = kms_request_str_new_from_chars (path_and_query, -1);
request->query = kms_request_str_new ();
request->query_params = kms_kv_list_new ();
}
request->payload = kms_request_str_new ();
request->date = kms_request_str_new ();
request->datetime = kms_request_str_new ();
request->method = kms_request_str_new_from_chars (method, -1);
request->header_fields = kms_kv_list_new ();
request->auto_content_length = true;
if (!kms_request_set_date (request, NULL)) {
return request;
}
if (opt && opt->connection_close) {
if (!kms_request_add_header_field (request, "Connection", "close")) {
return request;
}
}
if (opt && opt->crypto.sha256) {
memcpy (&request->crypto, &opt->crypto, sizeof (opt->crypto));
} else {
request->crypto.sha256 = kms_sha256;
request->crypto.sha256_hmac = kms_sha256_hmac;
}
return request;
}
void
kms_request_destroy (kms_request_t *request)
{
kms_request_str_destroy (request->region);
kms_request_str_destroy (request->service);
kms_request_str_destroy (request->access_key_id);
kms_request_str_destroy (request->secret_key);
kms_request_str_destroy (request->method);
kms_request_str_destroy (request->path);
kms_request_str_destroy (request->query);
kms_request_str_destroy (request->payload);
kms_request_str_destroy (request->datetime);
kms_request_str_destroy (request->date);
kms_kv_list_destroy (request->query_params);
kms_kv_list_destroy (request->header_fields);
free (request);
}
const char *
kms_request_get_error (kms_request_t *request)
{
return request->failed ? request->error : NULL;
}
#define AMZ_DT_FORMAT "YYYYmmDDTHHMMSSZ"
bool
kms_request_set_date (kms_request_t *request, const struct tm *tm)
{
char buf[sizeof AMZ_DT_FORMAT];
struct tm tmp_tm;
if (request->failed) {
return false;
}
if (!tm) {
/* use current time */
time_t t;
time (&t);
#ifdef _WIN32
gmtime_s (&tmp_tm, &t);
#else
gmtime_r (&t, &tmp_tm);
#endif
tm = &tmp_tm;
}
if (0 == strftime (buf, sizeof AMZ_DT_FORMAT, "%Y%m%dT%H%M%SZ", tm)) {
KMS_ERROR (request, "Invalid tm struct");
return false;
}
kms_request_str_set_chars (request->date, buf, sizeof "YYYYmmDD" - 1);
kms_request_str_set_chars (request->datetime, buf, sizeof AMZ_DT_FORMAT - 1);
kms_kv_list_del (request->header_fields, "X-Amz-Date");
if (!kms_request_add_header_field (request, "X-Amz-Date", buf)) {
return false;
}
return true;
}
#undef AMZ_DT_FORMAT
bool
kms_request_set_region (kms_request_t *request, const char *region)
{
kms_request_str_set_chars (request->region, region, -1);
return true;
}
bool
kms_request_set_service (kms_request_t *request, const char *service)
{
kms_request_str_set_chars (request->service, service, -1);
return true;
}
bool
kms_request_set_access_key_id (kms_request_t *request, const char *akid)
{
kms_request_str_set_chars (request->access_key_id, akid, -1);
return true;
}
bool
kms_request_set_secret_key (kms_request_t *request, const char *key)
{
kms_request_str_set_chars (request->secret_key, key, -1);
return true;
}
bool
kms_request_add_header_field (kms_request_t *request,
const char *field_name,
const char *value)
{
kms_request_str_t *k, *v;
CHECK_FAILED;
k = kms_request_str_new_from_chars (field_name, -1);
v = kms_request_str_new_from_chars (value, -1);
kms_kv_list_add (request->header_fields, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
return true;
}
bool
kms_request_append_header_field_value (kms_request_t *request,
const char *value,
size_t len)
{
kms_request_str_t *v;
CHECK_FAILED;
if (request->header_fields->len == 0) {
KMS_ERROR (
request,
"Ensure the request has at least one header field before calling %s",
__FUNCTION__);
}
v = request->header_fields->kvs[request->header_fields->len - 1].value;
kms_request_str_append_chars (v, value, len);
return true;
}
bool
kms_request_append_payload (kms_request_t *request,
const char *payload,
size_t len)
{
CHECK_FAILED;
kms_request_str_append_chars (request->payload, payload, len);
return true;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
*
* "Sort the parameter names by character code point in ascending order. For
* example, a parameter name that begins with the uppercase letter F precedes a
* parameter name that begins with a lowercase letter b."
*/
static int
cmp_query_params (const void *a, const void *b)
{
int r = strcmp (((kms_kv_t *) a)->key->str, ((kms_kv_t *) b)->key->str);
if (r != 0) {
return r;
}
/* not in docs, but tested in get-vanilla-query-order-key: sort by value */
return strcmp (((kms_kv_t *) a)->value->str, ((kms_kv_t *) b)->value->str);
}
static void
append_canonical_query (kms_request_t *request, kms_request_str_t *str)
{
size_t i;
kms_kv_list_t *lst;
if (!request->query_params->len) {
return;
}
lst = kms_kv_list_dup (request->query_params);
kms_kv_list_sort (lst, cmp_query_params);
for (i = 0; i < lst->len; i++) {
kms_request_str_append_escaped (str, lst->kvs[i].key, true);
kms_request_str_append_char (str, '=');
kms_request_str_append_escaped (str, lst->kvs[i].value, true);
if (i < lst->len - 1) {
kms_request_str_append_char (str, '&');
}
}
kms_kv_list_destroy (lst);
}
/* "lst" is a sorted list of headers */
static void
append_canonical_headers (kms_kv_list_t *lst, kms_request_str_t *str)
{
size_t i;
kms_kv_t *kv;
const kms_request_str_t *previous_key = NULL;
/* aws docs: "To create the canonical headers list, convert all header names
* to lowercase and remove leading spaces and trailing spaces. Convert
* sequential spaces in the header value to a single space." "Do not sort the
* values in headers that have multiple values." */
for (i = 0; i < lst->len; i++) {
kv = &lst->kvs[i];
- if (previous_key && 0 == strcasecmp (previous_key->str, kv->key->str)) {
+ if (previous_key &&
+ 0 == kms_strcasecmp (previous_key->str, kv->key->str)) {
/* duplicate header */
kms_request_str_append_char (str, ',');
kms_request_str_append_stripped (str, kv->value);
continue;
}
if (i > 0) {
kms_request_str_append_newline (str);
}
kms_request_str_append_lowercase (str, kv->key);
kms_request_str_append_char (str, ':');
kms_request_str_append_stripped (str, kv->value);
previous_key = kv->key;
}
kms_request_str_append_newline (str);
}
static void
append_signed_headers (kms_kv_list_t *lst, kms_request_str_t *str)
{
size_t i;
kms_kv_t *kv;
const kms_request_str_t *previous_key = NULL;
for (i = 0; i < lst->len; i++) {
kv = &lst->kvs[i];
- if (previous_key && 0 == strcasecmp (previous_key->str, kv->key->str)) {
+ if (previous_key &&
+ 0 == kms_strcasecmp (previous_key->str, kv->key->str)) {
/* duplicate header */
continue;
}
- if (0 == strcasecmp (kv->key->str, "connection")) {
+ if (0 == kms_strcasecmp (kv->key->str, "connection")) {
continue;
}
kms_request_str_append_lowercase (str, kv->key);
if (i < lst->len - 1) {
kms_request_str_append_char (str, ';');
}
previous_key = kv->key;
}
}
static bool
finalize (kms_request_t *request)
{
kms_kv_list_t *lst;
kms_request_str_t *k;
kms_request_str_t *v;
if (request->failed) {
return false;
}
if (request->finalized) {
return true;
}
request->finalized = true;
lst = request->header_fields;
/* By default, if no explicit Host was set, it is derived from region +
* service */
if (!kms_kv_list_find (lst, "Host")) {
/* like "kms.us-east-1.amazonaws.com" */
k = kms_request_str_new_from_chars ("Host", -1);
v = kms_request_str_dup (request->service);
kms_request_str_append_char (v, '.');
kms_request_str_append (v, request->region);
kms_request_str_append_chars (v, ".amazonaws.com", -1);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
}
if (!kms_kv_list_find (lst, "Content-Length") && request->payload->len &&
request->auto_content_length) {
k = kms_request_str_new_from_chars ("Content-Length", -1);
v = kms_request_str_new ();
kms_request_str_appendf (v, "%zu", request->payload->len);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
}
return true;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
*
* "Build the canonical headers list by sorting the (lowercase) headers by
* character code... Do not sort the values in headers that have multiple
* values."
*/
static int
cmp_header_field_names (const void *a, const void *b)
{
- return strcasecmp (((kms_kv_t *) a)->key->str, ((kms_kv_t *) b)->key->str);
+ return kms_strcasecmp (((kms_kv_t *) a)->key->str,
+ ((kms_kv_t *) b)->key->str);
}
static kms_kv_list_t *
canonical_headers (const kms_request_t *request)
{
kms_kv_list_t *lst;
KMS_ASSERT (request->finalized);
lst = kms_kv_list_dup (request->header_fields);
kms_kv_list_sort (lst, cmp_header_field_names);
kms_kv_list_del (lst, "Connection");
return lst;
}
char *
kms_request_get_canonical (kms_request_t *request)
{
kms_request_str_t *canonical;
kms_request_str_t *normalized;
kms_kv_list_t *lst;
if (request->failed) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
canonical = kms_request_str_new ();
kms_request_str_append (canonical, request->method);
kms_request_str_append_newline (canonical);
normalized = kms_request_str_path_normalized (request->path);
kms_request_str_append_escaped (canonical, normalized, false);
kms_request_str_destroy (normalized);
kms_request_str_append_newline (canonical);
append_canonical_query (request, canonical);
kms_request_str_append_newline (canonical);
lst = canonical_headers (request);
append_canonical_headers (lst, canonical);
kms_request_str_append_newline (canonical);
append_signed_headers (lst, canonical);
kms_kv_list_destroy (lst);
kms_request_str_append_newline (canonical);
if (!kms_request_str_append_hashed (
&request->crypto, canonical, request->payload)) {
KMS_ERROR (request, "could not generate hash");
kms_request_str_destroy (canonical);
return NULL;
}
return kms_request_str_detach (canonical);
}
const char *
kms_request_get_canonical_header (kms_request_t *request, const char *header)
{
const kms_kv_t *value;
if (request->failed) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
value = kms_kv_list_find (request->header_fields, header);
if (!value) {
return NULL;
}
return value->value->str;
}
char *
kms_request_get_string_to_sign (kms_request_t *request)
{
bool success = false;
kms_request_str_t *sts;
kms_request_str_t *creq = NULL; /* canonical request */
if (request->failed) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
sts = kms_request_str_new ();
kms_request_str_append_chars (sts, "AWS4-HMAC-SHA256\n", -1);
kms_request_str_append (sts, request->datetime);
kms_request_str_append_newline (sts);
/* credential scope, like "20150830/us-east-1/service/aws4_request" */
kms_request_str_append (sts, request->date);
kms_request_str_append_char (sts, '/');
kms_request_str_append (sts, request->region);
kms_request_str_append_char (sts, '/');
kms_request_str_append (sts, request->service);
kms_request_str_append_chars (sts, "/aws4_request\n", -1);
creq = kms_request_str_wrap (kms_request_get_canonical (request), -1);
if (!creq) {
goto done;
}
if (!kms_request_str_append_hashed (&request->crypto, sts, creq)) {
goto done;
}
success = true;
done:
kms_request_str_destroy (creq);
if (!success) {
kms_request_str_destroy (sts);
sts = NULL;
}
return kms_request_str_detach (sts);
}
static bool
kms_request_hmac (_kms_crypto_t *crypto,
unsigned char *out,
kms_request_str_t *key,
kms_request_str_t *data)
{
return crypto->sha256_hmac (
crypto->ctx, key->str, (int) key->len, data->str, data->len, out);
}
static bool
kms_request_hmac_again (_kms_crypto_t *crypto,
unsigned char *out,
unsigned char *in,
kms_request_str_t *data)
{
return crypto->sha256_hmac (
crypto->ctx, (const char *) in, 32, data->str, data->len, out);
}
bool
kms_request_get_signing_key (kms_request_t *request, unsigned char *key)
{
bool success = false;
kms_request_str_t *aws4_plus_secret = NULL;
kms_request_str_t *aws4_request = NULL;
unsigned char k_date[32];
unsigned char k_region[32];
unsigned char k_service[32];
if (request->failed) {
return false;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
* Pseudocode for deriving a signing key
*
* kSecret = your secret access key
* kDate = HMAC("AWS4" + kSecret, Date)
* kRegion = HMAC(kDate, Region)
* kService = HMAC(kRegion, Service)
* kSigning = HMAC(kService, "aws4_request")
*/
aws4_plus_secret = kms_request_str_new_from_chars ("AWS4", -1);
kms_request_str_append (aws4_plus_secret, request->secret_key);
aws4_request = kms_request_str_new_from_chars ("aws4_request", -1);
if (!(kms_request_hmac (
&request->crypto, k_date, aws4_plus_secret, request->date) &&
kms_request_hmac_again (
&request->crypto, k_region, k_date, request->region) &&
kms_request_hmac_again (
&request->crypto, k_service, k_region, request->service) &&
kms_request_hmac_again (
&request->crypto, key, k_service, aws4_request))) {
goto done;
}
success = true;
done:
kms_request_str_destroy (aws4_plus_secret);
kms_request_str_destroy (aws4_request);
return success;
}
char *
kms_request_get_signature (kms_request_t *request)
{
bool success = false;
kms_kv_list_t *lst = NULL;
kms_request_str_t *sig = NULL;
kms_request_str_t *sts = NULL;
unsigned char signing_key[32];
unsigned char signature[32];
if (request->failed) {
return NULL;
}
sts = kms_request_str_wrap (kms_request_get_string_to_sign (request), -1);
if (!sts) {
goto done;
}
sig = kms_request_str_new ();
kms_request_str_append_chars (sig, "AWS4-HMAC-SHA256 Credential=", -1);
kms_request_str_append (sig, request->access_key_id);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->date);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->region);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->service);
kms_request_str_append_chars (sig, "/aws4_request, SignedHeaders=", -1);
lst = canonical_headers (request);
append_signed_headers (lst, sig);
kms_request_str_append_chars (sig, ", Signature=", -1);
if (!(kms_request_get_signing_key (request, signing_key) &&
kms_request_hmac_again (
&request->crypto, signature, signing_key, sts))) {
goto done;
}
kms_request_str_append_hex (sig, signature, sizeof (signature));
success = true;
done:
kms_kv_list_destroy (lst);
kms_request_str_destroy (sts);
if (!success) {
kms_request_str_destroy (sig);
sig = NULL;
}
return kms_request_str_detach (sig);
}
void
kms_request_validate (kms_request_t *request)
{
if (0 == request->region->len) {
KMS_ERROR (request, "Region not set");
} else if (0 == request->service->len) {
KMS_ERROR (request, "Service not set");
} else if (0 == request->access_key_id->len) {
KMS_ERROR (request, "Access key ID not set");
} else if (0 == request->method->len) {
KMS_ERROR (request, "Method not set");
} else if (0 == request->path->len) {
KMS_ERROR (request, "Path not set");
} else if (0 == request->date->len) {
KMS_ERROR (request, "Date not set");
} else if (0 == request->secret_key->len) {
KMS_ERROR (request, "Secret key not set");
}
}
char *
kms_request_get_signed (kms_request_t *request)
{
bool success = false;
kms_kv_list_t *lst = NULL;
char *signature = NULL;
kms_request_str_t *sreq = NULL;
size_t i;
kms_request_validate (request);
if (request->failed) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
sreq = kms_request_str_new ();
/* like "POST / HTTP/1.1" */
kms_request_str_append (sreq, request->method);
kms_request_str_append_char (sreq, ' ');
kms_request_str_append (sreq, request->path);
if (request->query->len) {
kms_request_str_append_char (sreq, '?');
kms_request_str_append (sreq, request->query);
}
kms_request_str_append_chars (sreq, " HTTP/1.1", -1);
kms_request_str_append_newline (sreq);
/* headers */
lst = kms_kv_list_dup (request->header_fields);
kms_kv_list_sort (lst, cmp_header_field_names);
for (i = 0; i < lst->len; i++) {
kms_request_str_append (sreq, lst->kvs[i].key);
kms_request_str_append_char (sreq, ':');
kms_request_str_append (sreq, lst->kvs[i].value);
kms_request_str_append_newline (sreq);
}
/* authorization header */
signature = kms_request_get_signature (request);
if (!signature) {
goto done;
}
/* note space after ':', to match test .sreq files */
kms_request_str_append_chars (sreq, "Authorization: ", -1);
kms_request_str_append_chars (sreq, signature, -1);
/* body */
if (request->payload->len) {
kms_request_str_append_newline (sreq);
kms_request_str_append_newline (sreq);
kms_request_str_append (sreq, request->payload);
}
success = true;
done:
free (signature);
kms_kv_list_destroy (lst);
if (!success) {
kms_request_str_destroy (sreq);
sreq = NULL;
}
return kms_request_str_detach (sreq);
}
void
kms_request_free_string (char *ptr)
{
free (ptr);
}
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_opt.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_opt.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_opt.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_opt.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_opt_private.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_opt_private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_opt_private.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_opt_private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_str.c
similarity index 99%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_str.c
index c94b3f58..65207d2f 100644
--- a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.c
+++ b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_str.c
@@ -1,514 +1,514 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include "hexlify.h"
#include "kms_crypto.h"
#include "kms_message/kms_message.h"
#include "kms_message_private.h"
#include "kms_request_str.h"
#include "kms_port.h"
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
bool rfc_3986_tab[256] = {0};
bool kms_initialized = false;
static void
tables_init ()
{
int i;
if (kms_initialized) {
return;
}
for (i = 0; i < 256; ++i) {
rfc_3986_tab[i] =
isalnum (i) || i == '~' || i == '-' || i == '.' || i == '_';
}
kms_initialized = true;
}
kms_request_str_t *
kms_request_str_new (void)
{
kms_request_str_t *s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
s->len = 0;
s->size = 16;
s->str = malloc (s->size);
KMS_ASSERT (s->str);
s->str[0] = '\0';
return s;
}
kms_request_str_t *
kms_request_str_new_from_chars (const char *chars, ssize_t len)
{
kms_request_str_t *s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
size_t actual_len;
actual_len = len < 0 ? strlen (chars) : (size_t) len;
s->size = actual_len + 1;
s->str = malloc (s->size);
KMS_ASSERT (s->str);
memcpy (s->str, chars, actual_len);
s->str[actual_len] = '\0';
s->len = actual_len;
return s;
}
kms_request_str_t *
kms_request_str_wrap (char *chars, ssize_t len)
{
kms_request_str_t *s;
if (!chars) {
return NULL;
}
s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
s->str = chars;
s->len = len < 0 ? strlen (chars) : (size_t) len;
s->size = s->len;
return s;
}
void
kms_request_str_destroy (kms_request_str_t *str)
{
if (!str) {
return;
}
free (str->str);
free (str);
}
char *
kms_request_str_detach (kms_request_str_t *str)
{
if (!str) {
return NULL;
}
char *r = str->str;
free (str);
return r;
}
const char *
kms_request_str_get (kms_request_str_t *str)
{
return str->str;
}
bool
kms_request_str_reserve (kms_request_str_t *str, size_t size)
{
size_t next_size = str->len + size + 1;
if (str->size < next_size) {
/* next power of 2 */
--next_size;
next_size |= next_size >> 1U;
next_size |= next_size >> 2U;
next_size |= next_size >> 4U;
next_size |= next_size >> 8U;
next_size |= next_size >> 16U;
++next_size;
str->size = next_size;
str->str = realloc (str->str, next_size);
}
return str->str != NULL;
}
kms_request_str_t *
kms_request_str_dup (kms_request_str_t *str)
{
kms_request_str_t *dup = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (dup);
- dup->str = strndup (str->str, str->len);
+ dup->str = kms_strndup (str->str, str->len);
dup->len = str->len;
dup->size = str->len + 1;
return dup;
}
void
kms_request_str_set_chars (kms_request_str_t *str,
const char *chars,
ssize_t len)
{
size_t actual_len = len < 0 ? strlen (chars) : (size_t) len;
kms_request_str_reserve (str, actual_len); /* adds 1 for nil */
memcpy (str->str, chars, actual_len + 1);
str->len = actual_len;
}
bool
kms_request_str_ends_with (kms_request_str_t *str, kms_request_str_t *suffix)
{
if (str->len >= suffix->len &&
0 == strncmp (
&str->str[str->len - suffix->len], suffix->str, suffix->len)) {
return true;
}
return false;
}
void
kms_request_str_append (kms_request_str_t *str, kms_request_str_t *appended)
{
size_t next_len = str->len + appended->len;
kms_request_str_reserve (str, next_len);
memcpy (str->str + str->len, appended->str, appended->len);
str->len += appended->len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_char (kms_request_str_t *str, char c)
{
kms_request_str_reserve (str, 1);
*(str->str + str->len) = c;
++str->len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_chars (kms_request_str_t *str,
const char *appended,
ssize_t len)
{
if (len < 0) {
len = strlen (appended);
}
kms_request_str_reserve (str, (size_t) len);
memcpy (str->str + str->len, appended, (size_t) len);
str->len += len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_newline (kms_request_str_t *str)
{
kms_request_str_append_char (str, '\n');
}
void
kms_request_str_append_lowercase (kms_request_str_t *str,
kms_request_str_t *appended)
{
size_t i;
char *p;
i = str->len;
kms_request_str_append (str, appended);
/* downcase the chars from the old end to the new end of str */
for (; i < str->len; ++i) {
p = &str->str[i];
/* ignore UTF-8 non-ASCII chars, which have 1 in the top bit */
if ((*p & (0x1U << 7U)) == 0) {
*p = (char) tolower (*p);
}
}
}
void
kms_request_str_appendf (kms_request_str_t *str, const char *format, ...)
{
va_list args;
size_t remaining;
int n;
KMS_ASSERT (format);
while (true) {
remaining = str->size - str->len;
va_start (args, format);
n = vsnprintf (&str->str[str->len], remaining, format, args);
va_end (args);
if (n > -1 && (size_t) n < remaining) {
/* success */
str->len += (size_t) n;
return;
}
if (n > -1) {
kms_request_str_reserve (str, (size_t) n);
} else {
/* TODO: error! */
abort ();
}
}
}
void
kms_request_str_append_escaped (kms_request_str_t *str,
kms_request_str_t *appended,
bool escape_slash)
{
uint8_t *in;
uint8_t *out;
size_t i;
tables_init ();
/* might replace each input char with 3 output chars: "%AB" */
kms_request_str_reserve (str, 3 * appended->len);
in = (uint8_t *) appended->str;
out = (uint8_t *) str->str + str->len;
for (i = 0; i < appended->len; ++i) {
if (rfc_3986_tab[*in] || (*in == '/' && !escape_slash)) {
*out = *in;
++out;
++str->len;
} else {
sprintf ((char *) out, "%%%02X", *in);
out += 3;
str->len += 3;
}
++in;
}
}
void
kms_request_str_append_stripped (kms_request_str_t *str,
kms_request_str_t *appended)
{
const char *src = appended->str;
const char *end = appended->str + appended->len;
bool space = false;
bool comma = false;
kms_request_str_reserve (str, appended->len);
// msvcrt is unhappy when it gets non-ANSI characters in isspace
while (*src >= 0 && isspace (*src)) {
++src;
}
while (src < end) {
/* replace newlines with commas. not documented but see
* get-header-value-multiline.creq */
if (*src == '\n') {
comma = true;
space = false;
} else if (*src >= 0 && isspace (*src)) {
space = true;
} else {
if (comma) {
kms_request_str_append_char (str, ',');
comma = false;
space = false;
}
/* is there a run of spaces waiting to be written as one space? */
if (space) {
kms_request_str_append_char (str, ' ');
space = false;
}
kms_request_str_append_char (str, *src);
}
++src;
}
}
bool
kms_request_str_append_hashed (_kms_crypto_t *crypto,
kms_request_str_t *str,
kms_request_str_t *appended)
{
uint8_t hash[32];
char *hex_chars;
if (!crypto->sha256 (crypto->ctx, appended->str, appended->len, hash)) {
return false;
}
hex_chars = hexlify (hash, sizeof (hash));
kms_request_str_append_chars (str, hex_chars, 2 * sizeof (hash));
free (hex_chars);
return true;
}
bool
kms_request_str_append_hex (kms_request_str_t *str,
unsigned char *data,
size_t len)
{
char *hex_chars;
hex_chars = hexlify (data, len);
kms_request_str_append_chars (str, hex_chars, len * 2);
free (hex_chars);
return true;
}
static bool
starts_with (char *s, const char *prefix)
{
if (strstr (s, prefix) == s) {
return true;
}
return false;
}
/* remove from last slash to the end, but don't remove slash from start */
static void
delete_last_segment (kms_request_str_t *str, bool is_absolute)
{
ssize_t i;
if (!str->len) {
return;
}
for (i = str->len - 1; i >= 0; --i) {
if (str->str[i] == '/') {
if (i == 0 && is_absolute) {
str->len = 1;
} else {
str->len = (size_t) i;
}
goto done;
}
}
/* no slashes */
str->len = 0;
done:
str->str[str->len] = '\0';
}
/* follow algorithm in https://tools.ietf.org/html/rfc3986#section-5.2.4,
* the block comments are copied from there */
kms_request_str_t *
kms_request_str_path_normalized (kms_request_str_t *str)
{
kms_request_str_t *slash = kms_request_str_new_from_chars ("/", 1);
kms_request_str_t *out = kms_request_str_new ();
char *in = strdup (str->str);
char *p = in;
char *end = in + str->len;
bool is_absolute = (*p == '/');
if (0 == strcmp (p, "/")) {
goto done;
}
while (p < end) {
/* If the input buffer begins with a prefix of "../" or "./",
* then remove that prefix from the input buffer */
if (starts_with (p, "../")) {
p += 3;
} else if (starts_with (p, "./")) {
p += 2;
}
/* otherwise, if the input buffer begins with a prefix of "/./" or "/.",
* where "." is a complete path segment, then replace that prefix with "/"
* in the input buffer */
else if (starts_with (p, "/./")) {
p += 2;
} else if (0 == strcmp (p, "/.")) {
break;
}
/* otherwise, if the input buffer begins with a prefix of "/../" or "/..",
* where ".." is a complete path segment, then replace that prefix with
* "/" in the input buffer and remove the last segment and its preceding
* "/" (if any) from the output buffer */
else if (starts_with (p, "/../")) {
p += 3;
delete_last_segment (out, is_absolute);
} else if (0 == strcmp (p, "/..")) {
delete_last_segment (out, is_absolute);
break;
}
/* otherwise, if the input buffer consists only of "." or "..", then
remove that from the input buffer */
else if (0 == strcmp (p, ".") || 0 == strcmp (p, "..")) {
break;
}
/* otherwise, move the first path segment in the input buffer to the end
* of the output buffer, including the initial "/" character (if any) and
* any subsequent characters up to, but not including, the next "/"
* character or the end of the input buffer. */
else {
char *next_slash = strchr (p + 1, '/');
if (!next_slash) {
next_slash = end;
}
/* fold repeated slashes */
if (kms_request_str_ends_with (out, slash) && *p == '/') {
++p;
}
/* normalize "a/../b" as "b", not as "/b" */
if (out->len == 0 && !is_absolute && *p == '/') {
++p;
}
kms_request_str_append_chars (out, p, next_slash - p);
p = next_slash;
}
}
done:
free (in);
kms_request_str_destroy (slash);
if (!out->len) {
kms_request_str_append_char (out, '/');
}
return out;
}
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_str.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_request_str.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_request_str.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_response.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_response.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_response.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_response.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_response_parser.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_response_parser.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/kms_response_parser.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/kms_response_parser.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/sort.c b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/sort.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/sort.c
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/sort.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/kms-message/src/sort.h b/mongodb-1.8.1/src/libmongocrypt/kms-message/src/sort.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/kms-message/src/sort.h
rename to mongodb-1.8.1/src/libmongocrypt/kms-message/src/sort.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/crypto/cng.c b/mongodb-1.8.1/src/libmongocrypt/src/crypto/cng.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/crypto/cng.c
rename to mongodb-1.8.1/src/libmongocrypt/src/crypto/cng.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/crypto/commoncrypto.c b/mongodb-1.8.1/src/libmongocrypt/src/crypto/commoncrypto.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/crypto/commoncrypto.c
rename to mongodb-1.8.1/src/libmongocrypt/src/crypto/commoncrypto.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/crypto/libcrypto.c b/mongodb-1.8.1/src/libmongocrypt/src/crypto/libcrypto.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/crypto/libcrypto.c
rename to mongodb-1.8.1/src/libmongocrypt/src/crypto/libcrypto.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/crypto/none.c b/mongodb-1.8.1/src/libmongocrypt/src/crypto/none.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/crypto/none.c
rename to mongodb-1.8.1/src/libmongocrypt/src/crypto/none.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-binary-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-binary-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-binary-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-binary-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-binary.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-binary.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-binary.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-binary.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-buffer-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-buffer-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-buffer-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-buffer-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-buffer.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-buffer.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-buffer.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-buffer.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-collinfo.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-collinfo.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-collinfo.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-collinfo.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-key-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-key-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-key-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-key-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-key.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-key.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-key.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-key.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-cache.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-cache.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ciphertext-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ciphertext-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ciphertext-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ciphertext-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ciphertext.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ciphertext.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ciphertext.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ciphertext.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-compat.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-compat.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-compat.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-compat.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-config.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-config.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-config.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-config.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-config.h.in b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-config.h.in
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-config.h.in
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-config.h.in
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-crypto-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-crypto-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-crypto-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-crypto-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-crypto.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-crypto.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-crypto.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-crypto.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx-datakey.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx-datakey.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx-datakey.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx-datakey.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-ctx.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-ctx.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-key-broker-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-key-broker-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-key-broker-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-key-broker-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-key-broker.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-key-broker.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-key-broker.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-key-broker.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-key-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-key-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-key-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-key-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-key.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-key.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-key.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-key.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-kms-ctx.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-kms-ctx.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-kms-ctx.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-kms-ctx.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-log-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-log-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-log-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-log-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-log.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-log.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-log.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-log.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-marking-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-marking-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-marking-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-marking-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-marking.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-marking.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-marking.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-marking.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-mutex-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-mutex-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-mutex-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-mutex-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-opts-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-opts-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-opts-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-opts-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-opts.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-opts.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-opts.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-opts.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-os-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-os-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-os-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-os-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-status-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-status-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-status-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-status-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-status.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-status.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-status.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-status.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-traverse-util-private.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-traverse-util-private.h
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-traverse-util-private.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-traverse-util-private.h
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-traverse-util.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-traverse-util.c
similarity index 98%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-traverse-util.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-traverse-util.c
index 8aba5258..a4470077 100644
--- a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt-traverse-util.c
+++ b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt-traverse-util.c
@@ -1,216 +1,216 @@
/*
* Copyright 2018-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
*
* 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.
*/
#include <bson/bson.h>
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-log-private.h"
#include "mongocrypt-private.h"
#include "mongocrypt-status-private.h"
#include "mongocrypt-traverse-util-private.h"
typedef struct {
void *ctx;
bson_iter_t iter;
bson_t *copy; /* implies transform */
char *path; /* only enabled during tracing. */
_mongocrypt_traverse_callback_t traverse_cb;
_mongocrypt_transform_callback_t transform_cb;
mongocrypt_status_t *status;
traversal_match_t match;
bson_t child;
} _recurse_state_t;
static bool
_check_first_byte (uint8_t byte, traversal_match_t match)
{
#define FIRST_BYTE_MARKING 0
#define FIRST_BYTE_DETERMINISTIC 1
#define FIRST_BYTE_RANDOMIZED 2
switch (match) {
case TRAVERSE_MATCH_MARKING:
return byte == FIRST_BYTE_MARKING;
case TRAVERSE_MATCH_CIPHERTEXT:
return byte == FIRST_BYTE_DETERMINISTIC || byte == FIRST_BYTE_RANDOMIZED;
}
return false;
}
static bool
_recurse (_recurse_state_t *state)
{
mongocrypt_status_t *status;
status = state->status;
while (bson_iter_next (&state->iter)) {
if (BSON_ITER_HOLDS_BINARY (&state->iter)) {
_mongocrypt_buffer_t value;
BSON_ASSERT (
_mongocrypt_buffer_from_binary_iter (&value, &state->iter));
if (value.subtype == 6 && value.len > 0 &&
_check_first_byte (value.data[0], state->match)) {
bool ret;
/* call the right callback. */
if (state->copy) {
bson_value_t value_out;
ret =
state->transform_cb (state->ctx, &value, &value_out, status);
if (ret) {
bson_append_value (state->copy,
bson_iter_key (&state->iter),
bson_iter_key_len (&state->iter),
&value_out);
bson_value_destroy (&value_out);
}
} else {
ret = state->traverse_cb (state->ctx, &value, status);
}
if (!ret) {
return false;
}
continue;
}
/* fall through and copy */
}
if (BSON_ITER_HOLDS_ARRAY (&state->iter)) {
_recurse_state_t child_state;
bool ret;
memcpy (&child_state, state, sizeof (_recurse_state_t));
if (!bson_iter_recurse (&state->iter, &child_state.iter)) {
CLIENT_ERR ("error recursing into array");
return false;
}
if (state->copy) {
bson_append_array_begin (state->copy,
bson_iter_key (&state->iter),
bson_iter_key_len (&state->iter),
&state->child);
child_state.copy = &state->child;
}
ret = _recurse (&child_state);
if (state->copy) {
bson_append_array_end (state->copy, &state->child);
}
if (!ret) {
return false;
}
continue;
}
if (BSON_ITER_HOLDS_DOCUMENT (&state->iter)) {
_recurse_state_t child_state;
bool ret;
memcpy (&child_state, state, sizeof (_recurse_state_t));
if (!bson_iter_recurse (&state->iter, &child_state.iter)) {
CLIENT_ERR ("error recursing into document");
return false;
}
/* TODO: check for errors everywhere. */
if (state->copy) {
bson_append_document_begin (state->copy,
bson_iter_key (&state->iter),
bson_iter_key_len (&state->iter),
&state->child);
child_state.copy = &state->child;
}
ret = _recurse (&child_state);
if (state->copy) {
if (!bson_append_document_end (state->copy, &state->child)) {
CLIENT_ERR ("error appending document");
return false;
}
}
if (!ret) {
return false;
}
continue;
}
if (state->copy) {
bson_append_value (state->copy,
bson_iter_key (&state->iter),
bson_iter_key_len (&state->iter),
bson_iter_value (&state->iter));
}
}
return true;
}
bool
_mongocrypt_transform_binary_in_bson (_mongocrypt_transform_callback_t cb,
void *ctx,
traversal_match_t match,
bson_iter_t *iter,
bson_t *out,
mongocrypt_status_t *status)
{
_recurse_state_t starting_state = {ctx,
*iter,
out /* copy */,
NULL /* path */,
NULL /* traverse callback */,
cb,
status,
match,
- 0};
+ {0}};
return _recurse (&starting_state);
}
/*-----------------------------------------------------------------------------
*
* _mongocrypt_traverse_binary_in_bson
*
* Traverse the BSON being iterated with iter, and call cb for every binary
* subtype 06 value where the first byte corresponds to 'match'.
*
* Return:
* True on success. Returns false on failure and sets error.
*
*-----------------------------------------------------------------------------
*/
bool
_mongocrypt_traverse_binary_in_bson (_mongocrypt_traverse_callback_t cb,
void *ctx,
traversal_match_t match,
bson_iter_t *iter,
mongocrypt_status_t *status)
{
_recurse_state_t starting_state = {ctx,
*iter,
NULL /* copy */,
NULL /* path */,
cb,
NULL /* transform callback */,
status,
match,
- 0};
+ {0}};
return _recurse (&starting_state);
}
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt.c b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt.c
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt.h b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt.h
similarity index 99%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt.h
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt.h
index c2397f54..04fd08b8 100644
--- a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt.h
+++ b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt.h
@@ -1,1044 +1,1044 @@
/*
* Copyright 2019-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
*
* 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.
*/
#ifndef MONGOCRYPT_H
#define MONGOCRYPT_H
/** @file mongocrypt.h The top-level handle to libmongocrypt. */
/**
* @mainpage libmongocrypt
* See all public API documentation in: @ref mongocrypt.h
*/
#include "mongocrypt-export.h"
#include "mongocrypt-compat.h"
#include "mongocrypt-config.h"
/**
* @def MONGOCRYPT_VERSION
* The version string describing libmongocrypt.
* Has the form x.y.z-<pre>+<date>+git<sha>.
*/
-#define MONGOCRYPT_VERSION "1.0.3"
+#define MONGOCRYPT_VERSION "1.0.4"
/**
* Returns the version string for libmongocrypt.
*
* @param[out] len An optional length of the returned string. May be NULL.
* @returns a NULL terminated version string for libmongocrypt.
*/
MONGOCRYPT_EXPORT
const char *
mongocrypt_version (uint32_t *len);
/**
* A non-owning view of a byte buffer.
*
* When constructing a mongocrypt_binary_t it is the responsibility of the
* caller to maintain the lifetime of the viewed data. However, all public
* functions that take a mongocrypt_binary_t as an argument will make a copy of
* the viewed data. For example, the following is valid:
*
* @code{.c}
* mongocrypt_binary_t bin = mongocrypt_binary_new_from_data(mydata, mylen);
* assert (mongocrypt_setopt_kms_provider_local (crypt), bin);
* // The viewed data of bin has been copied. Ok to free the view and the data.
* mongocrypt_binary_destroy (bin);
* my_free_fn (mydata);
* @endcode
*
* Functions with a mongocrypt_binary_t* out guarantee the lifetime of the
* viewed data to live as long as the parent object. For example, @ref
* mongocrypt_ctx_mongo_op guarantees that the viewed data of
* mongocrypt_binary_t is valid until the parent ctx is destroyed with @ref
* mongocrypt_ctx_destroy.
*/
typedef struct _mongocrypt_binary_t mongocrypt_binary_t;
/**
* Create a new non-owning view of a buffer (data + length).
*
* Use this to create a mongocrypt_binary_t used for output parameters.
*
* @returns A new mongocrypt_binary_t.
*/
MONGOCRYPT_EXPORT
mongocrypt_binary_t *
mongocrypt_binary_new (void);
/**
* Create a new non-owning view of a buffer (data + length).
*
* @param[in] data A pointer to an array of bytes. This data is not copied. @p
* data must outlive the binary object.
* @param[in] len The length of the @p data byte array.
*
* @returns A new @ref mongocrypt_binary_t.
*/
MONGOCRYPT_EXPORT
mongocrypt_binary_t *
mongocrypt_binary_new_from_data (uint8_t *data, uint32_t len);
/**
* Get a pointer to the viewed data.
*
* @param[in] binary The @ref mongocrypt_binary_t.
*
* @returns A pointer to the viewed data.
*/
MONGOCRYPT_EXPORT
uint8_t *
mongocrypt_binary_data (const mongocrypt_binary_t *binary);
/**
* Get the length of the viewed data.
*
* @param[in] binary The @ref mongocrypt_binary_t.
*
* @returns The length of the viewed data.
*/
MONGOCRYPT_EXPORT
uint32_t
mongocrypt_binary_len (const mongocrypt_binary_t *binary);
/**
* Free the @ref mongocrypt_binary_t.
*
* This does not free the viewed data.
*
* @param[in] binary The mongocrypt_binary_t destroy.
*/
MONGOCRYPT_EXPORT
void
mongocrypt_binary_destroy (mongocrypt_binary_t *binary);
/**
* Indicates success or contains error information.
*
* Functions like @ref mongocrypt_ctx_encrypt_init follow a pattern to expose a
* status. A boolean is returned. True indicates success, and false indicates
* failure. On failure a status on the handle is set, and is accessible with a
* corresponding (handle)_status function. E.g. @ref mongocrypt_ctx_status.
*/
typedef struct _mongocrypt_status_t mongocrypt_status_t;
/**
* Indicates the type of error.
*/
typedef enum {
MONGOCRYPT_STATUS_OK = 0,
MONGOCRYPT_STATUS_ERROR_CLIENT = 1,
MONGOCRYPT_STATUS_ERROR_KMS = 2
} mongocrypt_status_type_t;
/**
* Create a new status object.
*
* Use a new status object to retrieve the status from a handle by passing
* this as an out-parameter to functions like @ref mongocrypt_ctx_status.
* When done, destroy it with @ref mongocrypt_status_destroy.
*
* @returns A new status object.
*/
MONGOCRYPT_EXPORT
mongocrypt_status_t *
mongocrypt_status_new (void);
/**
* Set a status object with message, type, and code.
*
* Use this to set the @ref mongocrypt_status_t given in the crypto hooks.
*
* @param[in] type The status type.
* @param[in] code The status code.
* @param[in] message The message.
* @param[in] message_len Due to historical behavior, pass 1 + the string length
* of @p message (which differs from other functions accepting string
* arguments).
* Alternatively, if message is NULL terminated this may be -1 to tell
* mongocrypt
* to determine the string's length with strlen.
*
*/
MONGOCRYPT_EXPORT
void
mongocrypt_status_set (mongocrypt_status_t *status,
mongocrypt_status_type_t type,
uint32_t code,
const char *message,
int32_t message_len);
/**
* Indicates success or the type of error.
*
* @param[in] status The status object.
*
* @returns A @ref mongocrypt_status_type_t.
*/
MONGOCRYPT_EXPORT
mongocrypt_status_type_t
mongocrypt_status_type (mongocrypt_status_t *status);
/**
* Get an error code or 0.
*
* @param[in] status The status object.
*
* @returns An error code.
*/
MONGOCRYPT_EXPORT
uint32_t
mongocrypt_status_code (mongocrypt_status_t *status);
/**
* Get the error message associated with a status or NULL.
*
* @param[in] status The status object.
* @param[out] len An optional length of the returned string (excluding the
* trailing NULL byte). May be NULL.
*
* @returns A NULL terminated error message or NULL.
*/
MONGOCRYPT_EXPORT
const char *
mongocrypt_status_message (mongocrypt_status_t *status, uint32_t *len);
/**
* Returns true if the status indicates success.
*
* @param[in] status The status to check.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_status_ok (mongocrypt_status_t *status);
/**
* Free the memory for a status object.
*
* @param[in] status The status to destroy.
*/
MONGOCRYPT_EXPORT
void
mongocrypt_status_destroy (mongocrypt_status_t *status);
/**
* Indicates the type of log message.
*/
typedef enum {
MONGOCRYPT_LOG_LEVEL_FATAL = 0,
MONGOCRYPT_LOG_LEVEL_ERROR = 1,
MONGOCRYPT_LOG_LEVEL_WARNING = 2,
MONGOCRYPT_LOG_LEVEL_INFO = 3,
MONGOCRYPT_LOG_LEVEL_TRACE = 4
} mongocrypt_log_level_t;
/**
* A log callback function. Set a custom log callback with @ref
* mongocrypt_setopt_log_handler.
*
* @param[in] message A NULL terminated message.
* @param[in] message_len The length of message.
* @param[in] ctx A context provided by the caller of @ref
* mongocrypt_setopt_log_handler.
*/
typedef void (*mongocrypt_log_fn_t) (mongocrypt_log_level_t level,
const char *message,
uint32_t message_len,
void *ctx);
/**
* The top-level handle to libmongocrypt.
*
* Create a mongocrypt_t handle to perform operations within libmongocrypt:
* encryption, decryption, registering log callbacks, etc.
*
* Functions on a mongocrypt_t are thread safe, though functions on derived
* handles (e.g. mongocrypt_ctx_t) are not and must be owned by a single
* thread. See each handle's documentation for thread-safety considerations.
*
* Multiple mongocrypt_t handles may be created.
*/
typedef struct _mongocrypt_t mongocrypt_t;
/**
* Allocate a new @ref mongocrypt_t object.
*
* Set options using mongocrypt_setopt_* functions, then initialize with @ref
* mongocrypt_init. When done with the @ref mongocrypt_t, free with @ref
* mongocrypt_destroy.
*
* @returns A new @ref mongocrypt_t object.
*/
MONGOCRYPT_EXPORT
mongocrypt_t *
mongocrypt_new (void);
/**
* Set a handler on the @ref mongocrypt_t object to get called on every log
* message.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] log_fn The log callback.
* @param[in] log_ctx A context passed as an argument to the log callback every
* invokation.
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_log_handler (mongocrypt_t *crypt,
mongocrypt_log_fn_t log_fn,
void *log_ctx);
/**
* Configure an AWS KMS provider on the @ref mongocrypt_t object.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] aws_access_key_id The AWS access key ID used to generate KMS
* messages.
* @param[in] aws_access_key_id_len The string length (in bytes) of @p
* aws_access_key_id. Pass -1 to determine the string length with strlen (must
* be NULL terminated).
* @param[in] aws_secret_access_key The AWS secret access key used to generate
* KMS messages.
* @param[in] aws_secret_access_key_len The string length (in bytes) of @p
* aws_secret_access_key. Pass -1 to determine the string length with strlen
* (must be NULL terminated).
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_kms_provider_aws (mongocrypt_t *crypt,
const char *aws_access_key_id,
int32_t aws_access_key_id_len,
const char *aws_secret_access_key,
int32_t aws_secret_access_key_len);
/**
* Configure a local KMS provider on the @ref mongocrypt_t object.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] key A 96 byte master key used to encrypt and decrypt key vault
* keys. The viewed data is copied. It is valid to destroy @p key with @ref
* mongocrypt_binary_destroy immediately after.
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_kms_provider_local (mongocrypt_t *crypt,
mongocrypt_binary_t *key);
/**
* Set a local schema map for encryption.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] schema_map A BSON document representing the schema map supplied by
* the user. The keys are collection namespaces and values are JSON schemas. The
* viewed data copied. It is valid to destroy @p schema_map with @ref
* mongocrypt_binary_destroy immediately after.
* @pre @p crypt has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_schema_map (mongocrypt_t *crypt,
mongocrypt_binary_t *schema_map);
/**
* Initialize new @ref mongocrypt_t object.
*
* Set options before using @ref mongocrypt_setopt_kms_provider_local, @ref
* mongocrypt_setopt_kms_provider_aws, or @ref mongocrypt_setopt_log_handler.
*
* @param[in] crypt The @ref mongocrypt_t object.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status Failure may occur if previously
* set
* options are invalid.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_init (mongocrypt_t *crypt);
/**
* Get the status associated with a @ref mongocrypt_t object.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[out] status Receives the status.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_status (mongocrypt_t *crypt, mongocrypt_status_t *status);
/**
* Destroy the @ref mongocrypt_t object.
*
* @param[in] crypt The @ref mongocrypt_t object to destroy.
*/
MONGOCRYPT_EXPORT
void
mongocrypt_destroy (mongocrypt_t *crypt);
/**
* Manages the state machine for encryption or decryption.
*/
typedef struct _mongocrypt_ctx_t mongocrypt_ctx_t;
/**
* Create a new uninitialized @ref mongocrypt_ctx_t.
*
* Initialize the context with functions like @ref mongocrypt_ctx_encrypt_init.
* When done, destroy it with @ref mongocrypt_ctx_destroy.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @returns A new context.
*/
MONGOCRYPT_EXPORT
mongocrypt_ctx_t *
mongocrypt_ctx_new (mongocrypt_t *crypt);
/**
* Get the status associated with a @ref mongocrypt_ctx_t object.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[out] status Receives the status.
*
* @returns True if the output is an ok status, false if it is an error
* status.
*
* @see mongocrypt_status_ok
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_status (mongocrypt_ctx_t *ctx, mongocrypt_status_t *status);
/**
* Set the key id to use for explicit encryption.
*
* It is an error to set both this and the key alt name.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] key_id The binary corresponding to the _id (a UUID) of the data
* key to use from the key vault collection. Note, the UUID must be encoded with
* RFC-4122 byte order. The viewed data is copied. It is valid to destroy
* @p key_id with @ref mongocrypt_binary_destroy immediately after.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_key_id (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *key_id);
/**
* Set the keyAltName to use for explicit encryption or
* data key creation.
*
* Pass the binary encoding a BSON document like the following:
*
* { "keyAltName" : (BSON UTF8 value) }
*
* For explicit encryption, it is an error to set both the keyAltName
* and the key id.
*
* For creating data keys, call this function repeatedly to set
* multiple keyAltNames.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] key_alt_name The name to use. The viewed data is copied. It is
* valid to destroy @p key_alt_name with @ref mongocrypt_binary_destroy
* immediately after.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_key_alt_name (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *key_alt_name);
/**
* Set the algorithm used for encryption to either
* deterministic or random encryption. This value
* should only be set when using explicit encryption.
*
* If -1 is passed in for "len", then "algorithm" is
* assumed to be a null-terminated string.
*
* Valid values for algorithm are:
* "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
* "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] algorithm A string specifying the algorithm to
* use for encryption.
* @param[in] len The length of the algorithm string.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_algorithm (mongocrypt_ctx_t *ctx,
const char *algorithm,
int len);
/**
* Identify the AWS KMS master key to use for creating a data key.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] region The AWS region.
* @param[in] region_len The string length of @p region. Pass -1 to determine
* the string length with strlen (must be NULL terminated).
* @param[in] cmk The Amazon Resource Name (ARN) of the customer master key
* (CMK).
* @param[in] cmk_len The string length of @p cmk_len. Pass -1 to determine the
* string length with strlen (must be NULL terminated).
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_masterkey_aws (mongocrypt_ctx_t *ctx,
const char *region,
int32_t region_len,
const char *cmk,
int32_t cmk_len);
/**
* Identify a custom AWS endpoint when creating a data key.
* This is used internally to construct the correct HTTP request
* (with the Host header set to this endpoint). This endpoint
* is persisted in the new data key, and will be returned via
* @ref mongocrypt_kms_ctx_endpoint.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] endpoint The endpoint.
* @param[in] endpoint_len The string length of @p endpoint. Pass -1 to
* determine the string length with strlen (must be NULL terminated).
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_masterkey_aws_endpoint (mongocrypt_ctx_t *ctx,
const char *endpoint,
int32_t endpoint_len);
/**
* Set the master key to "local" for creating a data key.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_masterkey_local (mongocrypt_ctx_t *ctx);
/**
* Initialize a context to create a data key.
*
* Associated options:
* - @ref mongocrypt_ctx_setopt_masterkey_aws
* - @ref mongocrypt_ctx_setopt_masterkey_aws_endpoint
* - @ref mongocrypt_ctx_setopt_masterkey_local
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
* @pre A master key option has been set, and an associated KMS provider
* has been set on the parent @ref mongocrypt_t.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_datakey_init (mongocrypt_ctx_t *ctx);
/**
* Initialize a context for encryption.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] db The database name.
* @param[in] db_len The byte length of @p db. Pass -1 to determine the string
* length with strlen (must
* be NULL terminated).
* @param[in] cmd The BSON command to be encrypted. The viewed data is copied.
* It is valid to destroy @p cmd with @ref mongocrypt_binary_destroy immediately
* after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_encrypt_init (mongocrypt_ctx_t *ctx,
const char *db,
int32_t db_len,
mongocrypt_binary_t *cmd);
/**
* Explicit helper method to encrypt a single BSON object. Contexts
* created for explicit encryption will not go through mongocryptd.
*
* To specify a key_id, algorithm, or iv to use, please use the
* corresponding mongocrypt_setopt methods before calling this.
*
* This method expects the passed-in BSON to be of the form:
* { "v" : BSON value to encrypt }
*
* Associated options:
* - @ref mongocrypt_ctx_setopt_key_id
* - @ref mongocrypt_ctx_setopt_key_alt_name
* - @ref mongocrypt_ctx_setopt_algorithm
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
* @param[in] msg A @ref mongocrypt_binary_t the plaintext BSON value. The
* viewed data is copied. It is valid to destroy @p msg with @ref
* mongocrypt_binary_destroy immediately after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *msg);
/**
* Initialize a context for decryption.
*
* This method expects the passed-in BSON to be of the form:
* { "v" : BSON value to encrypt }
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] doc The document to be decrypted. The viewed data is copied. It is
* valid to destroy @p doc with @ref mongocrypt_binary_destroy immediately
* after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_decrypt_init (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *doc);
/**
* Explicit helper method to decrypt a single BSON object.
*
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
* @param[in] msg A @ref mongocrypt_binary_t the encrypted BSON. The viewed data
* is copied. It is valid to destroy @p msg with @ref mongocrypt_binary_destroy
* immediately after.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_explicit_decrypt_init (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *msg);
/**
* Indicates the state of the @ref mongocrypt_ctx_t. Each state requires
* different handling. See [the integration
* guide](https://github.com/mongodb/libmongocrypt/blob/master/integrating.md#state-machine)
* for information on what to do for each state.
*/
typedef enum {
MONGOCRYPT_CTX_ERROR = 0,
MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1, /* run on main MongoClient */
MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2, /* run on mongocryptd. */
MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3, /* run on key vault */
MONGOCRYPT_CTX_NEED_KMS = 4,
MONGOCRYPT_CTX_READY = 5, /* ready for encryption/decryption */
MONGOCRYPT_CTX_DONE = 6
} mongocrypt_ctx_state_t;
/**
* Get the current state of a context.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @returns A @ref mongocrypt_ctx_state_t.
*/
MONGOCRYPT_EXPORT
mongocrypt_ctx_state_t
mongocrypt_ctx_state (mongocrypt_ctx_t *ctx);
/**
* Get BSON necessary to run the mongo operation when mongocrypt_ctx_t
* is in MONGOCRYPT_CTX_NEED_MONGO_* states.
*
* @p op_bson is a BSON document to be used for the operation.
* - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a listCollections filter.
* - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a find filter.
* - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a command to send to
* mongocryptd.
*
* The lifetime of @p op_bson is tied to the lifetime of @p ctx. It is valid
* until @ref mongocrypt_ctx_destroy is called.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[out] op_bson A BSON document for the MongoDB operation. The data
* viewed by @p op_bson is guaranteed to be valid until @p ctx is destroyed with
* @ref mongocrypt_ctx_destroy.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_mongo_op (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *op_bson);
/**
* Feed a BSON reply or result when mongocrypt_ctx_t is in
* MONGOCRYPT_CTX_NEED_MONGO_* states. This may be called multiple times
* depending on the operation.
*
* reply is a BSON document result being fed back for this operation.
* - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a doc from a listCollections
* cursor. (Note, if listCollections returned no result, do not call this
* function.)
* - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a doc from a find cursor.
* (Note, if find returned no results, do not call this function. reply must
* not
* be NULL.)
* - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a reply from mongocryptd.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] reply A BSON document for the MongoDB operation. The viewed data
* is copied. It is valid to destroy @p reply with @ref
* mongocrypt_binary_destroy immediately after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_mongo_feed (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *reply);
/**
* Call when done feeding the reply (or replies) back to the context.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_mongo_done (mongocrypt_ctx_t *ctx);
/**
* Manages a single KMS HTTP request/response.
*/
typedef struct _mongocrypt_kms_ctx_t mongocrypt_kms_ctx_t;
/**
* Get the next KMS handle.
*
* Multiple KMS handles may be retrieved at once. Drivers may do this to fan
* out multiple concurrent KMS HTTP requests. Feeding multiple KMS requests
* is thread-safe.
*
* If KMS handles are being handled synchronously, the driver can reuse the same
* TLS socket to send HTTP requests and receive responses.
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
* @returns a new @ref mongocrypt_kms_ctx_t or NULL.
*/
MONGOCRYPT_EXPORT
mongocrypt_kms_ctx_t *
mongocrypt_ctx_next_kms_ctx (mongocrypt_ctx_t *ctx);
/**
* Get the HTTP request message for a KMS handle.
*
* The lifetime of @p msg is tied to the lifetime of @p kms. It is valid
* until @ref mongocrypt_ctx_kms_done is called.
*
* @param[in] kms A @ref mongocrypt_kms_ctx_t.
* @param[out] msg The HTTP request to send to KMS. The data viewed by @p msg is
* guaranteed to be valid until the call of @ref mongocrypt_ctx_kms_done of the
* parent @ref mongocrypt_ctx_t.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_kms_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_kms_ctx_message (mongocrypt_kms_ctx_t *kms,
mongocrypt_binary_t *msg);
/**
* Get the hostname from which to connect over TLS.
*
* The storage for @p endpoint is not owned by the caller, but
* is valid until calling @ref mongocrypt_ctx_kms_done.
*
* @param[in] kms A @ref mongocrypt_kms_ctx_t.
* @param[out] endpoint The output hostname as a NULL terminated string. This
* may include a port (e.g. "example.com:123"). If it does not, default to port
* 443.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_kms_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_kms_ctx_endpoint (mongocrypt_kms_ctx_t *kms, const char **endpoint);
/**
* Indicates how many bytes to feed into @ref mongocrypt_kms_ctx_feed.
*
* @param[in] kms The @ref mongocrypt_kms_ctx_t.
* @returns The number of requested bytes.
*/
MONGOCRYPT_EXPORT
uint32_t
mongocrypt_kms_ctx_bytes_needed (mongocrypt_kms_ctx_t *kms);
/**
* Feed bytes from the HTTP response.
*
* Feeding more bytes than what has been returned in @ref
* mongocrypt_kms_ctx_bytes_needed is an error.
*
* @param[in] kms The @ref mongocrypt_kms_ctx_t.
* @param[in] bytes The bytes to feed. The viewed data is copied. It is valid to
* destroy @p bytes with @ref mongocrypt_binary_destroy immediately after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_kms_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_kms_ctx_feed (mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes);
/**
* Get the status associated with a @ref mongocrypt_kms_ctx_t object.
*
* @param[in] kms The @ref mongocrypt_kms_ctx_t object.
* @param[out] status Receives the status.
*
* @returns A boolean indicating success. If false, an error status is set.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_kms_ctx_status (mongocrypt_kms_ctx_t *kms,
mongocrypt_status_t *status);
/**
* Call when done handling all KMS contexts.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_kms_done (mongocrypt_ctx_t *ctx);
/**
* Perform the final encryption or decryption.
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
* @param[out] out The final BSON. The data viewed by @p out is guaranteed
* to be valid until @p ctx is destroyed with @ref mongocrypt_ctx_destroy.
* The meaning of this BSON depends on the type of @p ctx.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_encrypt_init, then
* this BSON is the (possibly) encrypted command to send to the server.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_decrypt_init, then
* this BSON is the decrypted result to return to the user.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_explicit_encrypt_init,
* then this BSON has the form { "v": (BSON binary) } where the BSON binary
* is the resulting encrypted value.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_explicit_decrypt_init,
* then this BSON has the form { "v": (BSON value) } where the BSON value
* is the resulting decrypted value.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_datakey_init, then
* this BSON is the document containing the new data key to be inserted into
* the key vault collection.
*
* @returns a bool indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out);
/**
* Destroy and free all memory associated with a @ref mongocrypt_ctx_t.
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
*/
MONGOCRYPT_EXPORT
void
mongocrypt_ctx_destroy (mongocrypt_ctx_t *ctx);
/**
* An crypto AES-256-CBC encrypt or decrypt function.
*
* Note, @p in is already padded. Encrypt with padding disabled.
* @param[in] ctx An optional context object that may have been set when hooks
* were enabled.
* @param[in] key An encryption key (32 bytes for AES_256).
* @param[in] iv An initialization vector (16 bytes for AES_256);
* @param[in] in The input.
* @param[out] out A preallocated byte array for the output. See @ref
* mongocrypt_binary_data.
* @param[out] bytes_written Set this to the number of bytes written to @p out.
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indiciating the error using @ref mongocrypt_status_ste.
*/
typedef bool (*mongocrypt_crypto_fn) (void *ctx,
mongocrypt_binary_t *key,
mongocrypt_binary_t *iv,
mongocrypt_binary_t *in,
mongocrypt_binary_t *out,
uint32_t *bytes_written,
mongocrypt_status_t *status);
/**
* A crypto HMAC SHA-512 or SHA-256 function.
*
* @param[in] ctx An optional context object that may have been set when hooks
* were enabled.
* @param[in] key An encryption key (32 bytes for HMAC_SHA512).
* @param[in] in The input.
* @param[out] out A preallocated byte array for the output. See @ref
* mongocrypt_binary_data.
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indiciating the error using @ref mongocrypt_status_ste.
*/
typedef bool (*mongocrypt_hmac_fn) (void *ctx,
mongocrypt_binary_t *key,
mongocrypt_binary_t *in,
mongocrypt_binary_t *out,
mongocrypt_status_t *status);
/**
* A crypto hash (SHA-256) function.
*
* @param[in] ctx An optional context object that may have been set when hooks
* were enabled.
* @param[in] in The input.
* @param[out] out A preallocated byte array for the output. See @ref
* mongocrypt_binary_data.
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indiciating the error using @ref mongocrypt_status_ste.
*/
typedef bool (*mongocrypt_hash_fn) (void *ctx,
mongocrypt_binary_t *in,
mongocrypt_binary_t *out,
mongocrypt_status_t *status);
/**
* A crypto secure random function.
*
* @param[in] ctx An optional context object that may have been set when hooks
* were enabled.
* @param[out] out A preallocated byte array for the output. See @ref
* mongocrypt_binary_data.
* @param[in] count The number of random bytes requested.
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indiciating the error using @ref mongocrypt_status_ste.
*/
typedef bool (*mongocrypt_random_fn) (void *ctx,
mongocrypt_binary_t *out,
uint32_t count,
mongocrypt_status_t *status);
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_crypto_hooks (mongocrypt_t *crypt,
mongocrypt_crypto_fn aes_256_cbc_encrypt,
mongocrypt_crypto_fn aes_256_cbc_decrypt,
mongocrypt_random_fn random,
mongocrypt_hmac_fn hmac_sha_512,
mongocrypt_hmac_fn hmac_sha_256,
mongocrypt_hash_fn sha_256,
void *ctx);
#endif /* MONGOCRYPT_H */
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/mongocrypt.h.in b/mongodb-1.8.1/src/libmongocrypt/src/mongocrypt.h.in
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/mongocrypt.h.in
rename to mongodb-1.8.1/src/libmongocrypt/src/mongocrypt.h.in
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/os_posix/os_mutex.c b/mongodb-1.8.1/src/libmongocrypt/src/os_posix/os_mutex.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/os_posix/os_mutex.c
rename to mongodb-1.8.1/src/libmongocrypt/src/os_posix/os_mutex.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/os_posix/os_once.c b/mongodb-1.8.1/src/libmongocrypt/src/os_posix/os_once.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/os_posix/os_once.c
rename to mongodb-1.8.1/src/libmongocrypt/src/os_posix/os_once.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/os_win/os_mutex.c b/mongodb-1.8.1/src/libmongocrypt/src/os_win/os_mutex.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/os_win/os_mutex.c
rename to mongodb-1.8.1/src/libmongocrypt/src/os_win/os_mutex.c
diff --git a/mongodb-1.7.4/src/libmongocrypt/src/os_win/os_once.c b/mongodb-1.8.1/src/libmongocrypt/src/os_win/os_once.c
similarity index 100%
rename from mongodb-1.7.4/src/libmongocrypt/src/os_win/os_once.c
rename to mongodb-1.8.1/src/libmongocrypt/src/os_win/os_once.c
diff --git a/mongodb-1.7.4/tests/apm/bug0950-001.phpt b/mongodb-1.8.1/tests/apm/bug0950-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/bug0950-001.phpt
rename to mongodb-1.8.1/tests/apm/bug0950-001.phpt
diff --git a/mongodb-1.7.4/tests/apm/bug0950-002.phpt b/mongodb-1.8.1/tests/apm/bug0950-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/bug0950-002.phpt
rename to mongodb-1.8.1/tests/apm/bug0950-002.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-addSubscriber-001.phpt b/mongodb-1.8.1/tests/apm/monitoring-addSubscriber-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-addSubscriber-001.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-addSubscriber-001.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-addSubscriber-002.phpt b/mongodb-1.8.1/tests/apm/monitoring-addSubscriber-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-addSubscriber-002.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-addSubscriber-002.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-addSubscriber-003.phpt b/mongodb-1.8.1/tests/apm/monitoring-addSubscriber-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-addSubscriber-003.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-addSubscriber-003.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-addSubscriber-004.phpt b/mongodb-1.8.1/tests/apm/monitoring-addSubscriber-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-addSubscriber-004.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-addSubscriber-004.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-commandFailed-001.phpt b/mongodb-1.8.1/tests/apm/monitoring-commandFailed-001.phpt
similarity index 98%
rename from mongodb-1.7.4/tests/apm/monitoring-commandFailed-001.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-commandFailed-001.phpt
index c0a838e5..056eb1e9 100644
--- a/mongodb-1.7.4/tests/apm/monitoring-commandFailed-001.phpt
+++ b/mongodb-1.8.1/tests/apm/monitoring-commandFailed-001.phpt
@@ -1,67 +1,68 @@
--TEST--
MongoDB\Driver\Monitoring\CommandFailedEvent
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_appveyor(); /* TODO: PHPC-1613 */ ?>
<?php skip_if_not_live(); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$m = new MongoDB\Driver\Manager(URI);
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event )
{
echo "started: ", $event->getCommandName(), "\n";
}
public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event )
{
}
public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event )
{
echo "failed: ", $event->getCommandName(), "\n";
echo "- getError() returns an object: ", is_object( $event->getError() ) ? 'yes' : 'no', "\n";
echo "- getError() returns an MongoDB\Driver\Exception\Exception object: ", $event->getError() instanceof MongoDB\Driver\Exception\Exception ? 'yes' : 'no', "\n";
echo "- getDurationMicros() returns an integer: ", is_integer( $event->getDurationMicros() ) ? 'yes' : 'no', "\n";
echo "- getDurationMicros() returns > 0: ", $event->getDurationMicros() > 0 ? 'yes' : 'no', "\n";
echo "- getCommandName() returns a string: ", is_string( $event->getCommandName() ) ? 'yes' : 'no', "\n";
echo "- getCommandName() returns '", $event->getCommandName(), "'\n";
echo "- getServer() returns an object: ", is_object( $event->getServer() ) ? 'yes' : 'no', "\n";
echo "- getServer() returns a Server object: ", $event->getServer() instanceof MongoDB\Driver\Server ? 'yes' : 'no', "\n";
echo "- getOperationId() returns a string: ", is_string( $event->getOperationId() ) ? 'yes' : 'no', "\n";
echo "- getRequestId() returns a string: ", is_string( $event->getRequestId() ) ? 'yes' : 'no', "\n";
}
}
$subscriber = new MySubscriber;
MongoDB\Driver\Monitoring\addSubscriber( $subscriber );
$primary = get_primary_server(URI);
$command = new \MongoDB\Driver\Command([
'aggregate' => COLLECTION_NAME,
'pipeline' => [['$unsupported' => 1]]
]);
try {
$primary->executeCommand(DATABASE_NAME, $command);
} catch (Exception $e) {
/* Swallow */
}
?>
--EXPECT--
started: aggregate
failed: aggregate
- getError() returns an object: yes
- getError() returns an MongoDB\Driver\Exception\Exception object: yes
- getDurationMicros() returns an integer: yes
- getDurationMicros() returns > 0: yes
- getCommandName() returns a string: yes
- getCommandName() returns 'aggregate'
- getServer() returns an object: yes
- getServer() returns a Server object: yes
- getOperationId() returns a string: yes
- getRequestId() returns a string: yes
diff --git a/mongodb-1.7.4/tests/apm/monitoring-commandFailed-002.phpt b/mongodb-1.8.1/tests/apm/monitoring-commandFailed-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-commandFailed-002.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-commandFailed-002.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-commandFailed-003.phpt b/mongodb-1.8.1/tests/apm/monitoring-commandFailed-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-commandFailed-003.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-commandFailed-003.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-commandStarted-001.phpt b/mongodb-1.8.1/tests/apm/monitoring-commandStarted-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-commandStarted-001.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-commandStarted-001.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-commandSucceeded-001.phpt b/mongodb-1.8.1/tests/apm/monitoring-commandSucceeded-001.phpt
similarity index 98%
rename from mongodb-1.7.4/tests/apm/monitoring-commandSucceeded-001.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-commandSucceeded-001.phpt
index bc42684a..120e1946 100644
--- a/mongodb-1.7.4/tests/apm/monitoring-commandSucceeded-001.phpt
+++ b/mongodb-1.8.1/tests/apm/monitoring-commandSucceeded-001.phpt
@@ -1,59 +1,60 @@
--TEST--
MongoDB\Driver\Monitoring\CommandSucceededEvent
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_appveyor(); /* TODO: PHPC-1613 */ ?>
<?php skip_if_not_live(); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$m = new MongoDB\Driver\Manager(URI);
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event )
{
echo "started: ", $event->getCommandName(), "\n";
}
public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event )
{
echo "succeeded: ", $event->getCommandName(), "\n";
echo "- getReply() returns an object: ", is_object( $event->getReply() ) ? 'yes' : 'no', "\n";
echo "- getReply() returns a stdClass object: ", $event->getReply() instanceof stdClass ? 'yes' : 'no', "\n";
echo "- getDurationMicros() returns an integer: ", is_integer( $event->getDurationMicros() ) ? 'yes' : 'no', "\n";
echo "- getDurationMicros() returns > 0: ", $event->getDurationMicros() > 0 ? 'yes' : 'no', "\n";
echo "- getCommandName() returns a string: ", is_string( $event->getCommandName() ) ? 'yes' : 'no', "\n";
echo "- getCommandName() returns '", $event->getCommandName(), "'\n";
echo "- getServer() returns an object: ", is_object( $event->getServer() ) ? 'yes' : 'no', "\n";
echo "- getServer() returns a Server object: ", $event->getServer() instanceof MongoDB\Driver\Server ? 'yes' : 'no', "\n";
echo "- getOperationId() returns a string: ", is_string( $event->getOperationId() ) ? 'yes' : 'no', "\n";
echo "- getRequestId() returns a string: ", is_string( $event->getRequestId() ) ? 'yes' : 'no', "\n";
}
public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event )
{
}
}
$query = new MongoDB\Driver\Query( [] );
$subscriber = new MySubscriber;
MongoDB\Driver\Monitoring\addSubscriber( $subscriber );
$cursor = $m->executeQuery( "demo.test", $query );
?>
--EXPECT--
started: find
succeeded: find
- getReply() returns an object: yes
- getReply() returns a stdClass object: yes
- getDurationMicros() returns an integer: yes
- getDurationMicros() returns > 0: yes
- getCommandName() returns a string: yes
- getCommandName() returns 'find'
- getServer() returns an object: yes
- getServer() returns a Server object: yes
- getOperationId() returns a string: yes
- getRequestId() returns a string: yes
diff --git a/mongodb-1.7.4/tests/apm/monitoring-commandSucceeded-002.phpt b/mongodb-1.8.1/tests/apm/monitoring-commandSucceeded-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-commandSucceeded-002.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-commandSucceeded-002.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-removeSubscriber-001.phpt b/mongodb-1.8.1/tests/apm/monitoring-removeSubscriber-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-removeSubscriber-001.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-removeSubscriber-001.phpt
diff --git a/mongodb-1.7.4/tests/apm/monitoring-removeSubscriber-002.phpt b/mongodb-1.8.1/tests/apm/monitoring-removeSubscriber-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/apm/monitoring-removeSubscriber-002.phpt
rename to mongodb-1.8.1/tests/apm/monitoring-removeSubscriber-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/array-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/array-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/array-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/array-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/array-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/array-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/array-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/array-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/array-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/array-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/array-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/array-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/array-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/array-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/array-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/array-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/array-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/array-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/array-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/array-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/array-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/array-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/array-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/array-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/array-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/array-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/array-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/array-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/array-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/array-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/array-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/array-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-decodeError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-decodeError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-decodeError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-decodeError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-decodeError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-decodeError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-008.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-009.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-010.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/binary-valid-011.phpt b/mongodb-1.8.1/tests/bson-corpus/binary-valid-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/binary-valid-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/binary-valid-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/boolean-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/boolean-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/boolean-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/boolean-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/boolean-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/boolean-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/boolean-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/boolean-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/boolean-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/boolean-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/boolean-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/boolean-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/boolean-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/boolean-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/boolean-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/boolean-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/code-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/code-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/code-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-decodeError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/code-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-decodeError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-decodeError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-decodeError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/code-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-decodeError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-decodeError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-decodeError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/code-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-decodeError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-decodeError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-decodeError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/code-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-decodeError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-decodeError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/code-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/code-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/code-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/code-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/code-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/code-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-008.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-009.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-010.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-011.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-decodeError-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-decodeError-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/code_w_scope-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/code_w_scope-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/datetime-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/datetime-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/datetime-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/datetime-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/datetime-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/datetime-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/datetime-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/datetime-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/datetime-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/datetime-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/datetime-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/datetime-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/datetime-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/datetime-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/datetime-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/datetime-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/datetime-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/datetime-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/datetime-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/datetime-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/datetime-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/datetime-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/datetime-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/datetime-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-decodeError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-decodeError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbpointer-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/dbpointer-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbpointer-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbpointer-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbref-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/dbref-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbref-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbref-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbref-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/dbref-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbref-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbref-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbref-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/dbref-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbref-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbref-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbref-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/dbref-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbref-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbref-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/dbref-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/dbref-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/dbref-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/dbref-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-008.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-009.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-010.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-011.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-012.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-013.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-014.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-015.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-015.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-015.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-016.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-016.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-016.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-016.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-017.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-017.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-017.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-017.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-018.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-018.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-018.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-018.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-019.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-019.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-019.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-019.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-020.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-020.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-020.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-020.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-021.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-021.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-021.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-021.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-022.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-022.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-022.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-022.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-023.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-023.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-023.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-023.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-024.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-024.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-024.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-024.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-025.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-025.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-025.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-025.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-026.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-026.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-026.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-026.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-027.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-027.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-027.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-027.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-028.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-028.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-028.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-028.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-029.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-029.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-029.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-029.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-030.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-030.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-030.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-030.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-031.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-031.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-031.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-031.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-032.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-032.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-032.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-032.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-033.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-033.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-033.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-033.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-034.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-034.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-034.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-034.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-035.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-035.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-035.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-035.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-036.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-036.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-036.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-036.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-037.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-037.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-037.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-037.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-038.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-038.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-038.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-038.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-039.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-039.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-039.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-039.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-040.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-040.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-040.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-040.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-041.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-041.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-041.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-041.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-042.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-042.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-042.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-042.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-043.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-043.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-043.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-043.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-044.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-044.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-044.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-044.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-045.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-045.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-045.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-045.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-046.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-046.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-046.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-046.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-047.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-047.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-047.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-047.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-048.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-048.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-048.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-048.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-049.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-049.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-049.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-049.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-050.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-050.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-050.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-050.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-051.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-051.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-051.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-051.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-052.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-052.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-052.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-052.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-053.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-053.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-053.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-053.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-054.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-054.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-054.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-054.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-055.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-055.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-055.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-055.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-056.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-056.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-1-valid-056.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-1-valid-056.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-008.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-009.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-010.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-011.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-012.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-013.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-014.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-015.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-015.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-015.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-016.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-016.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-016.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-016.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-017.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-017.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-017.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-017.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-018.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-018.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-018.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-018.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-019.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-019.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-019.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-019.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-020.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-020.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-020.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-020.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-021.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-021.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-021.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-021.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-022.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-022.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-022.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-022.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-023.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-023.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-023.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-023.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-024.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-024.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-024.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-024.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-025.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-025.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-025.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-025.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-026.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-026.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-026.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-026.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-027.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-027.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-027.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-027.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-028.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-028.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-028.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-028.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-029.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-029.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-029.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-029.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-030.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-030.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-030.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-030.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-031.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-031.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-031.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-031.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-032.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-032.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-032.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-032.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-033.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-033.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-033.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-033.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-034.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-034.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-034.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-034.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-035.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-035.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-035.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-035.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-036.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-036.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-036.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-036.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-037.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-037.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-037.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-037.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-038.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-038.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-038.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-038.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-039.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-039.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-039.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-039.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-040.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-040.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-040.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-040.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-041.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-041.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-041.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-041.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-042.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-042.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-042.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-042.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-043.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-043.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-043.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-043.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-044.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-044.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-044.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-044.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-045.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-045.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-045.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-045.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-046.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-046.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-046.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-046.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-047.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-047.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-047.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-047.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-048.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-048.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-048.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-048.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-049.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-049.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-049.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-049.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-050.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-050.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-050.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-050.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-051.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-051.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-051.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-051.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-052.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-052.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-052.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-052.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-053.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-053.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-053.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-053.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-054.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-054.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-054.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-054.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-055.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-055.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-055.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-055.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-056.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-056.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-056.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-056.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-057.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-057.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-057.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-057.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-058.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-058.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-058.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-058.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-059.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-059.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-059.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-059.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-060.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-060.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-060.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-060.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-061.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-061.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-061.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-061.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-062.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-062.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-062.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-062.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-063.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-063.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-063.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-063.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-064.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-064.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-064.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-064.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-065.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-065.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-065.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-065.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-066.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-066.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-066.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-066.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-067.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-067.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-067.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-067.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-068.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-068.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-068.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-068.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-069.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-069.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-069.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-069.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-070.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-070.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-070.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-070.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-071.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-071.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-071.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-071.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-072.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-072.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-072.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-072.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-073.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-073.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-073.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-073.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-074.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-074.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-074.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-074.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-075.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-075.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-075.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-075.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-076.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-076.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-076.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-076.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-077.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-077.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-077.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-077.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-078.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-078.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-078.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-078.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-079.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-079.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-079.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-079.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-080.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-080.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-080.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-080.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-081.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-081.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-081.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-081.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-082.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-082.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-082.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-082.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-083.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-083.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-083.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-083.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-084.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-084.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-084.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-084.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-085.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-085.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-085.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-085.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-086.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-086.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-086.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-086.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-087.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-087.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-087.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-087.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-088.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-088.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-088.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-088.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-089.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-089.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-089.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-089.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-090.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-090.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-090.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-090.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-091.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-091.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-091.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-091.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-092.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-092.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-092.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-092.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-093.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-093.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-093.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-093.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-094.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-094.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-094.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-094.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-095.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-095.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-095.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-095.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-096.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-096.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-096.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-096.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-097.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-097.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-097.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-097.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-098.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-098.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-098.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-098.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-099.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-099.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-099.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-099.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-100.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-100.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-100.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-100.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-101.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-101.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-101.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-101.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-102.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-102.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-102.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-102.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-103.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-103.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-103.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-103.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-104.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-104.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-104.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-104.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-105.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-105.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-105.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-105.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-106.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-106.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-106.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-106.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-107.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-107.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-107.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-107.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-108.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-108.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-108.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-108.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-109.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-109.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-109.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-109.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-110.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-110.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-110.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-110.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-111.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-111.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-111.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-111.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-112.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-112.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-112.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-112.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-113.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-113.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-113.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-113.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-114.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-114.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-114.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-114.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-115.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-115.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-115.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-115.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-116.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-116.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-116.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-116.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-117.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-117.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-117.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-117.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-118.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-118.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-118.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-118.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-119.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-119.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-119.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-119.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-120.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-120.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-120.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-120.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-121.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-121.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-121.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-121.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-122.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-122.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-122.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-122.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-123.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-123.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-123.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-123.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-124.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-124.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-124.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-124.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-125.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-125.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-125.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-125.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-126.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-126.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-126.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-126.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-127.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-127.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-127.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-127.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-128.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-128.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-128.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-128.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-129.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-129.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-129.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-129.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-130.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-130.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-130.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-130.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-131.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-131.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-131.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-131.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-132.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-132.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-132.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-132.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-133.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-133.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-133.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-133.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-134.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-134.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-134.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-134.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-135.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-135.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-135.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-135.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-136.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-136.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-136.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-136.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-137.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-137.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-137.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-137.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-138.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-138.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-138.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-138.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-139.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-139.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-139.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-139.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-140.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-140.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-140.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-140.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-141.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-141.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-141.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-141.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-142.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-142.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-142.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-142.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-143.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-143.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-143.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-143.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-144.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-144.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-144.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-144.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-145.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-145.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-145.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-145.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-146.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-146.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-146.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-146.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-147.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-147.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-147.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-147.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-148.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-148.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-148.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-148.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-149.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-149.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-149.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-149.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-150.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-150.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-150.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-150.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-151.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-151.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-151.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-151.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-152.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-152.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-152.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-152.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-153.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-153.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-153.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-153.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-154.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-154.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-154.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-154.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-155.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-155.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-155.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-155.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-156.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-156.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-156.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-156.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-157.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-157.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-2-valid-157.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-2-valid-157.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-008.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-009.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-010.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-011.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-012.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-013.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-014.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-015.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-015.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-015.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-016.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-016.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-016.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-016.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-017.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-017.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-017.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-017.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-018.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-018.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-018.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-018.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-019.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-019.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-019.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-019.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-020.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-020.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-020.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-020.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-021.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-021.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-021.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-021.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-022.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-022.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-022.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-022.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-023.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-023.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-023.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-023.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-024.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-024.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-024.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-024.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-025.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-025.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-025.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-025.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-026.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-026.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-026.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-026.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-027.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-027.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-027.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-027.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-028.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-028.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-028.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-028.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-029.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-029.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-029.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-029.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-030.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-030.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-030.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-030.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-031.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-031.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-031.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-031.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-032.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-032.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-032.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-032.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-033.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-033.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-033.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-033.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-034.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-034.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-034.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-034.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-035.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-035.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-035.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-035.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-036.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-036.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-036.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-036.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-037.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-037.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-037.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-037.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-038.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-038.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-038.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-038.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-039.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-039.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-039.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-039.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-040.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-040.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-040.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-040.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-041.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-041.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-041.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-041.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-042.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-042.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-042.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-042.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-043.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-043.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-043.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-043.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-044.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-044.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-044.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-044.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-045.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-045.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-045.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-045.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-046.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-046.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-046.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-046.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-047.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-047.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-047.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-047.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-048.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-048.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-048.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-048.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-049.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-049.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-049.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-049.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-050.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-050.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-050.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-050.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-051.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-051.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-051.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-051.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-052.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-052.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-052.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-052.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-053.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-053.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-053.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-053.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-054.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-054.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-054.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-054.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-055.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-055.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-055.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-055.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-056.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-056.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-056.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-056.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-057.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-057.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-057.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-057.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-058.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-058.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-058.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-058.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-059.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-059.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-059.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-059.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-060.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-060.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-060.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-060.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-061.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-061.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-061.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-061.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-062.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-062.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-062.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-062.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-063.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-063.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-063.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-063.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-064.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-064.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-064.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-064.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-065.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-065.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-065.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-065.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-066.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-066.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-066.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-066.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-067.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-067.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-067.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-067.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-068.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-068.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-068.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-068.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-069.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-069.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-069.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-069.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-070.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-070.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-070.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-070.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-071.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-071.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-071.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-071.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-072.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-072.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-072.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-072.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-073.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-073.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-073.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-073.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-074.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-074.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-074.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-074.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-075.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-075.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-075.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-075.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-076.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-076.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-076.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-076.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-077.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-077.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-077.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-077.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-078.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-078.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-078.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-078.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-079.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-079.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-079.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-079.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-080.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-080.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-080.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-080.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-081.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-081.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-081.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-081.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-082.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-082.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-082.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-082.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-083.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-083.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-083.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-083.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-084.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-084.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-084.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-084.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-085.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-085.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-085.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-085.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-086.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-086.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-086.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-086.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-087.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-087.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-087.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-087.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-088.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-088.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-088.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-088.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-089.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-089.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-089.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-089.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-090.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-090.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-090.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-090.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-091.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-091.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-091.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-091.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-092.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-092.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-092.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-092.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-093.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-093.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-093.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-093.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-094.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-094.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-094.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-094.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-095.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-095.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-095.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-095.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-096.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-096.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-096.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-096.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-097.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-097.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-097.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-097.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-098.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-098.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-098.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-098.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-099.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-099.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-099.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-099.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-100.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-100.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-100.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-100.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-101.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-101.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-101.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-101.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-102.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-102.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-102.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-102.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-103.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-103.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-103.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-103.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-104.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-104.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-104.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-104.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-105.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-105.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-105.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-105.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-106.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-106.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-106.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-106.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-107.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-107.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-107.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-107.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-108.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-108.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-108.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-108.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-109.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-109.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-109.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-109.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-110.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-110.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-110.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-110.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-111.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-111.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-111.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-111.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-112.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-112.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-112.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-112.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-113.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-113.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-113.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-113.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-114.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-114.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-114.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-114.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-115.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-115.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-115.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-115.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-116.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-116.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-116.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-116.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-117.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-117.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-117.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-117.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-118.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-118.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-118.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-118.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-119.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-119.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-119.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-119.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-120.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-120.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-120.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-120.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-121.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-121.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-121.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-121.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-122.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-122.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-122.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-122.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-123.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-123.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-123.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-123.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-124.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-124.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-124.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-124.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-125.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-125.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-125.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-125.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-126.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-126.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-126.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-126.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-127.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-127.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-127.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-127.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-128.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-128.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-128.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-128.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-129.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-129.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-129.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-129.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-130.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-130.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-130.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-130.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-131.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-131.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-131.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-131.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-132.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-132.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-132.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-132.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-133.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-133.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-133.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-133.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-134.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-134.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-134.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-134.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-135.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-135.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-135.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-135.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-136.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-136.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-136.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-136.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-137.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-137.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-137.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-137.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-138.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-138.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-138.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-138.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-139.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-139.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-139.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-139.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-140.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-140.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-140.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-140.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-141.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-141.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-141.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-141.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-142.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-142.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-142.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-142.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-143.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-143.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-143.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-143.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-144.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-144.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-144.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-144.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-145.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-145.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-145.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-145.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-146.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-146.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-146.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-146.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-147.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-147.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-147.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-147.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-148.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-148.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-148.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-148.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-149.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-149.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-149.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-149.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-150.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-150.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-150.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-150.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-151.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-151.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-151.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-151.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-152.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-152.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-152.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-152.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-153.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-153.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-153.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-153.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-154.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-154.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-154.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-154.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-155.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-155.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-155.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-155.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-156.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-156.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-156.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-156.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-157.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-157.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-157.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-157.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-158.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-158.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-158.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-158.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-159.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-159.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-159.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-159.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-160.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-160.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-160.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-160.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-161.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-161.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-161.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-161.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-162.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-162.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-162.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-162.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-163.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-163.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-163.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-163.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-164.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-164.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-164.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-164.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-165.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-165.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-165.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-165.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-166.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-166.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-166.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-166.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-167.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-167.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-167.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-167.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-168.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-168.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-168.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-168.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-169.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-169.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-169.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-169.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-170.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-170.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-170.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-170.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-171.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-171.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-171.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-171.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-172.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-172.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-172.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-172.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-173.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-173.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-173.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-173.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-174.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-174.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-174.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-174.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-175.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-175.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-175.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-175.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-176.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-176.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-176.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-176.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-177.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-177.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-177.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-177.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-178.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-178.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-178.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-178.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-179.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-179.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-179.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-179.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-180.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-180.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-180.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-180.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-181.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-181.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-181.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-181.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-182.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-182.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-182.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-182.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-183.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-183.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-183.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-183.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-184.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-184.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-184.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-184.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-185.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-185.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-185.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-185.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-186.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-186.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-186.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-186.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-187.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-187.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-187.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-187.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-188.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-188.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-188.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-188.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-189.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-189.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-189.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-189.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-190.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-190.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-190.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-190.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-191.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-191.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-191.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-191.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-192.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-192.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-192.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-192.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-193.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-193.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-193.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-193.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-194.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-194.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-194.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-194.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-195.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-195.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-195.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-195.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-196.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-196.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-196.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-196.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-197.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-197.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-197.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-197.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-198.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-198.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-198.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-198.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-199.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-199.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-199.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-199.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-200.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-200.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-200.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-200.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-201.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-201.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-201.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-201.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-202.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-202.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-202.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-202.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-203.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-203.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-203.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-203.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-204.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-204.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-204.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-204.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-205.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-205.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-205.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-205.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-206.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-206.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-206.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-206.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-207.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-207.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-207.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-207.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-208.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-208.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-208.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-208.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-209.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-209.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-209.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-209.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-210.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-210.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-210.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-210.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-211.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-211.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-211.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-211.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-212.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-212.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-212.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-212.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-213.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-213.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-213.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-213.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-214.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-214.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-214.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-214.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-215.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-215.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-215.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-215.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-216.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-216.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-216.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-216.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-217.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-217.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-217.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-217.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-218.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-218.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-218.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-218.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-219.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-219.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-219.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-219.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-220.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-220.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-220.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-220.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-221.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-221.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-221.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-221.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-222.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-222.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-222.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-222.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-223.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-223.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-223.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-223.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-224.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-224.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-224.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-224.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-225.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-225.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-225.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-225.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-226.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-226.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-226.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-226.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-227.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-227.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-227.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-227.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-228.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-228.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-228.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-228.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-229.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-229.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-229.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-229.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-230.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-230.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-230.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-230.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-231.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-231.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-231.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-231.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-232.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-232.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-232.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-232.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-233.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-233.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-233.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-233.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-234.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-234.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-234.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-234.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-235.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-235.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-235.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-235.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-236.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-236.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-236.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-236.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-237.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-237.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-237.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-237.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-238.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-238.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-238.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-238.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-239.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-239.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-239.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-239.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-240.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-240.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-240.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-240.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-241.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-241.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-241.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-241.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-242.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-242.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-242.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-242.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-243.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-243.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-243.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-243.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-244.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-244.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-244.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-244.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-245.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-245.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-245.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-245.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-246.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-246.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-246.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-246.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-247.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-247.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-247.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-247.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-248.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-248.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-248.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-248.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-249.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-249.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-249.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-249.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-250.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-250.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-250.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-250.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-251.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-251.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-251.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-251.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-252.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-252.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-252.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-252.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-253.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-253.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-253.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-253.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-254.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-254.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-254.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-254.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-255.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-255.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-255.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-255.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-256.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-256.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-256.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-256.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-257.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-257.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-257.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-257.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-258.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-258.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-258.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-258.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-259.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-259.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-259.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-259.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-260.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-260.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-260.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-260.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-261.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-261.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-261.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-261.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-262.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-262.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-262.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-262.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-263.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-263.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-263.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-263.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-264.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-264.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-264.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-264.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-265.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-265.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-265.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-265.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-266.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-266.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-266.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-266.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-267.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-267.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-267.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-267.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-268.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-268.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-268.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-268.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-269.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-269.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-269.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-269.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-270.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-270.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-270.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-270.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-271.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-271.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-271.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-271.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-272.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-272.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-272.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-272.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-273.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-273.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-273.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-273.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-274.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-274.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-274.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-274.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-275.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-275.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-275.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-275.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-276.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-276.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-276.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-276.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-277.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-277.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-277.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-277.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-278.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-278.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-278.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-278.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-279.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-279.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-279.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-279.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-280.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-280.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-280.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-280.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-281.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-281.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-281.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-281.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-282.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-282.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-282.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-282.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-283.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-283.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-283.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-283.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-284.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-284.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-284.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-284.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-285.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-285.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-285.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-285.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-286.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-286.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-286.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-286.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-287.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-287.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-287.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-287.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-288.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-288.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-288.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-288.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-289.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-289.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-289.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-289.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-290.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-290.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-290.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-290.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-291.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-291.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-291.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-291.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-292.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-292.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-292.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-292.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-293.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-293.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-293.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-293.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-294.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-294.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-294.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-294.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-295.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-295.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-295.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-295.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-296.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-296.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-296.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-296.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-297.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-297.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-297.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-297.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-298.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-298.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-298.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-298.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-299.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-299.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-299.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-299.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-300.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-300.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-300.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-300.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-301.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-301.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-301.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-301.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-302.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-302.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-302.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-302.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-303.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-303.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-303.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-303.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-304.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-304.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-304.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-304.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-305.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-305.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-305.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-305.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-306.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-306.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-306.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-306.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-307.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-307.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-307.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-307.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-308.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-308.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-3-valid-308.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-3-valid-308.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-008.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-009.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-010.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-011.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-012.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-013.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-014.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-015.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-015.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-015.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-016.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-016.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-016.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-016.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-017.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-017.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-017.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-017.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-018.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-018.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-018.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-018.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-019.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-019.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-019.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-019.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-020.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-020.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-parseError-020.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-parseError-020.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-008.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-009.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-010.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-011.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-012.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-013.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-4-valid-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-4-valid-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-008.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-009.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-010.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-011.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-012.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-013.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-014.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-015.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-015.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-015.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-016.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-016.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-016.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-016.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-017.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-017.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-017.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-017.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-018.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-018.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-018.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-018.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-019.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-019.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-019.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-019.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-020.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-020.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-020.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-020.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-021.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-021.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-021.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-021.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-022.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-022.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-022.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-022.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-023.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-023.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-023.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-023.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-024.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-024.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-024.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-024.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-025.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-025.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-025.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-025.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-026.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-026.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-026.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-026.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-027.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-027.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-027.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-027.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-028.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-028.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-028.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-028.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-029.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-029.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-029.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-029.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-030.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-030.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-030.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-030.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-031.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-031.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-031.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-031.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-032.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-032.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-032.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-032.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-033.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-033.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-033.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-033.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-034.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-034.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-034.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-034.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-035.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-035.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-035.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-035.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-036.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-036.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-036.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-036.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-037.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-037.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-037.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-037.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-038.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-038.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-038.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-038.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-039.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-039.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-039.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-039.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-040.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-040.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-040.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-040.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-041.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-041.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-041.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-041.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-042.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-042.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-042.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-042.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-043.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-043.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-043.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-043.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-044.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-044.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-044.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-044.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-045.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-045.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-045.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-045.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-046.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-046.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-046.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-046.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-047.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-047.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-047.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-047.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-048.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-048.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-048.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-048.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-049.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-049.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-049.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-049.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-050.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-050.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-050.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-050.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-051.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-051.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-051.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-051.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-052.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-052.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-052.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-052.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-053.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-053.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-053.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-053.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-054.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-054.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-054.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-054.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-055.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-055.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-055.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-055.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-056.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-056.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-056.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-056.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-057.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-057.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-057.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-057.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-058.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-058.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-058.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-058.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-059.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-059.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-059.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-059.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-060.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-060.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-060.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-060.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-061.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-061.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-061.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-061.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-062.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-062.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-062.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-062.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-063.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-063.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-063.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-063.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-064.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-064.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-064.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-064.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-065.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-065.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-065.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-065.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-066.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-066.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-066.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-066.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-067.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-067.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-5-valid-067.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-5-valid-067.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-008.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-009.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-010.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-011.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-012.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-013.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-014.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-015.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-015.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-015.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-016.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-016.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-016.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-016.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-017.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-017.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-017.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-017.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-018.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-018.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-018.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-018.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-019.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-019.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-019.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-019.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-020.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-020.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-020.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-020.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-021.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-021.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-021.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-021.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-022.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-022.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-022.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-022.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-023.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-023.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-023.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-023.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-024.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-024.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-024.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-024.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-025.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-025.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-025.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-025.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-026.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-026.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-026.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-026.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-027.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-027.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-027.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-027.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-028.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-028.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-028.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-028.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-029.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-029.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-029.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-029.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-030.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-030.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-030.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-030.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-031.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-031.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-6-parseError-031.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-6-parseError-031.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-008.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-009.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-010.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-011.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-012.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-013.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-014.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-015.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-015.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-015.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-016.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-016.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-016.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-016.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-017.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-017.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-017.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-017.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-018.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-018.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-018.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-018.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-019.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-019.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-019.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-019.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-020.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-020.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-020.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-020.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-021.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-021.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-021.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-021.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-022.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-022.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-022.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-022.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-023.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-023.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-023.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-023.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-024.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-024.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-024.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-024.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-025.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-025.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-025.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-025.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-026.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-026.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-026.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-026.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-027.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-027.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-027.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-027.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-028.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-028.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-028.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-028.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-029.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-029.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-029.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-029.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-030.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-030.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-030.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-030.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-031.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-031.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-031.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-031.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-032.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-032.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-032.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-032.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-033.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-033.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-033.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-033.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-034.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-034.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-034.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-034.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-035.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-035.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-035.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-035.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-036.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-036.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-036.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-036.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-037.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-037.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-037.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-037.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-038.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-038.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-038.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-038.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-039.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-039.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-039.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-039.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-040.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-040.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-040.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-040.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-041.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-041.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-041.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-041.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-042.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-042.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-042.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-042.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-043.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-043.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-043.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-043.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-044.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-044.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-044.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-044.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-045.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-045.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-045.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-045.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-046.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-046.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-046.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-046.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-047.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-047.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-047.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-047.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-048.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-048.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-048.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-048.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-049.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-049.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-049.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-049.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-050.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-050.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-050.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-050.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-051.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-051.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-051.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-051.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-052.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-052.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-052.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-052.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-053.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-053.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-053.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-053.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-054.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-054.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-054.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-054.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-055.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-055.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-055.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-055.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-056.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-056.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-056.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-056.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-057.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-057.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-057.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-057.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-058.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-058.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-058.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-058.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-059.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-059.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-059.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-059.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-060.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-060.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-060.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-060.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-061.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-061.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-061.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-061.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-062.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-062.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-062.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-062.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-063.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-063.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-063.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-063.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-064.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-064.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-064.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-064.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-065.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-065.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-065.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-065.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-066.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-066.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-066.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-066.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-067.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-067.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-067.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-067.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-068.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-068.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-068.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-068.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-069.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-069.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-069.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-069.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-070.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-070.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-070.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-070.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-071.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-071.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-071.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-071.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-072.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-072.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-072.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-072.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-073.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-073.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-073.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-073.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-074.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-074.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-074.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-074.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-075.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-075.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-075.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-075.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-076.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-076.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-076.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-076.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-077.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-077.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-077.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-077.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-078.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-078.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-078.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-078.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-079.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-079.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-079.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-079.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-080.phpt b/mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-080.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/decimal128-7-parseError-080.phpt
rename to mongodb-1.8.1/tests/bson-corpus/decimal128-7-parseError-080.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/document-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/document-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/document-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/document-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/document-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/document-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/document-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/document-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/document-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/document-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/document-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/document-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/document-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/document-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/document-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/document-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/document-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/document-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/document-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/document-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/document-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/document-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/document-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/document-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/double-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-008.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-009.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-010.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-011.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/double-valid-012.phpt b/mongodb-1.8.1/tests/bson-corpus/double-valid-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/double-valid-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/double-valid-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int32-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/int32-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int32-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int32-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int32-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/int32-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int32-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int32-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int32-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/int32-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int32-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int32-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int32-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/int32-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int32-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int32-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int32-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/int32-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int32-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int32-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int32-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/int32-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int32-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int32-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int64-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/int64-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int64-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int64-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int64-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/int64-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int64-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int64-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int64-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/int64-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int64-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int64-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int64-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/int64-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int64-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int64-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int64-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/int64-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int64-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int64-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/int64-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/int64-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/int64-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/int64-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/maxkey-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/maxkey-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/maxkey-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/maxkey-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/minkey-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/minkey-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/minkey-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/minkey-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/multi-type-deprecated-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/multi-type-deprecated-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/multi-type-deprecated-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/multi-type-deprecated-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/multi-type-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/multi-type-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/multi-type-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/multi-type-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/null-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/null-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/null-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/null-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/oid-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/oid-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/oid-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/oid-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/oid-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/oid-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/oid-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/oid-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/oid-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/oid-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/oid-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/oid-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/oid-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/oid-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/oid-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/oid-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-008.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/regex-valid-009.phpt b/mongodb-1.8.1/tests/bson-corpus/regex-valid-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/regex-valid-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/regex-valid-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/string-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/string-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/string-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-decodeError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/string-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-decodeError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-decodeError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-decodeError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/string-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-decodeError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-decodeError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-decodeError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/string-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-decodeError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-decodeError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-decodeError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/string-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-decodeError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-decodeError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/string-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/string-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/string-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/string-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/string-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/string-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/string-valid-007.phpt b/mongodb-1.8.1/tests/bson-corpus/string-valid-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/string-valid-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/string-valid-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-decodeError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-decodeError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-valid-004.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-valid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-valid-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-valid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-valid-005.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-valid-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-valid-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-valid-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/symbol-valid-006.phpt b/mongodb-1.8.1/tests/bson-corpus/symbol-valid-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/symbol-valid-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/symbol-valid-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/timestamp-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/timestamp-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/timestamp-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/timestamp-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/timestamp-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/timestamp-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/timestamp-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/timestamp-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/timestamp-valid-002.phpt b/mongodb-1.8.1/tests/bson-corpus/timestamp-valid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/timestamp-valid-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/timestamp-valid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/timestamp-valid-003.phpt b/mongodb-1.8.1/tests/bson-corpus/timestamp-valid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/timestamp-valid-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/timestamp-valid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-008.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-009.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-010.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-011.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-012.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-013.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-decodeError-014.phpt b/mongodb-1.8.1/tests/bson-corpus/top-decodeError-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-decodeError-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-decodeError-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-001.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-002.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-002.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-002.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-003.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-003.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-003.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-004.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-004.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-004.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-005.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-005.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-005.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-006.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-006.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-006.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-007.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-007.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-007.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-008.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-008.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-008.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-009.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-009.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-009.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-010.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-010.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-010.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-011.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-011.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-011.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-012.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-012.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-012.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-013.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-013.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-013.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-014.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-014.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-014.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-014.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-015.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-015.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-015.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-016.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-016.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-016.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-016.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-017.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-017.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-017.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-017.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-018.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-018.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-018.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-018.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-019.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-019.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-019.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-019.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-020.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-020.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-020.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-020.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-021.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-021.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-021.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-021.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-022.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-022.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-022.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-022.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-023.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-023.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-023.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-023.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-024.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-024.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-024.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-024.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-025.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-025.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-025.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-025.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-026.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-026.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-026.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-026.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-027.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-027.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-027.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-027.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-028.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-028.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-028.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-028.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-029.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-029.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-029.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-029.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-030.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-030.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-030.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-030.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-031.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-031.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-031.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-031.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-032.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-032.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-032.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-032.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-033.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-033.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-033.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-033.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-034.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-034.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-034.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-034.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-035.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-035.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-035.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-035.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-036.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-036.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-036.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-036.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-037.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-037.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-037.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-037.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-038.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-038.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-038.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-038.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-039.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-039.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-039.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-039.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-040.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-040.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-040.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-040.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-parseError-041.phpt b/mongodb-1.8.1/tests/bson-corpus/top-parseError-041.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-parseError-041.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-parseError-041.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/top-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/top-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/top-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/top-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson-corpus/undefined-valid-001.phpt b/mongodb-1.8.1/tests/bson-corpus/undefined-valid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson-corpus/undefined-valid-001.phpt
rename to mongodb-1.8.1/tests/bson-corpus/undefined-valid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-compare-002.phpt b/mongodb-1.8.1/tests/bson/bson-binary-compare-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-compare-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-compare-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-binary-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-binary-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-binary-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-serialization_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-binary-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-serialization_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-serialization_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-set_state_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-set_state_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-binary-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-set_state_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-set_state_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-set_state_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-binary-set_state_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-set_state_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-set_state_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary-tostring-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary-tostring-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary-tostring-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary-tostring-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-binary_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-binary_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-binary_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binary_error-004.phpt b/mongodb-1.8.1/tests/bson/bson-binary_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binary_error-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-binary_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-binaryinterface-001.phpt b/mongodb-1.8.1/tests/bson/bson-binaryinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-binaryinterface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-binaryinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-001.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-002.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-jsonserialize-003.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-jsonserialize-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-jsonserialize-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-jsonserialize-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer-tostring-001.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer-tostring-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer-tostring-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer-tostring-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-dbpointer_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-dbpointer_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-dbpointer_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-dbpointer_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-002.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-003.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-004.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-set_state_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128-set_state_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128-set_state_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128-set_state_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decimal128interface-001.phpt b/mongodb-1.8.1/tests/bson/bson-decimal128interface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decimal128interface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decimal128interface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decode-001.phpt b/mongodb-1.8.1/tests/bson/bson-decode-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decode-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-decode-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-decode-002.phpt b/mongodb-1.8.1/tests/bson/bson-decode-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-decode-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-decode-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-encode-001.phpt b/mongodb-1.8.1/tests/bson/bson-encode-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-encode-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-encode-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-encode-002.phpt b/mongodb-1.8.1/tests/bson/bson-encode-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-encode-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-encode-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-encode-003.phpt b/mongodb-1.8.1/tests/bson/bson-encode-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-encode-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-encode-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-encode-004.phpt b/mongodb-1.8.1/tests/bson/bson-encode-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-encode-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-encode-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-encode-005.phpt b/mongodb-1.8.1/tests/bson/bson-encode-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-encode-005.phpt
rename to mongodb-1.8.1/tests/bson/bson-encode-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromJSON-001.phpt b/mongodb-1.8.1/tests/bson/bson-fromJSON-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromJSON-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromJSON-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromJSON-002.phpt b/mongodb-1.8.1/tests/bson/bson-fromJSON-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromJSON-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromJSON-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromJSON_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-fromJSON_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromJSON_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromJSON_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP-001.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP-002.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP-003.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP-005.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP-005.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP-006.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP-006.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP-006.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP_error-004.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP_error-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP_error-005.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP_error-005.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP_error-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP_error-006.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP_error-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP_error-006.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP_error-006.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP_error-007.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP_error-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP_error-007.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP_error-007.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-fromPHP_error-008.phpt b/mongodb-1.8.1/tests/bson/bson-fromPHP_error-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-fromPHP_error-008.phpt
rename to mongodb-1.8.1/tests/bson/bson-fromPHP_error-008.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-generate-document-id.phpt b/mongodb-1.8.1/tests/bson/bson-generate-document-id.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-generate-document-id.phpt
rename to mongodb-1.8.1/tests/bson/bson-generate-document-id.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-002.phpt b/mongodb-1.8.1/tests/bson/bson-int64-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-003.phpt b/mongodb-1.8.1/tests/bson/bson-int64-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-debug-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-debug-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-int64-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-int64-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-int64-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64-tostring-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64-tostring-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64-tostring-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64-tostring-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-int64_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-int64_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-int64_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-int64_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-002.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-compare-002.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-compare-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-compare-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-compare-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-getCode-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-getCode-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-getCode-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-getCode-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-getScope-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-getScope-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-getScope-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-getScope-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-jsonserialize-003.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-jsonserialize-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-jsonserialize-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-jsonserialize-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-jsonserialize-004.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-jsonserialize-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-jsonserialize-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-jsonserialize-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-serialization_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-serialization_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-serialization_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-set_state_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-set_state_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-set_state_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-set_state_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-set_state_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-set_state_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-set_state_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-set_state_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript-tostring-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript-tostring-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript-tostring-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript-tostring-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascript_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-javascript_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascript_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-javascript_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascript_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascript_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-javascriptinterface-001.phpt b/mongodb-1.8.1/tests/bson/bson-javascriptinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-javascriptinterface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-javascriptinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkey-001.phpt b/mongodb-1.8.1/tests/bson/bson-maxkey-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkey-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkey-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkey-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-maxkey-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkey-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkey-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkey-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-maxkey-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkey-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkey-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkey-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-maxkey-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkey-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkey-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkey-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-maxkey-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkey-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkey-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkey-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-maxkey-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkey-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkey-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkey-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-maxkey-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkey-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkey-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkey_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-maxkey_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkey_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkey_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-maxkeyinterface-001.phpt b/mongodb-1.8.1/tests/bson/bson-maxkeyinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-maxkeyinterface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-maxkeyinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkey-001.phpt b/mongodb-1.8.1/tests/bson/bson-minkey-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkey-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkey-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkey-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-minkey-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkey-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkey-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkey-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-minkey-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkey-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkey-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkey-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-minkey-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkey-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkey-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkey-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-minkey-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkey-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkey-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkey-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-minkey-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkey-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkey-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkey-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-minkey-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkey-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkey-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkey_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-minkey_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkey_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkey_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-minkeyinterface-001.phpt b/mongodb-1.8.1/tests/bson/bson-minkeyinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-minkeyinterface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-minkeyinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-002.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-003.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-004.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-compare-002.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-compare-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-compare-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-compare-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-getTimestamp-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-getTimestamp-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-getTimestamp-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-getTimestamp-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-getTimestamp-002.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-getTimestamp-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-getTimestamp-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-getTimestamp-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-set_state_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid-set_state_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-objectid-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid-set_state_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid-set_state_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectid_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-objectid_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectid_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-objectid_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectid_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectid_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-objectidinterface-001.phpt b/mongodb-1.8.1/tests/bson/bson-objectidinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-objectidinterface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-objectidinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-003.phpt b/mongodb-1.8.1/tests/bson/bson-regex-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-004.phpt b/mongodb-1.8.1/tests/bson/bson-regex-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-005.phpt b/mongodb-1.8.1/tests/bson/bson-regex-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-005.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-compare-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex-compare-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-compare-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-compare-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-jsonserialize-003.phpt b/mongodb-1.8.1/tests/bson/bson-regex-jsonserialize-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-jsonserialize-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-jsonserialize-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-jsonserialize-004.phpt b/mongodb-1.8.1/tests/bson/bson-regex-jsonserialize-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-jsonserialize-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-jsonserialize-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-serialization-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex-serialization-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-serialization-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-serialization-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-serialization-003.phpt b/mongodb-1.8.1/tests/bson/bson-regex-serialization-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-serialization-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-serialization-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-set_state-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex-set_state-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-set_state-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-set_state-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-set_state_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex-set_state_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex-set_state_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex-set_state_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-regex_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-regex_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regex_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-regex_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regex_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-regex_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-regexinterface-001.phpt b/mongodb-1.8.1/tests/bson/bson-regexinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-regexinterface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-regexinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol-tostring-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol-tostring-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol-tostring-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol-tostring-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-symbol_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-symbol_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-symbol_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-symbol_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-002.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-003.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-004.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-005.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-005.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-getIncrement-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-getIncrement-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-getIncrement-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-getIncrement-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-getTimestamp-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-getTimestamp-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-getTimestamp-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-getTimestamp-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-serialization-002.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-serialization-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-serialization-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-serialization-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-serialization_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-serialization_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-serialization_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-serialization_error-004.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-serialization_error-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-serialization_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-set_state-002.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-set_state-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-set_state-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-set_state-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-set_state_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-set_state_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-set_state_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-set_state_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-set_state_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-set_state_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-set_state_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-set_state_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp-set_state_error-004.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp-set_state_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp-set_state_error-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp-set_state_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp_error-004.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp_error-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp_error-005.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp_error-005.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp_error-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestamp_error-006.phpt b/mongodb-1.8.1/tests/bson/bson-timestamp_error-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestamp_error-006.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestamp_error-006.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-timestampinterface-001.phpt b/mongodb-1.8.1/tests/bson/bson-timestampinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-timestampinterface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-timestampinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toCanonicalJSON-001.phpt b/mongodb-1.8.1/tests/bson/bson-toCanonicalJSON-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toCanonicalJSON-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-toCanonicalJSON-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toCanonicalJSON-002.phpt b/mongodb-1.8.1/tests/bson/bson-toCanonicalJSON-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toCanonicalJSON-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-toCanonicalJSON-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toCanonicalJSON_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-toCanonicalJSON_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toCanonicalJSON_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-toCanonicalJSON_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toCanonicalJSON_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-toCanonicalJSON_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toCanonicalJSON_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-toCanonicalJSON_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toCanonicalJSON_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-toCanonicalJSON_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toCanonicalJSON_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-toCanonicalJSON_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toJSON-001.phpt b/mongodb-1.8.1/tests/bson/bson-toJSON-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toJSON-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-toJSON-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toJSON-002.phpt b/mongodb-1.8.1/tests/bson/bson-toJSON-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toJSON-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-toJSON-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toJSON_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-toJSON_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toJSON_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-toJSON_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toJSON_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-toJSON_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toJSON_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-toJSON_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toJSON_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-toJSON_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toJSON_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-toJSON_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-001.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-002.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-003.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-004.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-006.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-006.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-006.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-007.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-007.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-007.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-008.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-008.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-008.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-009.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-009.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-009.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-010.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-010.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-010.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP-011.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP-011.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP-011.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP_error-004.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP_error-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP_error-005.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP_error-005.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP_error-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toPHP_error-006.phpt b/mongodb-1.8.1/tests/bson/bson-toPHP_error-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toPHP_error-006.phpt
rename to mongodb-1.8.1/tests/bson/bson-toPHP_error-006.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toRelaxedJSON-001.phpt b/mongodb-1.8.1/tests/bson/bson-toRelaxedJSON-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toRelaxedJSON-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-toRelaxedJSON-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toRelaxedJSON-002.phpt b/mongodb-1.8.1/tests/bson/bson-toRelaxedJSON-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toRelaxedJSON-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-toRelaxedJSON-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toRelaxedJSON_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-toRelaxedJSON_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toRelaxedJSON_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-toRelaxedJSON_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toRelaxedJSON_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-toRelaxedJSON_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toRelaxedJSON_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-toRelaxedJSON_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-toRelaxedJSON_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-toRelaxedJSON_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-toRelaxedJSON_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-toRelaxedJSON_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-undefined-001.phpt b/mongodb-1.8.1/tests/bson/bson-undefined-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-undefined-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-undefined-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-undefined-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-undefined-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-undefined-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-undefined-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-undefined-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-undefined-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-undefined-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-undefined-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-undefined-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-undefined-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-undefined-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-undefined-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-undefined-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-undefined-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-undefined-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-undefined-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-undefined-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-undefined-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-undefined-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-undefined-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-undefined-tostring-001.phpt b/mongodb-1.8.1/tests/bson/bson-undefined-tostring-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-undefined-tostring-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-undefined-tostring-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-undefined_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-undefined_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-undefined_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-undefined_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-unknown-001.phpt b/mongodb-1.8.1/tests/bson/bson-unknown-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-unknown-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-unknown-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-003.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-004.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-005.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-005.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-006.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-006.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-006.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-007.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-007.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-007.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-clone-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-clone-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-clone-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-clone-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-compare-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-compare-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-compare-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-compare-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-get_properties-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-get_properties-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-get_properties-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-get_properties-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-get_properties-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-get_properties-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-int-size-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-int-size-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-int-size-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-int-size-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-int-size-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-int-size-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-int-size-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-int-size-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-jsonserialize-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-jsonserialize-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-jsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-jsonserialize-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-jsonserialize-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-jsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-serialization-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-serialization-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-serialization-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-serialization-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-serialization-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-serialization-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-serialization_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-serialization_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-serialization_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-serialization_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-serialization_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-serialization_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-set_state-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-set_state-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-set_state-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-set_state-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-set_state-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-set_state-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-set_state_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-set_state_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-set_state_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-set_state_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-todatetime-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-todatetime-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-todatetime-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-todatetime-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-todatetime-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-todatetime-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-todatetime-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-todatetime-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime-tostring-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime-tostring-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime-tostring-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime-tostring-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime_error-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime_error-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime_error-002.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime_error-002.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime_error-003.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime_error-003.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetime_error-004.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetime_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetime_error-004.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetime_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/bson-utcdatetimeinterface-001.phpt b/mongodb-1.8.1/tests/bson/bson-utcdatetimeinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bson-utcdatetimeinterface-001.phpt
rename to mongodb-1.8.1/tests/bson/bson-utcdatetimeinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0274.phpt b/mongodb-1.8.1/tests/bson/bug0274.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0274.phpt
rename to mongodb-1.8.1/tests/bson/bug0274.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0325.phpt b/mongodb-1.8.1/tests/bson/bug0325.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0325.phpt
rename to mongodb-1.8.1/tests/bson/bug0325.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0334-001.phpt b/mongodb-1.8.1/tests/bson/bug0334-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0334-001.phpt
rename to mongodb-1.8.1/tests/bson/bug0334-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0334-002.phpt b/mongodb-1.8.1/tests/bson/bug0334-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0334-002.phpt
rename to mongodb-1.8.1/tests/bson/bug0334-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0341.phpt b/mongodb-1.8.1/tests/bson/bug0341.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0341.phpt
rename to mongodb-1.8.1/tests/bson/bug0341.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0347.phpt b/mongodb-1.8.1/tests/bson/bug0347.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0347.phpt
rename to mongodb-1.8.1/tests/bson/bug0347.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0528.phpt b/mongodb-1.8.1/tests/bson/bug0528.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0528.phpt
rename to mongodb-1.8.1/tests/bson/bug0528.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0531-001.phpt b/mongodb-1.8.1/tests/bson/bug0531-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0531-001.phpt
rename to mongodb-1.8.1/tests/bson/bug0531-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0544.phpt b/mongodb-1.8.1/tests/bson/bug0544.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0544.phpt
rename to mongodb-1.8.1/tests/bson/bug0544.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0592.phpt b/mongodb-1.8.1/tests/bson/bug0592.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0592.phpt
rename to mongodb-1.8.1/tests/bson/bug0592.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0623.phpt b/mongodb-1.8.1/tests/bson/bug0623.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0623.phpt
rename to mongodb-1.8.1/tests/bson/bug0623.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0631.phpt b/mongodb-1.8.1/tests/bson/bug0631.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0631.phpt
rename to mongodb-1.8.1/tests/bson/bug0631.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0672.phpt b/mongodb-1.8.1/tests/bson/bug0672.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0672.phpt
rename to mongodb-1.8.1/tests/bson/bug0672.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0894-001.phpt b/mongodb-1.8.1/tests/bson/bug0894-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0894-001.phpt
rename to mongodb-1.8.1/tests/bson/bug0894-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0923-001.phpt b/mongodb-1.8.1/tests/bson/bug0923-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0923-001.phpt
rename to mongodb-1.8.1/tests/bson/bug0923-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0923-002.phpt b/mongodb-1.8.1/tests/bson/bug0923-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0923-002.phpt
rename to mongodb-1.8.1/tests/bson/bug0923-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0939-001.phpt b/mongodb-1.8.1/tests/bson/bug0939-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0939-001.phpt
rename to mongodb-1.8.1/tests/bson/bug0939-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug0974-001.phpt b/mongodb-1.8.1/tests/bson/bug0974-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug0974-001.phpt
rename to mongodb-1.8.1/tests/bson/bug0974-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug1006-001.phpt b/mongodb-1.8.1/tests/bson/bug1006-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug1006-001.phpt
rename to mongodb-1.8.1/tests/bson/bug1006-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug1006-002.phpt b/mongodb-1.8.1/tests/bson/bug1006-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug1006-002.phpt
rename to mongodb-1.8.1/tests/bson/bug1006-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug1053.phpt b/mongodb-1.8.1/tests/bson/bug1053.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug1053.phpt
rename to mongodb-1.8.1/tests/bson/bug1053.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug1067.phpt b/mongodb-1.8.1/tests/bson/bug1067.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug1067.phpt
rename to mongodb-1.8.1/tests/bson/bug1067.phpt
diff --git a/mongodb-1.7.4/tests/bson/bug1266.phpt b/mongodb-1.8.1/tests/bson/bug1266.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/bug1266.phpt
rename to mongodb-1.8.1/tests/bson/bug1266.phpt
diff --git a/mongodb-1.8.1/tests/bson/bug1598-001.phpt b/mongodb-1.8.1/tests/bson/bug1598-001.phpt
new file mode 100644
index 00000000..6d988681
--- /dev/null
+++ b/mongodb-1.8.1/tests/bson/bug1598-001.phpt
@@ -0,0 +1,97 @@
+--TEST--
+PHPC-1598: BSON type get_gc should not invoke get_properties
+--FILE--
+<?php
+
+$tests = [
+ [ 'binary' => new MongoDB\BSON\Binary('foo', MongoDB\BSON\Binary::TYPE_GENERIC) ],
+ // Use serialized strings to construct types with disabled constructors
+ [ 'dbpointer' => unserialize('C:22:"MongoDB\BSON\DBPointer":76:{a:2:{s:3:"ref";s:11:"phongo.test";s:2:"id";s:24:"5a2e78accd485d55b4050000";}}') ],
+ [ 'decimal128' => new MongoDB\BSON\Decimal128('1234.5678') ],
+ [ 'int64' => unserialize('C:18:"MongoDB\BSON\Int64":47:{a:1:{s:7:"integer";s:19:"9223372036854775807";}}') ],
+ // JavaScript w/ scope may not be necessary (same code path as w/o scope), but we'll test it anyway
+ [ 'javascript' => new MongoDB\BSON\Javascript('function() { return 1; }') ],
+ [ 'javascript_ws' => new MongoDB\BSON\Javascript('function() { return a; }', ['a' => 1]) ],
+ // MaxKey and MinKey don't have get_properties or get_gc handlers, but we'll test them anyway
+ [ 'maxkey' => new MongoDB\BSON\MaxKey ],
+ [ 'minkey' => new MongoDB\BSON\MinKey ],
+ [ 'objectid' => new MongoDB\BSON\ObjectId ],
+ [ 'regex' => new MongoDB\BSON\Regex('pattern', 'i') ],
+ [ 'symbol' => unserialize('C:19:"MongoDB\BSON\Symbol":38:{a:1:{s:6:"symbol";s:11:"symbolValue";}}') ],
+ [ 'timestamp' => new MongoDB\BSON\Timestamp(1234, 5678) ],
+ [ 'utcdatetime' => new MongoDB\BSON\UTCDateTime ],
+];
+
+foreach ($tests as $test) {
+ echo key($test), "\n";
+
+ $a = (object) $test;
+ $b = (object) $test;
+
+ $a->b = $b;
+ $b->a = $a;
+
+ printf("Collected cycles: %d\n", gc_collect_cycles());
+
+ unset($a, $b);
+
+ printf("Collected cycles: %d\n\n", gc_collect_cycles());
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+binary
+Collected cycles: 0
+Collected cycles: 2
+
+dbpointer
+Collected cycles: 0
+Collected cycles: 2
+
+decimal128
+Collected cycles: 0
+Collected cycles: 2
+
+int64
+Collected cycles: 0
+Collected cycles: 2
+
+javascript
+Collected cycles: 0
+Collected cycles: 2
+
+javascript_ws
+Collected cycles: 0
+Collected cycles: 2
+
+maxkey
+Collected cycles: 0
+Collected cycles: 2
+
+minkey
+Collected cycles: 0
+Collected cycles: 2
+
+objectid
+Collected cycles: 0
+Collected cycles: 2
+
+regex
+Collected cycles: 0
+Collected cycles: 2
+
+symbol
+Collected cycles: 0
+Collected cycles: 2
+
+timestamp
+Collected cycles: 0
+Collected cycles: 2
+
+utcdatetime
+Collected cycles: 0
+Collected cycles: 2
+
+===DONE===
diff --git a/mongodb-1.8.1/tests/bson/bug1598-002.phpt b/mongodb-1.8.1/tests/bson/bug1598-002.phpt
new file mode 100644
index 00000000..ddce01fa
--- /dev/null
+++ b/mongodb-1.8.1/tests/bson/bug1598-002.phpt
@@ -0,0 +1,103 @@
+--TEST--
+PHPC-1598: BSON type get_gc should delegate to zend_std_get_properties
+--FILE--
+<?php
+
+$tests = [
+ [ 'binary' => new MongoDB\BSON\Binary('foo', MongoDB\BSON\Binary::TYPE_GENERIC) ],
+ // Use serialized strings to construct types with disabled constructors
+ [ 'dbpointer' => unserialize('C:22:"MongoDB\BSON\DBPointer":76:{a:2:{s:3:"ref";s:11:"phongo.test";s:2:"id";s:24:"5a2e78accd485d55b4050000";}}') ],
+ [ 'decimal128' => new MongoDB\BSON\Decimal128('1234.5678') ],
+ [ 'int64' => unserialize('C:18:"MongoDB\BSON\Int64":47:{a:1:{s:7:"integer";s:19:"9223372036854775807";}}') ],
+ // JavaScript w/ scope may not be necessary (same code path as w/o scope), but we'll test it anyway
+ [ 'javascript' => new MongoDB\BSON\Javascript('function() { return 1; }') ],
+ [ 'javascript_ws' => new MongoDB\BSON\Javascript('function() { return a; }', ['a' => 1]) ],
+ // MaxKey and MinKey don't have get_properties or get_gc handlers, but we'll test them anyway
+ [ 'maxkey' => new MongoDB\BSON\MaxKey ],
+ [ 'minkey' => new MongoDB\BSON\MinKey ],
+ [ 'objectid' => new MongoDB\BSON\ObjectId ],
+ [ 'regex' => new MongoDB\BSON\Regex('pattern', 'i') ],
+ [ 'symbol' => unserialize('C:19:"MongoDB\BSON\Symbol":38:{a:1:{s:6:"symbol";s:11:"symbolValue";}}') ],
+ [ 'timestamp' => new MongoDB\BSON\Timestamp(1234, 5678) ],
+ [ 'utcdatetime' => new MongoDB\BSON\UTCDateTime ],
+];
+
+foreach ($tests as &$test) {
+ echo key($test), "\n";
+
+ /* Store an additional object reference as a public property on the BSON
+ * object. This will leak if get_gc returns internally cached properties
+ * (from our get_properties handler) instead of zend_std_get_properties. */
+ $a = new stdClass;
+ $a->bson = current($test);
+ $a->bson->a = $a;
+
+ /* Unset the original BSON object from the test so that its only reference
+ * is from the new object we just created. This also requires iterating the
+ * test cases by reference. */
+ unset($test[key($test)]);
+
+ printf("Collected cycles: %d\n", gc_collect_cycles());
+
+ unset($a);
+
+ printf("Collected cycles: %d\n\n", gc_collect_cycles());
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+binary
+Collected cycles: 0
+Collected cycles: 2
+
+dbpointer
+Collected cycles: 0
+Collected cycles: 2
+
+decimal128
+Collected cycles: 0
+Collected cycles: 2
+
+int64
+Collected cycles: 0
+Collected cycles: 2
+
+javascript
+Collected cycles: 0
+Collected cycles: 2
+
+javascript_ws
+Collected cycles: 0
+Collected cycles: 2
+
+maxkey
+Collected cycles: 0
+Collected cycles: 2
+
+minkey
+Collected cycles: 0
+Collected cycles: 2
+
+objectid
+Collected cycles: 0
+Collected cycles: 2
+
+regex
+Collected cycles: 0
+Collected cycles: 2
+
+symbol
+Collected cycles: 0
+Collected cycles: 2
+
+timestamp
+Collected cycles: 0
+Collected cycles: 2
+
+utcdatetime
+Collected cycles: 0
+Collected cycles: 2
+
+===DONE===
diff --git a/mongodb-1.7.4/tests/bson/typemap-001.phpt b/mongodb-1.8.1/tests/bson/typemap-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/typemap-001.phpt
rename to mongodb-1.8.1/tests/bson/typemap-001.phpt
diff --git a/mongodb-1.7.4/tests/bson/typemap-002.phpt b/mongodb-1.8.1/tests/bson/typemap-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/typemap-002.phpt
rename to mongodb-1.8.1/tests/bson/typemap-002.phpt
diff --git a/mongodb-1.7.4/tests/bson/typemap-003.phpt b/mongodb-1.8.1/tests/bson/typemap-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/typemap-003.phpt
rename to mongodb-1.8.1/tests/bson/typemap-003.phpt
diff --git a/mongodb-1.7.4/tests/bson/typemap-004.phpt b/mongodb-1.8.1/tests/bson/typemap-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/typemap-004.phpt
rename to mongodb-1.8.1/tests/bson/typemap-004.phpt
diff --git a/mongodb-1.7.4/tests/bson/typemap-005.phpt b/mongodb-1.8.1/tests/bson/typemap-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/typemap-005.phpt
rename to mongodb-1.8.1/tests/bson/typemap-005.phpt
diff --git a/mongodb-1.7.4/tests/bson/typemap-006.phpt b/mongodb-1.8.1/tests/bson/typemap-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/typemap-006.phpt
rename to mongodb-1.8.1/tests/bson/typemap-006.phpt
diff --git a/mongodb-1.7.4/tests/bson/typemap-007.phpt b/mongodb-1.8.1/tests/bson/typemap-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bson/typemap-007.phpt
rename to mongodb-1.8.1/tests/bson/typemap-007.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bug0667.phpt b/mongodb-1.8.1/tests/bulk/bug0667.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bug0667.phpt
rename to mongodb-1.8.1/tests/bulk/bug0667.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-count-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-count-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-count-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-count-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-countable-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-countable-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-countable-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-countable-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-debug-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-debug-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-delete-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-delete-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-delete-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-delete-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update-004.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-delete-002.phpt
similarity index 69%
copy from mongodb-1.7.4/tests/bulk/bulkwrite-update-004.phpt
copy to mongodb-1.8.1/tests/bulk/bulkwrite-delete-002.phpt
index 1e21cc0b..674fb761 100644
--- a/mongodb-1.7.4/tests/bulk/bulkwrite-update-004.phpt
+++ b/mongodb-1.8.1/tests/bulk/bulkwrite-delete-002.phpt
@@ -1,55 +1,55 @@
--TEST--
-MongoDB\Driver\BulkWrite::update() with hint option
+MongoDB\Driver\BulkWrite::delete() with hint option
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
-<?php skip_if_server_version('<', '4.2'); ?>
+<?php skip_if_server_version('<', '4.3.4'); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class CommandLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
- if ($event->getCommandName() !== 'update') {
+ if ($event->getCommandName() !== 'delete') {
return;
}
- printf("update included hint: %s\n", json_encode($event->getCommand()->updates[0]->hint));
+ printf("delete included hint: %s\n", json_encode($event->getCommand()->deletes[0]->hint));
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
}
}
$manager = new MongoDB\Driver\Manager(URI);
$bulk = new MongoDB\Driver\BulkWrite();
$bulk->insert(['x' => 1]);
$bulk->insert(['x' => 2]);
$manager->executeBulkWrite(NS, $bulk);
MongoDB\Driver\Monitoring\addSubscriber(new CommandLogger);
$bulk = new MongoDB\Driver\BulkWrite;
-$bulk->update(['_id' => 1], ['$set' => ['x' => 11]], ['hint' => '_id_']);
+$bulk->delete(['_id' => 1], ['hint' => '_id_']);
$manager->executeBulkWrite(NS, $bulk);
$bulk = new MongoDB\Driver\BulkWrite;
-$bulk->update(['_id' => 2], ['$set' => ['x' => 22]], ['hint' => ['_id' => 1]]);
+$bulk->delete(['_id' => 2], ['hint' => ['_id' => 1]]);
$manager->executeBulkWrite(NS, $bulk);
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
-update included hint: "_id_"
-update included hint: {"_id":1}
+delete included hint: "_id_"
+delete included hint: {"_id":1}
===DONE===
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-001.phpt
similarity index 64%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-001.phpt
index fc1efe38..f802e217 100644
--- a/mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-001.phpt
+++ b/mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-001.phpt
@@ -1,20 +1,27 @@
--TEST--
MongoDB\Driver\BulkWrite::delete() with invalid options
--FILE--
<?php
require_once __DIR__ . '/../utils/tools.php';
$bulk = new MongoDB\Driver\BulkWrite;
echo throws(function() use ($bulk) {
$bulk->delete(['x' => 1], ['collation' => 1]);
+}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n";
+
+echo throws(function() use ($bulk) {
+ $bulk->delete(['x' => 1], ['hint' => 1]);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "collation" option to be array or object, int%S given
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "hint" option to be string, array, or object, int%S given
===DONE===
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-002.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-002.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-003.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-003.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-004.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-delete_error-004.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-008.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-005.phpt
similarity index 61%
copy from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-008.phpt
copy to mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-005.phpt
index f927d3c8..0ddef2ac 100644
--- a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-008.phpt
+++ b/mongodb-1.8.1/tests/bulk/bulkwrite-delete_error-005.phpt
@@ -1,26 +1,27 @@
--TEST--
-MongoDB\Driver\BulkWrite::update() hint option requires MongoDB 4.2
+MongoDB\Driver\BulkWrite::delete() hint option requires MongoDB 4.4 (server-side error)
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
-<?php skip_if_server_version('>=', '4.2'); ?>
+<?php skip_if_server_version('>=', '4.3.4'); ?>
+<?php skip_if_server_version('<=', '3.6.0'); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$manager = new MongoDB\Driver\Manager(URI);
$bulk = new MongoDB\Driver\BulkWrite;
-$bulk->update(['_id' => 1], ['$set' => ['x' => 11]], ['hint' => '_id_']);
+$bulk->delete(['_id' => 1], ['hint' => '_id_']);
echo throws(function() use ($manager, $bulk) {
$manager->executeBulkWrite(NS, $bulk);
}, 'MongoDB\Driver\Exception\BulkWriteException'), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\BulkWriteException
-Bulk write failed due to previous MongoDB\Driver\Exception\RuntimeException: The selected server does not support hint for update
+BSON field 'delete.deletes.hint' is an unknown field.
===DONE===
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-insert-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-insert-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-insert-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-insert-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-insert-004.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-insert-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-insert-004.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-insert-004.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-insert_error-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-insert_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-insert_error-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-insert_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-insert_error-002.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-insert_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-insert_error-002.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-insert_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-insert_error-003.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-insert_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-insert_error-003.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-insert_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update-002.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update-002.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update-002.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update-003.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update-003.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update-003.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update-004.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update-004.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update-004.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-002.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-002.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-003.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-003.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update_error-003.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-004.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-004.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update_error-004.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-005.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-005.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update_error-005.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-006.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-006.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update_error-006.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-007.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-007.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update_error-007.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-008.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-008.phpt
similarity index 83%
rename from mongodb-1.7.4/tests/bulk/bulkwrite-update_error-008.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite-update_error-008.phpt
index f927d3c8..da17c563 100644
--- a/mongodb-1.7.4/tests/bulk/bulkwrite-update_error-008.phpt
+++ b/mongodb-1.8.1/tests/bulk/bulkwrite-update_error-008.phpt
@@ -1,26 +1,27 @@
--TEST--
-MongoDB\Driver\BulkWrite::update() hint option requires MongoDB 4.2
+MongoDB\Driver\BulkWrite::update() hint option requires MongoDB 4.2 (server-side error)
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
<?php skip_if_server_version('>=', '4.2'); ?>
+<?php skip_if_server_version('<=', '3.6.0'); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$manager = new MongoDB\Driver\Manager(URI);
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->update(['_id' => 1], ['$set' => ['x' => 11]], ['hint' => '_id_']);
echo throws(function() use ($manager, $bulk) {
$manager->executeBulkWrite(NS, $bulk);
}, 'MongoDB\Driver\Exception\BulkWriteException'), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\BulkWriteException
-Bulk write failed due to previous MongoDB\Driver\Exception\RuntimeException: The selected server does not support hint for update
+BSON field 'update.updates.hint' is an unknown field.
===DONE===
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite_error-001.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite_error-001.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite_error-001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/bulkwrite_error-002.phpt b/mongodb-1.8.1/tests/bulk/bulkwrite_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/bulkwrite_error-002.phpt
rename to mongodb-1.8.1/tests/bulk/bulkwrite_error-002.phpt
diff --git a/mongodb-1.7.4/tests/bulk/write-0001.phpt b/mongodb-1.8.1/tests/bulk/write-0001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/write-0001.phpt
rename to mongodb-1.8.1/tests/bulk/write-0001.phpt
diff --git a/mongodb-1.7.4/tests/bulk/write-0002.phpt b/mongodb-1.8.1/tests/bulk/write-0002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/bulk/write-0002.phpt
rename to mongodb-1.8.1/tests/bulk/write-0002.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-001.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-001.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-001.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-002.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-002.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-002.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-003.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-003.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-003.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-004.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-004.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-004.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-005.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-005.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-005.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-006.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-006.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-006.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-007.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-007.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-007.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-008.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-008.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-008.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-009.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-009.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-009.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-010.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-010.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-010.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-011.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-011.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-011.phpt
diff --git a/mongodb-1.7.4/tests/causal-consistency/causal-consistency-012.phpt b/mongodb-1.8.1/tests/causal-consistency/causal-consistency-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/causal-consistency/causal-consistency-012.phpt
rename to mongodb-1.8.1/tests/causal-consistency/causal-consistency-012.phpt
diff --git a/mongodb-1.7.4/tests/clientEncryption/clientEncryption-constants.phpt b/mongodb-1.8.1/tests/clientEncryption/clientEncryption-constants.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/clientEncryption/clientEncryption-constants.phpt
rename to mongodb-1.8.1/tests/clientEncryption/clientEncryption-constants.phpt
diff --git a/mongodb-1.7.4/tests/clientEncryption/clientEncryption-createDataKey-001.phpt b/mongodb-1.8.1/tests/clientEncryption/clientEncryption-createDataKey-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/clientEncryption/clientEncryption-createDataKey-001.phpt
rename to mongodb-1.8.1/tests/clientEncryption/clientEncryption-createDataKey-001.phpt
diff --git a/mongodb-1.7.4/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt b/mongodb-1.8.1/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt
rename to mongodb-1.8.1/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt
diff --git a/mongodb-1.7.4/tests/clientEncryption/clientEncryption-decrypt-001.phpt b/mongodb-1.8.1/tests/clientEncryption/clientEncryption-decrypt-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/clientEncryption/clientEncryption-decrypt-001.phpt
rename to mongodb-1.8.1/tests/clientEncryption/clientEncryption-decrypt-001.phpt
diff --git a/mongodb-1.7.4/tests/clientEncryption/clientEncryption-encrypt-001.phpt b/mongodb-1.8.1/tests/clientEncryption/clientEncryption-encrypt-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/clientEncryption/clientEncryption-encrypt-001.phpt
rename to mongodb-1.8.1/tests/clientEncryption/clientEncryption-encrypt-001.phpt
diff --git a/mongodb-1.7.4/tests/command/command-ctor-001.phpt b/mongodb-1.8.1/tests/command/command-ctor-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/command/command-ctor-001.phpt
rename to mongodb-1.8.1/tests/command/command-ctor-001.phpt
diff --git a/mongodb-1.7.4/tests/command/command_error-001.phpt b/mongodb-1.8.1/tests/command/command_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/command/command_error-001.phpt
rename to mongodb-1.8.1/tests/command/command_error-001.phpt
diff --git a/mongodb-1.7.4/tests/command/cursor-batchsize-001.phpt b/mongodb-1.8.1/tests/command/cursor-batchsize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/command/cursor-batchsize-001.phpt
rename to mongodb-1.8.1/tests/command/cursor-batchsize-001.phpt
diff --git a/mongodb-1.7.4/tests/command/cursor-batchsize-002.phpt b/mongodb-1.8.1/tests/command/cursor-batchsize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/command/cursor-batchsize-002.phpt
rename to mongodb-1.8.1/tests/command/cursor-batchsize-002.phpt
diff --git a/mongodb-1.7.4/tests/command/cursor-tailable-001.phpt b/mongodb-1.8.1/tests/command/cursor-tailable-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/command/cursor-tailable-001.phpt
rename to mongodb-1.8.1/tests/command/cursor-tailable-001.phpt
diff --git a/mongodb-1.7.4/tests/command/findAndModify-001.phpt b/mongodb-1.8.1/tests/command/findAndModify-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/command/findAndModify-001.phpt
rename to mongodb-1.8.1/tests/command/findAndModify-001.phpt
diff --git a/mongodb-1.7.4/tests/command/update-001.phpt b/mongodb-1.8.1/tests/command/update-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/command/update-001.phpt
rename to mongodb-1.8.1/tests/command/update-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/bug0720.phpt b/mongodb-1.8.1/tests/connect/bug0720.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/bug0720.phpt
rename to mongodb-1.8.1/tests/connect/bug0720.phpt
diff --git a/mongodb-1.7.4/tests/connect/bug1015.phpt b/mongodb-1.8.1/tests/connect/bug1015.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/bug1015.phpt
rename to mongodb-1.8.1/tests/connect/bug1015.phpt
diff --git a/mongodb-1.7.4/tests/connect/bug1045.phpt b/mongodb-1.8.1/tests/connect/bug1045.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/bug1045.phpt
rename to mongodb-1.8.1/tests/connect/bug1045.phpt
diff --git a/mongodb-1.7.4/tests/connect/compression_error-001.phpt b/mongodb-1.8.1/tests/connect/compression_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/compression_error-001.phpt
rename to mongodb-1.8.1/tests/connect/compression_error-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/compression_error-002.phpt b/mongodb-1.8.1/tests/connect/compression_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/compression_error-002.phpt
rename to mongodb-1.8.1/tests/connect/compression_error-002.phpt
diff --git a/mongodb-1.7.4/tests/connect/replicaset-seedlist-001.phpt b/mongodb-1.8.1/tests/connect/replicaset-seedlist-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/replicaset-seedlist-001.phpt
rename to mongodb-1.8.1/tests/connect/replicaset-seedlist-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/replicaset-seedlist-002.phpt b/mongodb-1.8.1/tests/connect/replicaset-seedlist-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/replicaset-seedlist-002.phpt
rename to mongodb-1.8.1/tests/connect/replicaset-seedlist-002.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-auth-001.phpt b/mongodb-1.8.1/tests/connect/standalone-auth-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-auth-001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-auth-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-auth_error-001.phpt b/mongodb-1.8.1/tests/connect/standalone-auth_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-auth_error-001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-auth_error-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-plain-0001.phpt b/mongodb-1.8.1/tests/connect/standalone-plain-0001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-plain-0001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-plain-0001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-plain-0002.phpt b/mongodb-1.8.1/tests/connect/standalone-plain-0002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-plain-0002.phpt
rename to mongodb-1.8.1/tests/connect/standalone-plain-0002.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-ssl-no_verify-001.phpt b/mongodb-1.8.1/tests/connect/standalone-ssl-no_verify-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-ssl-no_verify-001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-ssl-no_verify-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-ssl-no_verify-002.phpt b/mongodb-1.8.1/tests/connect/standalone-ssl-no_verify-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-ssl-no_verify-002.phpt
rename to mongodb-1.8.1/tests/connect/standalone-ssl-no_verify-002.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-ssl-verify_cert-001.phpt b/mongodb-1.8.1/tests/connect/standalone-ssl-verify_cert-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-ssl-verify_cert-001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-ssl-verify_cert-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-ssl-verify_cert-002.phpt b/mongodb-1.8.1/tests/connect/standalone-ssl-verify_cert-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-ssl-verify_cert-002.phpt
rename to mongodb-1.8.1/tests/connect/standalone-ssl-verify_cert-002.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-ssl-verify_cert-error-001.phpt b/mongodb-1.8.1/tests/connect/standalone-ssl-verify_cert-error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-ssl-verify_cert-error-001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-ssl-verify_cert-error-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-ssl-verify_cert-error-002.phpt b/mongodb-1.8.1/tests/connect/standalone-ssl-verify_cert-error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-ssl-verify_cert-error-002.phpt
rename to mongodb-1.8.1/tests/connect/standalone-ssl-verify_cert-error-002.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-x509-auth-001.phpt b/mongodb-1.8.1/tests/connect/standalone-x509-auth-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-x509-auth-001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-x509-auth-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-x509-auth-002.phpt b/mongodb-1.8.1/tests/connect/standalone-x509-auth-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-x509-auth-002.phpt
rename to mongodb-1.8.1/tests/connect/standalone-x509-auth-002.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-x509-error-0001.phpt b/mongodb-1.8.1/tests/connect/standalone-x509-error-0001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-x509-error-0001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-x509-error-0001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-x509-extract_username-001.phpt b/mongodb-1.8.1/tests/connect/standalone-x509-extract_username-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-x509-extract_username-001.phpt
rename to mongodb-1.8.1/tests/connect/standalone-x509-extract_username-001.phpt
diff --git a/mongodb-1.7.4/tests/connect/standalone-x509-extract_username-002.phpt b/mongodb-1.8.1/tests/connect/standalone-x509-extract_username-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/connect/standalone-x509-extract_username-002.phpt
rename to mongodb-1.8.1/tests/connect/standalone-x509-extract_username-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug0671-001.phpt b/mongodb-1.8.1/tests/cursor/bug0671-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug0671-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug0671-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug0732-001.phpt b/mongodb-1.8.1/tests/cursor/bug0732-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug0732-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug0732-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug0849-001.phpt b/mongodb-1.8.1/tests/cursor/bug0849-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug0849-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug0849-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug0924-001.phpt b/mongodb-1.8.1/tests/cursor/bug0924-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug0924-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug0924-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug0924-002.phpt b/mongodb-1.8.1/tests/cursor/bug0924-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug0924-002.phpt
rename to mongodb-1.8.1/tests/cursor/bug0924-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1050-001.phpt b/mongodb-1.8.1/tests/cursor/bug1050-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1050-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug1050-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1050-002.phpt b/mongodb-1.8.1/tests/cursor/bug1050-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1050-002.phpt
rename to mongodb-1.8.1/tests/cursor/bug1050-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1151-001.phpt b/mongodb-1.8.1/tests/cursor/bug1151-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1151-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug1151-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1151-002.phpt b/mongodb-1.8.1/tests/cursor/bug1151-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1151-002.phpt
rename to mongodb-1.8.1/tests/cursor/bug1151-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1151-003.phpt b/mongodb-1.8.1/tests/cursor/bug1151-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1151-003.phpt
rename to mongodb-1.8.1/tests/cursor/bug1151-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1151-004.phpt b/mongodb-1.8.1/tests/cursor/bug1151-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1151-004.phpt
rename to mongodb-1.8.1/tests/cursor/bug1151-004.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1152-001.phpt b/mongodb-1.8.1/tests/cursor/bug1152-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1152-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug1152-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1152-002.phpt b/mongodb-1.8.1/tests/cursor/bug1152-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1152-002.phpt
rename to mongodb-1.8.1/tests/cursor/bug1152-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1162-001.phpt b/mongodb-1.8.1/tests/cursor/bug1162-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1162-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug1162-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1274-001.phpt b/mongodb-1.8.1/tests/cursor/bug1274-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1274-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug1274-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1274-002.phpt b/mongodb-1.8.1/tests/cursor/bug1274-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1274-002.phpt
rename to mongodb-1.8.1/tests/cursor/bug1274-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1274-003.phpt b/mongodb-1.8.1/tests/cursor/bug1274-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1274-003.phpt
rename to mongodb-1.8.1/tests/cursor/bug1274-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/bug1419-001.phpt b/mongodb-1.8.1/tests/cursor/bug1419-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/bug1419-001.phpt
rename to mongodb-1.8.1/tests/cursor/bug1419-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-IteratorIterator-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-IteratorIterator-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-IteratorIterator-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-IteratorIterator-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-IteratorIterator-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-IteratorIterator-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-IteratorIterator-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-IteratorIterator-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-IteratorIterator-003.phpt b/mongodb-1.8.1/tests/cursor/cursor-IteratorIterator-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-IteratorIterator-003.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-IteratorIterator-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-IteratorIterator-004.phpt b/mongodb-1.8.1/tests/cursor/cursor-IteratorIterator-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-IteratorIterator-004.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-IteratorIterator-004.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-NoRewindIterator-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-NoRewindIterator-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-NoRewindIterator-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-NoRewindIterator-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-destruct-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-destruct-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-destruct-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-destruct-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-get_iterator-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-get_iterator-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-get_iterator-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-get_iterator-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-get_iterator-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-get_iterator-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-get_iterator-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-get_iterator-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-get_iterator-003.phpt b/mongodb-1.8.1/tests/cursor/cursor-get_iterator-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-get_iterator-003.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-get_iterator-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-getmore-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-getmore-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-getmore-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-getmore-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-getmore-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-getmore-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-getmore-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-getmore-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-getmore-003.phpt b/mongodb-1.8.1/tests/cursor/cursor-getmore-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-getmore-003.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-getmore-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-getmore-004.phpt b/mongodb-1.8.1/tests/cursor/cursor-getmore-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-getmore-004.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-getmore-004.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-getmore-005.phpt b/mongodb-1.8.1/tests/cursor/cursor-getmore-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-getmore-005.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-getmore-005.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-getmore-006.phpt b/mongodb-1.8.1/tests/cursor/cursor-getmore-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-getmore-006.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-getmore-006.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-getmore-007.phpt b/mongodb-1.8.1/tests/cursor/cursor-getmore-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-getmore-007.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-getmore-007.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-getmore-008.phpt b/mongodb-1.8.1/tests/cursor/cursor-getmore-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-getmore-008.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-getmore-008.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-isDead-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-isDead-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-isDead-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-isDead-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-isDead-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-isDead-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-isDead-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-isDead-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-isDead-003.phpt b/mongodb-1.8.1/tests/cursor/cursor-isDead-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-isDead-003.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-isDead-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-isDead-004.phpt b/mongodb-1.8.1/tests/cursor/cursor-isDead-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-isDead-004.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-isDead-004.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-iterator_handlers-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-iterator_handlers-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-iterator_handlers-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-iterator_handlers-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-rewind-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-rewind-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-rewind-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-rewind-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-session-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-session-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-session-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-session-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-session-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-session-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-session-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-session-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-session-003.phpt b/mongodb-1.8.1/tests/cursor/cursor-session-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-session-003.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-session-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-session-004.phpt b/mongodb-1.8.1/tests/cursor/cursor-session-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-session-004.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-session-004.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-setTypeMap_error-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-setTypeMap_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-setTypeMap_error-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-setTypeMap_error-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-setTypeMap_error-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-setTypeMap_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-setTypeMap_error-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-setTypeMap_error-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-setTypeMap_error-003.phpt b/mongodb-1.8.1/tests/cursor/cursor-setTypeMap_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-setTypeMap_error-003.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-setTypeMap_error-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-setTypeMap_error-004.phpt b/mongodb-1.8.1/tests/cursor/cursor-setTypeMap_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-setTypeMap_error-004.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-setTypeMap_error-004.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-tailable-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-tailable-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-tailable-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-tailable-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-tailable-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-tailable-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-tailable-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-tailable-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-tailable-003.phpt b/mongodb-1.8.1/tests/cursor/cursor-tailable-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-tailable-003.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-tailable-003.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-tailable_error-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-tailable_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-tailable_error-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-tailable_error-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-tailable_error-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-tailable_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-tailable_error-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-tailable_error-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-toArray-001.phpt b/mongodb-1.8.1/tests/cursor/cursor-toArray-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-toArray-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-toArray-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor-toArray-002.phpt b/mongodb-1.8.1/tests/cursor/cursor-toArray-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor-toArray-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursor-toArray-002.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursor_error-001.phpt b/mongodb-1.8.1/tests/cursor/cursor_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursor_error-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursor_error-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursorinterface-001.phpt b/mongodb-1.8.1/tests/cursor/cursorinterface-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursorinterface-001.phpt
rename to mongodb-1.8.1/tests/cursor/cursorinterface-001.phpt
diff --git a/mongodb-1.7.4/tests/cursor/cursorinterface-002.phpt b/mongodb-1.8.1/tests/cursor/cursorinterface-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursor/cursorinterface-002.phpt
rename to mongodb-1.8.1/tests/cursor/cursorinterface-002.phpt
diff --git a/mongodb-1.7.4/tests/cursorid/cursorid-001.phpt b/mongodb-1.8.1/tests/cursorid/cursorid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursorid/cursorid-001.phpt
rename to mongodb-1.8.1/tests/cursorid/cursorid-001.phpt
diff --git a/mongodb-1.7.4/tests/cursorid/cursorid-002.phpt b/mongodb-1.8.1/tests/cursorid/cursorid-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursorid/cursorid-002.phpt
rename to mongodb-1.8.1/tests/cursorid/cursorid-002.phpt
diff --git a/mongodb-1.7.4/tests/cursorid/cursorid-serialization-001.phpt b/mongodb-1.8.1/tests/cursorid/cursorid-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursorid/cursorid-serialization-001.phpt
rename to mongodb-1.8.1/tests/cursorid/cursorid-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/cursorid/cursorid_error-001.phpt b/mongodb-1.8.1/tests/cursorid/cursorid_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/cursorid/cursorid_error-001.phpt
rename to mongodb-1.8.1/tests/cursorid/cursorid_error-001.phpt
diff --git a/mongodb-1.7.4/tests/exception/bulkwriteexception-getwriteresult-001.phpt b/mongodb-1.8.1/tests/exception/bulkwriteexception-getwriteresult-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/bulkwriteexception-getwriteresult-001.phpt
rename to mongodb-1.8.1/tests/exception/bulkwriteexception-getwriteresult-001.phpt
diff --git a/mongodb-1.7.4/tests/exception/bulkwriteexception-haserrorlabel-001.phpt b/mongodb-1.8.1/tests/exception/bulkwriteexception-haserrorlabel-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/bulkwriteexception-haserrorlabel-001.phpt
rename to mongodb-1.8.1/tests/exception/bulkwriteexception-haserrorlabel-001.phpt
diff --git a/mongodb-1.8.1/tests/exception/bulkwriteexception-haserrorlabel-002.phpt b/mongodb-1.8.1/tests/exception/bulkwriteexception-haserrorlabel-002.phpt
new file mode 100644
index 00000000..e6792844
--- /dev/null
+++ b/mongodb-1.8.1/tests/exception/bulkwriteexception-haserrorlabel-002.phpt
@@ -0,0 +1,41 @@
+--TEST--
+MongoDB\Driver\Exception\BulkWriteException::hasErrorLabel() with writeConcernError
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_no_failcommand_failpoint(); ?>
+<?php skip_if_not_clean(); ?>
+--FILE--
+<?php
+require_once __DIR__ . "/../utils/basic.inc";
+
+// Disable retryWrites since we want to check for a RetryableWriteError error label
+$manager = new MongoDB\Driver\Manager(URI, ['retryWrites' => false]);
+
+// Select a specific server for future operations to avoid mongos switching in sharded clusters
+$server = $manager->selectServer(new \MongoDB\Driver\ReadPreference('primary'));
+
+configureTargetedFailPoint($server, 'failCommand', [ 'times' => 1 ], [
+ 'failCommands' => ['insert'],
+ 'writeConcernError' => [
+ 'code' => 91,
+ 'errmsg' => 'Replication is being shut down',
+ 'errorLabels' => ['RetryableWriteError'],
+ ],
+]);
+
+$bulk = new MongoDB\Driver\BulkWrite;
+$bulk->insert(['x' => 1]);
+
+try {
+ $server->executeBulkWrite(NS, $bulk);
+} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
+ var_dump($e->hasErrorLabel('RetryableWriteError'));
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+bool(true)
+===DONE===
diff --git a/mongodb-1.7.4/tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt b/mongodb-1.8.1/tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt
rename to mongodb-1.8.1/tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt
diff --git a/mongodb-1.7.4/tests/exception/commandexception-getresultdocument-001.phpt b/mongodb-1.8.1/tests/exception/commandexception-getresultdocument-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/commandexception-getresultdocument-001.phpt
rename to mongodb-1.8.1/tests/exception/commandexception-getresultdocument-001.phpt
diff --git a/mongodb-1.7.4/tests/exception/commandexception-haserrorlabel-001.phpt b/mongodb-1.8.1/tests/exception/commandexception-haserrorlabel-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/commandexception-haserrorlabel-001.phpt
rename to mongodb-1.8.1/tests/exception/commandexception-haserrorlabel-001.phpt
diff --git a/mongodb-1.7.4/tests/exception/commandexception-haserrorlabel_error-001.phpt b/mongodb-1.8.1/tests/exception/commandexception-haserrorlabel_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/commandexception-haserrorlabel_error-001.phpt
rename to mongodb-1.8.1/tests/exception/commandexception-haserrorlabel_error-001.phpt
diff --git a/mongodb-1.7.4/tests/exception/exception-001.phpt b/mongodb-1.8.1/tests/exception/exception-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/exception-001.phpt
rename to mongodb-1.8.1/tests/exception/exception-001.phpt
diff --git a/mongodb-1.7.4/tests/exception/runtimeexception-haserrorlabel-001.phpt b/mongodb-1.8.1/tests/exception/runtimeexception-haserrorlabel-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/runtimeexception-haserrorlabel-001.phpt
rename to mongodb-1.8.1/tests/exception/runtimeexception-haserrorlabel-001.phpt
diff --git a/mongodb-1.7.4/tests/exception/runtimeexception-haserrorlabel_error-001.phpt b/mongodb-1.8.1/tests/exception/runtimeexception-haserrorlabel_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/exception/runtimeexception-haserrorlabel_error-001.phpt
rename to mongodb-1.8.1/tests/exception/runtimeexception-haserrorlabel_error-001.phpt
diff --git a/mongodb-1.7.4/tests/functional/cursor-001.phpt b/mongodb-1.8.1/tests/functional/cursor-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/functional/cursor-001.phpt
rename to mongodb-1.8.1/tests/functional/cursor-001.phpt
diff --git a/mongodb-1.7.4/tests/functional/cursorid-001.phpt b/mongodb-1.8.1/tests/functional/cursorid-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/functional/cursorid-001.phpt
rename to mongodb-1.8.1/tests/functional/cursorid-001.phpt
diff --git a/mongodb-1.7.4/tests/functional/phpinfo-1.phpt b/mongodb-1.8.1/tests/functional/phpinfo-1.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/functional/phpinfo-1.phpt
rename to mongodb-1.8.1/tests/functional/phpinfo-1.phpt
diff --git a/mongodb-1.7.4/tests/functional/phpinfo-2.phpt b/mongodb-1.8.1/tests/functional/phpinfo-2.phpt
similarity index 94%
rename from mongodb-1.7.4/tests/functional/phpinfo-2.phpt
rename to mongodb-1.8.1/tests/functional/phpinfo-2.phpt
index 9f5b8f10..2a240f7f 100644
--- a/mongodb-1.7.4/tests/functional/phpinfo-2.phpt
+++ b/mongodb-1.8.1/tests/functional/phpinfo-2.phpt
@@ -1,18 +1,18 @@
--TEST--
phpinfo() reports mongodb.debug (default and overridden)
--INI--
mongodb.debug=stderr
--FILE--
<?php
ini_set("mongodb.debug", "stdout");
phpinfo();
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
%a
mongodb.debug => stdout => stderr
%a
-===DONE===
+===DONE===%A
diff --git a/mongodb-1.7.4/tests/functional/query-sort-001.phpt b/mongodb-1.8.1/tests/functional/query-sort-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/functional/query-sort-001.phpt
rename to mongodb-1.8.1/tests/functional/query-sort-001.phpt
diff --git a/mongodb-1.7.4/tests/functional/query-sort-002.phpt b/mongodb-1.8.1/tests/functional/query-sort-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/functional/query-sort-002.phpt
rename to mongodb-1.8.1/tests/functional/query-sort-002.phpt
diff --git a/mongodb-1.7.4/tests/functional/query-sort-003.phpt b/mongodb-1.8.1/tests/functional/query-sort-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/functional/query-sort-003.phpt
rename to mongodb-1.8.1/tests/functional/query-sort-003.phpt
diff --git a/mongodb-1.7.4/tests/functional/query-sort-004.phpt b/mongodb-1.8.1/tests/functional/query-sort-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/functional/query-sort-004.phpt
rename to mongodb-1.8.1/tests/functional/query-sort-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/bug0572.phpt b/mongodb-1.8.1/tests/manager/bug0572.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/bug0572.phpt
rename to mongodb-1.8.1/tests/manager/bug0572.phpt
diff --git a/mongodb-1.7.4/tests/manager/bug0851-001.phpt b/mongodb-1.8.1/tests/manager/bug0851-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/bug0851-001.phpt
rename to mongodb-1.8.1/tests/manager/bug0851-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/bug0851-002.phpt b/mongodb-1.8.1/tests/manager/bug0851-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/bug0851-002.phpt
rename to mongodb-1.8.1/tests/manager/bug0851-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/bug0912-001.phpt b/mongodb-1.8.1/tests/manager/bug0912-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/bug0912-001.phpt
rename to mongodb-1.8.1/tests/manager/bug0912-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/bug0913-001.phpt b/mongodb-1.8.1/tests/manager/bug0913-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/bug0913-001.phpt
rename to mongodb-1.8.1/tests/manager/bug0913-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/bug0940-001.phpt b/mongodb-1.8.1/tests/manager/bug0940-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/bug0940-001.phpt
rename to mongodb-1.8.1/tests/manager/bug0940-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/bug0940-002.phpt b/mongodb-1.8.1/tests/manager/bug0940-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/bug0940-002.phpt
rename to mongodb-1.8.1/tests/manager/bug0940-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/bug1163-001.phpt b/mongodb-1.8.1/tests/manager/bug1163-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/bug1163-001.phpt
rename to mongodb-1.8.1/tests/manager/bug1163-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-createClientEncryption-001.phpt b/mongodb-1.8.1/tests/manager/manager-createClientEncryption-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-createClientEncryption-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-createClientEncryption-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-createClientEncryption-error-001.phpt b/mongodb-1.8.1/tests/manager/manager-createClientEncryption-error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-createClientEncryption-error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-createClientEncryption-error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-createClientEncryption-error-002.phpt b/mongodb-1.8.1/tests/manager/manager-createClientEncryption-error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-createClientEncryption-error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-createClientEncryption-error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-003.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-004.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-005.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-005.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-005.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-006.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-006.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-006.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-appname-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-appname-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-appname-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-appname-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-appname_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-appname_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-appname_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-appname_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-auth_mechanism-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-auth_mechanism-001.phpt
similarity index 88%
rename from mongodb-1.7.4/tests/manager/manager-ctor-auth_mechanism-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-auth_mechanism-001.phpt
index 135500ac..e4ebd35a 100644
--- a/mongodb-1.7.4/tests/manager/manager-ctor-auth_mechanism-001.phpt
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-auth_mechanism-001.phpt
@@ -1,27 +1,29 @@
--TEST--
MongoDB\Driver\Manager::__construct(): authMechanism option
--FILE--
<?php
$tests = [
['mongodb://username@127.0.0.1/?authMechanism=MONGODB-X509', []],
['mongodb://127.0.0.1/?authMechanism=MONGODB-X509', []],
['mongodb://username@127.0.0.1/?authMechanism=GSSAPI', []],
+ ['mongodb://127.0.0.1/?authMechanism=MONGODB-AWS', []],
[null, ['authMechanism' => 'MONGODB-X509', 'username' => 'username']],
[null, ['authMechanism' => 'MONGODB-X509']],
[null, ['authMechanism' => 'GSSAPI', 'username' => 'username']],
+ [null, ['authMechanism' => 'MONGODB-AWS']],
];
foreach ($tests as $test) {
list($uri, $options) = $test;
/* Note: the Manager's debug information does not include the auth mechanism
* so we are merely testing that no exception is thrown. */
$manager = new MongoDB\Driver\Manager($uri, $options);
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-auth_mechanism-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-auth_mechanism-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-auth_mechanism-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-auth_mechanism-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-auth_mechanism-error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-auth_mechanism-error-001.phpt
similarity index 80%
rename from mongodb-1.7.4/tests/manager/manager-ctor-auth_mechanism-error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-auth_mechanism-error-001.phpt
index 77b926a1..7f523ceb 100644
--- a/mongodb-1.7.4/tests/manager/manager-ctor-auth_mechanism-error-001.phpt
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-auth_mechanism-error-001.phpt
@@ -1,54 +1,66 @@
--TEST--
MongoDB\Driver\Manager::__construct(): authentication options are validated
--FILE--
<?php
require_once __DIR__ . '/../utils/tools.php';
echo throws(function() {
new MongoDB\Driver\Manager('mongodb://localhost:27017/?authMechanism=GSSAPI&authSource=admin');
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
echo throws(function() {
new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['authMechanism' => 'GSSAPI', 'authSource' => 'admin']);
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
echo throws(function() {
new MongoDB\Driver\Manager('mongodb://localhost:27017/?authMechanism=MONGODB-X509&authSource=admin');
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
echo throws(function() {
new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['authMechanism' => 'MONGODB-X509', 'authSource' => 'admin']);
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
echo throws(function() {
new MongoDB\Driver\Manager('mongodb://@localhost:27017/?authMechanism=SCRAM-SHA-1');
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
echo throws(function() {
new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['username' => '', 'authMechanism' => 'SCRAM-SHA-1']);
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
echo throws(function() {
new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['password' => 'password', 'authMechanism' => 'MONGODB-X509']);
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
+echo throws(function() {
+ new MongoDB\Driver\Manager('mongodb://localhost:27017/?authSource=foo');
+}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
+
+echo throws(function() {
+ new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['authSource' => 'foo']);
+}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
+
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Failed to parse MongoDB URI: 'mongodb://localhost:27017/?authMechanism=GSSAPI&authSource=admin'. GSSAPI and X509 require "$external" authSource.
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Failed to parse URI options: GSSAPI and X509 require "$external" authSource.
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Failed to parse MongoDB URI: 'mongodb://localhost:27017/?authMechanism=MONGODB-X509&authSource=admin'. GSSAPI and X509 require "$external" authSource.
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Failed to parse URI options: GSSAPI and X509 require "$external" authSource.
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Failed to parse MongoDB URI: 'mongodb://@localhost:27017/?authMechanism=SCRAM-SHA-1'. 'SCRAM-SHA-1' authentication mechanism requires username.
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Failed to parse URI options: 'SCRAM-SHA-1' authentication mechanism requires username.
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Failed to parse URI options: X509 authentication mechanism does not accept a password.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?authSource=foo'. Default authentication mechanism requires username.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: Default authentication mechanism requires username.
===DONE===
diff --git a/mongodb-1.8.1/tests/manager/manager-ctor-auth_source-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-auth_source-001.phpt
new file mode 100644
index 00000000..ec752e8a
--- /dev/null
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-auth_source-001.phpt
@@ -0,0 +1,23 @@
+--TEST--
+MongoDB\Driver\Manager::__construct(): authSource option
+--FILE--
+<?php
+
+$tests = [
+ ['mongodb://username@127.0.0.1/?authSource=$external', []],
+ [null, ['authSource' => '$external']],
+];
+
+foreach ($tests as $test) {
+ list($uri, $options) = $test;
+
+ /* Note: the Manager's debug information does not include the auth mechanism
+ * so we are merely testing that no exception is thrown. */
+ $manager = new MongoDB\Driver\Manager($uri, $options);
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-001.phpt
similarity index 95%
rename from mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-001.phpt
index 31cf3f7a..9742b692 100644
--- a/mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-001.phpt
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-001.phpt
@@ -1,50 +1,51 @@
--TEST--
MongoDB\Driver\Manager::__construct(): auto encryption options
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_appveyor(); /* AppVeyor does not have mongocryptd installed */ ?>
<?php skip_if_not_libmongocrypt(); ?>
--FILE--
<?php
$baseOptions = [
'keyVaultNamespace' => 'admin.dataKeys',
'kmsProviders' => ['aws' => (object) ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']]
];
$tests = [
[],
['keyVaultClient' => new MongoDB\Driver\Manager()],
['schemaMap' => [
'default.default' => [
'properties' => [
'encrypted_objectId' => [
'encrypt' => [
'keyId' => [
[
'$binary' => [
'base64' => 'AAAAAAAAAAAAAAAAAAAAAA==',
'subType' => '04',
],
],
],
'bsonType' => 'objectId',
'algorithm' => MongoDB\Driver\ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
],
],
],
'bsonType' => 'object',
],
]],
['bypassAutoEncryption' => true],
['extraOptions' => ['mongocryptdBypassSpawn' => true]],
];
foreach ($tests as $autoEncryptionOptions) {
$manager = new MongoDB\Driver\Manager(null, [], ['autoEncryption' => $autoEncryptionOptions + $baseOptions]);
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-error-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-error-003.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-auto_encryption-error-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-auto_encryption-error-003.phpt
diff --git a/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-001.phpt
new file mode 100644
index 00000000..c1e0bb73
--- /dev/null
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-001.phpt
@@ -0,0 +1,31 @@
+--TEST--
+MongoDB\Driver\Manager::__construct(): directConnection option
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_replica_set(); ?>
+<?php skip_if_not_enough_data_nodes(2); ?>
+--FILE--
+<?php
+
+require_once __DIR__ . "/../utils/basic.inc";
+
+$manager = new \MongoDB\Driver\Manager(URI, ['directConnection' => false]);
+$server = $manager->selectServer(new \MongoDB\Driver\ReadPreference('primaryPreferred'));
+
+printf("Topology has multiple nodes when directConnection=false: %s\n", count($manager->getServers()) > 1 ? 'true' : 'false');
+
+$uri = sprintf('mongodb://%s:%d', $server->getHost(), $server->getPort());
+$manager2 = new \MongoDB\Driver\Manager($uri, ['directConnection' => true]);
+$server2 = $manager2->selectServer(new \MongoDB\Driver\ReadPreference('primaryPreferred'));
+
+printf("Topology has single node when directConnection=true: %s\n", count($manager2->getServers()) == 1 ? 'true' : 'false');
+printf("Single node in topology matches seed in URI: %s\n", ($server2 == $server) ? 'true' : 'false');
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+Topology has multiple nodes when directConnection=false: true
+Topology has single node when directConnection=true: true
+Single node in topology matches seed in URI: true
+===DONE===
diff --git a/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-error-001.phpt
new file mode 100644
index 00000000..2fae8f97
--- /dev/null
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-error-001.phpt
@@ -0,0 +1,25 @@
+--TEST--
+MongoDB\Driver\Manager::__construct(): directConnection=true conflicts with multiple seeds
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/tools.php';
+
+echo throws(function() {
+ $manager = new \MongoDB\Driver\Manager('mongodb://a.example.com,b.example.com/?directConnection=true');
+}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n\n";
+
+echo throws(function() {
+ $manager = new \MongoDB\Driver\Manager('mongodb://a.example.com,b.example.com', ['directConnection' => true]);
+}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://a.example.com,b.example.com/?directConnection=true'. Multiple seeds not allowed with directConnection option.
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: Multiple seeds not allowed with directConnection option.
+===DONE===
diff --git a/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-error-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-error-002.phpt
new file mode 100644
index 00000000..3eb8386a
--- /dev/null
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-directconnection-error-002.phpt
@@ -0,0 +1,25 @@
+--TEST--
+MongoDB\Driver\Manager::__construct(): directConnection=true conflicts with SRV
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/tools.php';
+
+echo throws(function() {
+ $manager = new \MongoDB\Driver\Manager('mongodb+srv://a.example.com/?directConnection=true');
+}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n\n";
+
+echo throws(function() {
+ $manager = new \MongoDB\Driver\Manager('mongodb+srv://a.example.com', ['directConnection' => true]);
+}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb+srv://a.example.com/?directConnection=true'. SRV URI not allowed with directConnection option.
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: SRV URI not allowed with directConnection option.
+===DONE===
diff --git a/mongodb-1.8.1/tests/manager/manager-ctor-driver-metadata-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-driver-metadata-001.phpt
new file mode 100644
index 00000000..aae14a37
--- /dev/null
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-driver-metadata-001.phpt
@@ -0,0 +1,17 @@
+--TEST--
+MongoDB\Driver\Manager: Pass custom handshake data
+--INI--
+mongodb.debug=stderr
+--FILE--
+<?php
+
+$manager = new MongoDB\Driver\Manager(null, [], ['driver' => ['name' => 'test', 'version' => '0.1', 'platform' => 'mine']]);
+$manager = new MongoDB\Driver\Manager(null, [], ['driver' => ['name' => 'test']]);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+%A[%s] PHONGO: DEBUG > Setting driver handshake data: name ext-mongodb:PHP / test, version %s / 0.1, platform PHP %s / mine
+%A[%s] PHONGO: DEBUG > Setting driver handshake data: name ext-mongodb:PHP / test, version %s, platform PHP %s
+%A===DONE===%A
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-duplicate-option-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-duplicate-option-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-duplicate-option-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-duplicate-option-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-duplicate-option-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-duplicate-option-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-duplicate-option-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-duplicate-option-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-duplicate-option-003.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-duplicate-option-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-duplicate-option-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-duplicate-option-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-duplicate-option-004.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-duplicate-option-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-duplicate-option-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-duplicate-option-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_concern-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_concern-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_concern-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_concern-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_concern-error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_concern-error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_concern-error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_concern-error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_preference-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_preference-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_preference-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_preference-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_preference-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_preference-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_preference-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_preference-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_preference-004.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_preference-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_preference-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_preference-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_preference-error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_preference-error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_preference-error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_preference-error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_preference-error-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_preference-error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_preference-error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_preference-error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_preference-error-003.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_preference-error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_preference-error-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_preference-error-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-read_preference-error-004.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-read_preference-error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-read_preference-error-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-read_preference-error-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-server.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-server.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-server.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-server.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-ssl-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-ssl-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-ssl-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-ssl-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-ssl-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-ssl-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-ssl-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-ssl-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-ssl-003.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-ssl-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-ssl-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-ssl-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-ssl-deprecated-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-ssl-deprecated-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-ssl-deprecated-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-ssl-deprecated-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-ssl-deprecated-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-ssl-deprecated-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-ssl-deprecated-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-ssl-deprecated-002.phpt
diff --git a/mongodb-1.8.1/tests/manager/manager-ctor-tls-error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-tls-error-001.phpt
new file mode 100644
index 00000000..113a96f1
--- /dev/null
+++ b/mongodb-1.8.1/tests/manager/manager-ctor-tls-error-001.phpt
@@ -0,0 +1,152 @@
+--TEST--
+MongoDB\Driver\Manager::__construct(): Test invalid URI option combinations
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/tools.php';
+
+$invalidCombinations = [
+ ['tlsInsecure', 'tlsAllowInvalidHostnames'],
+ ['tlsInsecure', 'tlsAllowInvalidCertificates'],
+ ['tlsInsecure', 'tlsDisableOCSPEndpointCheck'],
+ ['tlsInsecure', 'tlsDisableCertificateRevocationCheck'],
+ ['tlsAllowInvalidCertificates', 'tlsDisableOCSPEndpointCheck'],
+ ['tlsAllowInvalidCertificates', 'tlsDisableCertificateRevocationCheck'],
+];
+
+foreach ($invalidCombinations as list($optionA, $optionB)) {
+ foreach ([false, true] as $valueA) {
+ foreach ([false, true] as $valueB) {
+ echo throws(function() use ($optionA, $valueA, $optionB, $valueB) {
+ new MongoDB\Driver\Manager(sprintf(
+ 'mongodb://localhost:27017/?%s=%s&%s=%s',
+ $optionA,
+ $valueA ? 'true' : 'false',
+ $optionB,
+ $valueB ? 'true' : 'false'
+ ));
+ }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
+
+ echo throws(function() use ($optionA, $valueA, $optionB, $valueB) {
+ new MongoDB\Driver\Manager(
+ sprintf(
+ 'mongodb://localhost:27017/?%s=%s',
+ $optionA,
+ $valueA ? 'true' : 'false'
+ ),
+ [ $optionB => $valueB ]
+ );
+ }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
+ }
+ }
+
+ echo "\n";
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=false&tlsAllowInvalidHostnames=false'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=false&tlsAllowInvalidHostnames=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidHostnames=false'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidHostnames=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=false&tlsAllowInvalidCertificates=false'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=false&tlsAllowInvalidCertificates=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidCertificates=false'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidCertificates=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=false&tlsDisableOCSPEndpointCheck=false'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=false&tlsDisableOCSPEndpointCheck=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsDisableOCSPEndpointCheck=false'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsDisableOCSPEndpointCheck=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=false&tlsDisableCertificateRevocationCheck=false'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=false&tlsDisableCertificateRevocationCheck=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsDisableCertificateRevocationCheck=false'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsDisableCertificateRevocationCheck=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates, tlsallowinvalidhostnames, tlsdisableocspendpointcheck, or tlsdisablecertificaterevocationcheck.
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsAllowInvalidCertificates=false&tlsDisableOCSPEndpointCheck=false'. tlsallowinvalidcertificates may not be specified with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsallowinvalidcertificates may not be combined with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsAllowInvalidCertificates=false&tlsDisableOCSPEndpointCheck=true'. tlsallowinvalidcertificates may not be specified with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsallowinvalidcertificates may not be combined with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsAllowInvalidCertificates=true&tlsDisableOCSPEndpointCheck=false'. tlsallowinvalidcertificates may not be specified with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsallowinvalidcertificates may not be combined with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsAllowInvalidCertificates=true&tlsDisableOCSPEndpointCheck=true'. tlsallowinvalidcertificates may not be specified with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsallowinvalidcertificates may not be combined with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsAllowInvalidCertificates=false&tlsDisableCertificateRevocationCheck=false'. tlsallowinvalidcertificates may not be specified with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsallowinvalidcertificates may not be combined with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsAllowInvalidCertificates=false&tlsDisableCertificateRevocationCheck=true'. tlsallowinvalidcertificates may not be specified with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsallowinvalidcertificates may not be combined with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsAllowInvalidCertificates=true&tlsDisableCertificateRevocationCheck=false'. tlsallowinvalidcertificates may not be specified with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsallowinvalidcertificates may not be combined with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsAllowInvalidCertificates=true&tlsDisableCertificateRevocationCheck=true'. tlsallowinvalidcertificates may not be specified with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Failed to parse URI options: tlsallowinvalidcertificates may not be combined with tlsdisableocspendpointcheck or tlsdisablecertificaterevocationcheck.
+
+===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-wireversion.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-wireversion.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-wireversion.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-wireversion.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-003.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-004.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-005.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-005.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-005.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-006.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-006.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-006.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-003.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-005.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-005.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-005.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-006.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-006.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-006.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-007.phpt b/mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor-write_concern-error-007.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor-write_concern-error-007.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor_error-002.phpt b/mongodb-1.8.1/tests/manager/manager-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor_error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor_error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor_error-003.phpt b/mongodb-1.8.1/tests/manager/manager-ctor_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor_error-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor_error-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-ctor_error-004.phpt b/mongodb-1.8.1/tests/manager/manager-ctor_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-ctor_error-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-ctor_error-004.phpt
diff --git a/mongodb-1.8.1/tests/manager/manager-ctor_error-005.phpt b/mongodb-1.8.1/tests/manager/manager-ctor_error-005.phpt
new file mode 100644
index 00000000..fd17629f
--- /dev/null
+++ b/mongodb-1.8.1/tests/manager/manager-ctor_error-005.phpt
@@ -0,0 +1,35 @@
+--TEST--
+MongoDB\Driver\Manager::__construct(): Invalid handshake data
+--FILE--
+<?php
+require_once __DIR__ . "/../utils/basic.inc";
+
+$tests = [
+ (object) [],
+ 'string',
+ ['name' => []],
+ ['version' => []],
+ ['platform' => []],
+];
+
+foreach ($tests as $driver) {
+ echo throws(function () use ($driver) {
+ $manager = new MongoDB\Driver\Manager(null, [], ['driver' => $driver]);
+ }, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "driver" driver option to be an array, stdClass given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "driver" driver option to be an array, string given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "name" handshake option to be a string, array given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "version" handshake option to be a string, array given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "platform" handshake option to be a string, array given
+===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-debug-001.phpt b/mongodb-1.8.1/tests/manager/manager-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-debug-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-debug-002.phpt b/mongodb-1.8.1/tests/manager/manager-debug-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-debug-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-debug-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-debug-003.phpt b/mongodb-1.8.1/tests/manager/manager-debug-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-debug-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-debug-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-destruct-001.phpt b/mongodb-1.8.1/tests/manager/manager-destruct-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-destruct-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-destruct-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-003.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-004.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-005.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-005.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-005.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-006.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-006.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-006.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-007.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-007.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-007.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-008.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-008.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-008.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-009.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-009.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-009.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-010.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-010.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-010.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-011.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-011.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-011.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-012.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-012.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-012.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite-013.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite-013.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite-013.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite-013.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-003.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-003.phpt
similarity index 97%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-003.phpt
index 449cbabe..ebc49e64 100644
--- a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-003.phpt
+++ b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-003.phpt
@@ -1,64 +1,64 @@
--TEST--
MongoDB\Driver\Manager::executeBulkWrite() write concern error
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_replica_set(); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$manager = new MongoDB\Driver\Manager(URI);
$bulk = new MongoDB\Driver\BulkWrite();
$bulk->insert(array('_id' => 1, 'x' => 1));
try {
$manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(30));
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
printf("BulkWriteException: %s\n", $e->getMessage());
echo "\n===> WriteResult\n";
printWriteResult($e->getWriteResult());
}
echo "\n===> Collection\n";
$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array()));
var_dump(iterator_to_array($cursor));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
BulkWriteException: Not enough data-bearing nodes
===> WriteResult
server: %s:%d
insertedCount: 1
matchedCount: 0
modifiedCount: 0
upsertedCount: 0
deletedCount: 0
object(MongoDB\Driver\WriteConcernError)#%d (%d) {
["message"]=>
string(29) "Not enough data-bearing nodes"
["code"]=>
int(100)
["info"]=>
- NULL
+ %a
}
writeConcernError.message: Not enough data-bearing nodes
writeConcernError.code: 100
-writeConcernError.info: NULL
+writeConcernError.info: %a
===> Collection
array(1) {
[0]=>
object(stdClass)#%d (%d) {
["_id"]=>
int(1)
["x"]=>
int(1)
}
}
===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-004.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-005.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-005.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-005.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-006.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-006.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-006.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-007.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-007.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-007.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-008.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-008.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-008.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-009.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-009.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-009.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-010.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-010.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-010.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-011.phpt b/mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeBulkWrite_error-011.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeBulkWrite_error-011.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand-003.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand-004.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand-005.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand-005.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand-005.phpt
diff --git a/mongodb-1.8.1/tests/manager/manager-executeCommand-006.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand-006.phpt
new file mode 100644
index 00000000..9d2809dd
--- /dev/null
+++ b/mongodb-1.8.1/tests/manager/manager-executeCommand-006.phpt
@@ -0,0 +1,26 @@
+--TEST--
+MongoDB\Driver\Manager::executeCommand() does not inherit read preference
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_replica_set(); ?>
+<?php skip_if_no_secondary(); ?>
+<?php skip_if_not_clean(); ?>
+--FILE--
+<?php
+require_once __DIR__ . "/../utils/basic.inc";
+
+$manager = new MongoDB\Driver\Manager(URI, ['readPreference' => 'secondary']);
+
+$command = new MongoDB\Driver\Command(['ping' => 1]);
+$cursor = $manager->executeCommand(DATABASE_NAME, $command);
+
+echo "is_primary: ", $cursor->getServer()->isPrimary() ? 'true' : 'false', "\n";
+echo "is_secondary: ", $cursor->getServer()->isSecondary() ? 'true' : 'false', "\n\n";
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+is_primary: true
+is_secondary: false
+
+===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand_error-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand_error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand_error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand_error-003.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand_error-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand_error-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand_error-004.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand_error-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand_error-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeCommand_error-005.phpt b/mongodb-1.8.1/tests/manager/manager-executeCommand_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeCommand_error-005.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeCommand_error-005.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery-003.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery-004.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery-005.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery-005.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery-005.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery-006.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery-006.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery-006.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery_error-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery_error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery_error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeQuery_error-003.phpt b/mongodb-1.8.1/tests/manager/manager-executeQuery_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeQuery_error-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeQuery_error-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeReadCommand-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeReadCommand-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeReadCommand-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeReadCommand-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeReadCommand-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeReadCommand-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeReadCommand-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeReadCommand-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeReadCommand_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeReadCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeReadCommand_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeReadCommand_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeReadWriteCommand-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeReadWriteCommand-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeReadWriteCommand-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeReadWriteCommand-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeReadWriteCommand-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeReadWriteCommand-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeReadWriteCommand-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeReadWriteCommand-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeReadWriteCommand_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeReadWriteCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeReadWriteCommand_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeReadWriteCommand_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeReadWriteCommand_error-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeReadWriteCommand_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeReadWriteCommand_error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeReadWriteCommand_error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeWriteCommand-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeWriteCommand-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeWriteCommand-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeWriteCommand-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeWriteCommand-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeWriteCommand-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeWriteCommand-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeWriteCommand-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeWriteCommand_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-executeWriteCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeWriteCommand_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeWriteCommand_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeWriteCommand_error-002.phpt b/mongodb-1.8.1/tests/manager/manager-executeWriteCommand_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeWriteCommand_error-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeWriteCommand_error-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeWriteCommand_error-003.phpt b/mongodb-1.8.1/tests/manager/manager-executeWriteCommand_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeWriteCommand_error-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeWriteCommand_error-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-executeWriteCommand_error-004.phpt b/mongodb-1.8.1/tests/manager/manager-executeWriteCommand_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-executeWriteCommand_error-004.phpt
rename to mongodb-1.8.1/tests/manager/manager-executeWriteCommand_error-004.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-getreadconcern-001.phpt b/mongodb-1.8.1/tests/manager/manager-getreadconcern-001.phpt
similarity index 97%
rename from mongodb-1.7.4/tests/manager/manager-getreadconcern-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-getreadconcern-001.phpt
index 754ba2af..2b5866bb 100644
--- a/mongodb-1.7.4/tests/manager/manager-getreadconcern-001.phpt
+++ b/mongodb-1.8.1/tests/manager/manager-getreadconcern-001.phpt
@@ -1,61 +1,60 @@
--TEST--
MongoDB\Driver\Manager::getReadConcern()
--FILE--
<?php
$tests = [
[null, []],
['mongodb://127.0.0.1/?readconcernlevel=local', []],
['mongodb://127.0.0.1/?readconcernlevel=majority', []],
['mongodb://127.0.0.1/?readconcernlevel=not-yet-supported', []],
[null, ['readconcernlevel' => 'local']],
[null, ['readconcernlevel' => 'majority']],
[null, ['readconcernlevel' => 'not-yet-supported']],
['mongodb://127.0.0.1/?readconcernlevel=local', ['readconcernlevel' => 'majority']],
];
foreach ($tests as $i => $test) {
list($uri, $options) = $test;
$manager = new MongoDB\Driver\Manager($uri, $options);
var_dump($manager->getReadConcern());
- // Test for !return_value_used
$manager->getReadConcern();
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\ReadConcern)#%d (%d) {
}
object(MongoDB\Driver\ReadConcern)#%d (%d) {
["level"]=>
string(5) "local"
}
object(MongoDB\Driver\ReadConcern)#%d (%d) {
["level"]=>
string(8) "majority"
}
object(MongoDB\Driver\ReadConcern)#%d (%d) {
["level"]=>
string(17) "not-yet-supported"
}
object(MongoDB\Driver\ReadConcern)#%d (%d) {
["level"]=>
string(5) "local"
}
object(MongoDB\Driver\ReadConcern)#%d (%d) {
["level"]=>
string(8) "majority"
}
object(MongoDB\Driver\ReadConcern)#%d (%d) {
["level"]=>
string(17) "not-yet-supported"
}
object(MongoDB\Driver\ReadConcern)#%d (%d) {
["level"]=>
string(8) "majority"
}
===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-getreadpreference-001.phpt b/mongodb-1.8.1/tests/manager/manager-getreadpreference-001.phpt
similarity index 98%
rename from mongodb-1.7.4/tests/manager/manager-getreadpreference-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-getreadpreference-001.phpt
index 6a707bde..ff62f3a4 100644
--- a/mongodb-1.7.4/tests/manager/manager-getreadpreference-001.phpt
+++ b/mongodb-1.8.1/tests/manager/manager-getreadpreference-001.phpt
@@ -1,92 +1,91 @@
--TEST--
MongoDB\Driver\Manager::getReadPreference()
--FILE--
<?php
$tests = array(
array(null, array()),
array('mongodb://127.0.0.1/?readPreference=secondary', array()),
array(null, array('readPreference' => 'primaryPreferred')),
array('mongodb://127.0.0.1/?readPreference=secondary', array('readPreference' => 'secondaryPreferred')),
array('mongodb://127.0.0.1/?readPreference=secondary&readPreferenceTags=dc:ny,use:reports&readPreferenceTags=', array()),
array('mongodb://127.0.0.1/?readPreference=secondary', array('readPreferenceTags' => array(array('dc' => 'ny', 'use' => 'reports'), array()))),
array('mongodb://127.0.0.1/?readPreference=secondary&readPreferenceTags=dc:ny,use:reports', array('readPreferenceTags' => array(array('dc' => 'ca')))),
);
foreach ($tests as $i => $test) {
list($uri, $options) = $test;
$manager = new MongoDB\Driver\Manager($uri, $options);
var_dump($manager->getReadPreference());
- // Test for !return_value_used
$manager->getReadPreference();
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "primary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(16) "primaryPreferred"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(18) "secondaryPreferred"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(2) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ny"
["use"]=>
string(7) "reports"
}
[1]=>
object(stdClass)#%d (%d) {
}
}
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(2) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ny"
["use"]=>
string(7) "reports"
}
[1]=>
object(stdClass)#%d (%d) {
}
}
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(1) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ca"
}
}
}
===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-getservers-001.phpt b/mongodb-1.8.1/tests/manager/manager-getservers-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-getservers-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-getservers-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-getservers-002.phpt b/mongodb-1.8.1/tests/manager/manager-getservers-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-getservers-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-getservers-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-getwriteconcern-001.phpt b/mongodb-1.8.1/tests/manager/manager-getwriteconcern-001.phpt
similarity index 98%
rename from mongodb-1.7.4/tests/manager/manager-getwriteconcern-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-getwriteconcern-001.phpt
index dd1fbb05..16697c46 100644
--- a/mongodb-1.7.4/tests/manager/manager-getwriteconcern-001.phpt
+++ b/mongodb-1.8.1/tests/manager/manager-getwriteconcern-001.phpt
@@ -1,88 +1,87 @@
--TEST--
MongoDB\Driver\Manager::getWriteConcern()
--FILE--
<?php
$tests = array(
array(null, array()),
array('mongodb://127.0.0.1/?w=1', array()),
array('mongodb://127.0.0.1/?w=majority', array()),
array(null, array('w' => 1, 'journal' => true)),
array(null, array('w' => 'majority', 'journal' => true)),
array('mongodb://127.0.0.1/?w=majority&journal=true', array('w' => 1, 'journal' => false)),
array('mongodb://127.0.0.1/?wtimeoutms=1000', array()),
array(null, array('wtimeoutms' => 1000)),
array('mongodb://127.0.0.1/?w=2', array('wtimeoutms' => 1000)),
array('mongodb://127.0.0.1/?w=majority', array('wtimeoutms' => 1000)),
array('mongodb://127.0.0.1/?w=customTagSet', array('wtimeoutms' => 1000)),
);
foreach ($tests as $i => $test) {
list($uri, $options) = $test;
$manager = new MongoDB\Driver\Manager($uri, $options);
var_dump($manager->getWriteConcern());
- // Test for !return_value_used
$manager->getWriteConcern();
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\WriteConcern)#%d (%d) {
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
int(1)
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
string(8) "majority"
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
int(1)
["j"]=>
bool(true)
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
string(8) "majority"
["j"]=>
bool(true)
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
int(1)
["j"]=>
bool(false)
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["wtimeout"]=>
int(1000)
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["wtimeout"]=>
int(1000)
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
int(2)
["wtimeout"]=>
int(1000)
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
string(8) "majority"
["wtimeout"]=>
int(1000)
}
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
string(12) "customTagSet"
["wtimeout"]=>
int(1000)
}
===DONE===
diff --git a/mongodb-1.7.4/tests/manager/manager-invalidnamespace.phpt b/mongodb-1.8.1/tests/manager/manager-invalidnamespace.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-invalidnamespace.phpt
rename to mongodb-1.8.1/tests/manager/manager-invalidnamespace.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-selectserver-001.phpt b/mongodb-1.8.1/tests/manager/manager-selectserver-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-selectserver-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-selectserver-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-selectserver_error-001.phpt b/mongodb-1.8.1/tests/manager/manager-selectserver_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-selectserver_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-selectserver_error-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-set-uri-options-001.phpt b/mongodb-1.8.1/tests/manager/manager-set-uri-options-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-set-uri-options-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-set-uri-options-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-set-uri-options-002.phpt b/mongodb-1.8.1/tests/manager/manager-set-uri-options-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-set-uri-options-002.phpt
rename to mongodb-1.8.1/tests/manager/manager-set-uri-options-002.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-set-uri-options-003.phpt b/mongodb-1.8.1/tests/manager/manager-set-uri-options-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-set-uri-options-003.phpt
rename to mongodb-1.8.1/tests/manager/manager-set-uri-options-003.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-var-dump-001.phpt b/mongodb-1.8.1/tests/manager/manager-var-dump-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-var-dump-001.phpt
rename to mongodb-1.8.1/tests/manager/manager-var-dump-001.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager-wakeup.phpt b/mongodb-1.8.1/tests/manager/manager-wakeup.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager-wakeup.phpt
rename to mongodb-1.8.1/tests/manager/manager-wakeup.phpt
diff --git a/mongodb-1.7.4/tests/manager/manager_error-001.phpt b/mongodb-1.8.1/tests/manager/manager_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/manager/manager_error-001.phpt
rename to mongodb-1.8.1/tests/manager/manager_error-001.phpt
diff --git a/mongodb-1.7.4/tests/query/bug0430-001.phpt b/mongodb-1.8.1/tests/query/bug0430-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/bug0430-001.phpt
rename to mongodb-1.8.1/tests/query/bug0430-001.phpt
diff --git a/mongodb-1.7.4/tests/query/bug0430-002.phpt b/mongodb-1.8.1/tests/query/bug0430-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/bug0430-002.phpt
rename to mongodb-1.8.1/tests/query/bug0430-002.phpt
diff --git a/mongodb-1.7.4/tests/query/bug0430-003.phpt b/mongodb-1.8.1/tests/query/bug0430-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/bug0430-003.phpt
rename to mongodb-1.8.1/tests/query/bug0430-003.phpt
diff --git a/mongodb-1.7.4/tests/query/bug0705-001.phpt b/mongodb-1.8.1/tests/query/bug0705-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/bug0705-001.phpt
rename to mongodb-1.8.1/tests/query/bug0705-001.phpt
diff --git a/mongodb-1.7.4/tests/query/bug0705-002.phpt b/mongodb-1.8.1/tests/query/bug0705-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/bug0705-002.phpt
rename to mongodb-1.8.1/tests/query/bug0705-002.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor-001.phpt b/mongodb-1.8.1/tests/query/query-ctor-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor-001.phpt
rename to mongodb-1.8.1/tests/query/query-ctor-001.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor-002.phpt b/mongodb-1.8.1/tests/query/query-ctor-002.phpt
similarity index 93%
rename from mongodb-1.7.4/tests/query/query-ctor-002.phpt
rename to mongodb-1.8.1/tests/query/query-ctor-002.phpt
index 47a4f1a7..af8449e6 100644
--- a/mongodb-1.7.4/tests/query/query-ctor-002.phpt
+++ b/mongodb-1.8.1/tests/query/query-ctor-002.phpt
@@ -1,172 +1,177 @@
--TEST--
MongoDB\Driver\Query construction with options
--FILE--
<?php
var_dump(new MongoDB\Driver\Query(
['x' => 1],
[
+ 'allowDiskUse' => false,
'allowPartialResults' => false,
'awaitData' => false,
'batchSize' => 10,
'collation' => ['locale' => 'en_US'],
'comment' => 'foo',
'exhaust' => false,
'limit' => 20,
'max' => ['y' => 100],
'maxScan' => 50,
'maxTimeMS' => 1000,
'min' => ['y' => 1],
'noCursorTimeout' => false,
'oplogReplay' => false,
'projection' => ['x' => 1, 'y' => 1],
'returnKey' => false,
'showRecordId' => false,
'singleBatch' => false,
'skip' => 5,
'sort' => ['y' => -1],
'snapshot' => false,
'tailable' => false,
]
));
var_dump(new MongoDB\Driver\Query(
['x' => 1],
['hint' => 'y_1']
));
var_dump(new MongoDB\Driver\Query(
['x' => 1],
['hint' => ['y' => 1]]
));
var_dump(new MongoDB\Driver\Query(
['x' => 1],
['readConcern' => new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::LOCAL)]
));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
Deprecated: MongoDB\Driver\Query::__construct(): The "maxScan" option is deprecated and will be removed in a future release in %s on line %d
+Deprecated: MongoDB\Driver\Query::__construct(): The "oplogReplay" option is deprecated and will be removed in a future release in %s on line %d
+
Deprecated: MongoDB\Driver\Query::__construct(): The "snapshot" option is deprecated and will be removed in a future release in %s on line %d
object(MongoDB\Driver\Query)#%d (%d) {
["filter"]=>
object(stdClass)#%d (%d) {
["x"]=>
int(1)
}
["options"]=>
object(stdClass)#%d (%d) {
+ ["allowDiskUse"]=>
+ bool(false)
["allowPartialResults"]=>
bool(false)
["awaitData"]=>
bool(false)
["batchSize"]=>
int(10)
["collation"]=>
object(stdClass)#%d (%d) {
["locale"]=>
string(5) "en_US"
}
["comment"]=>
string(3) "foo"
["exhaust"]=>
bool(false)
["max"]=>
object(stdClass)#%d (%d) {
["y"]=>
int(100)
}
["maxScan"]=>
int(50)
["maxTimeMS"]=>
int(1000)
["min"]=>
object(stdClass)#%d (%d) {
["y"]=>
int(1)
}
["noCursorTimeout"]=>
bool(false)
["oplogReplay"]=>
bool(false)
["projection"]=>
object(stdClass)#%d (%d) {
["x"]=>
int(1)
["y"]=>
int(1)
}
["returnKey"]=>
bool(false)
["showRecordId"]=>
bool(false)
["skip"]=>
int(5)
["sort"]=>
object(stdClass)#%d (%d) {
["y"]=>
int(-1)
}
["snapshot"]=>
bool(false)
["tailable"]=>
bool(false)
["limit"]=>
int(20)
["singleBatch"]=>
bool(false)
}
["readConcern"]=>
NULL
}
object(MongoDB\Driver\Query)#%d (%d) {
["filter"]=>
object(stdClass)#%d (%d) {
["x"]=>
int(1)
}
["options"]=>
object(stdClass)#%d (%d) {
["hint"]=>
string(3) "y_1"
}
["readConcern"]=>
NULL
}
object(MongoDB\Driver\Query)#%d (%d) {
["filter"]=>
object(stdClass)#%d (%d) {
["x"]=>
int(1)
}
["options"]=>
object(stdClass)#%d (%d) {
["hint"]=>
object(stdClass)#%d (%d) {
["y"]=>
int(1)
}
}
["readConcern"]=>
NULL
}
object(MongoDB\Driver\Query)#%d (%d) {
["filter"]=>
object(stdClass)#%d (%d) {
["x"]=>
int(1)
}
["options"]=>
object(stdClass)#%d (%d) {
}
["readConcern"]=>
array(1) {
["level"]=>
string(5) "local"
}
}
===DONE===
diff --git a/mongodb-1.7.4/tests/query/query-ctor-003.phpt b/mongodb-1.8.1/tests/query/query-ctor-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor-003.phpt
rename to mongodb-1.8.1/tests/query/query-ctor-003.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor-004.phpt b/mongodb-1.8.1/tests/query/query-ctor-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor-004.phpt
rename to mongodb-1.8.1/tests/query/query-ctor-004.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor-005.phpt b/mongodb-1.8.1/tests/query/query-ctor-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor-005.phpt
rename to mongodb-1.8.1/tests/query/query-ctor-005.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor-006.phpt b/mongodb-1.8.1/tests/query/query-ctor-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor-006.phpt
rename to mongodb-1.8.1/tests/query/query-ctor-006.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor_error-001.phpt b/mongodb-1.8.1/tests/query/query-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor_error-001.phpt
rename to mongodb-1.8.1/tests/query/query-ctor_error-001.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor_error-002.phpt b/mongodb-1.8.1/tests/query/query-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor_error-002.phpt
rename to mongodb-1.8.1/tests/query/query-ctor_error-002.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor_error-003.phpt b/mongodb-1.8.1/tests/query/query-ctor_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor_error-003.phpt
rename to mongodb-1.8.1/tests/query/query-ctor_error-003.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor_error-004.phpt b/mongodb-1.8.1/tests/query/query-ctor_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor_error-004.phpt
rename to mongodb-1.8.1/tests/query/query-ctor_error-004.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor_error-005.phpt b/mongodb-1.8.1/tests/query/query-ctor_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor_error-005.phpt
rename to mongodb-1.8.1/tests/query/query-ctor_error-005.phpt
diff --git a/mongodb-1.7.4/tests/query/query-ctor_error-006.phpt b/mongodb-1.8.1/tests/query/query-ctor_error-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-ctor_error-006.phpt
rename to mongodb-1.8.1/tests/query/query-ctor_error-006.phpt
diff --git a/mongodb-1.7.4/tests/query/query-debug-001.phpt b/mongodb-1.8.1/tests/query/query-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query-debug-001.phpt
rename to mongodb-1.8.1/tests/query/query-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/query/query_error-001.phpt b/mongodb-1.8.1/tests/query/query_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/query/query_error-001.phpt
rename to mongodb-1.8.1/tests/query/query_error-001.phpt
diff --git a/mongodb-1.8.1/tests/readConcern/bug1598-001.phpt b/mongodb-1.8.1/tests/readConcern/bug1598-001.phpt
new file mode 100644
index 00000000..bac17e74
--- /dev/null
+++ b/mongodb-1.8.1/tests/readConcern/bug1598-001.phpt
@@ -0,0 +1,26 @@
+--TEST--
+PHPC-1598: ReadConcern get_gc should not invoke get_properties
+--FILE--
+<?php
+
+$rc = new MongoDB\Driver\ReadConcern('local');
+
+$a = (object) ['rc' => $rc];
+$b = (object) ['rc' => $rc];
+
+$a->b = $b;
+$b->a = $a;
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+unset($a, $b);
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+Collected cycles: 0
+Collected cycles: 2
+===DONE===
diff --git a/mongodb-1.8.1/tests/readConcern/bug1598-002.phpt b/mongodb-1.8.1/tests/readConcern/bug1598-002.phpt
new file mode 100644
index 00000000..a343f81d
--- /dev/null
+++ b/mongodb-1.8.1/tests/readConcern/bug1598-002.phpt
@@ -0,0 +1,25 @@
+--TEST--
+PHPC-1598: ReadConcern get_gc should delegate to zend_std_get_properties
+--FILE--
+<?php
+
+/* Store an additional object reference as a public property on the ReadConcern.
+ * This will leak if get_gc returns internally cached properties (from our
+ * get_properties handler) instead of zend_std_get_properties. */
+$a = new stdClass;
+$a->rc = new MongoDB\Driver\ReadConcern('local');
+$a->rc->a = $a;
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+unset($a);
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+Collected cycles: 0
+Collected cycles: 2
+===DONE===
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-bsonserialize-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-bsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-bsonserialize-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-bsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-bsonserialize-002.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-bsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-bsonserialize-002.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-bsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-constants.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-constants.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-constants.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-constants.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-ctor-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-ctor-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-ctor-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-ctor-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-ctor_error-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-ctor_error-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-ctor_error-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-ctor_error-002.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-ctor_error-002.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-ctor_error-002.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-debug-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-debug-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-getlevel-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-getlevel-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-getlevel-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-getlevel-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-isdefault-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-isdefault-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-isdefault-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-isdefault-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-serialization-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-serialization-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-set_state-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-set_state-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-set_state_error-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern-var_export-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern-var_export-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern-var_export-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern-var_export-001.phpt
diff --git a/mongodb-1.7.4/tests/readConcern/readconcern_error-001.phpt b/mongodb-1.8.1/tests/readConcern/readconcern_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readConcern/readconcern_error-001.phpt
rename to mongodb-1.8.1/tests/readConcern/readconcern_error-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/bug0146-001.phpt b/mongodb-1.8.1/tests/readPreference/bug0146-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/bug0146-001.phpt
rename to mongodb-1.8.1/tests/readPreference/bug0146-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/bug0146-002.phpt b/mongodb-1.8.1/tests/readPreference/bug0146-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/bug0146-002.phpt
rename to mongodb-1.8.1/tests/readPreference/bug0146-002.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/bug0851-001.phpt b/mongodb-1.8.1/tests/readPreference/bug0851-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/bug0851-001.phpt
rename to mongodb-1.8.1/tests/readPreference/bug0851-001.phpt
diff --git a/mongodb-1.8.1/tests/readPreference/bug1598-001.phpt b/mongodb-1.8.1/tests/readPreference/bug1598-001.phpt
new file mode 100644
index 00000000..bf4497c0
--- /dev/null
+++ b/mongodb-1.8.1/tests/readPreference/bug1598-001.phpt
@@ -0,0 +1,26 @@
+--TEST--
+PHPC-1598: ReadPreference get_gc should not invoke get_properties
+--FILE--
+<?php
+
+$rp = new MongoDB\Driver\ReadPreference('primary');
+
+$a = (object) ['rp' => $rp];
+$b = (object) ['rp' => $rp];
+
+$a->b = $b;
+$b->a = $a;
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+unset($a, $b);
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+Collected cycles: 0
+Collected cycles: 2
+===DONE===
diff --git a/mongodb-1.8.1/tests/readPreference/bug1598-002.phpt b/mongodb-1.8.1/tests/readPreference/bug1598-002.phpt
new file mode 100644
index 00000000..2a57b8de
--- /dev/null
+++ b/mongodb-1.8.1/tests/readPreference/bug1598-002.phpt
@@ -0,0 +1,25 @@
+--TEST--
+PHPC-1598: ReadPreference get_gc should delegate to zend_std_get_properties
+--FILE--
+<?php
+
+/* Store an additional object reference as a public property on the
+ * ReadPreference. This will leak if get_gc returns internally cached properties
+ * (from our get_properties handler) instead of zend_std_get_properties. */
+$a = new stdClass;
+$a->rp = new MongoDB\Driver\ReadPreference('primary');
+$a->rp->a = $a;
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+unset($a);
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+Collected cycles: 0
+Collected cycles: 2
+===DONE===
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-bsonserialize-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-bsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-bsonserialize-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-bsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-bsonserialize-002.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-bsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-bsonserialize-002.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-bsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-constants.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-constants.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-constants.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-constants.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor-001.phpt
similarity index 67%
rename from mongodb-1.7.4/tests/readPreference/readpreference-ctor-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-ctor-001.phpt
index 04bbf43c..607f67a0 100644
--- a/mongodb-1.7.4/tests/readPreference/readpreference-ctor-001.phpt
+++ b/mongodb-1.8.1/tests/readPreference/readpreference-ctor-001.phpt
@@ -1,41 +1,56 @@
--TEST--
MongoDB\Driver\ReadPreference construction
--FILE--
<?php
var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY));
var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['tag' => 'one']]));
var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, []));
var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 1000]));
+var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['hedge' => ['enabled' => true]]));
+var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['hedge' => []]));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "primary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(1) {
[0]=>
object(stdClass)#%d (%d) {
["tag"]=>
string(3) "one"
}
}
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "primary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["maxStalenessSeconds"]=>
int(1000)
}
+object(MongoDB\Driver\ReadPreference)#%d (%d) {
+ ["mode"]=>
+ string(9) "secondary"
+ ["hedge"]=>
+ object(stdClass)#%d (%d) {
+ ["enabled"]=>
+ bool(true)
+ }
+}
+object(MongoDB\Driver\ReadPreference)#%d (%d) {
+ ["mode"]=>
+ string(9) "secondary"
+}
===DONE===
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor-002.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-ctor-002.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-ctor-002.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-001.phpt
similarity index 100%
copy from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-001.phpt
copy to mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-002.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-002.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-002.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-003.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-003.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-003.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-004.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-004.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-004.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-005.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-005.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-005.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-006.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-006.phpt
similarity index 100%
copy from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-006.phpt
copy to mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-006.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-006.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-007.phpt
similarity index 52%
rename from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-006.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-007.phpt
index 0199dbc1..0bbcbd39 100644
--- a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-006.phpt
+++ b/mongodb-1.8.1/tests/readPreference/readpreference-ctor_error-007.phpt
@@ -1,18 +1,18 @@
--TEST--
-MongoDB\Driver\ReadPreference construction (invalid type for mode)
+MongoDB\Driver\ReadPreference construction (combining hedge with primary read preference)
--FILE--
<?php
require_once __DIR__ . '/../utils/tools.php';
echo throws(function() {
- new MongoDB\Driver\ReadPreference(3.14);
+ new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, null, ['hedge' => ['enabled' => true]]);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected mode to be integer or string, %r(double|float)%r given
+hedge may not be used with primary mode
===DONE===
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-debug-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-debug-001.phpt
similarity index 89%
rename from mongodb-1.7.4/tests/readPreference/readpreference-debug-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-debug-001.phpt
index f8c55d9b..00186962 100644
--- a/mongodb-1.7.4/tests/readPreference/readpreference-debug-001.phpt
+++ b/mongodb-1.8.1/tests/readPreference/readpreference-debug-001.phpt
@@ -1,92 +1,102 @@
--TEST--
MongoDB\Driver\ReadPreference debug output
--FILE--
<?php
require_once __DIR__ . '/../utils/tools.php';
$tests = [
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_NEAREST),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, []),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny']]),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny'], ['dc' => 'sf', 'use' => 'reporting'], []]),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 1000]),
+ new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['hedge' => ['enabled' => true]]),
];
foreach ($tests as $test) {
var_dump($test);
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "primary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(16) "primaryPreferred"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(18) "secondaryPreferred"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "nearest"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "primary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(1) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ny"
}
}
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(3) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ny"
}
[1]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "sf"
["use"]=>
string(9) "reporting"
}
[2]=>
object(stdClass)#%d (%d) {
}
}
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["maxStalenessSeconds"]=>
int(1000)
}
+object(MongoDB\Driver\ReadPreference)#%d (%d) {
+ ["mode"]=>
+ string(9) "secondary"
+ ["hedge"]=>
+ object(stdClass)#%d (%d) {
+ ["enabled"]=>
+ bool(true)
+ }
+}
===DONE===
diff --git a/mongodb-1.8.1/tests/readPreference/readpreference-getHedge-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-getHedge-001.phpt
new file mode 100644
index 00000000..82b80a00
--- /dev/null
+++ b/mongodb-1.8.1/tests/readPreference/readpreference-getHedge-001.phpt
@@ -0,0 +1,37 @@
+--TEST--
+MongoDB\Driver\ReadPreference::getHedge()
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/tools.php';
+
+$tests = [
+ [],
+ ['enabled' => true],
+ (object) ['enabled' => true],
+ ['foo' => 'bar'],
+];
+
+foreach ($tests as $test) {
+ $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['hedge' => $test]);
+ var_dump($rp->getHedge());
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+NULL
+object(stdClass)#%d (%d) {
+ ["enabled"]=>
+ bool(true)
+}
+object(stdClass)#%d (%d) {
+ ["enabled"]=>
+ bool(true)
+}
+object(stdClass)#%d (%d) {
+ ["foo"]=>
+ string(3) "bar"
+}
+===DONE===
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-getMode-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-getMode-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-getMode-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-getMode-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-getModeString-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-getModeString-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-getModeString-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-getModeString-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-getTagSets-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-getTagSets-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-getTagSets-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-getTagSets-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-getTagSets-002.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-getTagSets-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-getTagSets-002.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-getTagSets-002.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-serialization-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-serialization-001.phpt
similarity index 88%
rename from mongodb-1.7.4/tests/readPreference/readpreference-serialization-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-serialization-001.phpt
index 71526c52..e8dc6f87 100644
--- a/mongodb-1.7.4/tests/readPreference/readpreference-serialization-001.phpt
+++ b/mongodb-1.8.1/tests/readPreference/readpreference-serialization-001.phpt
@@ -1,187 +1,209 @@
--TEST--
MongoDB\Driver\ReadPreference serialization
--FILE--
<?php
require_once __DIR__ . '/../utils/tools.php';
$tests = [
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_NEAREST),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, []),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny']]),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny'], ['dc' => 'sf', 'use' => 'reporting'], []]),
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 1000]),
+ new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['hedge' => ['enabled' => true]]),
];
foreach ($tests as $test) {
var_dump($test);
var_dump($test instanceof Serializable);
echo $s = serialize($test), "\n";
var_dump(unserialize($s));
echo "\n";
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "primary"
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":31:{a:1:{s:4:"mode";s:7:"primary";}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "primary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(16) "primaryPreferred"
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":41:{a:1:{s:4:"mode";s:16:"primaryPreferred";}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(16) "primaryPreferred"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":33:{a:1:{s:4:"mode";s:9:"secondary";}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(18) "secondaryPreferred"
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":43:{a:1:{s:4:"mode";s:18:"secondaryPreferred";}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(18) "secondaryPreferred"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "nearest"
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":31:{a:1:{s:4:"mode";s:7:"nearest";}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(7) "nearest"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":33:{a:1:{s:4:"mode";s:9:"secondary";}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(1) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ny"
}
}
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":78:{a:2:{s:4:"mode";s:9:"secondary";s:4:"tags";a:1:{i:0;a:1:{s:2:"dc";s:2:"ny";}}}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(1) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ny"
}
}
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(3) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ny"
}
[1]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "sf"
["use"]=>
string(9) "reporting"
}
[2]=>
object(stdClass)#%d (%d) {
}
}
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":142:{a:2:{s:4:"mode";s:9:"secondary";s:4:"tags";a:3:{i:0;a:1:{s:2:"dc";s:2:"ny";}i:1;a:2:{s:2:"dc";s:2:"sf";s:3:"use";s:9:"reporting";}i:2;a:0:{}}}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(3) {
[0]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "ny"
}
[1]=>
object(stdClass)#%d (%d) {
["dc"]=>
string(2) "sf"
["use"]=>
string(9) "reporting"
}
[2]=>
object(stdClass)#%d (%d) {
}
}
}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["maxStalenessSeconds"]=>
int(1000)
}
bool(true)
C:29:"MongoDB\Driver\ReadPreference":67:{a:2:{s:4:"mode";s:9:"secondary";s:19:"maxStalenessSeconds";i:1000;}}
object(MongoDB\Driver\ReadPreference)#%d (%d) {
["mode"]=>
string(9) "secondary"
["maxStalenessSeconds"]=>
int(1000)
}
+object(MongoDB\Driver\ReadPreference)#%d (%d) {
+ ["mode"]=>
+ string(9) "secondary"
+ ["hedge"]=>
+ object(stdClass)#%d (%d) {
+ ["enabled"]=>
+ bool(true)
+ }
+}
+bool(true)
+C:29:"MongoDB\Driver\ReadPreference":82:{a:2:{s:4:"mode";s:9:"secondary";s:5:"hedge";O:8:"stdClass":1:{s:7:"enabled";b:1;}}}
+object(MongoDB\Driver\ReadPreference)#%d (%d) {
+ ["mode"]=>
+ string(9) "secondary"
+ ["hedge"]=>
+ object(stdClass)#%d (%d) {
+ ["enabled"]=>
+ bool(true)
+ }
+}
+
===DONE===
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-set_state-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-set_state-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-set_state_error-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-set_state_error-001.phpt
similarity index 77%
rename from mongodb-1.7.4/tests/readPreference/readpreference-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-set_state_error-001.phpt
index ae25eea6..c927ee24 100644
--- a/mongodb-1.7.4/tests/readPreference/readpreference-set_state_error-001.phpt
+++ b/mongodb-1.8.1/tests/readPreference/readpreference-set_state_error-001.phpt
@@ -1,56 +1,69 @@
--TEST--
MongoDB\Driver\ReadPreference::__set_state() requires correct data types and values
--FILE--
<?php
require_once __DIR__ . '/../utils/tools.php';
echo throws(function() {
MongoDB\Driver\ReadPreference::__set_state(['mode' => 'furthest']);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
echo throws(function() {
MongoDB\Driver\ReadPreference::__set_state(['mode' => M_PI]);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
echo throws(function() {
MongoDB\Driver\ReadPreference::__set_state(['mode' => 'secondary', 'tags' => -1]);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
echo throws(function() {
MongoDB\Driver\ReadPreference::__set_state(['mode' => 'secondary', 'tags' => [ 42 ] ]);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
echo throws(function() {
MongoDB\Driver\ReadPreference::__set_state(['mode' => 'primary', 'tags' => [['dc' => 'ny']]]);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
echo throws(function() {
MongoDB\Driver\ReadPreference::__set_state(['mode' => 'secondary', 'maxStalenessSeconds' => 1]);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
echo throws(function() {
MongoDB\Driver\ReadPreference::__set_state(['mode' => 'primary', 'maxStalenessSeconds' => 100]);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
+
+echo throws(function() {
+ MongoDB\Driver\ReadPreference::__set_state(['mode' => 'secondary', 'hedge' => 'foo']);
+}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
+
+echo throws(function() {
+ MongoDB\Driver\ReadPreference::__set_state(['mode' => 'primary', 'hedge' => []]);
+}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
+
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
MongoDB\Driver\ReadPreference initialization requires specific values for "mode" string field
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
MongoDB\Driver\ReadPreference initialization requires "mode" field to be string
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
MongoDB\Driver\ReadPreference initialization requires "tags" field to be array
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
MongoDB\Driver\ReadPreference initialization requires "tags" array field to have zero or more documents
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
MongoDB\Driver\ReadPreference initialization requires "tags" array field to not be present with "primary" mode
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
MongoDB\Driver\ReadPreference initialization requires "maxStalenessSeconds" integer field to be >= 90
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-MongoDB\Driver\ReadPreference initialization requires "maxStalenessSeconds" array field to not be present with "primary" mode
+MongoDB\Driver\ReadPreference initialization requires "maxStalenessSeconds" field to not be present with "primary" mode
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+MongoDB\Driver\ReadPreference initialization requires "hedge" field to be an array or object
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+MongoDB\Driver\ReadPreference initialization requires "hedge" field to not be present with "primary" mode
===DONE===
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-set_state_error-002.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-set_state_error-002.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-set_state_error-002.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-var_export-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference-var_export-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference-var_export-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference-var_export-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference_error-001.phpt b/mongodb-1.8.1/tests/readPreference/readpreference_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/readPreference/readpreference_error-001.phpt
rename to mongodb-1.8.1/tests/readPreference/readpreference_error-001.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/bug0155.phpt b/mongodb-1.8.1/tests/replicaset/bug0155.phpt
similarity index 99%
rename from mongodb-1.7.4/tests/replicaset/bug0155.phpt
rename to mongodb-1.8.1/tests/replicaset/bug0155.phpt
index 218b3017..53f784ae 100644
--- a/mongodb-1.7.4/tests/replicaset/bug0155.phpt
+++ b/mongodb-1.8.1/tests/replicaset/bug0155.phpt
@@ -1,35 +1,35 @@
--TEST--
PHPC-155: WriteConcernError->getInfo() can be scalar
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_replica_set(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$manager = new MongoDB\Driver\Manager(URI);
$wc = new MongoDB\Driver\WriteConcern("MultipleDC", 500);
$bulk = new MongoDB\Driver\BulkWrite();
$bulk->insert(array('example' => 'document'));
try {
$manager->executeBulkWrite(NS, $bulk, $wc);
} catch(MongoDB\Driver\Exception\BulkWriteException $e) {
var_dump($e->getWriteResult()->getWriteConcernError());
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\WriteConcernError)#%d (%d) {
["message"]=>
string(%d) "%s"
["code"]=>
int(79)
["info"]=>
- NULL
+ %a
}
===DONE===
diff --git a/mongodb-1.7.4/tests/replicaset/bug0898-001.phpt b/mongodb-1.8.1/tests/replicaset/bug0898-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/bug0898-001.phpt
rename to mongodb-1.8.1/tests/replicaset/bug0898-001.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/bug0898-002.phpt b/mongodb-1.8.1/tests/replicaset/bug0898-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/bug0898-002.phpt
rename to mongodb-1.8.1/tests/replicaset/bug0898-002.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/manager-getservers-001.phpt b/mongodb-1.8.1/tests/replicaset/manager-getservers-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/manager-getservers-001.phpt
rename to mongodb-1.8.1/tests/replicaset/manager-getservers-001.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/manager-selectserver-001.phpt b/mongodb-1.8.1/tests/replicaset/manager-selectserver-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/manager-selectserver-001.phpt
rename to mongodb-1.8.1/tests/replicaset/manager-selectserver-001.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/readconcern-001.phpt b/mongodb-1.8.1/tests/replicaset/readconcern-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/readconcern-001.phpt
rename to mongodb-1.8.1/tests/replicaset/readconcern-001.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/readconcern-002.phpt b/mongodb-1.8.1/tests/replicaset/readconcern-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/readconcern-002.phpt
rename to mongodb-1.8.1/tests/replicaset/readconcern-002.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/server-001.phpt b/mongodb-1.8.1/tests/replicaset/server-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/server-001.phpt
rename to mongodb-1.8.1/tests/replicaset/server-001.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/server-002.phpt b/mongodb-1.8.1/tests/replicaset/server-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/server-002.phpt
rename to mongodb-1.8.1/tests/replicaset/server-002.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/writeconcernerror-001.phpt b/mongodb-1.8.1/tests/replicaset/writeconcernerror-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/writeconcernerror-001.phpt
rename to mongodb-1.8.1/tests/replicaset/writeconcernerror-001.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/writeconcernerror-002.phpt b/mongodb-1.8.1/tests/replicaset/writeconcernerror-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/writeconcernerror-002.phpt
rename to mongodb-1.8.1/tests/replicaset/writeconcernerror-002.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/writeresult-getserver-001.phpt b/mongodb-1.8.1/tests/replicaset/writeresult-getserver-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/writeresult-getserver-001.phpt
rename to mongodb-1.8.1/tests/replicaset/writeresult-getserver-001.phpt
diff --git a/mongodb-1.7.4/tests/replicaset/writeresult-getserver-002.phpt b/mongodb-1.8.1/tests/replicaset/writeresult-getserver-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/replicaset/writeresult-getserver-002.phpt
rename to mongodb-1.8.1/tests/replicaset/writeresult-getserver-002.phpt
diff --git a/mongodb-1.7.4/tests/retryable-reads/retryable-reads-001.phpt b/mongodb-1.8.1/tests/retryable-reads/retryable-reads-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-reads/retryable-reads-001.phpt
rename to mongodb-1.8.1/tests/retryable-reads/retryable-reads-001.phpt
diff --git a/mongodb-1.7.4/tests/retryable-reads/retryable-reads-002.phpt b/mongodb-1.8.1/tests/retryable-reads/retryable-reads-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-reads/retryable-reads-002.phpt
rename to mongodb-1.8.1/tests/retryable-reads/retryable-reads-002.phpt
diff --git a/mongodb-1.7.4/tests/retryable-reads/retryable-reads_error-001.phpt b/mongodb-1.8.1/tests/retryable-reads/retryable-reads_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-reads/retryable-reads_error-001.phpt
rename to mongodb-1.8.1/tests/retryable-reads/retryable-reads_error-001.phpt
diff --git a/mongodb-1.7.4/tests/retryable-reads/retryable-reads_error-002.phpt b/mongodb-1.8.1/tests/retryable-reads/retryable-reads_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-reads/retryable-reads_error-002.phpt
rename to mongodb-1.8.1/tests/retryable-reads/retryable-reads_error-002.phpt
diff --git a/mongodb-1.7.4/tests/retryable-writes/retryable-writes-001.phpt b/mongodb-1.8.1/tests/retryable-writes/retryable-writes-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-writes/retryable-writes-001.phpt
rename to mongodb-1.8.1/tests/retryable-writes/retryable-writes-001.phpt
diff --git a/mongodb-1.7.4/tests/retryable-writes/retryable-writes-002.phpt b/mongodb-1.8.1/tests/retryable-writes/retryable-writes-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-writes/retryable-writes-002.phpt
rename to mongodb-1.8.1/tests/retryable-writes/retryable-writes-002.phpt
diff --git a/mongodb-1.7.4/tests/retryable-writes/retryable-writes-003.phpt b/mongodb-1.8.1/tests/retryable-writes/retryable-writes-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-writes/retryable-writes-003.phpt
rename to mongodb-1.8.1/tests/retryable-writes/retryable-writes-003.phpt
diff --git a/mongodb-1.7.4/tests/retryable-writes/retryable-writes-004.phpt b/mongodb-1.8.1/tests/retryable-writes/retryable-writes-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-writes/retryable-writes-004.phpt
rename to mongodb-1.8.1/tests/retryable-writes/retryable-writes-004.phpt
diff --git a/mongodb-1.7.4/tests/retryable-writes/retryable-writes-005.phpt b/mongodb-1.8.1/tests/retryable-writes/retryable-writes-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-writes/retryable-writes-005.phpt
rename to mongodb-1.8.1/tests/retryable-writes/retryable-writes-005.phpt
diff --git a/mongodb-1.7.4/tests/retryable-writes/retryable-writes_error-001.phpt b/mongodb-1.8.1/tests/retryable-writes/retryable-writes_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/retryable-writes/retryable-writes_error-001.phpt
rename to mongodb-1.8.1/tests/retryable-writes/retryable-writes_error-001.phpt
diff --git a/mongodb-1.7.4/tests/server/bug0671-002.phpt b/mongodb-1.8.1/tests/server/bug0671-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/bug0671-002.phpt
rename to mongodb-1.8.1/tests/server/bug0671-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server-constants.phpt b/mongodb-1.8.1/tests/server/server-constants.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-constants.phpt
rename to mongodb-1.8.1/tests/server/server-constants.phpt
diff --git a/mongodb-1.7.4/tests/server/server-construct-001.phpt b/mongodb-1.8.1/tests/server/server-construct-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-construct-001.phpt
rename to mongodb-1.8.1/tests/server/server-construct-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-debug.phpt b/mongodb-1.8.1/tests/server/server-debug.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-debug.phpt
rename to mongodb-1.8.1/tests/server/server-debug.phpt
diff --git a/mongodb-1.7.4/tests/server/server-errors.phpt b/mongodb-1.8.1/tests/server/server-errors.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-errors.phpt
rename to mongodb-1.8.1/tests/server/server-errors.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite-001.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite-002.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite-002.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite-003.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite-003.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite-003.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite-004.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite-004.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite-004.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite-005.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite-005.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite-005.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite-006.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite-006.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite-006.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite-007.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite-007.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite-007.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite-008.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite-008.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite-008.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite_error-001.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite_error-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite_error-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeBulkWrite_error-002.phpt b/mongodb-1.8.1/tests/server/server-executeBulkWrite_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeBulkWrite_error-002.phpt
rename to mongodb-1.8.1/tests/server/server-executeBulkWrite_error-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-001.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-002.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-002.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-003.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-003.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-003.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-004.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-004.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-004.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-005.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-005.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-005.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-006.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-006.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-006.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-007.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-007.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-007.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-008.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-008.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-008.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand-009.phpt b/mongodb-1.8.1/tests/server/server-executeCommand-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand-009.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand-009.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeCommand_error-001.phpt b/mongodb-1.8.1/tests/server/server-executeCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeCommand_error-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeCommand_error-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-001.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-002.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-002.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-003.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-003.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-003.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-004.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-004.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-004.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-005.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-005.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-005.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-006.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-006.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-006.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-007.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-007.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-007.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-008.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-008.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-008.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-008.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-009.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-009.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-009.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-009.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-010.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-010.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-010.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-010.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-011.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-011.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-011.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-011.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery-012.phpt b/mongodb-1.8.1/tests/server/server-executeQuery-012.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery-012.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery-012.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeQuery_error-001.phpt b/mongodb-1.8.1/tests/server/server-executeQuery_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeQuery_error-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeQuery_error-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeReadCommand-001.phpt b/mongodb-1.8.1/tests/server/server-executeReadCommand-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeReadCommand-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeReadCommand-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeReadCommand-002.phpt b/mongodb-1.8.1/tests/server/server-executeReadCommand-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeReadCommand-002.phpt
rename to mongodb-1.8.1/tests/server/server-executeReadCommand-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeReadCommand_error-001.phpt b/mongodb-1.8.1/tests/server/server-executeReadCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeReadCommand_error-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeReadCommand_error-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeReadWriteCommand-001.phpt b/mongodb-1.8.1/tests/server/server-executeReadWriteCommand-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeReadWriteCommand-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeReadWriteCommand-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeReadWriteCommand-002.phpt b/mongodb-1.8.1/tests/server/server-executeReadWriteCommand-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeReadWriteCommand-002.phpt
rename to mongodb-1.8.1/tests/server/server-executeReadWriteCommand-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeReadWriteCommand_error-001.phpt b/mongodb-1.8.1/tests/server/server-executeReadWriteCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeReadWriteCommand_error-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeReadWriteCommand_error-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeWriteCommand-001.phpt b/mongodb-1.8.1/tests/server/server-executeWriteCommand-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeWriteCommand-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeWriteCommand-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeWriteCommand-002.phpt b/mongodb-1.8.1/tests/server/server-executeWriteCommand-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeWriteCommand-002.phpt
rename to mongodb-1.8.1/tests/server/server-executeWriteCommand-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server-executeWriteCommand_error-001.phpt b/mongodb-1.8.1/tests/server/server-executeWriteCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-executeWriteCommand_error-001.phpt
rename to mongodb-1.8.1/tests/server/server-executeWriteCommand_error-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-getInfo-001.phpt b/mongodb-1.8.1/tests/server/server-getInfo-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-getInfo-001.phpt
rename to mongodb-1.8.1/tests/server/server-getInfo-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-getTags-001.phpt b/mongodb-1.8.1/tests/server/server-getTags-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-getTags-001.phpt
rename to mongodb-1.8.1/tests/server/server-getTags-001.phpt
diff --git a/mongodb-1.7.4/tests/server/server-getTags-002.phpt b/mongodb-1.8.1/tests/server/server-getTags-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server-getTags-002.phpt
rename to mongodb-1.8.1/tests/server/server-getTags-002.phpt
diff --git a/mongodb-1.7.4/tests/server/server_error-001.phpt b/mongodb-1.8.1/tests/server/server_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/server/server_error-001.phpt
rename to mongodb-1.8.1/tests/server/server_error-001.phpt
diff --git a/mongodb-1.7.4/tests/session/bug1274-001.phpt b/mongodb-1.8.1/tests/session/bug1274-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/bug1274-001.phpt
rename to mongodb-1.8.1/tests/session/bug1274-001.phpt
diff --git a/mongodb-1.7.4/tests/session/bug1274-002.phpt b/mongodb-1.8.1/tests/session/bug1274-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/bug1274-002.phpt
rename to mongodb-1.8.1/tests/session/bug1274-002.phpt
diff --git a/mongodb-1.7.4/tests/session/bug1274-003.phpt b/mongodb-1.8.1/tests/session/bug1274-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/bug1274-003.phpt
rename to mongodb-1.8.1/tests/session/bug1274-003.phpt
diff --git a/mongodb-1.7.4/tests/session/session-001.phpt b/mongodb-1.8.1/tests/session/session-001.phpt
similarity index 71%
rename from mongodb-1.7.4/tests/session/session-001.phpt
rename to mongodb-1.8.1/tests/session/session-001.phpt
index 613e7153..45c8be6d 100644
--- a/mongodb-1.7.4/tests/session/session-001.phpt
+++ b/mongodb-1.8.1/tests/session/session-001.phpt
@@ -1,29 +1,34 @@
--TEST--
MongoDB\Driver\Session spec test: Pool is LIFO
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongoc_crypto(); ?>
<?php skip_if_not_live(); ?>
<?php skip_if_server_version('<', '3.6'); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$manager = new MongoDB\Driver\Manager(URI);
$firstSession = $manager->startSession();
$firstSessionId = $firstSession->getLogicalSessionId();
+/* libmongoc does not pool unused sessions (CDRIVER-3322), so we must use this
+ * session with a command to ensure it enters the pool. */
+$command = new MongoDB\Driver\Command(['ping' => 1]);
+$manager->executeCommand(DATABASE_NAME, $command, ['session' => $firstSession]);
+
unset($firstSession);
$secondSession = $manager->startSession();
$secondSessionId = $secondSession->getLogicalSessionId();
var_dump($firstSessionId == $secondSessionId);
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
bool(true)
===DONE===
diff --git a/mongodb-1.7.4/tests/session/session-002.phpt b/mongodb-1.8.1/tests/session/session-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-002.phpt
rename to mongodb-1.8.1/tests/session/session-002.phpt
diff --git a/mongodb-1.7.4/tests/session/session-003.phpt b/mongodb-1.8.1/tests/session/session-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-003.phpt
rename to mongodb-1.8.1/tests/session/session-003.phpt
diff --git a/mongodb-1.7.4/tests/session/session-advanceClusterTime-001.phpt b/mongodb-1.8.1/tests/session/session-advanceClusterTime-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-advanceClusterTime-001.phpt
rename to mongodb-1.8.1/tests/session/session-advanceClusterTime-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-advanceOperationTime-001.phpt b/mongodb-1.8.1/tests/session/session-advanceOperationTime-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-advanceOperationTime-001.phpt
rename to mongodb-1.8.1/tests/session/session-advanceOperationTime-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-advanceOperationTime-002.phpt b/mongodb-1.8.1/tests/session/session-advanceOperationTime-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-advanceOperationTime-002.phpt
rename to mongodb-1.8.1/tests/session/session-advanceOperationTime-002.phpt
diff --git a/mongodb-1.7.4/tests/session/session-advanceOperationTime-003.phpt b/mongodb-1.8.1/tests/session/session-advanceOperationTime-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-advanceOperationTime-003.phpt
rename to mongodb-1.8.1/tests/session/session-advanceOperationTime-003.phpt
diff --git a/mongodb-1.7.4/tests/session/session-advanceOperationTime_error-001.phpt b/mongodb-1.8.1/tests/session/session-advanceOperationTime_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-advanceOperationTime_error-001.phpt
rename to mongodb-1.8.1/tests/session/session-advanceOperationTime_error-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-commitTransaction-001.phpt b/mongodb-1.8.1/tests/session/session-commitTransaction-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-commitTransaction-001.phpt
rename to mongodb-1.8.1/tests/session/session-commitTransaction-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-constants.phpt b/mongodb-1.8.1/tests/session/session-constants.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-constants.phpt
rename to mongodb-1.8.1/tests/session/session-constants.phpt
diff --git a/mongodb-1.7.4/tests/session/session-debug-001.phpt b/mongodb-1.8.1/tests/session/session-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-debug-001.phpt
rename to mongodb-1.8.1/tests/session/session-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-debug-002.phpt b/mongodb-1.8.1/tests/session/session-debug-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-debug-002.phpt
rename to mongodb-1.8.1/tests/session/session-debug-002.phpt
diff --git a/mongodb-1.7.4/tests/session/session-debug-003.phpt b/mongodb-1.8.1/tests/session/session-debug-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-debug-003.phpt
rename to mongodb-1.8.1/tests/session/session-debug-003.phpt
diff --git a/mongodb-1.7.4/tests/session/session-debug-004.phpt b/mongodb-1.8.1/tests/session/session-debug-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-debug-004.phpt
rename to mongodb-1.8.1/tests/session/session-debug-004.phpt
diff --git a/mongodb-1.7.4/tests/session/session-debug-005.phpt b/mongodb-1.8.1/tests/session/session-debug-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-debug-005.phpt
rename to mongodb-1.8.1/tests/session/session-debug-005.phpt
diff --git a/mongodb-1.7.4/tests/session/session-endSession-001.phpt b/mongodb-1.8.1/tests/session/session-endSession-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-endSession-001.phpt
rename to mongodb-1.8.1/tests/session/session-endSession-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-endSession-002.phpt b/mongodb-1.8.1/tests/session/session-endSession-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-endSession-002.phpt
rename to mongodb-1.8.1/tests/session/session-endSession-002.phpt
diff --git a/mongodb-1.7.4/tests/session/session-getClusterTime-001.phpt b/mongodb-1.8.1/tests/session/session-getClusterTime-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-getClusterTime-001.phpt
rename to mongodb-1.8.1/tests/session/session-getClusterTime-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-getLogicalSessionId-001.phpt b/mongodb-1.8.1/tests/session/session-getLogicalSessionId-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-getLogicalSessionId-001.phpt
rename to mongodb-1.8.1/tests/session/session-getLogicalSessionId-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-getOperationTime-001.phpt b/mongodb-1.8.1/tests/session/session-getOperationTime-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-getOperationTime-001.phpt
rename to mongodb-1.8.1/tests/session/session-getOperationTime-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-getTransactionOptions-001.phpt b/mongodb-1.8.1/tests/session/session-getTransactionOptions-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-getTransactionOptions-001.phpt
rename to mongodb-1.8.1/tests/session/session-getTransactionOptions-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-getTransactionState-001.phpt b/mongodb-1.8.1/tests/session/session-getTransactionState-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-getTransactionState-001.phpt
rename to mongodb-1.8.1/tests/session/session-getTransactionState-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-isInTransaction-001.phpt b/mongodb-1.8.1/tests/session/session-isInTransaction-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-isInTransaction-001.phpt
rename to mongodb-1.8.1/tests/session/session-isInTransaction-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-startTransaction-001.phpt b/mongodb-1.8.1/tests/session/session-startTransaction-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-startTransaction-001.phpt
rename to mongodb-1.8.1/tests/session/session-startTransaction-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-startTransaction_error-001.phpt b/mongodb-1.8.1/tests/session/session-startTransaction_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-startTransaction_error-001.phpt
rename to mongodb-1.8.1/tests/session/session-startTransaction_error-001.phpt
diff --git a/mongodb-1.7.4/tests/session/session-startTransaction_error-002.phpt b/mongodb-1.8.1/tests/session/session-startTransaction_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-startTransaction_error-002.phpt
rename to mongodb-1.8.1/tests/session/session-startTransaction_error-002.phpt
diff --git a/mongodb-1.7.4/tests/session/session-startTransaction_error-004.phpt b/mongodb-1.8.1/tests/session/session-startTransaction_error-004.phpt
similarity index 95%
rename from mongodb-1.7.4/tests/session/session-startTransaction_error-004.phpt
rename to mongodb-1.8.1/tests/session/session-startTransaction_error-004.phpt
index 87ce8b1c..dafda735 100644
--- a/mongodb-1.7.4/tests/session/session-startTransaction_error-004.phpt
+++ b/mongodb-1.8.1/tests/session/session-startTransaction_error-004.phpt
@@ -1,35 +1,34 @@
--TEST--
MongoDB\Driver\Session::startTransaction() with wrong argument for options array on PHP 7.0
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongoc_crypto() ?>
<?php skip_if_no_transactions(); ?>
-<?php skip_if_php_version('<', '7.0.0'); ?>
<?php skip_if_php_version('>=', '7.1.0'); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$manager = new MongoDB\Driver\Manager(URI);
$session = $manager->startSession();
$options = [
2,
new stdClass,
];
foreach ($options as $txnOptions) {
echo throws(function () use ($session, $txnOptions) {
$session->startTransaction($txnOptions);
}, TypeError::class), "\n";
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
OK: Got TypeError
Argument 1 passed to MongoDB\Driver\Session::startTransaction() must be of the type array, int%S given
OK: Got TypeError
Argument 1 passed to MongoDB\Driver\Session::startTransaction() must be of the type array, object given
===DONE===
diff --git a/mongodb-1.7.4/tests/session/session-startTransaction_error-005.phpt b/mongodb-1.8.1/tests/session/session-startTransaction_error-005.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-startTransaction_error-005.phpt
rename to mongodb-1.8.1/tests/session/session-startTransaction_error-005.phpt
diff --git a/mongodb-1.7.4/tests/session/session-startTransaction_error-006.phpt b/mongodb-1.8.1/tests/session/session-startTransaction_error-006.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-startTransaction_error-006.phpt
rename to mongodb-1.8.1/tests/session/session-startTransaction_error-006.phpt
diff --git a/mongodb-1.7.4/tests/session/session-startTransaction_error-007.phpt b/mongodb-1.8.1/tests/session/session-startTransaction_error-007.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session-startTransaction_error-007.phpt
rename to mongodb-1.8.1/tests/session/session-startTransaction_error-007.phpt
diff --git a/mongodb-1.7.4/tests/session/session_error-001.phpt b/mongodb-1.8.1/tests/session/session_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/session_error-001.phpt
rename to mongodb-1.8.1/tests/session/session_error-001.phpt
diff --git a/mongodb-1.7.4/tests/session/transaction-integration-001.phpt b/mongodb-1.8.1/tests/session/transaction-integration-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/transaction-integration-001.phpt
rename to mongodb-1.8.1/tests/session/transaction-integration-001.phpt
diff --git a/mongodb-1.7.4/tests/session/transaction-integration-002.phpt b/mongodb-1.8.1/tests/session/transaction-integration-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/transaction-integration-002.phpt
rename to mongodb-1.8.1/tests/session/transaction-integration-002.phpt
diff --git a/mongodb-1.7.4/tests/session/transaction-integration-003.phpt b/mongodb-1.8.1/tests/session/transaction-integration-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/transaction-integration-003.phpt
rename to mongodb-1.8.1/tests/session/transaction-integration-003.phpt
diff --git a/mongodb-1.7.4/tests/session/transaction-integration_error-001.phpt b/mongodb-1.8.1/tests/session/transaction-integration_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/transaction-integration_error-001.phpt
rename to mongodb-1.8.1/tests/session/transaction-integration_error-001.phpt
diff --git a/mongodb-1.7.4/tests/session/transaction-integration_error-002.phpt b/mongodb-1.8.1/tests/session/transaction-integration_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/transaction-integration_error-002.phpt
rename to mongodb-1.8.1/tests/session/transaction-integration_error-002.phpt
diff --git a/mongodb-1.7.4/tests/session/transaction-integration_error-003.phpt b/mongodb-1.8.1/tests/session/transaction-integration_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/transaction-integration_error-003.phpt
rename to mongodb-1.8.1/tests/session/transaction-integration_error-003.phpt
diff --git a/mongodb-1.7.4/tests/session/transaction-integration_error-004.phpt b/mongodb-1.8.1/tests/session/transaction-integration_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/session/transaction-integration_error-004.phpt
rename to mongodb-1.8.1/tests/session/transaction-integration_error-004.phpt
diff --git a/mongodb-1.7.4/tests/standalone/bug0166.phpt b/mongodb-1.8.1/tests/standalone/bug0166.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/bug0166.phpt
rename to mongodb-1.8.1/tests/standalone/bug0166.phpt
diff --git a/mongodb-1.7.4/tests/standalone/bug0231.phpt b/mongodb-1.8.1/tests/standalone/bug0231.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/bug0231.phpt
rename to mongodb-1.8.1/tests/standalone/bug0231.phpt
diff --git a/mongodb-1.7.4/tests/standalone/bug0357.phpt b/mongodb-1.8.1/tests/standalone/bug0357.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/bug0357.phpt
rename to mongodb-1.8.1/tests/standalone/bug0357.phpt
diff --git a/mongodb-1.7.4/tests/standalone/bug0545.phpt b/mongodb-1.8.1/tests/standalone/bug0545.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/bug0545.phpt
rename to mongodb-1.8.1/tests/standalone/bug0545.phpt
diff --git a/mongodb-1.7.4/tests/standalone/bug0655.phpt b/mongodb-1.8.1/tests/standalone/bug0655.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/bug0655.phpt
rename to mongodb-1.8.1/tests/standalone/bug0655.phpt
diff --git a/mongodb-1.7.4/tests/standalone/command-aggregate-001.phpt b/mongodb-1.8.1/tests/standalone/command-aggregate-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/command-aggregate-001.phpt
rename to mongodb-1.8.1/tests/standalone/command-aggregate-001.phpt
diff --git a/mongodb-1.7.4/tests/standalone/connectiontimeoutexception-001.phpt b/mongodb-1.8.1/tests/standalone/connectiontimeoutexception-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/connectiontimeoutexception-001.phpt
rename to mongodb-1.8.1/tests/standalone/connectiontimeoutexception-001.phpt
diff --git a/mongodb-1.7.4/tests/standalone/executiontimeoutexception-001.phpt b/mongodb-1.8.1/tests/standalone/executiontimeoutexception-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/executiontimeoutexception-001.phpt
rename to mongodb-1.8.1/tests/standalone/executiontimeoutexception-001.phpt
diff --git a/mongodb-1.7.4/tests/standalone/executiontimeoutexception-002.phpt b/mongodb-1.8.1/tests/standalone/executiontimeoutexception-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/executiontimeoutexception-002.phpt
rename to mongodb-1.8.1/tests/standalone/executiontimeoutexception-002.phpt
diff --git a/mongodb-1.7.4/tests/standalone/manager-as-singleton.phpt b/mongodb-1.8.1/tests/standalone/manager-as-singleton.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/manager-as-singleton.phpt
rename to mongodb-1.8.1/tests/standalone/manager-as-singleton.phpt
diff --git a/mongodb-1.7.4/tests/standalone/query-errors.phpt b/mongodb-1.8.1/tests/standalone/query-errors.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/query-errors.phpt
rename to mongodb-1.8.1/tests/standalone/query-errors.phpt
diff --git a/mongodb-1.7.4/tests/standalone/update-multi-001.phpt b/mongodb-1.8.1/tests/standalone/update-multi-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/update-multi-001.phpt
rename to mongodb-1.8.1/tests/standalone/update-multi-001.phpt
diff --git a/mongodb-1.7.4/tests/standalone/write-error-001.phpt b/mongodb-1.8.1/tests/standalone/write-error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/write-error-001.phpt
rename to mongodb-1.8.1/tests/standalone/write-error-001.phpt
diff --git a/mongodb-1.7.4/tests/standalone/writeresult-isacknowledged-001.phpt b/mongodb-1.8.1/tests/standalone/writeresult-isacknowledged-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/writeresult-isacknowledged-001.phpt
rename to mongodb-1.8.1/tests/standalone/writeresult-isacknowledged-001.phpt
diff --git a/mongodb-1.7.4/tests/standalone/writeresult-isacknowledged-002.phpt b/mongodb-1.8.1/tests/standalone/writeresult-isacknowledged-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/writeresult-isacknowledged-002.phpt
rename to mongodb-1.8.1/tests/standalone/writeresult-isacknowledged-002.phpt
diff --git a/mongodb-1.7.4/tests/standalone/writeresult-isacknowledged-003.phpt b/mongodb-1.8.1/tests/standalone/writeresult-isacknowledged-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/standalone/writeresult-isacknowledged-003.phpt
rename to mongodb-1.8.1/tests/standalone/writeresult-isacknowledged-003.phpt
diff --git a/mongodb-1.7.4/tests/utils/PHONGO-FIXTURES.json.gz b/mongodb-1.8.1/tests/utils/PHONGO-FIXTURES.json.gz
similarity index 100%
rename from mongodb-1.7.4/tests/utils/PHONGO-FIXTURES.json.gz
rename to mongodb-1.8.1/tests/utils/PHONGO-FIXTURES.json.gz
diff --git a/mongodb-1.7.4/tests/utils/basic-skipif.inc b/mongodb-1.8.1/tests/utils/basic-skipif.inc
similarity index 100%
rename from mongodb-1.7.4/tests/utils/basic-skipif.inc
rename to mongodb-1.8.1/tests/utils/basic-skipif.inc
diff --git a/mongodb-1.7.4/tests/utils/basic.inc b/mongodb-1.8.1/tests/utils/basic.inc
similarity index 100%
rename from mongodb-1.7.4/tests/utils/basic.inc
rename to mongodb-1.8.1/tests/utils/basic.inc
diff --git a/mongodb-1.7.4/tests/utils/classes.inc b/mongodb-1.8.1/tests/utils/classes.inc
similarity index 100%
rename from mongodb-1.7.4/tests/utils/classes.inc
rename to mongodb-1.8.1/tests/utils/classes.inc
diff --git a/mongodb-1.7.4/tests/utils/observer.php b/mongodb-1.8.1/tests/utils/observer.php
similarity index 100%
rename from mongodb-1.7.4/tests/utils/observer.php
rename to mongodb-1.8.1/tests/utils/observer.php
diff --git a/mongodb-1.7.4/tests/utils/skipif.php b/mongodb-1.8.1/tests/utils/skipif.php
similarity index 98%
rename from mongodb-1.7.4/tests/utils/skipif.php
rename to mongodb-1.8.1/tests/utils/skipif.php
index 52a65bef..9f239654 100644
--- a/mongodb-1.7.4/tests/utils/skipif.php
+++ b/mongodb-1.8.1/tests/utils/skipif.php
@@ -1,433 +1,440 @@
<?php
use MongoDB\Driver\Command;
use MongoDB\Driver\Manager;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Server;
use MongoDB\Driver\Exception\ConnectionException;
use MongoDB\Driver\Exception\RuntimeException;
require_once __DIR__ . '/basic.inc';
require_once __DIR__ . '/tools.php';
/**
* Skips the test if the topology is a sharded cluster.
*/
function skip_if_mongos()
{
is_mongos(URI) and exit('skip topology is a sharded cluster');
}
/**
* Skips the test if the topology contains multiple mongos nodes.
*
* This is particularly useful for tests that rely on configureFailPoint, since
* randomized server selection can interfere with testing.
*/
function skip_if_multiple_mongos()
{
$manager = new Manager(URI);
// Ensure SDAM is initialized before calling Manager::getServers()
$manager->selectServer(new ReadPreference('nearest'));
$mongosNodes = array_filter($manager->getServers(), function(Server $server) {
return $server->getType() === Server::TYPE_MONGOS;
});
if (count($mongosNodes) > 1) {
exit('skip topology contains multiple mongos nodes');
}
}
/**
* Skips the test if the topology is not a shard cluster.
*/
function skip_if_not_mongos()
{
is_mongos(URI) or exit('skip topology is not a sharded cluster');
}
function skip_if_not_mongos_with_replica_set()
{
is_mongos_with_replica_set(URI) or exit('skip topology is not a sharded cluster with replica set');
}
/**
* Skips the test if the topology is a replica set.
*/
function skip_if_replica_set()
{
is_replica_set(URI) and exit('skip topology is a replica set');
}
/**
* Skips the test if the topology is not a replica set.
*/
function skip_if_not_replica_set()
{
is_replica_set(URI) or exit('skip topology is not a replica set');
}
/**
* Skips the test if the topology is not a replica set or sharded cluster backed by replica sets
*/
function skip_if_not_replica_set_or_mongos_with_replica_set()
{
is_replica_set(URI) or is_mongos_with_replica_set(URI) or exit('skip topology is not a replica set or sharded cluster with replica set');
}
function skip_if_no_transactions()
{
if (is_mongos_with_replica_set(URI)) {
skip_if_server_version('<', '4.2');
} elseif (is_replica_set(URI)) {
skip_if_server_version('<', '4.0');
} else {
exit('skip topology does not support transactions');
}
}
/**
* Skips the test if the topology has no arbiter.
*/
function skip_if_no_arbiter()
{
try {
$primary = get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip primary server is not accessible: ' . $e->getMessage());
}
$info = $primary->getInfo();
if (!isset($info['arbiters']) || count($info['arbiters']) < 1) {
exit('skip no arbiters available');
}
}
/**
* Skips the test if the topology has no secondary.
*/
function skip_if_no_secondary()
{
try {
$primary = get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip primary server is not accessible: ' . $e->getMessage());
}
$info = $primary->getInfo();
if (!isset($info['hosts']) || count($info['hosts']) < 2) {
exit('skip no secondaries available');
}
}
/**
* Skips the test if the topology does not have enough data carrying nodes
*/
function skip_if_not_enough_data_nodes($requiredNodes, $maxNodeCount = null)
{
try {
$primary = get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip primary server is not accessible: ' . $e->getMessage());
}
$info = $primary->getInfo();
$dataNodeCount = isset($info['hosts']) ? count($info['hosts']) : 0;
if ($dataNodeCount < $requiredNodes) {
exit("skip not enough nodes available (wanted: {$requiredNodes}, available: " . count($info['hosts']) . ')');
}
if ($maxNodeCount !== null && $dataNodeCount > $requiredNodes) {
exit("skip too many nodes available (wanted: {$requiredNodes}, available: " . count($info['hosts']) . ')');
}
}
/**
* Skips the test if the topology does not have enough nodes
*/
function skip_if_not_enough_nodes($requiredNodes, $maxNodeCount = null)
{
try {
$primary = get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip primary server is not accessible: ' . $e->getMessage());
}
$info = $primary->getInfo();
$nodeCount =
(isset($info['hosts']) ? count($info['hosts']) : 0) +
(isset($info['arbiters']) ? count($info['arbiters']) : 0);
if ($nodeCount < $requiredNodes) {
exit("skip not enough nodes available (wanted: {$requiredNodes}, available: " . count($info['hosts']) . ')');
}
if ($maxNodeCount !== null && $nodeCount > $requiredNodes) {
exit("skip too many nodes available (wanted: {$requiredNodes}, available: " . count($info['hosts']) . ')');
}
}
/**
* Skips the test if the topology is a standalone.
*/
function skip_if_standalone()
{
is_standalone(URI) and exit('skip topology is a standalone');
}
/**
* Skips the test if the topology is not a standalone.
*/
function skip_if_not_standalone()
{
is_standalone(URI) or exit('skip topology is not a standalone');
}
/**
* Skips the test if the connection string uses SSL.
*/
function skip_if_ssl()
{
is_ssl(URI) and exit('skip URI is using SSL');
}
/**
* Skips the test if the connection string uses SSL.
*/
function skip_if_not_ssl()
{
is_ssl(URI) or exit('skip URI is not using SSL');
}
/**
* Skips the test if the connection string is using auth.
*/
function skip_if_auth()
{
is_auth(URI) and exit('skip URI is using auth');
}
/**
* Skips the test if the connection string is not using auth.
*/
function skip_if_not_auth()
{
is_auth(URI) or exit('skip URI is not using auth');
}
/**
* Skips the test if the connection string is not using a particular
* authMechanism.
*
* @param string $authMechanism
*/
function skip_if_not_auth_mechanism($authMechanism)
{
$uriAuthMechanism = get_uri_option(URI, 'authMechanism');
if ($uriAuthMechanism === null && $authMechanism !== null) {
exit('skip URI is not using authMechanism');
}
if ($uriAuthMechanism !== $authMechanism) {
exit("skip URI authMechanism is '$uriAuthMechanism' (needed: '$authMechanism')");
}
}
/**
* Skips the test if the server is not accessible.
*/
function skip_if_not_live()
{
try {
get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip server is not accessible: ' . $e->getMessage());
}
}
/**
* Skips the test if the server version satisfies a comparison.
*
* @see http://php.net/version_compare
* @param string $operator Comparison operator
* @param string $version Version to compare against
*/
function skip_if_server_version($operator, $version)
{
$serverVersion = get_server_version(URI);
if (version_compare($serverVersion, $version, $operator)) {
exit("skip Server version '$serverVersion' $operator '$version'");
}
}
/**
* Skips the test if the PHP version satisfies a comparison.
*
* @see http://php.net/version_compare
* @param string $operator Comparison operator
* @param string $version Version to compare against
*/
function skip_if_php_version($operator, $version)
{
if (version_compare(PHP_VERSION, $version, $operator)) {
exit("skip PHP version '" . PHP_VERSION . "' $operator '$version'");
}
}
/**
* Skips the test if the server not using a particular storage engine.
*
* @param string $storageEngine Storage engine name
*/
function skip_if_not_server_storage_engine($storageEngine)
{
$serverStorageEngine = get_server_storage_engine(URI);
if ($serverStorageEngine !== $storageEngine) {
exit("skip Server storage engine is '$serverStorageEngine' (needed '$storageEngine')");
}
}
/**
* Skips the test if the server does not support the sleep command.
*/
function skip_if_sleep_command_unavailable()
{
if (!command_works(URI, ['sleep' => 1, 'secs' => 1, 'w' => false])) {
exit('skip sleep command not available');
}
}
/**
* Skips the test if the server does not support test commands.
*/
function skip_if_test_commands_disabled()
{
if (!get_server_parameter(URI, 'enableTestCommands')) {
exit('skip test commands are disabled');
}
}
/**
* Skips the test if libmongoc does not support crypto.
*
* If one or more libaries are provided, additionally check that the reported
* library is in that array. Possible values are "libcrypto", "Common Crypto",
* and "CNG".
*
* @param array $libs Optional list of crypto libraries to require
*/
function skip_if_not_libmongoc_crypto(array $libs = [])
{
$lib = get_module_info('libmongoc crypto library');
if ($lib === null) {
exit('skip libmongoc crypto is not enabled');
}
if (!empty($libs) && !in_array($lib, $libs)) {
exit('skip Needs libmongoc crypto library ' . implode(', ', $libs) . ', but found ' . $lib);
}
}
/**
* Skips the test if libmongoc does not support SSL.
*
* If one or more libaries are provided, additionally check that the reported
* library is in that array. Possible values are "OpenSSL", "LibreSSL",
* "Secure Transport", and "Secure Channel".
*
* @param array $libs Optional list of SSL libraries to require
*/
function skip_if_not_libmongoc_ssl(array $libs = [])
{
$lib = get_module_info('libmongoc SSL library');
if ($lib === null) {
exit('skip libmongoc SSL is not enabled');
}
if (!empty($libs) && !in_array($lib, $libs)) {
exit('skip Needs libmongoc SSL library ' . implode(', ', $libs) . ', but found ' . $lib);
}
}
/**
* Skips the test if the driver was not compiled with support for FLE
*/
function skip_if_not_libmongocrypt()
{
$lib = get_module_info('libmongocrypt');
if ($lib === 'disabled') {
exit('skip libmongocrypt is not enabled');
}
}
/**
* Skips the test if the driver was compiled with support for FLE
*/
function skip_if_libmongocrypt()
{
$lib = get_module_info('libmongocrypt');
if ($lib !== 'disabled') {
exit('skip libmongocrypt is enabled');
}
}
/**
* Skips the test if the collection cannot be dropped.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
*/
function skip_if_not_clean($databaseName = DATABASE_NAME, $collectionName = COLLECTION_NAME)
{
try {
drop_collection(URI, $databaseName, $collectionName);
} catch (RuntimeException $e) {
exit("skip Could not drop '$databaseName.$collectionName': " . $e->getMessage());
}
}
function skip_if_no_getmore_failpoint()
{
$serverVersion = get_server_version(URI);
if (
version_compare($serverVersion, '3.2', '>=') &&
version_compare($serverVersion, '4.0', '<')
) {
exit("skip Server version '$serverVersion' does not support a getMore failpoint'");
}
}
function skip_if_no_failcommand_failpoint()
{
skip_if_test_commands_disabled();
$serverVersion = get_server_version(URI);
if (is_mongos(URI) && version_compare($serverVersion, '4.1.8', '<')) {
exit("skip mongos version '$serverVersion' does not support 'failCommand' failpoint'");
} elseif (version_compare($serverVersion, '4.0', '<')) {
exit("skip mongod version '$serverVersion' does not support 'failCommand' failpoint'");
}
}
function skip_if_no_mongo_orchestration()
{
$ctx = stream_context_create(['http' => ['timeout' => 0.5]]);
$result = @file_get_contents(MONGO_ORCHESTRATION_URI, false, $ctx);
/* Note: file_get_contents emits an E_WARNING on failure, which will be
* caught by the error handler in basic-skipif.inc. In that case, this may
* never be reached. */
if ($result === false) {
exit("skip mongo-orchestration is not accessible: '" . MONGO_ORCHESTRATION_URI . "'");
}
}
+
+function skip_if_appveyor()
+{
+ if (getenv('APPVEYOR')) {
+ exit('skip Test cannot be run on AppVeyor');
+ }
+}
diff --git a/mongodb-1.7.4/tests/utils/tools.php b/mongodb-1.8.1/tests/utils/tools.php
similarity index 100%
rename from mongodb-1.7.4/tests/utils/tools.php
rename to mongodb-1.8.1/tests/utils/tools.php
diff --git a/mongodb-1.8.1/tests/writeConcern/bug1598-001.phpt b/mongodb-1.8.1/tests/writeConcern/bug1598-001.phpt
new file mode 100644
index 00000000..8c0012c5
--- /dev/null
+++ b/mongodb-1.8.1/tests/writeConcern/bug1598-001.phpt
@@ -0,0 +1,28 @@
+--TEST--
+PHPC-1598: WriteConcern get_gc should not invoke get_properties
+--FILE--
+<?php
+
+/* Note: the segfault only manifests if the get_properties handler reports an
+ * allocated value (e.g. string instead of integer for "w" field). */
+$wc = new MongoDB\Driver\WriteConcern('string');
+
+$a = (object) ['wc' => $wc];
+$b = (object) ['wc' => $wc];
+
+$a->b = $b;
+$b->a = $a;
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+unset($a, $b);
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+Collected cycles: 0
+Collected cycles: 2
+===DONE===
diff --git a/mongodb-1.8.1/tests/writeConcern/bug1598-002.phpt b/mongodb-1.8.1/tests/writeConcern/bug1598-002.phpt
new file mode 100644
index 00000000..686392c9
--- /dev/null
+++ b/mongodb-1.8.1/tests/writeConcern/bug1598-002.phpt
@@ -0,0 +1,28 @@
+--TEST--
+PHPC-1598: WriteConcern get_gc should delegate to zend_std_get_properties
+--FILE--
+<?php
+
+/* Store an additional object reference as a public property on the
+ * WriteConcern. This will leak if get_gc returns internally cached properties
+ * (from our get_properties handler) instead of zend_std_get_properties.
+ *
+ * Note: we also use a string value for WriteConcern's "w" field to ensure its
+ * internal properties have an allocated zval. */
+$a = new stdClass;
+$a->wc = new MongoDB\Driver\WriteConcern('string');
+$a->wc->a = $a;
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+unset($a);
+
+printf("Collected cycles: %d\n", gc_collect_cycles());
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+Collected cycles: 0
+Collected cycles: 2
+===DONE===
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-bsonserialize-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-bsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-bsonserialize-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-bsonserialize-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-bsonserialize-002.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-bsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-bsonserialize-002.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-bsonserialize-002.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-bsonserialize-003.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-bsonserialize-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-bsonserialize-003.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-bsonserialize-003.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-bsonserialize-004.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-bsonserialize-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-bsonserialize-004.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-bsonserialize-004.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-constants.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-constants.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-constants.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-constants.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-ctor-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-ctor-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-ctor-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-ctor-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-ctor-002.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-ctor-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-ctor-002.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-ctor-002.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-ctor_error-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-ctor_error-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-ctor_error-002.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-ctor_error-002.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-002.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-ctor_error-003.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-ctor_error-003.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-003.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-ctor_error-004.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-004.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-ctor_error-004.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-004.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-005.phpt
similarity index 62%
copy from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-001.phpt
copy to mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-005.phpt
index 23127797..1b654bb8 100644
--- a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-001.phpt
+++ b/mongodb-1.8.1/tests/writeConcern/writeconcern-ctor_error-005.phpt
@@ -1,18 +1,18 @@
--TEST--
-MongoDB\Driver\ReadPreference construction (invalid mode)
+MongoDB\Driver\WriteConcern construction (journaling with unacknowledged w)
--FILE--
<?php
require_once __DIR__ . '/../utils/tools.php';
echo throws(function() {
- new MongoDB\Driver\ReadPreference(42);
+ new MongoDB\Driver\WriteConcern(0, 0, true);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Invalid mode: 42
+Cannot enable journaling when using w = 0
===DONE===
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-debug-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-debug-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-debug-002.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-debug-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-debug-002.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-debug-002.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-debug-003.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-debug-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-debug-003.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-debug-003.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-getjournal-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-getjournal-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-getjournal-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-getjournal-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-getw-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-getw-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-getw-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-getw-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-getwtimeout-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-getwtimeout-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-getwtimeout-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-getwtimeout-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-getwtimeout-002.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-getwtimeout-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-getwtimeout-002.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-getwtimeout-002.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-isdefault-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-isdefault-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-isdefault-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-isdefault-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-serialization-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-serialization-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-serialization-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-serialization-001.phpt
diff --git a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-serialization_error-001.phpt
similarity index 60%
rename from mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-serialization_error-001.phpt
index 23127797..4cd80f23 100644
--- a/mongodb-1.7.4/tests/readPreference/readpreference-ctor_error-001.phpt
+++ b/mongodb-1.8.1/tests/writeConcern/writeconcern-serialization_error-001.phpt
@@ -1,18 +1,18 @@
--TEST--
-MongoDB\Driver\ReadPreference construction (invalid mode)
+MongoDB\Driver\WriteConcern serialization errors
--FILE--
<?php
require_once __DIR__ . '/../utils/tools.php';
echo throws(function() {
- new MongoDB\Driver\ReadPreference(42);
+ unserialize('C:27:"MongoDB\Driver\WriteConcern":30:{a:2:{s:1:"w";i:0;s:1:"j";b:1;}}');
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Invalid mode: 42
+Cannot enable journaling when using w = 0
===DONE===
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-set_state-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-set_state-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-set_state-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-set_state-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-set_state_error-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-set_state_error-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-set_state_error-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern-var_export-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern-var_export-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern-var_export-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern-var_export-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcern/writeconcern_error-001.phpt b/mongodb-1.8.1/tests/writeConcern/writeconcern_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcern/writeconcern_error-001.phpt
rename to mongodb-1.8.1/tests/writeConcern/writeconcern_error-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcernError/writeconcernerror-debug-001.phpt b/mongodb-1.8.1/tests/writeConcernError/writeconcernerror-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcernError/writeconcernerror-debug-001.phpt
rename to mongodb-1.8.1/tests/writeConcernError/writeconcernerror-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcernError/writeconcernerror-debug-002.phpt b/mongodb-1.8.1/tests/writeConcernError/writeconcernerror-debug-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcernError/writeconcernerror-debug-002.phpt
rename to mongodb-1.8.1/tests/writeConcernError/writeconcernerror-debug-002.phpt
diff --git a/mongodb-1.7.4/tests/writeConcernError/writeconcernerror-getcode-001.phpt b/mongodb-1.8.1/tests/writeConcernError/writeconcernerror-getcode-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcernError/writeconcernerror-getcode-001.phpt
rename to mongodb-1.8.1/tests/writeConcernError/writeconcernerror-getcode-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcernError/writeconcernerror-getinfo-001.phpt b/mongodb-1.8.1/tests/writeConcernError/writeconcernerror-getinfo-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcernError/writeconcernerror-getinfo-001.phpt
rename to mongodb-1.8.1/tests/writeConcernError/writeconcernerror-getinfo-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcernError/writeconcernerror-getinfo-002.phpt b/mongodb-1.8.1/tests/writeConcernError/writeconcernerror-getinfo-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcernError/writeconcernerror-getinfo-002.phpt
rename to mongodb-1.8.1/tests/writeConcernError/writeconcernerror-getinfo-002.phpt
diff --git a/mongodb-1.7.4/tests/writeConcernError/writeconcernerror-getmessage-001.phpt b/mongodb-1.8.1/tests/writeConcernError/writeconcernerror-getmessage-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcernError/writeconcernerror-getmessage-001.phpt
rename to mongodb-1.8.1/tests/writeConcernError/writeconcernerror-getmessage-001.phpt
diff --git a/mongodb-1.7.4/tests/writeConcernError/writeconcernerror_error-001.phpt b/mongodb-1.8.1/tests/writeConcernError/writeconcernerror_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeConcernError/writeconcernerror_error-001.phpt
rename to mongodb-1.8.1/tests/writeConcernError/writeconcernerror_error-001.phpt
diff --git a/mongodb-1.7.4/tests/writeError/writeerror-debug-001.phpt b/mongodb-1.8.1/tests/writeError/writeerror-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeError/writeerror-debug-001.phpt
rename to mongodb-1.8.1/tests/writeError/writeerror-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/writeError/writeerror-getCode-001.phpt b/mongodb-1.8.1/tests/writeError/writeerror-getCode-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeError/writeerror-getCode-001.phpt
rename to mongodb-1.8.1/tests/writeError/writeerror-getCode-001.phpt
diff --git a/mongodb-1.7.4/tests/writeError/writeerror-getIndex-001.phpt b/mongodb-1.8.1/tests/writeError/writeerror-getIndex-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeError/writeerror-getIndex-001.phpt
rename to mongodb-1.8.1/tests/writeError/writeerror-getIndex-001.phpt
diff --git a/mongodb-1.7.4/tests/writeError/writeerror-getInfo-001.phpt b/mongodb-1.8.1/tests/writeError/writeerror-getInfo-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeError/writeerror-getInfo-001.phpt
rename to mongodb-1.8.1/tests/writeError/writeerror-getInfo-001.phpt
diff --git a/mongodb-1.7.4/tests/writeError/writeerror-getMessage-001.phpt b/mongodb-1.8.1/tests/writeError/writeerror-getMessage-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeError/writeerror-getMessage-001.phpt
rename to mongodb-1.8.1/tests/writeError/writeerror-getMessage-001.phpt
diff --git a/mongodb-1.7.4/tests/writeError/writeerror_error-001.phpt b/mongodb-1.8.1/tests/writeError/writeerror_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeError/writeerror_error-001.phpt
rename to mongodb-1.8.1/tests/writeError/writeerror_error-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/bug0671-003.phpt b/mongodb-1.8.1/tests/writeResult/bug0671-003.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/bug0671-003.phpt
rename to mongodb-1.8.1/tests/writeResult/bug0671-003.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-debug-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-debug-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-debug-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-debug-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-debug-002.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-debug-002.phpt
similarity index 99%
rename from mongodb-1.7.4/tests/writeResult/writeresult-debug-002.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-debug-002.phpt
index 101093fe..45d93e9b 100644
--- a/mongodb-1.7.4/tests/writeResult/writeresult-debug-002.phpt
+++ b/mongodb-1.8.1/tests/writeResult/writeresult-debug-002.phpt
@@ -1,119 +1,119 @@
--TEST--
MongoDB\Driver\WriteResult debug output with errors
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_replica_set(); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$manager = new MongoDB\Driver\Manager(URI);
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
$bulk->update(['x' => 1], ['$set' => ['y' => 1]], ['upsert' => true]);
$bulk->update(['x' => 2], ['$set' => ['y' => 2]], ['upsert' => true]);
$bulk->insert(['_id' => 1]);
$bulk->insert(['_id' => 1]);
$bulk->insert(['_id' => 2]);
$bulk->insert(['_id' => 2]);
$bulk->insert(['_id' => 3]);
$bulk->insert(['_id' => 3]);
try {
/* We assume that the replica set does not have 30 nodes */
$result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(30));
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
var_dump($e->getWriteResult());
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\WriteResult)#%d (%d) {
["nInserted"]=>
int(3)
["nMatched"]=>
int(0)
["nModified"]=>
int(0)
["nRemoved"]=>
int(0)
["nUpserted"]=>
int(2)
["upsertedIds"]=>
array(2) {
[0]=>
array(2) {
["index"]=>
int(0)
["_id"]=>
object(MongoDB\BSON\ObjectId)#%d (%d) {
["oid"]=>
string(24) "%x"
}
}
[1]=>
array(2) {
["index"]=>
int(1)
["_id"]=>
object(MongoDB\BSON\ObjectId)#%d (%d) {
["oid"]=>
string(24) "%x"
}
}
}
["writeErrors"]=>
array(3) {
[0]=>
object(MongoDB\Driver\WriteError)#%d (%d) {
["message"]=>
string(%d) "E11000 duplicate key %S phongo.writeResult_writeresult_debug_002%s dup key: { %S: 1 }"
["code"]=>
int(11000)
["index"]=>
int(3)
["info"]=>
NULL
}
[1]=>
object(MongoDB\Driver\WriteError)#%d (%d) {
["message"]=>
string(%d) "E11000 duplicate key %S phongo.writeResult_writeresult_debug_002%s dup key: { %S: 2 }"
["code"]=>
int(11000)
["index"]=>
int(5)
["info"]=>
NULL
}
[2]=>
object(MongoDB\Driver\WriteError)#%d (%d) {
["message"]=>
string(%d) "E11000 duplicate key %S phongo.writeResult_writeresult_debug_002%s dup key: { %S: 3 }"
["code"]=>
int(11000)
["index"]=>
int(7)
["info"]=>
NULL
}
}
["writeConcernError"]=>
object(MongoDB\Driver\WriteConcernError)#%d (%d) {
["message"]=>
string(29) "Not enough data-bearing nodes"
["code"]=>
int(100)
["info"]=>
- NULL
+ %a
}
["writeConcern"]=>
object(MongoDB\Driver\WriteConcern)#%d (%d) {
["w"]=>
int(30)
}
}
===DONE===
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getdeletedcount-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getdeletedcount-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getdeletedcount-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getdeletedcount-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getdeletedcount-002.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getdeletedcount-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getdeletedcount-002.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getdeletedcount-002.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getinsertedcount-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getinsertedcount-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getinsertedcount-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getinsertedcount-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getinsertedcount-002.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getinsertedcount-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getinsertedcount-002.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getinsertedcount-002.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getmatchedcount-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getmatchedcount-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getmatchedcount-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getmatchedcount-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getmatchedcount-002.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getmatchedcount-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getmatchedcount-002.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getmatchedcount-002.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getmodifiedcount-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getmodifiedcount-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getmodifiedcount-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getmodifiedcount-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getmodifiedcount-002.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getmodifiedcount-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getmodifiedcount-002.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getmodifiedcount-002.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getserver-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getserver-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getserver-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getserver-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getupsertedcount-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getupsertedcount-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getupsertedcount-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getupsertedcount-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getupsertedcount-002.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getupsertedcount-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getupsertedcount-002.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getupsertedcount-002.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getupsertedids-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getupsertedids-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getupsertedids-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getupsertedids-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getupsertedids-002.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getupsertedids-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getupsertedids-002.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getupsertedids-002.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getwriteconcernerror-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getwriteconcernerror-001.phpt
similarity index 99%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getwriteconcernerror-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getwriteconcernerror-001.phpt
index 41f17387..02db6ab2 100644
--- a/mongodb-1.7.4/tests/writeResult/writeresult-getwriteconcernerror-001.phpt
+++ b/mongodb-1.8.1/tests/writeResult/writeresult-getwriteconcernerror-001.phpt
@@ -1,35 +1,35 @@
--TEST--
MongoDB\Driver\WriteResult::getWriteConcernError()
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_replica_set(); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
$manager = new MongoDB\Driver\Manager(URI);
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert(['x' => 1]);
try {
/* We assume that the replica set does not have 12 nodes */
$result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(12));
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
var_dump($e->getWriteResult()->getWriteConcernError());
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\WriteConcernError)#%d (%d) {
["message"]=>
string(29) "Not enough data-bearing nodes"
["code"]=>
int(100)
["info"]=>
- NULL
+ %a
}
===DONE===
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getwriteerrors-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getwriteerrors-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getwriteerrors-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getwriteerrors-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-getwriteerrors-002.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-getwriteerrors-002.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-getwriteerrors-002.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-getwriteerrors-002.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult-isacknowledged-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult-isacknowledged-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult-isacknowledged-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult-isacknowledged-001.phpt
diff --git a/mongodb-1.7.4/tests/writeResult/writeresult_error-001.phpt b/mongodb-1.8.1/tests/writeResult/writeresult_error-001.phpt
similarity index 100%
rename from mongodb-1.7.4/tests/writeResult/writeresult_error-001.phpt
rename to mongodb-1.8.1/tests/writeResult/writeresult_error-001.phpt
diff --git a/package.xml b/package.xml
index 3b601689..081eb4bf 100644
--- a/package.xml
+++ b/package.xml
@@ -1,2489 +1,2565 @@
<?xml version="1.0" encoding="UTF-8"?>
-<package packagerversion="1.10.10" version="2.1" xmlns="http://pear.php.net/dtd/package-2.1" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.1 http://pear.php.net/dtd/package-2.1.xsd">
+<package packagerversion="1.10.12" version="2.1" xmlns="http://pear.php.net/dtd/package-2.1" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.1 http://pear.php.net/dtd/package-2.1.xsd">
<name>mongodb</name>
<channel>pecl.php.net</channel>
<summary>MongoDB driver for PHP</summary>
<description>The purpose of this driver is to provide exceptionally thin glue between MongoDB
and PHP, implementing only fundamental and performance-critical components
necessary to build a fully-functional MongoDB driver.</description>
<lead>
<name>Andreas Braun</name>
<user>alcaeus</user>
<email>alcaeus@php.net</email>
<active>yes</active>
</lead>
<lead>
<name>Jeremy Mikola</name>
<user>jmikola</user>
<email>jmikola@php.net</email>
<active>yes</active>
</lead>
<lead>
<name>Derick Rethans</name>
<user>derick</user>
<email>derick@php.net</email>
<active>no</active>
</lead>
<lead>
<name>Hannes Magnusson</name>
<user>bjori</user>
<email>bjori@php.net</email>
<active>no</active>
</lead>
<developer>
<name>Katherine Walker</name>
<user>kvwalker</user>
<email>kvwalker@php.net</email>
- <active>yes</active>
+ <active>no</active>
</developer>
- <date>2020-03-11</date>
- <time>12:36:36</time>
+ <date>2020-10-06</date>
+ <time>11:11:23</time>
<version>
- <release>1.7.4</release>
- <api>1.7.4</api>
+ <release>1.8.1</release>
+ <api>1.8.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.apache.org/licenses/LICENSE-2.0">Apache License</license>
<notes>
** Bug
-* [PHPC-1560] - MongoDB compile fails due to missing openssl
+* [PHPC-1683] - Collect error labels from writeConcernErrors in libmongoc bulk write replies
+* [PHPC-1687] - Session::commitTransaction() leaks reply document on success
</notes>
<contents>
<dir name="/">
<file md5sum="c78c5e9b49b67a725e831823492642da" name="scripts/autotools/libbson/CheckAtomics.m4" role="src" />
<file md5sum="24efc529aa9f2b40d80cbec3bb635d01" name="scripts/autotools/libbson/CheckHeaders.m4" role="src" />
<file md5sum="fcce6a6a1e782b4482a50b18f78a2114" name="scripts/autotools/libbson/Endian.m4" role="src" />
<file md5sum="f1678968409f821893deb37ce58de6ee" name="scripts/autotools/libbson/FindDependencies.m4" role="src" />
<file md5sum="0ea5922bfcf826e14a5f3c0a5563e410" name="scripts/autotools/libbson/Versions.m4" role="src" />
- <file md5sum="68a001d61bb4bff706a3eeb66970b892" name="scripts/autotools/libmongoc/CheckCompression.m4" role="src" />
+ <file md5sum="8ad59ded5a1ccc434742345553373cfd" name="scripts/autotools/libmongoc/CheckCompression.m4" role="src" />
<file md5sum="96ddbeccbaa3c00f367810f56df074e4" name="scripts/autotools/libmongoc/CheckICU.m4" role="src" />
<file md5sum="3961221ff64e183bc4847fc4b02f3eb5" name="scripts/autotools/libmongoc/CheckResolv.m4" role="src" />
- <file md5sum="20541f7825a95173139cb32b53d5c6d9" name="scripts/autotools/libmongoc/CheckSSL.m4" role="src" />
+ <file md5sum="1402931faf1e48f2159acbb7f0a36452" name="scripts/autotools/libmongoc/CheckSSL.m4" role="src" />
<file md5sum="39e1c1663469b0d6222b6babd183fb40" name="scripts/autotools/libmongoc/CheckSasl.m4" role="src" />
<file md5sum="02def5697535eb19ab7be5b52b1da863" name="scripts/autotools/libmongoc/FindDependencies.m4" role="src" />
<file md5sum="bba9dc2de93bdadc29dc0927676161c7" name="scripts/autotools/libmongoc/PlatformFlags.m4" role="src" />
<file md5sum="08214982201e2c7805b62a3a4ca915a6" name="scripts/autotools/libmongoc/Versions.m4" role="src" />
<file md5sum="76e2c1a2aa19f5fab3661c992ac603fa" name="scripts/autotools/libmongoc/WeakSymbols.m4" role="src" />
- <file md5sum="095c833ac6fd670b34cc324ae2ccd13e" name="scripts/autotools/libmongocrypt/CheckSSL.m4" role="src" />
+ <file md5sum="906a71d7858713742f5febc043b9b51b" name="scripts/autotools/libmongocrypt/CheckSSL.m4" role="src" />
<file md5sum="471ed55586aaeef30e1d54a235133735" name="scripts/autotools/libmongocrypt/Version.m4" role="src" />
<file md5sum="0091c30d8927966e5ba54ce90b62bf6e" name="scripts/autotools/m4/as_var_copy.m4" role="src" />
<file md5sum="8d942f69b5f3c15ecae4b75bb7e80614" name="scripts/autotools/m4/ax_check_compile_flag.m4" role="src" />
<file md5sum="c2221efd4309e58ff7e2ef989c8e8ac4" name="scripts/autotools/m4/ax_prototype.m4" role="src" />
<file md5sum="b5114dfcf027b0f9a47b6e6841015be6" name="scripts/autotools/m4/ax_pthread.m4" role="src" />
<file md5sum="01a9faee79ca2be030b72f2046976b09" name="scripts/autotools/m4/php_mongodb.m4" role="src" />
<file md5sum="ad8d52d54e0f97c0e4e385376ea73bc0" name="scripts/autotools/m4/pkg.m4" role="src" />
<file md5sum="0601fcdfbdc1e25d6f5601cf78693669" name="scripts/autotools/CheckCompiler.m4" role="src" />
<file md5sum="869012c9009774810bc6789022c110ff" name="scripts/autotools/CheckHost.m4" role="src" />
<file md5sum="b301ead064e031b76fa08488a1055594" name="scripts/centos/ldap/Domain.ldif" role="test" />
<file md5sum="4daa783214593b6d7deb42f35c6e027c" name="scripts/centos/ldap/Users.ldif" role="test" />
<file md5sum="001e9cfe2c64b4afe413c12da3a75103" name="scripts/centos/ldap/basics.ldif" role="test" />
<file md5sum="624db776065d2ce0e76c3dd252c86c27" name="scripts/centos/ldap/install.sh" role="test" />
<file md5sum="a36639292f69b5a3ed651ce2b91c9e51" name="scripts/centos/ldap/ldapconfig.py" role="test" />
<file md5sum="3373471c13615482fcb5abd156a99013" name="scripts/centos/ldap/mongod.ldif" role="test" />
<file md5sum="79641e9055dc9a4c810cdc580d420ccf" name="scripts/centos/ldap/pw.ldif" role="test" />
<file md5sum="7069ce3fbf9612eb20df4de56e2915e7" name="scripts/centos/ldap/saslauthd.conf" role="test" />
<file md5sum="c2d1c7b3b12d970c295ebceda4bd429f" name="scripts/centos/ldap/users" role="test" />
<file md5sum="9add0018a9ebebb32e6f9d689d53ce14" name="scripts/centos/essentials.sh" role="test" />
<file md5sum="43a925c212fc965e90d89951d04945c1" name="scripts/freebsd/essentials.sh" role="test" />
<file md5sum="18b03fd810bde00c7493002a94e24865" name="scripts/freebsd/phongo.sh" role="test" />
<file md5sum="0761d232dfeacdec8308a100bbc9d03d" name="scripts/presets/replicaset-30.json" role="test" />
<file md5sum="ae88260932ae81a57d01480056fc595b" name="scripts/presets/replicaset-dns.json" role="test" />
<file md5sum="2e1c24fc2047589c5c38c07f09ff5b16" name="scripts/presets/replicaset.json" role="test" />
<file md5sum="6174401ebaba915d51de6394e962f627" name="scripts/presets/standalone-30.json" role="test" />
<file md5sum="be430bb8913b8c397fb2c7ebe6bf95a4" name="scripts/presets/standalone-auth.json" role="test" />
<file md5sum="cb26affccf6b2fef9374fb7d74050258" name="scripts/presets/standalone-plain.json" role="test" />
<file md5sum="d44e450c347829ae55c229bd2e018181" name="scripts/presets/standalone-ssl.json" role="test" />
<file md5sum="88d003b1fa5efe0ad7c625bc43764bf6" name="scripts/presets/standalone-x509.json" role="test" />
<file md5sum="44f3827004245db36ccd5a9388fa9ac0" name="scripts/presets/standalone.json" role="test" />
<file md5sum="097ef755ecbaed0f3fe8495e4d56207e" name="scripts/ssl/ca.pem" role="test" />
<file md5sum="c2c6fbfad3c6623584171da4b486fb61" name="scripts/ssl/client.pem" role="test" />
<file md5sum="7b41860fa327d7c5cf5bc63b681efac2" name="scripts/ssl/crl.pem" role="test" />
<file md5sum="143c83fdfcd0f1d011e416c853e634de" name="scripts/ssl/server.pem" role="test" />
<file md5sum="cb636b47cf37dace58be73272a74efc3" name="scripts/ubuntu/ldap/install.sh" role="test" />
<file md5sum="c4c1a6c234d983da8fe0382bcb8c1420" name="scripts/ubuntu/ldap/saslauthd.conf" role="test" />
<file md5sum="b199baa1ee52bc252773485de56b10f6" name="scripts/ubuntu/essentials.sh" role="test" />
<file md5sum="339ab9c62ab4b7f09ac5a7b3f6b62c73" name="scripts/ubuntu/mongo-orchestration.sh" role="test" />
<file md5sum="903c38a7e9d59fec770c1138de85d7be" name="scripts/ubuntu/phongo.sh" role="test" />
<file md5sum="a51616233fb311f458391b668e0254e9" name="scripts/vmware/kernel.sh" role="test" />
<file md5sum="a914c0f8add31145700dfb8eceb44654" name="scripts/clang-format.sh" role="test" />
<file md5sum="4f3d1683e946d021958f7d11a8a6c2e2" name="scripts/convert-bson-corpus-tests.php" role="test" />
<file md5sum="35671ea9b24b02610710ef676bc539a2" name="scripts/list-servers.php" role="test" />
<file md5sum="59b4cf65e9412c174b2641a6a1602d95" name="scripts/run-tests-on.sh" role="test" />
<file md5sum="38d7db8918c49a4549e322d079e644b2" name="scripts/start-servers.php" role="test" />
- <file md5sum="93c109a401cb1073a5e483ffb2b124cc" name="src/BSON/Binary.c" role="src" />
- <file md5sum="0b918e807d1b86312ade4e1fad3b086e" name="src/BSON/BinaryInterface.c" role="src" />
- <file md5sum="5914c549279b316a3058879556d8f16a" name="src/BSON/DBPointer.c" role="src" />
- <file md5sum="3b382b2299c1419c9241f72afd38ef48" name="src/BSON/Decimal128.c" role="src" />
- <file md5sum="6222d80149249b5407ee718464f57f8a" name="src/BSON/Decimal128Interface.c" role="src" />
- <file md5sum="e4642e706ca77171ae9f45574b4c5f9b" name="src/BSON/Int64.c" role="src" />
- <file md5sum="d1b7f55b14d81bad647fcb43e173aa49" name="src/BSON/Javascript.c" role="src" />
- <file md5sum="d96f1b94e52a688c6a22902fe54a2a0b" name="src/BSON/JavascriptInterface.c" role="src" />
- <file md5sum="4267d57cf0704531ed0603c8ae44a568" name="src/BSON/MaxKey.c" role="src" />
- <file md5sum="4f08e921b2d223af81b7643b085a2c9b" name="src/BSON/MaxKeyInterface.c" role="src" />
- <file md5sum="e5651bbd881ea03c65465cb00e11df79" name="src/BSON/MinKey.c" role="src" />
- <file md5sum="36dedf0752f6165df24d808e3f726a93" name="src/BSON/MinKeyInterface.c" role="src" />
- <file md5sum="fba7e07c5eee39c3c951d9c9dcb97b0c" name="src/BSON/ObjectId.c" role="src" />
- <file md5sum="7857ea3a78855d5ef612bd9c38732cbd" name="src/BSON/ObjectIdInterface.c" role="src" />
- <file md5sum="93e3c5ce6b3ada9aa051e6dfc4e673d7" name="src/BSON/Persistable.c" role="src" />
- <file md5sum="b740ea62b18edc79a566f6612bc496db" name="src/BSON/Regex.c" role="src" />
- <file md5sum="050e83e20f4403b992880988d42e8b84" name="src/BSON/RegexInterface.c" role="src" />
- <file md5sum="3df4875ff7fd002b6716a550c317ffb2" name="src/BSON/Serializable.c" role="src" />
- <file md5sum="1dd60785776dca5db517637c112ff976" name="src/BSON/Symbol.c" role="src" />
- <file md5sum="a9e92411b4d9124b238d19c7e88d9870" name="src/BSON/Timestamp.c" role="src" />
- <file md5sum="037c2d63c7ea949d4a3380f9241d39a2" name="src/BSON/TimestampInterface.c" role="src" />
- <file md5sum="d17bdc99da7cda08afcf4aa5c307052a" name="src/BSON/Type.c" role="src" />
- <file md5sum="1e49f9bca6294370cf5a9c1422dc1661" name="src/BSON/UTCDateTime.c" role="src" />
- <file md5sum="afa3cc796787a5adf18ab2bf6f3a5377" name="src/BSON/UTCDateTimeInterface.c" role="src" />
- <file md5sum="f16250e935795aa509bc9dba9d766426" name="src/BSON/Undefined.c" role="src" />
- <file md5sum="7f8b358cf7c9971fc52139bddfe398ae" name="src/BSON/Unserializable.c" role="src" />
- <file md5sum="941f31383d33477ea578dd68197ad750" name="src/BSON/functions.c" role="src" />
+ <file md5sum="282e5f5a621c16b1b63c17ea7cb5b5ac" name="src/BSON/Binary.c" role="src" />
+ <file md5sum="753d0f9455e588bba1fbd3299be5510f" name="src/BSON/BinaryInterface.c" role="src" />
+ <file md5sum="4b5ec5c04e9cae2a5dc42239de3a3237" name="src/BSON/DBPointer.c" role="src" />
+ <file md5sum="6342ba898e0217e7fb109f12d079242c" name="src/BSON/Decimal128.c" role="src" />
+ <file md5sum="584142c02500f54faf86325c5e2448b0" name="src/BSON/Decimal128Interface.c" role="src" />
+ <file md5sum="78480e1b968d60a582a2be8a9bc48d16" name="src/BSON/Int64.c" role="src" />
+ <file md5sum="75455bf1dc85097860ef6ff7c049e48e" name="src/BSON/Javascript.c" role="src" />
+ <file md5sum="e9c148621825de0b94ab21c9f9a81bce" name="src/BSON/JavascriptInterface.c" role="src" />
+ <file md5sum="adc76b241d20caaf36f7fcf5e60093a5" name="src/BSON/MaxKey.c" role="src" />
+ <file md5sum="3b0cdc3c4ec44eff177dba33f3e41f7e" name="src/BSON/MaxKeyInterface.c" role="src" />
+ <file md5sum="e4e8989d7beefdff34904e23ca1b48e6" name="src/BSON/MinKey.c" role="src" />
+ <file md5sum="5ab20f03675dcaca3856fa33db3e7ff1" name="src/BSON/MinKeyInterface.c" role="src" />
+ <file md5sum="42d3ec87dd9d342f8f05902276ab096e" name="src/BSON/ObjectId.c" role="src" />
+ <file md5sum="ea65bbb2fc742f2b24a8d2f3da9cdcc7" name="src/BSON/ObjectIdInterface.c" role="src" />
+ <file md5sum="50ab8a7d60043030a9a1f0105db15ff7" name="src/BSON/Persistable.c" role="src" />
+ <file md5sum="bd4eedadea9875ca0d8731f5539d3d65" name="src/BSON/Regex.c" role="src" />
+ <file md5sum="c71cec32f1d2eeae66761495dcadf829" name="src/BSON/RegexInterface.c" role="src" />
+ <file md5sum="80f92b8aa08d22e7dc6e60165b8f5c5b" name="src/BSON/Serializable.c" role="src" />
+ <file md5sum="d760a27c00454c3356dfadd5e6fdcc40" name="src/BSON/Symbol.c" role="src" />
+ <file md5sum="cfd13a1e63663e0d5cca3450f49f0250" name="src/BSON/Timestamp.c" role="src" />
+ <file md5sum="c91de93de8f86abd5b014766d7dc5770" name="src/BSON/TimestampInterface.c" role="src" />
+ <file md5sum="d8555d9cdccc9964de9533a8eef9076b" name="src/BSON/Type.c" role="src" />
+ <file md5sum="2f12c199b9dc79f9e481938af843ec96" name="src/BSON/UTCDateTime.c" role="src" />
+ <file md5sum="6212def544f4d6287549215f9cbabaae" name="src/BSON/UTCDateTimeInterface.c" role="src" />
+ <file md5sum="bd277005753f9ebf896a594d39acdc95" name="src/BSON/Undefined.c" role="src" />
+ <file md5sum="38f7e902c9b91e23d217bb754094f390" name="src/BSON/Unserializable.c" role="src" />
+ <file md5sum="0320a6c2b20570ac459c3a3d4c9de323" name="src/BSON/functions.c" role="src" />
<file md5sum="cb163d0a2877617c39259cb2ff7b70cb" name="src/BSON/functions.h" role="src" />
- <file md5sum="4fd26f0fba4081887ed8bea4d04d773f" name="src/MongoDB/Exception/AuthenticationException.c" role="src" />
- <file md5sum="f8266686d3168975caea5d0310bd47ec" name="src/MongoDB/Exception/BulkWriteException.c" role="src" />
- <file md5sum="f8398d8173d8db4e07ff0fce73743ec2" name="src/MongoDB/Exception/CommandException.c" role="src" />
- <file md5sum="4cf49d8d57ad59b9daf83539a28ec58c" name="src/MongoDB/Exception/ConnectionException.c" role="src" />
- <file md5sum="f9e287b61879713322e45dd3bc434f2d" name="src/MongoDB/Exception/ConnectionTimeoutException.c" role="src" />
- <file md5sum="66b14e1f6e1cabda115035dafe29fe37" name="src/MongoDB/Exception/EncryptionException.c" role="src" />
- <file md5sum="76be7ff7525240625576e63d6c6f5ba7" name="src/MongoDB/Exception/Exception.c" role="src" />
- <file md5sum="f3b1ca0c4ec2fbfc02b5067a4c76c6f4" name="src/MongoDB/Exception/ExecutionTimeoutException.c" role="src" />
- <file md5sum="3094ad02921398ca5b236d40370f7501" name="src/MongoDB/Exception/InvalidArgumentException.c" role="src" />
- <file md5sum="1d02bd650fe94c415ed2791260c4ee3d" name="src/MongoDB/Exception/LogicException.c" role="src" />
- <file md5sum="8a2b2895fca514db580ddbf830e33e2a" name="src/MongoDB/Exception/RuntimeException.c" role="src" />
- <file md5sum="d544ceba899f2088905f740556be8de0" name="src/MongoDB/Exception/SSLConnectionException.c" role="src" />
- <file md5sum="cf4b2634dce8af86a747d1665d507650" name="src/MongoDB/Exception/ServerException.c" role="src" />
- <file md5sum="2332d624bc6ee1690ef2e55357167def" name="src/MongoDB/Exception/UnexpectedValueException.c" role="src" />
- <file md5sum="e5332f1c7307ac3e8f964468668ebae0" name="src/MongoDB/Exception/WriteException.c" role="src" />
- <file md5sum="02d09c992cf42e13b157bb0d7b32655c" name="src/MongoDB/Monitoring/CommandFailedEvent.c" role="src" />
- <file md5sum="082427c5642fb56ead99d05e24507f7e" name="src/MongoDB/Monitoring/CommandStartedEvent.c" role="src" />
- <file md5sum="9f44c489d5fb3f2fb31cba06b4f83eb1" name="src/MongoDB/Monitoring/CommandSubscriber.c" role="src" />
- <file md5sum="3e0f0a83a5e5349ed3be9d224de0e3a9" name="src/MongoDB/Monitoring/CommandSucceededEvent.c" role="src" />
- <file md5sum="e9465a30c5fc37c51635cf7323afdac1" name="src/MongoDB/Monitoring/Subscriber.c" role="src" />
- <file md5sum="975a94a881c92d9694bd172bc9852cf5" name="src/MongoDB/Monitoring/functions.c" role="src" />
+ <file md5sum="92b58651c5db78439eeb26df9d486072" name="src/MongoDB/Exception/AuthenticationException.c" role="src" />
+ <file md5sum="9763969f4bdab61eb951363f47d7e63c" name="src/MongoDB/Exception/BulkWriteException.c" role="src" />
+ <file md5sum="ab8a8227389c1a4fdd69d7b288fd044e" name="src/MongoDB/Exception/CommandException.c" role="src" />
+ <file md5sum="a67ad8f0e59149c24e700a8c398c3506" name="src/MongoDB/Exception/ConnectionException.c" role="src" />
+ <file md5sum="fa22f93a40b27af930f516f2b0ff3f8d" name="src/MongoDB/Exception/ConnectionTimeoutException.c" role="src" />
+ <file md5sum="66b4bfffde44b1bf833a99ca5f1b917a" name="src/MongoDB/Exception/EncryptionException.c" role="src" />
+ <file md5sum="72a992cdeb7aba73e8b3ebb6db86aa46" name="src/MongoDB/Exception/Exception.c" role="src" />
+ <file md5sum="dcbe67280cd0405f57e1980ff04be7f3" name="src/MongoDB/Exception/ExecutionTimeoutException.c" role="src" />
+ <file md5sum="82d97ed975f9d392117a26ece5e1df70" name="src/MongoDB/Exception/InvalidArgumentException.c" role="src" />
+ <file md5sum="bd802cb7e6853f8dc10113a3c0ed38a2" name="src/MongoDB/Exception/LogicException.c" role="src" />
+ <file md5sum="f9d609fac8651cd11b94a6bd79bf7104" name="src/MongoDB/Exception/RuntimeException.c" role="src" />
+ <file md5sum="f0fda29946e70ef7dfcec126a64b49aa" name="src/MongoDB/Exception/SSLConnectionException.c" role="src" />
+ <file md5sum="c45b0e7d03183a663eca89403a015d82" name="src/MongoDB/Exception/ServerException.c" role="src" />
+ <file md5sum="fa4b5248d101c051f9cc036143e611d6" name="src/MongoDB/Exception/UnexpectedValueException.c" role="src" />
+ <file md5sum="621ac99d75e3f9f7abf77d694d336e68" name="src/MongoDB/Exception/WriteException.c" role="src" />
+ <file md5sum="33a8b49e625b80112eabef184e7d2e86" name="src/MongoDB/Monitoring/CommandFailedEvent.c" role="src" />
+ <file md5sum="e9ec9552ba894fdfda9f80c17106c96f" name="src/MongoDB/Monitoring/CommandStartedEvent.c" role="src" />
+ <file md5sum="9aab545180e10364311c12aafc3ea832" name="src/MongoDB/Monitoring/CommandSubscriber.c" role="src" />
+ <file md5sum="7533560097e3544941f8da491f431cd3" name="src/MongoDB/Monitoring/CommandSucceededEvent.c" role="src" />
+ <file md5sum="5001dc52cc2cc8e0ddedd0b987d455a0" name="src/MongoDB/Monitoring/Subscriber.c" role="src" />
+ <file md5sum="ff5ec55e450f69e4636b30382e44a023" name="src/MongoDB/Monitoring/functions.c" role="src" />
<file md5sum="c5ba2e385a5d6200f9646c7264c21651" name="src/MongoDB/Monitoring/functions.h" role="src" />
- <file md5sum="2f3613b417d5fe7c38b9c750e6a2df43" name="src/MongoDB/BulkWrite.c" role="src" />
- <file md5sum="a7ab734283093aa1995c2d45674ea8ae" name="src/MongoDB/ClientEncryption.c" role="src" />
- <file md5sum="6de13881a4b329ca121b608016abd2bc" name="src/MongoDB/Command.c" role="src" />
- <file md5sum="821f552cd29e93d59a6af86bdd1a57cd" name="src/MongoDB/Cursor.c" role="src" />
- <file md5sum="0c4e40876e0b13218887acc68d382d58" name="src/MongoDB/CursorId.c" role="src" />
- <file md5sum="7cd5e4963645643da0713c6986754d4e" name="src/MongoDB/CursorInterface.c" role="src" />
- <file md5sum="9c7737fde471feeedd34c4676b8d3a26" name="src/MongoDB/Manager.c" role="src" />
- <file md5sum="5f240a3729a8cce5a1b94ad53006c54c" name="src/MongoDB/Query.c" role="src" />
- <file md5sum="ae3c49d3ff074dd0f835f05d9f11f147" name="src/MongoDB/ReadConcern.c" role="src" />
- <file md5sum="c853a90c02c7308fee8a12ba7031802a" name="src/MongoDB/ReadPreference.c" role="src" />
- <file md5sum="cbd3d64b074039d466154b11c2820b90" name="src/MongoDB/Server.c" role="src" />
- <file md5sum="4a3654dbf8a4f0a023aed1444e8e091e" name="src/MongoDB/Session.c" role="src" />
- <file md5sum="e8391e6b4cf50733e073925e398907fe" name="src/MongoDB/Session.h" role="src" />
- <file md5sum="eb001e148b3ace9c0244ace1814bbb08" name="src/MongoDB/WriteConcern.c" role="src" />
- <file md5sum="bea6b3a6b23a602dcbe9ae6f25e4e8e7" name="src/MongoDB/WriteConcernError.c" role="src" />
- <file md5sum="233f6661ecde05bfec5790b52916b9b6" name="src/MongoDB/WriteError.c" role="src" />
- <file md5sum="ed38814b42a0a4ae7b0b243466dbc299" name="src/MongoDB/WriteResult.c" role="src" />
- <file md5sum="2cd305005cf360092da469c97cfb21f4" name="src/contrib/php_array_api.h" role="src" />
- <file md5sum="3f351667495e4c9964c35829e26e3b32" name="src/libmongoc/src/common/common-b64-private.h" role="src" />
- <file md5sum="716e639f1fda8ca5d02dcf77267dfa50" name="src/libmongoc/src/common/common-b64.c" role="src" />
- <file md5sum="a6f149d394deb7dfb3f839f7fcce9a33" name="src/libmongoc/src/common/common-md5-private.h" role="src" />
- <file md5sum="6b9ff4f6a4833e3c5b44e2537969e1e4" name="src/libmongoc/src/common/common-md5.c" role="src" />
- <file md5sum="87d85c8032bb4636e3d09822f1d4dbaf" name="src/libmongoc/src/common/common-prelude.h" role="src" />
- <file md5sum="733178d319454d6cf68c42653f377c7a" name="src/libmongoc/src/common/common-thread-private.h" role="src" />
+ <file md5sum="713b21367450df0cfb6227771cb803fa" name="src/MongoDB/BulkWrite.c" role="src" />
+ <file md5sum="428be865cdd18de2733255d0610dc4e6" name="src/MongoDB/ClientEncryption.c" role="src" />
+ <file md5sum="1f82ae4c7f3a4fe491a5e0d9f6bf2dea" name="src/MongoDB/Command.c" role="src" />
+ <file md5sum="9e7a6ad9290fb82ac6c3e4df455c1597" name="src/MongoDB/Cursor.c" role="src" />
+ <file md5sum="93d8879b503f579b2e89873d9893905b" name="src/MongoDB/CursorId.c" role="src" />
+ <file md5sum="1ecb727f1b35198f55aec08445ed3c6b" name="src/MongoDB/CursorInterface.c" role="src" />
+ <file md5sum="fb31996be10c6e4f4d7001e23950bcf4" name="src/MongoDB/Manager.c" role="src" />
+ <file md5sum="0f3eacf1e4aade3d780050c402138f8c" name="src/MongoDB/Query.c" role="src" />
+ <file md5sum="58ced21c764f4a004cca2dfe62b1816a" name="src/MongoDB/ReadConcern.c" role="src" />
+ <file md5sum="97141e98e0817d36aedc8625d2f301d4" name="src/MongoDB/ReadPreference.c" role="src" />
+ <file md5sum="b77c4a1b4c3d11c756492023ec00790c" name="src/MongoDB/Server.c" role="src" />
+ <file md5sum="b329a02d90ee05cd652b9fbf7abcec16" name="src/MongoDB/Session.c" role="src" />
+ <file md5sum="ec2dee8130d73fef8a733f0f1bd4320d" name="src/MongoDB/Session.h" role="src" />
+ <file md5sum="475931fbf7607e9ce5a635264faf4db1" name="src/MongoDB/WriteConcern.c" role="src" />
+ <file md5sum="eba2079a0693ac010b93d3562080f4e0" name="src/MongoDB/WriteConcernError.c" role="src" />
+ <file md5sum="7c16763c43943b70b7206d9597a27526" name="src/MongoDB/WriteError.c" role="src" />
+ <file md5sum="6c6baa1383b4ac8d0a35ba25d000068a" name="src/MongoDB/WriteResult.c" role="src" />
+ <file md5sum="7bf0e8df986b3ec841060f4a37b8dac0" name="src/contrib/php_array_api.h" role="src" />
+ <file md5sum="d36f9ceb3ac1fc1c5a9e5add685cf12a" name="src/libmongoc/src/common/common-b64-private.h" role="src" />
+ <file md5sum="66f9014b39f05a20a26d288d51ab5485" name="src/libmongoc/src/common/common-b64.c" role="src" />
+ <file md5sum="de3c3dfa7949127b9ca6bced2928b728" name="src/libmongoc/src/common/common-config.h" role="src" />
+ <file md5sum="15b3cf122cbd4a57f4477169f367fde9" name="src/libmongoc/src/common/common-md5-private.h" role="src" />
+ <file md5sum="50917245079095c514f4955c8ea62687" name="src/libmongoc/src/common/common-md5.c" role="src" />
+ <file md5sum="0918456265baeddaf1234efe7c8ad055" name="src/libmongoc/src/common/common-prelude.h" role="src" />
+ <file md5sum="638f8dc3b4994c78e2f9028f1bab8e62" name="src/libmongoc/src/common/common-thread-private.h" role="src" />
+ <file md5sum="0a9df59d1044784dff42c5aaa4901ba3" name="src/libmongoc/src/common/common-thread.c" role="src" />
+ <file md5sum="6afe2ac1833309ef5337e5a04945b4d3" name="src/libmongoc/src/kms-message/src/kms_message/kms_b64.h" role="src" />
+ <file md5sum="d4883934913f8b0693f90207b21bcc8b" name="src/libmongoc/src/kms-message/src/kms_message/kms_caller_identity_request.h" role="src" />
+ <file md5sum="3a4c30c28593474cb53c81bb30c0b656" name="src/libmongoc/src/kms-message/src/kms_message/kms_decrypt_request.h" role="src" />
+ <file md5sum="c6dc01b044efe5c7ba582bd36b3f18e0" name="src/libmongoc/src/kms-message/src/kms_message/kms_encrypt_request.h" role="src" />
+ <file md5sum="9463d1727695035852304d5947d2e86a" name="src/libmongoc/src/kms-message/src/kms_message/kms_message.h" role="src" />
+ <file md5sum="d00d408056f02b5ad2bd515e6dda4450" name="src/libmongoc/src/kms-message/src/kms_message/kms_message_defines.h" role="src" />
+ <file md5sum="a3bc2896fca774b80db0c60cdd1ecb60" name="src/libmongoc/src/kms-message/src/kms_message/kms_request.h" role="src" />
+ <file md5sum="771832eae920dc27ee493a736dcd0f07" name="src/libmongoc/src/kms-message/src/kms_message/kms_request_opt.h" role="src" />
+ <file md5sum="5341a53253bb71fdde40ef2733eed413" name="src/libmongoc/src/kms-message/src/kms_message/kms_response.h" role="src" />
+ <file md5sum="5d8416124f251cd69c9b6c37305aed1e" name="src/libmongoc/src/kms-message/src/kms_message/kms_response_parser.h" role="src" />
+ <file md5sum="001504937a1c62a19d6c1b56fe353eb1" name="src/libmongoc/src/kms-message/src/hexlify.c" role="src" />
+ <file md5sum="3ae9830c7804a56d602283845ed86651" name="src/libmongoc/src/kms-message/src/hexlify.h" role="src" />
+ <file md5sum="e8a52f0b2bc3e28f7c64f0a777ce3770" name="src/libmongoc/src/kms-message/src/kms_b64.c" role="src" />
+ <file md5sum="9cb501a5bfed23a74f5e38be89c1a6d5" name="src/libmongoc/src/kms-message/src/kms_caller_identity_request.c" role="src" />
+ <file md5sum="9c64a953bbdfa8ba90cbdc1a1d4519c9" name="src/libmongoc/src/kms-message/src/kms_crypto.h" role="src" />
+ <file md5sum="f4c1b39c72e5f25c7660bd86d87ca85e" name="src/libmongoc/src/kms-message/src/kms_crypto_apple.c" role="src" />
+ <file md5sum="32436c05f4a3e55cd176a882e21e13ad" name="src/libmongoc/src/kms-message/src/kms_crypto_libcrypto.c" role="src" />
+ <file md5sum="74b56cf66ea6e9cff053efb192a29add" name="src/libmongoc/src/kms-message/src/kms_crypto_none.c" role="src" />
+ <file md5sum="37f833a2d0dbb40323de0ddbacd461d6" name="src/libmongoc/src/kms-message/src/kms_crypto_windows.c" role="src" />
+ <file md5sum="9142dedbdc54951149219e8d7d733e36" name="src/libmongoc/src/kms-message/src/kms_decrypt_request.c" role="src" />
+ <file md5sum="69ec5d3da1ee1f8d3185854c883cd707" name="src/libmongoc/src/kms-message/src/kms_encrypt_request.c" role="src" />
+ <file md5sum="2a7f41d0b533d839384c449f05db13c5" name="src/libmongoc/src/kms-message/src/kms_kv_list.c" role="src" />
+ <file md5sum="69e374f65d9b21695d194e3495941f37" name="src/libmongoc/src/kms-message/src/kms_kv_list.h" role="src" />
+ <file md5sum="c2189649bce27380a9b07897662901e0" name="src/libmongoc/src/kms-message/src/kms_message.c" role="src" />
+ <file md5sum="47167d6a5e423a441d7df65d9feda9d7" name="src/libmongoc/src/kms-message/src/kms_message_private.h" role="src" />
+ <file md5sum="7b246b6b0a5c36862b79364d8e336b2a" name="src/libmongoc/src/kms-message/src/kms_port.c" role="src" />
+ <file md5sum="52247eca34cb25b7d80aad345e393e81" name="src/libmongoc/src/kms-message/src/kms_port.h" role="src" />
+ <file md5sum="f38035514480120b10b4bcb2c334e2a0" name="src/libmongoc/src/kms-message/src/kms_request.c" role="src" />
+ <file md5sum="0e650d43199b0e12ffb08b38f54c9b90" name="src/libmongoc/src/kms-message/src/kms_request_opt.c" role="src" />
+ <file md5sum="4c851b149d17a8d3818de213af8f2d06" name="src/libmongoc/src/kms-message/src/kms_request_opt_private.h" role="src" />
+ <file md5sum="888bf715d142e373232463eccf0dffcf" name="src/libmongoc/src/kms-message/src/kms_request_str.c" role="src" />
+ <file md5sum="7d8d321cf69c6316096ca2aab4c9728c" name="src/libmongoc/src/kms-message/src/kms_request_str.h" role="src" />
+ <file md5sum="ea5d236af2499b31ad2d6b8820376313" name="src/libmongoc/src/kms-message/src/kms_response.c" role="src" />
+ <file md5sum="2253d59b564ae589d7f0bc6c41626ec2" name="src/libmongoc/src/kms-message/src/kms_response_parser.c" role="src" />
+ <file md5sum="dff15b5018efb6269a2a0269c5ddb798" name="src/libmongoc/src/kms-message/src/sort.c" role="src" />
+ <file md5sum="18f9bd055f6a60e7702603b6b8bf07d5" name="src/libmongoc/src/kms-message/src/sort.h" role="src" />
<file md5sum="a3954d2b3ca305d1b4e370d9f73f209d" name="src/libmongoc/src/libbson/src/bson/bcon.c" role="src" />
<file md5sum="af5d3c6890b4fec8709a349289f8f9d3" name="src/libmongoc/src/libbson/src/bson/bcon.h" role="src" />
- <file md5sum="d56b6329106f234baf874a951bac928c" name="src/libmongoc/src/libbson/src/bson/bson-atomic.c" role="src" />
- <file md5sum="2cc3aa6057b7d08c3d201e9fa8891031" name="src/libmongoc/src/libbson/src/bson/bson-atomic.h" role="src" />
- <file md5sum="9fb2a81a7105538cb05e4a2368082127" name="src/libmongoc/src/libbson/src/bson/bson-clock.c" role="src" />
+ <file md5sum="e15fbacfd4a96fb4802466e6c79900d9" name="src/libmongoc/src/libbson/src/bson/bson-atomic.c" role="src" />
+ <file md5sum="1aa97c2fb1c212edc233f3e254071b9f" name="src/libmongoc/src/libbson/src/bson/bson-atomic.h" role="src" />
+ <file md5sum="ef3d475df2f82f4fdd78daaf6d754a35" name="src/libmongoc/src/libbson/src/bson/bson-clock.c" role="src" />
<file md5sum="941aa21f16b18e768fd8072a15a4da71" name="src/libmongoc/src/libbson/src/bson/bson-clock.h" role="src" />
<file md5sum="b3fc50563b55173ae5a4f7cf10bcf05b" name="src/libmongoc/src/libbson/src/bson/bson-compat.h" role="src" />
<file md5sum="df183a682a0b8d89176519af026b43d0" name="src/libmongoc/src/libbson/src/bson/bson-config.h" role="src" />
<file md5sum="bbc8d38a5e5985912bcd454e7ca3320b" name="src/libmongoc/src/libbson/src/bson/bson-config.h.in" role="src" />
<file md5sum="5b655a3af4caa6c8369dd000e482292a" name="src/libmongoc/src/libbson/src/bson/bson-context-private.h" role="src" />
- <file md5sum="84eb08847c2c0005b004f3acf84e7a18" name="src/libmongoc/src/libbson/src/bson/bson-context.c" role="src" />
+ <file md5sum="bf5fced31d69326007d9c623223bf707" name="src/libmongoc/src/libbson/src/bson/bson-context.c" role="src" />
<file md5sum="ac370a2562029eaed0f8b97b0d6fe90f" name="src/libmongoc/src/libbson/src/bson/bson-context.h" role="src" />
<file md5sum="c4b84f454a6cabaee587d151f2365858" name="src/libmongoc/src/libbson/src/bson/bson-decimal128.c" role="src" />
<file md5sum="6700198519a93ee85b8c95bcddfced30" name="src/libmongoc/src/libbson/src/bson/bson-decimal128.h" role="src" />
<file md5sum="8bbf15ea4a0155435036722b564ed558" name="src/libmongoc/src/libbson/src/bson/bson-endian.h" role="src" />
<file md5sum="4f643560fbb549b900ea02d2a7b34484" name="src/libmongoc/src/libbson/src/bson/bson-error.c" role="src" />
<file md5sum="5ee55f4f9a3401900b82a0381ab8f2a8" name="src/libmongoc/src/libbson/src/bson/bson-error.h" role="src" />
<file md5sum="6910b34f7cf6d0b522f548aa2599b490" name="src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h" role="src" />
<file md5sum="4d80e24fadedcfce63799efad8333489" name="src/libmongoc/src/libbson/src/bson/bson-iso8601.c" role="src" />
<file md5sum="e726ae34c8b34e8ab7e414032791160b" name="src/libmongoc/src/libbson/src/bson/bson-iter.c" role="src" />
<file md5sum="1d7b25e4b7051c95da6dda05e8703894" name="src/libmongoc/src/libbson/src/bson/bson-iter.h" role="src" />
- <file md5sum="a944583513c5143baa79c5db3a6c95b6" name="src/libmongoc/src/libbson/src/bson/bson-json.c" role="src" />
+ <file md5sum="6e4804003eac5361111e2a13d97d58f4" name="src/libmongoc/src/libbson/src/bson/bson-json.c" role="src" />
<file md5sum="02c790fc48ff27f4735e20434650827b" name="src/libmongoc/src/libbson/src/bson/bson-json.h" role="src" />
<file md5sum="5addb8761faac2e8d52f4ded8ecdc0c0" name="src/libmongoc/src/libbson/src/bson/bson-keys.c" role="src" />
<file md5sum="e1973fc044b52bfc2bb35b440350d228" name="src/libmongoc/src/libbson/src/bson/bson-keys.h" role="src" />
- <file md5sum="85c582a2339ab20fb50c107338b2242a" name="src/libmongoc/src/libbson/src/bson/bson-macros.h" role="src" />
- <file md5sum="4e0497e7b41a770c75961ccd1f1b68e1" name="src/libmongoc/src/libbson/src/bson/bson-md5.c" role="src" />
+ <file md5sum="70274d21db33bd61716e95d66978bf70" name="src/libmongoc/src/libbson/src/bson/bson-macros.h" role="src" />
+ <file md5sum="69c9a5bd0fcdeacffadb994c6d2e9e57" name="src/libmongoc/src/libbson/src/bson/bson-md5.c" role="src" />
<file md5sum="64bfaad7b9c371ac3cc5b19ae0d88fb5" name="src/libmongoc/src/libbson/src/bson/bson-md5.h" role="src" />
<file md5sum="902e9d1538121524c6f9944c1198f1d7" name="src/libmongoc/src/libbson/src/bson/bson-memory.c" role="src" />
<file md5sum="a50cea3f9a11bd1a11448b2b865b656e" name="src/libmongoc/src/libbson/src/bson/bson-memory.h" role="src" />
<file md5sum="1d11c5001d5975fbed63e11b96edbf49" name="src/libmongoc/src/libbson/src/bson/bson-oid.c" role="src" />
<file md5sum="1fc22f6fb12d962ff23ba7eebad1c18e" name="src/libmongoc/src/libbson/src/bson/bson-oid.h" role="src" />
- <file md5sum="cf3c296c1c722999173e51ecc211a6b2" name="src/libmongoc/src/libbson/src/bson/bson-prelude.h" role="src" />
+ <file md5sum="1cf75fbb62bcbe7bfed5906fce7bd0cd" name="src/libmongoc/src/libbson/src/bson/bson-prelude.h" role="src" />
<file md5sum="9173795c678991efc29bec5c95e402b4" name="src/libmongoc/src/libbson/src/bson/bson-private.h" role="src" />
<file md5sum="b351f160949566778783d1ba7a5b4d60" name="src/libmongoc/src/libbson/src/bson/bson-reader.c" role="src" />
<file md5sum="eda7ef0c3380276709b2f8e833867689" name="src/libmongoc/src/libbson/src/bson/bson-reader.h" role="src" />
- <file md5sum="2452dd14b91dc17892f0b0f29c36abfa" name="src/libmongoc/src/libbson/src/bson/bson-string.c" role="src" />
+ <file md5sum="fc1eb647810867d1db76dccb3ea3b663" name="src/libmongoc/src/libbson/src/bson/bson-string.c" role="src" />
<file md5sum="84bb7fecb29271e3a8fdc145cb33a77b" name="src/libmongoc/src/libbson/src/bson/bson-string.h" role="src" />
<file md5sum="f80c7197ff122c24f1a2642b083fb523" name="src/libmongoc/src/libbson/src/bson/bson-timegm-private.h" role="src" />
<file md5sum="cf1148af5b260d787b5a8de5ba82de77" name="src/libmongoc/src/libbson/src/bson/bson-timegm.c" role="src" />
- <file md5sum="239b8eeaba3d0e546c155bd9c84a201b" name="src/libmongoc/src/libbson/src/bson/bson-types.h" role="src" />
+ <file md5sum="e19adc54059d2b8c212380250da2c1d0" name="src/libmongoc/src/libbson/src/bson/bson-types.h" role="src" />
<file md5sum="1465f0c3c893f194091f6de94583e8de" name="src/libmongoc/src/libbson/src/bson/bson-utf8.c" role="src" />
<file md5sum="f23b07d93c8c65df5c0142f8ede21612" name="src/libmongoc/src/libbson/src/bson/bson-utf8.h" role="src" />
<file md5sum="5db2801d1c52e5027937dd5facab1b3d" name="src/libmongoc/src/libbson/src/bson/bson-value.c" role="src" />
<file md5sum="6d175e5373d24e3f403416b7871be3ca" name="src/libmongoc/src/libbson/src/bson/bson-value.h" role="src" />
<file md5sum="0bcfe98e683ae4fa5a6321fd6cafd9cd" name="src/libmongoc/src/libbson/src/bson/bson-version-functions.c" role="src" />
<file md5sum="0f7724eca64476682b9fd7f7a970cc04" name="src/libmongoc/src/libbson/src/bson/bson-version-functions.h" role="src" />
- <file md5sum="52f3e00261074381500797370055e39c" name="src/libmongoc/src/libbson/src/bson/bson-version.h" role="src" />
+ <file md5sum="9b7bc17c9ce9cca781d875328b4dc52e" name="src/libmongoc/src/libbson/src/bson/bson-version.h" role="src" />
<file md5sum="1f473fea4d18c65e7bb00be8bf2e841c" name="src/libmongoc/src/libbson/src/bson/bson-version.h.in" role="src" />
<file md5sum="61ba6f5aa4028b691ee22ea27eb3c3c5" name="src/libmongoc/src/libbson/src/bson/bson-writer.c" role="src" />
<file md5sum="05d85f6ccc42974bc14cf0eab289ebce" name="src/libmongoc/src/libbson/src/bson/bson-writer.h" role="src" />
- <file md5sum="f3e58fece16d8042b76fb38ea9cb97ca" name="src/libmongoc/src/libbson/src/bson/bson.c" role="src" />
- <file md5sum="ad04a02036cbbe64b01ab890d6968330" name="src/libmongoc/src/libbson/src/bson/bson.h" role="src" />
+ <file md5sum="39d715edb1b7fe0b3ee35e36dfcf6339" name="src/libmongoc/src/libbson/src/bson/bson.c" role="src" />
+ <file md5sum="fb771cd46e69dd1eec58588d3df4b68e" name="src/libmongoc/src/libbson/src/bson/bson.h" role="src" />
<file md5sum="cc8e625953a6cdb6147172f86f8d0c20" name="src/libmongoc/src/libbson/src/jsonsl/jsonsl.c" role="src" />
<file md5sum="cc4d69576f4fe9b87cd116d399309454" name="src/libmongoc/src/libbson/src/jsonsl/jsonsl.h" role="src" />
<file md5sum="715a53b77739b4f6d87b7236792b3501" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h" role="src" />
<file md5sum="3176cbf8be4a4eb647bd521841e6edfd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c" role="src" />
- <file md5sum="63d0c0652a42ec40885bd3c0fbb8abd9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h" role="src" />
- <file md5sum="bbcefc64b813f74af870a74d2fbd9b3b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c" role="src" />
- <file md5sum="f2283553723e8c820f2ccbd4e93cb111" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h" role="src" />
+ <file md5sum="36583ab212f82ed579a3e36e013666d1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h" role="src" />
+ <file md5sum="ebc6ee30f5a93b158da55b521362262a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c" role="src" />
+ <file md5sum="6d3c2e100526a1207839a6660fc594ca" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h" role="src" />
<file md5sum="02429f357ecd89327482930aec8bf34b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h" role="src" />
<file md5sum="475df6bf5cd4e55e0d4b26db29ea71fc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c" role="src" />
- <file md5sum="d44ef987cd9be344a5b5ed0d8887eb3f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h" role="src" />
- <file md5sum="3731b63fd6816bf1d82b1bf540cd535c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c" role="src" />
+ <file md5sum="766374d866c30f32a4e5a313494d7cce" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h" role="src" />
+ <file md5sum="9275b99cc55f52273efabce4f7766ee6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c" role="src" />
<file md5sum="6117af585e6f280e22535fee10458148" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h" role="src" />
<file md5sum="571e48bba13f93f7961ac831ab84675b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c" role="src" />
<file md5sum="5e7c0de09a22745fce5b273d8e9e964c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h" role="src" />
- <file md5sum="9a3812fadcc93bf1b520c381ab83d451" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c" role="src" />
+ <file md5sum="f4b3b177551d2703d24cd5be1add89e6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c" role="src" />
<file md5sum="d099437d7ea96ce3115170be386adceb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h" role="src" />
- <file md5sum="deacac9767b44f90f2aa01e4d8c7b8bf" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c" role="src" />
+ <file md5sum="190e9e9843d5449a86ff5a6a14cb8737" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c" role="src" />
<file md5sum="1f9cab77495164df9578f99d391ba3ef" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h" role="src" />
- <file md5sum="dd22fee1f4e3884305be9d96573159d3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h" role="src" />
- <file md5sum="696aeb76106c7c4041da71fd06286a0f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c" role="src" />
+ <file md5sum="178d695599ed8eb98de6672aff1ca0bc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h" role="src" />
+ <file md5sum="8d64ecc779913fde01ad5330d1113c47" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c" role="src" />
<file md5sum="a28176a567c6cd9b3e06246256c7ac7d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h" role="src" />
<file md5sum="dd048997f3230e0f019ad17ecfcf9dfd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h" role="src" />
- <file md5sum="fceb22c3c263df3625e4a73c64c0c6ce" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c" role="src" />
+ <file md5sum="2c53d366cb44a111e999bcf4f45fffe0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c" role="src" />
<file md5sum="3ec1fea991dad8b41a2ecb7c6d6f86ae" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h" role="src" />
- <file md5sum="5d0b7c26857f54d64961dad05e6843bb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h" role="src" />
- <file md5sum="b32e81dbbde78a3ce217bf0ca05c5e87" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h" role="src" />
- <file md5sum="e1c4d40290b631b6efec42d9785a9a4c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c" role="src" />
+ <file md5sum="27f95c7472939d6a53c24b589e322846" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h" role="src" />
+ <file md5sum="40119cebb0dc6fda04ef8b67240f886e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h" role="src" />
+ <file md5sum="f81ae8d5060879358979383eda105973" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c" role="src" />
<file md5sum="64160152789649758ff880c261539338" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h" role="src" />
- <file md5sum="631aad665a3bcab0a564ee07a5188b52" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h" role="src" />
+ <file md5sum="829e08021e4b012a3df657e9d3745aed" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h" role="src" />
<file md5sum="720fbcac1b58d2eb50572fb7167dba69" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c" role="src" />
<file md5sum="b1cfdbcfe8e5667db5081df44f9a4bb3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h" role="src" />
- <file md5sum="b3c2d33ca6116583991a6f11707306f7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c" role="src" />
- <file md5sum="a897658733abfff4368ad519228239fd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h" role="src" />
+ <file md5sum="625c7d1eee9720f344996c5829a6f940" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c" role="src" />
+ <file md5sum="9a3aea3ba403fa4101870e76dcf95936" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h" role="src" />
+ <file md5sum="ea98e4e4ae56c176e8286f3373b93872" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h" role="src" />
+ <file md5sum="579f3db57ff1657abe5e06309bf18abb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c" role="src" />
<file md5sum="abc87a40623b01a2848a13483f55c0eb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h" role="src" />
- <file md5sum="69f7eebc4d8200afeeb958fe546460db" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c" role="src" />
- <file md5sum="24714268621f144afc6e64c097997da8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h" role="src" />
+ <file md5sum="b478b60e0f7175075b1bc8b30f455b0a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c" role="src" />
+ <file md5sum="c75473fdc24e8351c9eb9d86a93e48da" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h" role="src" />
<file md5sum="7b7c909f1fa7029ea48d4d06e18c23a1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h" role="src" />
- <file md5sum="416e78686f97530eab6a66b2cc47333f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c" role="src" />
+ <file md5sum="9c05f27fa8164bfdb5b9d9d2afd7c8ec" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c" role="src" />
<file md5sum="820290eb3904bfc15d4b8bd246407472" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h" role="src" />
- <file md5sum="49e8eec90bb27047838afe9c03665ebc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c" role="src" />
- <file md5sum="0f990f0fd997a97737b7f16f01206cfc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c" role="src" />
- <file md5sum="f044c4a3e58ccc4c7f80c625095e5c2b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h" role="src" />
- <file md5sum="a4d544dd425dc91aae3d5f6f91de824f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c" role="src" />
- <file md5sum="81d2f6aa07ae8de4c241916d33c1593a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h" role="src" />
- <file md5sum="3fbc6ce534b1a7ab94f60ea52e689820" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c" role="src" />
+ <file md5sum="70f75a2c105330d0d52bf5a2e5acc686" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c" role="src" />
+ <file md5sum="c4b437871980ffed7d8c25c7f4a26acc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c" role="src" />
+ <file md5sum="3c57358e51734daaa86c6b957a2009eb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h" role="src" />
+ <file md5sum="0fcc24a9452be8f69fb01f045724388c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c" role="src" />
+ <file md5sum="7be3fb1fffde65a0a4f9864cc666585f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h" role="src" />
+ <file md5sum="228685e3395787418118a50b99b8aeef" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c" role="src" />
<file md5sum="631261c2b09625226e24063bffba8e25" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h" role="src" />
<file md5sum="51a5f2b055faf65386ed28d537af94e2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h" role="src" />
<file md5sum="c8efb75e7a6278b654502ad1f16b5e50" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c" role="src" />
- <file md5sum="882b0f41a32e82b7ed953827ff254491" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h" role="src" />
- <file md5sum="726c2ba870b2938800b17481c61a43d9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in" role="src" />
+ <file md5sum="5abd61e60996869b2b6e3ea602b6ce50" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h" role="src" />
+ <file md5sum="fb670b99174d436ab00fa4976585e9d1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in" role="src" />
<file md5sum="8a2612d3379fb68365a00c9e3f55ab17" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h" role="src" />
<file md5sum="c4aec9c96c3b5cc4bfcf610084b8c15d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c" role="src" />
<file md5sum="04d57743da7337aaec4dfe958a5742b7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs" role="src" />
- <file md5sum="9ec17de33ac64a2685607add6598d98f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h" role="src" />
- <file md5sum="569d95ceaccbbb2149843c038ea34108" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c" role="src" />
+ <file md5sum="b95275ee917d03dc554d0066309cfe32" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h" role="src" />
+ <file md5sum="f7bb72504f490c9f3ff6a3a51250e64d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c" role="src" />
<file md5sum="92fd26e85664f6c9d2d369c0fadc025b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h" role="src" />
- <file md5sum="93023d0498f4ec92bf2a3646775ea153" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c" role="src" />
+ <file md5sum="4962154517e614c682f72ec91a2dfb21" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c" role="src" />
<file md5sum="b3e1538050bff40cd2232ccc57978580" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h" role="src" />
<file md5sum="05bc88780422e1fecf959938dba4f37c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c" role="src" />
<file md5sum="b8182112c242fe00bfb665e7b7af8d09" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h" role="src" />
<file md5sum="0b30ddc797dd00fdcaf2a7d947d97c85" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c" role="src" />
<file md5sum="d917683855b94173416b062df755d960" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h" role="src" />
<file md5sum="2dc0df9846f851aead72d9fd4d734760" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c" role="src" />
<file md5sum="f1f255dcc6c9c9abc06423b00553a660" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c" role="src" />
<file md5sum="f39ea72235be77d77a30ad06c15be5b4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c" role="src" />
<file md5sum="13772036c14fa28597bae438270f5494" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c" role="src" />
<file md5sum="f68c43de1d7d090b6d9dc0d8f73911f5" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c" role="src" />
<file md5sum="436a0c9fea83bc37dfde5b82044db2de" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c" role="src" />
<file md5sum="d4664b89578808b1581a6a971e47f49e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c" role="src" />
<file md5sum="d2e19c9e8b69b30b2cf19639975cd51b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c" role="src" />
- <file md5sum="4f5b46dcc66d9c17c99e04588509e05b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c" role="src" />
- <file md5sum="b6f409f6977733d13d590aa8251bb6bb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h" role="src" />
- <file md5sum="c5f23a35939d515292f131905a349daa" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c" role="src" />
+ <file md5sum="30a6da3936834f4bebc281896d8a8ba7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c" role="src" />
+ <file md5sum="6e20628e397d4ae87d1fce85a5d59308" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h" role="src" />
+ <file md5sum="6d4724c59fda1ddbd8afc3d1b7ef8747" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c" role="src" />
<file md5sum="ab02e4cb247e4dedbf49e30b4b02e193" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h" role="src" />
- <file md5sum="e28c13d42f17507165531cbdbd264b0a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h" role="src" />
- <file md5sum="2dfb3f3d1a48da4ba5b51567ab7baf8e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c" role="src" />
- <file md5sum="c604f5b3fa1632b662991c98a7b49fda" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h" role="src" />
- <file md5sum="88fb9c43f7bc91d9d86c3c4410eb2730" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c" role="src" />
+ <file md5sum="cf20c0277c2b973281325739721d635b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h" role="src" />
+ <file md5sum="5c67ae23fe25b60c480c4955af75dfe2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c" role="src" />
+ <file md5sum="31a9b3420812c03b4446dd9ab13f222d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h" role="src" />
+ <file md5sum="46104d074e3c88a22e968d7148d6f22a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c" role="src" />
<file md5sum="ce96a3034434133359550a3703170282" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h" role="src" />
<file md5sum="28d90894b4e7c78bef2b1ca1834d0fcb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h" role="src" />
- <file md5sum="0aedb716711b50de2b17d3df6baf29d8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h" role="src" />
- <file md5sum="0bb505d92820f0f8b00e894a8c84fd0d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c" role="src" />
+ <file md5sum="3380d631de0134a6991833edb118e45b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h" role="src" />
+ <file md5sum="7cdb9d484ed7ebf4e2fbcafabce069d6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c" role="src" />
<file md5sum="f9633431ef574b83b0bd17783fdc0992" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h" role="src" />
<file md5sum="1ba39aca81a5d25857b77542e307b97b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h" role="src" />
- <file md5sum="73e1f2bce52e4d95a5bd173870fcd562" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c" role="src" />
+ <file md5sum="d0253ef5feb5587064d86eeb19577a1c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c" role="src" />
<file md5sum="1e2f790b08f8ddffc4d8b8f4c8d3971e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h" role="src" />
- <file md5sum="6920d571cbce4f3c451025dd69d42dc3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h" role="src" />
+ <file md5sum="75af2dc3e1069036fb8d78c1a94ca3c8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h" role="src" />
+ <file md5sum="8c187d85170153d453a851b3fa95a810" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h" role="src" />
<file md5sum="61a20bbf13213628a988af242bec479b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h" role="src" />
- <file md5sum="b7b1327180921d85eb260adad26c8dab" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c" role="src" />
+ <file md5sum="6a70f9e8dee7bae038fe63740011ed1b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c" role="src" />
<file md5sum="58fcf3011bfd394f310f3daa9594855b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h" role="src" />
- <file md5sum="f5df56376155bdda6ab5a2838805457e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c" role="src" />
+ <file md5sum="f889dd5343e0942b3b135a134eb30c1d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c" role="src" />
<file md5sum="99c2dcfa8367a0d1e7cb894ddfd0abff" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h" role="src" />
<file md5sum="952b93d5ee76b7402ea500906809161b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h" role="src" />
<file md5sum="8597d29f134e6d78cb6a34ea74423bab" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c" role="src" />
<file md5sum="6b303d070982631492f516b628d5198d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h" role="src" />
<file md5sum="282f5e691bb325deb6b8891eb13149f2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h" role="src" />
<file md5sum="6f0ed4d860816a02bfd98c9b50340227" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c" role="src" />
<file md5sum="3b932d73546d72dae9fcb918c41de57d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h" role="src" />
<file md5sum="c03dd7e85d3095caf235744ebb562a0e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h" role="src" />
<file md5sum="0a708de6ac97b858d9bf52cae92a660c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c" role="src" />
<file md5sum="4391ad3ca3396e9fc9b4c0c4e5772bfb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h" role="src" />
<file md5sum="ef7007f002b46c8354fee538e885de40" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h" role="src" />
- <file md5sum="fb35dd19a57c953d61e6389e85a8074f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c" role="src" />
+ <file md5sum="8a825992520617af35e9bddb0aabe9c6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c" role="src" />
<file md5sum="c771faf5c6235f50c357861a4c8516d3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h" role="src" />
<file md5sum="bbc260b536678d5331744aee0c186256" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h" role="src" />
<file md5sum="67039f2c6bc58df9e35fcb0cab2c2dbc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h" role="src" />
- <file md5sum="50ec06bcc5903400ee6892a8173d66cf" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h" role="src" />
- <file md5sum="c440a8901d9c8300dcfb1905b84fd308" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c" role="src" />
+ <file md5sum="f1cb056de4ee6d23bea3b02a31597667" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h" role="src" />
+ <file md5sum="3e3e2a2a5255d6f4099eebcc42958e2a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c" role="src" />
<file md5sum="68c985844829b5ff03f56f8eaeb9dd49" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h" role="src" />
- <file md5sum="b8d43bbbb22aaa049ca8daffc21746d7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h" role="src" />
- <file md5sum="eac226480f186ef67e06b7706a5fbc7a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c" role="src" />
+ <file md5sum="4fb133fd139b69892eea86eec693fac2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h" role="src" />
+ <file md5sum="08a38ce358289afe1d3946fd121d2fa9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c" role="src" />
<file md5sum="5e2da30e912e909ed594a59683833f7d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h" role="src" />
+ <file md5sum="c1934ce90e02b46a05a9a4751dbc0262" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h" role="src" />
+ <file md5sum="552f945bb02a4c698a66608dd30f1fe1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c" role="src" />
<file md5sum="5ac6b6febc5f47878215fbc74bd44de7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c" role="src" />
<file md5sum="dad1a4af8adf72a13809fd6c1c10afee" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h" role="src" />
- <file md5sum="724b13b1bebda1d5ce2f6ff2f3483a9c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c" role="src" />
+ <file md5sum="9a065aa2944698f9d0f64496cd59c8bd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c" role="src" />
<file md5sum="747ea7ab1744daf2a7e42508780575b1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h" role="src" />
+ <file md5sum="b9ea61d69501bc6e3b602117298aefb6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h" role="src" />
+ <file md5sum="3177cbfad1c5079952840fbb4c4dfbe4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c" role="src" />
<file md5sum="c3d4de8405f528f15caf2ab7f847ca12" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h" role="src" />
<file md5sum="c06c20bc7e775d6d8bced165cd04f8ee" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h" role="src" />
<file md5sum="0c90387fd3fe9289c20cf4354d6bd87e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c" role="src" />
<file md5sum="8c0701b9c767f009ba52d7231059d12b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h" role="src" />
- <file md5sum="c1234d64e33fd6e685966ee11f39478a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c" role="src" />
+ <file md5sum="54d78d18718c9b8705de0862b931f476" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c" role="src" />
<file md5sum="88813fcf803fccf84966f26431b3b71a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h" role="src" />
<file md5sum="ab4d31b167f229b490faf5b71a714339" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c" role="src" />
<file md5sum="be914702b66b1e1b8582cb9277239001" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h" role="src" />
<file md5sum="561c4ab0461c102a43cd877014707da8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c" role="src" />
<file md5sum="1c741c1aed2b563cacb6bced8e97d0b0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h" role="src" />
<file md5sum="439f25680fbc4c8a7542502287e3675e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h" role="src" />
<file md5sum="5a3506bda8c1638be4b76999c3c50f12" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h" role="src" />
<file md5sum="e3555fc6a1007c07d55f4f210097d689" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c" role="src" />
<file md5sum="dd1d23edde3907521792649267b48bc3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h" role="src" />
<file md5sum="cf91b7fcfb80ccaa33329d6bf14f8fbc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c" role="src" />
<file md5sum="05022e8ad5ea6da7158a0ce85c5f4762" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h" role="src" />
<file md5sum="86736045e6dcc91d8c525c87720b2911" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h" role="src" />
<file md5sum="cc510669bc8cdbfab031f54e143085e2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c" role="src" />
+ <file md5sum="a5d748bdf1c4b5cb845c6a81370d7961" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h" role="src" />
+ <file md5sum="f2c3545733f228d2457f64373ee5831b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c" role="src" />
<file md5sum="14f209fb86ed514cdde4b187d35ac83b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h" role="src" />
- <file md5sum="7943e9b04ac7e79f5b7b786a47e24f3c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h" role="src" />
- <file md5sum="4303d8edacee18a9df7c805e2a0c326a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c" role="src" />
+ <file md5sum="810df1337011be8f15d0719f1e03d798" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h" role="src" />
+ <file md5sum="e429f31c6f1d66a0ac819f2a27adee72" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c" role="src" />
<file md5sum="eb48d60cbcae6ce34b3b1b3edc3b9e73" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h" role="src" />
<file md5sum="abae85a1d96099484ea092abd7459a6a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c" role="src" />
- <file md5sum="a334dc929cf5dbf8781715c7ceb8d0e6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h" role="src" />
- <file md5sum="dc2e705a80ab745954ed3c8f81c0dc25" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c" role="src" />
- <file md5sum="84d0d9273c910256ad805c1982672c0f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h" role="src" />
+ <file md5sum="385a9b6a01db91a6c61f545f7593a9f1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h" role="src" />
+ <file md5sum="65409b32c9a9a497287e896586253873" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c" role="src" />
+ <file md5sum="a5a16bf330ec389692145c0a0f796d40" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h" role="src" />
<file md5sum="9d479bd2f13f239d558616322f8b4fb6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h" role="src" />
<file md5sum="7da2ed3fabbeee9a88c7ddeab9f11a20" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c" role="src" />
- <file md5sum="e57b2ef04f85e5b51aa16fe051c60cf1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c" role="src" />
+ <file md5sum="fa9297dcbff7191c36b6fb2b2a5a9c91" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c" role="src" />
<file md5sum="b8818c8c7c155272ab33a04dfb0c464c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c" role="src" />
<file md5sum="9335fc967215cfdee64e6f884bccf4ac" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c" role="src" />
<file md5sum="d665e822fefc6c01c4dd9ee4d1a02f2b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h" role="src" />
<file md5sum="41c7cd3177c60893f4eec6b144ceedc9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h" role="src" />
<file md5sum="a9abe88c57feeade91e4617b1582ea84" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h" role="src" />
<file md5sum="f877494d6f2aacb31a7aab8f2e46c911" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c" role="src" />
<file md5sum="f64bc23a48898ac8785963d3b3487500" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h" role="src" />
- <file md5sum="7b900af5deecc4a341defde83040d5ee" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h" role="src" />
- <file md5sum="2ee695da24c12a326d82a9f2f27bbf7d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c" role="src" />
- <file md5sum="ec856191ee4ef5ce4ef305f9eccb2901" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h" role="src" />
- <file md5sum="762ade8df3bacefe9254e426f6f739d8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h" role="src" />
- <file md5sum="2753e60343f2d7e4a71a10116a863baa" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c" role="src" />
+ <file md5sum="a200756c4228fc0675ab5e7057546068" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h" role="src" />
+ <file md5sum="c1a6c7d063f92ab81983a728c97ff981" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c" role="src" />
+ <file md5sum="be0fe246aac385340fd1ba746457d14e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h" role="src" />
+ <file md5sum="14d70d8935bf21f4c3239e45d86f4e6e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h" role="src" />
+ <file md5sum="7e6933c24f56c8d256f97f53bd443099" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c" role="src" />
<file md5sum="02680a898c086020b12d6efdcefaef1b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h" role="src" />
<file md5sum="f12439745ff93ee7d533b34cdfd76fdf" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c" role="src" />
- <file md5sum="ef55780fc98f5ae8a32fe552f9e8c024" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h" role="src" />
- <file md5sum="c7d78f86c48150b4bb99cae22ad8a1cc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c" role="src" />
+ <file md5sum="fb161be2bdaf05d53d5e8e4bb4760b0a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h" role="src" />
+ <file md5sum="0dd217d6feb694507b2c572b4f2e0762" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c" role="src" />
<file md5sum="403a7ed029b8d805676c762b0943987b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h" role="src" />
- <file md5sum="11f878f8ed25a0240412baf9f4938ad9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c" role="src" />
- <file md5sum="0e6c70d3bb44a2c4d06cb22cf4a09c31" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h" role="src" />
- <file md5sum="d4833fd7bd11e949307705edec489424" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c" role="src" />
- <file md5sum="be75389d8704c9f2206ec152d7959bcd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h" role="src" />
- <file md5sum="3e69080f02c1aac5157a56fa32ab4d68" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c" role="src" />
+ <file md5sum="492c536792727c38324e34c104ba06d8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c" role="src" />
+ <file md5sum="a6abefa0bc83ec37be8176b2df7de977" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h" role="src" />
+ <file md5sum="791823b6db4e4901f985450b553a65ca" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c" role="src" />
+ <file md5sum="7cba69880edc0bdd8c7d5d97226c2c08" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h" role="src" />
+ <file md5sum="78226ff7d018d717634ff56375f8873f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c" role="src" />
<file md5sum="c6ad195bdac20bc2d4e2ab55d940d6ba" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h" role="src" />
+ <file md5sum="727708f6492f8876f9c4ce50e755c0cd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h" role="src" />
+ <file md5sum="7c4188b2631864a2a0431eec130c73f0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c" role="src" />
<file md5sum="03bd5c9d7835ffba2717baf8e565c98b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h" role="src" />
<file md5sum="ffc10eef8451934a6ff8169a86b6bfa7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c" role="src" />
<file md5sum="834b9ec65671da3137ec37da39624e06" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h" role="src" />
<file md5sum="5c3f227bcc86c7209c4dd92591d3feaf" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c" role="src" />
<file md5sum="37376243128180b5b0d7eacef659f3d6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h" role="src" />
- <file md5sum="ebe80766423b8a9e8026b2c04809e84d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c" role="src" />
+ <file md5sum="98291bc054e2f0393dcbc5e61d4b226c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c" role="src" />
<file md5sum="4d6b7ea27bd6cb3e617c7d91b598acd0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h" role="src" />
- <file md5sum="52f293eb4623447a9cd47809db73cfd5" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h" role="src" />
- <file md5sum="63d11a559a681661a437f396afee6f93" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c" role="src" />
- <file md5sum="b5a8a7fdba64ea9108d9feee07d9e002" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h" role="src" />
+ <file md5sum="733fcb7eaca160fa809a7f7af70d6d15" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h" role="src" />
+ <file md5sum="4d7d67e4da4e442e925ee3c8bfde4486" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c" role="src" />
+ <file md5sum="42c133e3ad18a70058177091190401fd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h" role="src" />
<file md5sum="cc755861d5be912193591ad063bcad48" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h" role="src" />
<file md5sum="11a45877cdfc2df905aa0d162bb493b7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c" role="src" />
<file md5sum="cc3fc77850ae4bea293bd74b4cf60a04" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c" role="src" />
<file md5sum="b44455c950215262d30cbda9dd67aafe" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h" role="src" />
<file md5sum="f25a6cc9eeb840f34847f81cc2f36b60" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c" role="src" />
<file md5sum="6bfdb2875153e01323b8853ce27748fe" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h" role="src" />
<file md5sum="dc85d644079ad2e79d9d9dbe49facf10" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h" role="src" />
<file md5sum="131246e2d632381ce14d72fdbb1b3f21" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c" role="src" />
<file md5sum="7c0cce0559efc51ffe81a5465aa41484" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h" role="src" />
<file md5sum="b2eb639aae1caed00f7032b27e73cfbd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c" role="src" />
<file md5sum="d247dac07fdfffa79422f0682f546a77" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c" role="src" />
<file md5sum="0f90b785538b99de38421f87da0f6ede" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h" role="src" />
<file md5sum="fa30b8c754b1523186b0c0c19bf017dc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h" role="src" />
<file md5sum="3dbc0c52c735d318b3efbedb25a6005e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c" role="src" />
<file md5sum="f97854cb90d4a5fc797e7282675db01f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h" role="src" />
<file md5sum="90ec84cb182c98c7fc8fa8af0e85bdf0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h" role="src" />
- <file md5sum="3cb0554d73efbf23f62dbbdda2430273" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c" role="src" />
+ <file md5sum="116918bf8bb96c6f9165c13a4c1096a7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c" role="src" />
<file md5sum="4a2d1c22cf1e953cd86083246b0658bd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h" role="src" />
<file md5sum="3fd16580fa667309339b94b19a396b9e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h" role="src" />
<file md5sum="f72dd2878dcd9333a138e6c62adcd971" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c" role="src" />
- <file md5sum="7171d4df3cb48aed7acb96684ba2492c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h" role="src" />
- <file md5sum="a0590e0cd7f97ffaec8e386bc91ed491" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c" role="src" />
+ <file md5sum="377279ab2c57036be34ac0b8684d74c8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h" role="src" />
+ <file md5sum="5ebb1ca3d8f462fe51bc1b90e491fa60" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c" role="src" />
<file md5sum="026fab63add25604f7f3361274d4f9b0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h" role="src" />
<file md5sum="cfdd7f4e9b7619ec17a2af509ca99714" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h" role="src" />
<file md5sum="8df0fd4f5dc00181e9ebbe3eef3f321e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h" role="src" />
- <file md5sum="3231eb1a4af6266e97a605aa42178200" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c" role="src" />
+ <file md5sum="bed127055504f1baf8036a3504560fa7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c" role="src" />
<file md5sum="21696a6ec3026b2dac7204bb5c162209" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h" role="src" />
<file md5sum="0d18b0e579e693ff1e484632a7ffbe3c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h" role="src" />
- <file md5sum="c256d5f05dc1999b7dadaa714daed2c3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c" role="src" />
+ <file md5sum="6c7f4e134ef9fbe5ece63ede7b34e618" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c" role="src" />
<file md5sum="734df66c11a01ca83446d1d8b2b7edd0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h" role="src" />
<file md5sum="b4c2290ab76580b8428b18ada4760f53" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c" role="src" />
<file md5sum="b78a04064f599351509bf2f136174abb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h" role="src" />
- <file md5sum="c6dcbeabfd313f0f71c319461b33018c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c" role="src" />
+ <file md5sum="77d9779c925cbdcc010c708ceff13495" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c" role="src" />
<file md5sum="e8a3b99226da0b724dd3e01f845f3207" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h" role="src" />
- <file md5sum="3237c249220dec7d698672e74ae8584d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h" role="src" />
+ <file md5sum="33b2ffa7532ffe6b4437bc5968d887c4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h" role="src" />
+ <file md5sum="22bc0560741c8e37666f3a941caa6358" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h" role="src" />
+ <file md5sum="c8fc6828f9bfd123af78b078da58c2ad" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c" role="src" />
<file md5sum="395d5e3342ba5a943413926f65ccc9a1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h" role="src" />
<file md5sum="8f93b1626480c7c10b077d772ab35314" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c" role="src" />
- <file md5sum="1ce2e7fc2630a58e1708d80130c73cb2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h" role="src" />
- <file md5sum="179eea74e3352a41dcc1967d71749bd5" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c" role="src" />
+ <file md5sum="d9fa72e278645b1cccae74412f132c66" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h" role="src" />
+ <file md5sum="c271c338c60b50ca78e663a5bef27cb6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c" role="src" />
<file md5sum="f804c571d6036f2f7a67eb0ac0649c0b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h" role="src" />
- <file md5sum="bcd350ed7acb86e8e891be329a34c2d4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h" role="src" />
- <file md5sum="c5d2b0cbba650c1e95705d89f3dccec4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h" role="src" />
- <file md5sum="bc6763e9f994070f9e91bc4067bc9fa4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c" role="src" />
- <file md5sum="1fa52423d3050f4e1ec64258312932b1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c" role="src" />
- <file md5sum="655b0761588a2b89ef983df929d8241c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h" role="src" />
- <file md5sum="5561a45cbf00ccdf89dafe47f472e9c8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h" role="src" />
- <file md5sum="da7bbc64b3e3288c506a4df8bf836c52" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c" role="src" />
- <file md5sum="57337732fed5c33189ad9130ae8ac1a5" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h" role="src" />
- <file md5sum="9c1fd35ae05a7dd4f80a54c1bbaf2a56" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h" role="src" />
- <file md5sum="f6b1f30ae0d4aa38735066188c9c8fe3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c" role="src" />
+ <file md5sum="4043c4ee7b0eef35cd6cf68db2c53e96" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h" role="src" />
+ <file md5sum="0bf98835a50b55c797366d798295fa8e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h" role="src" />
+ <file md5sum="7ae3013d96f56128d06fb0a3bd6ed621" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c" role="src" />
+ <file md5sum="5ec644145ce339e13e12d0820a47e4cd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c" role="src" />
+ <file md5sum="fa4f353bf23ccae90497d2ef82b8b35f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h" role="src" />
+ <file md5sum="a8f81668d44a882a8032a8d85f869fd0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h" role="src" />
+ <file md5sum="531001a289a41eab1645c67f5716f853" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c" role="src" />
+ <file md5sum="27e908418c27335ff155b8d04c335a62" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h" role="src" />
+ <file md5sum="b88d7fc07934f173ff6e8c1d57533803" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h" role="src" />
+ <file md5sum="accae9f4575ca29d2d051da0d8efa0d9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c" role="src" />
<file md5sum="5c7c2a82e500e9a518fa596ff9c44021" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c" role="src" />
<file md5sum="c7cfe57411c17d6d3028ee180f1772e9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h" role="src" />
- <file md5sum="8ca9f2b4bdda2c45e6cb33225a23d271" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h" role="src" />
+ <file md5sum="a9ab2f20910eb06a7e1341cfc2535b78" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h" role="src" />
<file md5sum="ff10fb268641d60f7b14f911208fb2b1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in" role="src" />
<file md5sum="0808798e16ae4d6d7d8d01df40a54052" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h" role="src" />
- <file md5sum="020a5ba0741f52cb8f9ead37d6366889" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c" role="src" />
- <file md5sum="9c799e404c2239b0b95692f5315a9d05" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h" role="src" />
- <file md5sum="9f760913a246cacdbad00bf8c37b35e1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c" role="src" />
+ <file md5sum="88645a2deae1b19c4de2d089e008407c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c" role="src" />
+ <file md5sum="ee107bf849dd6644a6453a395651c2d0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h" role="src" />
+ <file md5sum="c526d42415961800fb727d241b4863ea" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c" role="src" />
<file md5sum="e5bce2b46dbf04b76fe5485db9de7e4e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h" role="src" />
- <file md5sum="7046cbbd26098cd066cf20317e5a4e04" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c" role="src" />
+ <file md5sum="2b01095b4919618f6d33b2c418c29455" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c" role="src" />
<file md5sum="6b44b7d7c834cd5ccbda4059d0a1fb1d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h" role="src" />
<file md5sum="22b9dfd9aacdbca888e8fb7a71dfe4f7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc.h" role="src" />
<file md5sum="f3e25b8f4865b4ff5ce5830870d8cec5" name="src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def" role="src" />
<file md5sum="ed1890accd7d9a1426fdac121ed42ad4" name="src/libmongoc/src/libmongoc/src/mongoc/op-delete.def" role="src" />
<file md5sum="9af88adf2ef432761bbe81db2f9bdce7" name="src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def" role="src" />
<file md5sum="242fff22640f143ae262e363e8552a7e" name="src/libmongoc/src/libmongoc/src/mongoc/op-header.def" role="src" />
<file md5sum="2efe34631dd0d540d0f1d2fdb2d57813" name="src/libmongoc/src/libmongoc/src/mongoc/op-insert.def" role="src" />
<file md5sum="79ab986cb49a47e7c9bccdc4005a9697" name="src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def" role="src" />
<file md5sum="7e1f1d29f10ca2b86aed48b4071b9800" name="src/libmongoc/src/libmongoc/src/mongoc/op-msg.def" role="src" />
<file md5sum="a986d22cb495d652dc6059d722bb3266" name="src/libmongoc/src/libmongoc/src/mongoc/op-query.def" role="src" />
<file md5sum="f82bc931404ce00b318675126572d667" name="src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def" role="src" />
<file md5sum="dd22bb15cb70d35fe25192f0f304871b" name="src/libmongoc/src/libmongoc/src/mongoc/op-reply.def" role="src" />
<file md5sum="03c6179a4fe8b51c606b03a763529d55" name="src/libmongoc/src/libmongoc/src/mongoc/op-update.def" role="src" />
<file md5sum="28e467e1c2bfe811edfcfc86662f3987" name="src/libmongoc/src/libmongoc/src/mongoc/utlist.h" role="src" />
<file md5sum="4dc406b7d1b6e49c22eee2e01177c195" name="src/libmongoc/src/zlib-1.2.11/adler32.c" role="src" />
<file md5sum="bca8dc2f982dfce8944aec9f4a83626c" name="src/libmongoc/src/zlib-1.2.11/compress.c" role="src" />
<file md5sum="f9a17af8e4efe8019fca94827ea1c0db" name="src/libmongoc/src/zlib-1.2.11/crc32.c" role="src" />
<file md5sum="f28d16b67efecdfafa0d816a7d982124" name="src/libmongoc/src/zlib-1.2.11/crc32.h" role="src" />
<file md5sum="9e645d2cc17f3e324028b90d25edc969" name="src/libmongoc/src/zlib-1.2.11/deflate.c" role="src" />
<file md5sum="c5839b3f66d79c5aa0daa5062de59bd5" name="src/libmongoc/src/zlib-1.2.11/deflate.h" role="src" />
<file md5sum="29d02cff161bde3e4e717b25a2ab7050" name="src/libmongoc/src/zlib-1.2.11/gzclose.c" role="src" />
<file md5sum="de472a3069a84c6e6b1eb083c3f91b53" name="src/libmongoc/src/zlib-1.2.11/gzguts.h" role="src" />
<file md5sum="2c08acd5014596272031fdd1a36d0f1c" name="src/libmongoc/src/zlib-1.2.11/gzlib.c" role="src" />
<file md5sum="a2a2f3a65c2891b1a8cf98be9b499e96" name="src/libmongoc/src/zlib-1.2.11/gzread.c" role="src" />
<file md5sum="92c3520553ac47aaa67f36ac9a571761" name="src/libmongoc/src/zlib-1.2.11/gzwrite.c" role="src" />
<file md5sum="f2adcadab3504b146be9c4928821f233" name="src/libmongoc/src/zlib-1.2.11/infback.c" role="src" />
<file md5sum="20d7b26f5ae64f4e8501f846beab550c" name="src/libmongoc/src/zlib-1.2.11/inffast.c" role="src" />
<file md5sum="f3669099d3f571dbc0426401ed5f50e3" name="src/libmongoc/src/zlib-1.2.11/inffast.h" role="src" />
<file md5sum="7fa3e91804601b6618c915b76a8dc332" name="src/libmongoc/src/zlib-1.2.11/inffixed.h" role="src" />
<file md5sum="c892c303a1be104ed0efb628e18ed85a" name="src/libmongoc/src/zlib-1.2.11/inflate.c" role="src" />
<file md5sum="12c1f3adaf005c8a4cfb629f2e266d30" name="src/libmongoc/src/zlib-1.2.11/inflate.h" role="src" />
<file md5sum="34a634c4c6e1de2e357f18c170e6b96c" name="src/libmongoc/src/zlib-1.2.11/inftrees.c" role="src" />
<file md5sum="ec87be89b9bcca8ced80a70f857e823b" name="src/libmongoc/src/zlib-1.2.11/inftrees.h" role="src" />
<file md5sum="fddcbf441ed0140dec23927ee34de9a7" name="src/libmongoc/src/zlib-1.2.11/trees.c" role="src" />
<file md5sum="51fdcb3e2ccf60ca13c06920c89296a3" name="src/libmongoc/src/zlib-1.2.11/trees.h" role="src" />
<file md5sum="dc210f08738914519d15edf1bb6e5141" name="src/libmongoc/src/zlib-1.2.11/uncompr.c" role="src" />
+ <file md5sum="66c6b3953f574eca8b709dd5f6865745" name="src/libmongoc/src/zlib-1.2.11/zconf.h" role="src" />
<file md5sum="66c6b3953f574eca8b709dd5f6865745" name="src/libmongoc/src/zlib-1.2.11/zconf.h.in" role="src" />
<file md5sum="0338828e9d00c94645648b1517108324" name="src/libmongoc/src/zlib-1.2.11/zlib.h" role="src" />
<file md5sum="69d0e0950d3ab5c1938d8566257c33a3" name="src/libmongoc/src/zlib-1.2.11/zutil.c" role="src" />
<file md5sum="b8a47cd8873cbfa8daf689f88dd62f75" name="src/libmongoc/src/zlib-1.2.11/zutil.h" role="src" />
<file md5sum="801dd41ee3301f2e0385658e8d409cb0" name="src/libmongocrypt-compat/mongocrypt/mongocrypt.h" role="src" />
<file md5sum="94b739a5ca4735c9efbef6c7c29c8e60" name="src/libmongocrypt-compat/mongocrypt-export.h" role="src" />
<file md5sum="6afe2ac1833309ef5337e5a04945b4d3" name="src/libmongocrypt/kms-message/src/kms_message/kms_b64.h" role="src" />
<file md5sum="d4883934913f8b0693f90207b21bcc8b" name="src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h" role="src" />
<file md5sum="3a4c30c28593474cb53c81bb30c0b656" name="src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h" role="src" />
<file md5sum="c6dc01b044efe5c7ba582bd36b3f18e0" name="src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h" role="src" />
<file md5sum="9463d1727695035852304d5947d2e86a" name="src/libmongocrypt/kms-message/src/kms_message/kms_message.h" role="src" />
<file md5sum="d00d408056f02b5ad2bd515e6dda4450" name="src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h" role="src" />
<file md5sum="a3bc2896fca774b80db0c60cdd1ecb60" name="src/libmongocrypt/kms-message/src/kms_message/kms_request.h" role="src" />
<file md5sum="771832eae920dc27ee493a736dcd0f07" name="src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h" role="src" />
<file md5sum="5341a53253bb71fdde40ef2733eed413" name="src/libmongocrypt/kms-message/src/kms_message/kms_response.h" role="src" />
<file md5sum="5d8416124f251cd69c9b6c37305aed1e" name="src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h" role="src" />
<file md5sum="001504937a1c62a19d6c1b56fe353eb1" name="src/libmongocrypt/kms-message/src/hexlify.c" role="src" />
<file md5sum="3ae9830c7804a56d602283845ed86651" name="src/libmongocrypt/kms-message/src/hexlify.h" role="src" />
<file md5sum="e8a52f0b2bc3e28f7c64f0a777ce3770" name="src/libmongocrypt/kms-message/src/kms_b64.c" role="src" />
<file md5sum="9cb501a5bfed23a74f5e38be89c1a6d5" name="src/libmongocrypt/kms-message/src/kms_caller_identity_request.c" role="src" />
<file md5sum="9c64a953bbdfa8ba90cbdc1a1d4519c9" name="src/libmongocrypt/kms-message/src/kms_crypto.h" role="src" />
<file md5sum="f4c1b39c72e5f25c7660bd86d87ca85e" name="src/libmongocrypt/kms-message/src/kms_crypto_apple.c" role="src" />
<file md5sum="32436c05f4a3e55cd176a882e21e13ad" name="src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c" role="src" />
<file md5sum="74b56cf66ea6e9cff053efb192a29add" name="src/libmongocrypt/kms-message/src/kms_crypto_none.c" role="src" />
<file md5sum="37f833a2d0dbb40323de0ddbacd461d6" name="src/libmongocrypt/kms-message/src/kms_crypto_windows.c" role="src" />
<file md5sum="9142dedbdc54951149219e8d7d733e36" name="src/libmongocrypt/kms-message/src/kms_decrypt_request.c" role="src" />
<file md5sum="69ec5d3da1ee1f8d3185854c883cd707" name="src/libmongocrypt/kms-message/src/kms_encrypt_request.c" role="src" />
- <file md5sum="f1d46a566a6539df2bb04c89359ef160" name="src/libmongocrypt/kms-message/src/kms_kv_list.c" role="src" />
+ <file md5sum="2a7f41d0b533d839384c449f05db13c5" name="src/libmongocrypt/kms-message/src/kms_kv_list.c" role="src" />
<file md5sum="69e374f65d9b21695d194e3495941f37" name="src/libmongocrypt/kms-message/src/kms_kv_list.h" role="src" />
<file md5sum="c2189649bce27380a9b07897662901e0" name="src/libmongocrypt/kms-message/src/kms_message.c" role="src" />
<file md5sum="47167d6a5e423a441d7df65d9feda9d7" name="src/libmongocrypt/kms-message/src/kms_message_private.h" role="src" />
- <file md5sum="9ff369b7a5b5073f041c13cb148c9cd9" name="src/libmongocrypt/kms-message/src/kms_port.h" role="src" />
- <file md5sum="ee162eb5be7c9915988d204117c917b1" name="src/libmongocrypt/kms-message/src/kms_request.c" role="src" />
+ <file md5sum="f27094bd3cd0c6174a279875623af84e" name="src/libmongocrypt/kms-message/src/kms_port.c" role="src" />
+ <file md5sum="52247eca34cb25b7d80aad345e393e81" name="src/libmongocrypt/kms-message/src/kms_port.h" role="src" />
+ <file md5sum="f38035514480120b10b4bcb2c334e2a0" name="src/libmongocrypt/kms-message/src/kms_request.c" role="src" />
<file md5sum="0e650d43199b0e12ffb08b38f54c9b90" name="src/libmongocrypt/kms-message/src/kms_request_opt.c" role="src" />
<file md5sum="4c851b149d17a8d3818de213af8f2d06" name="src/libmongocrypt/kms-message/src/kms_request_opt_private.h" role="src" />
- <file md5sum="78a6695f635d1acc445ee63fd58fb0c1" name="src/libmongocrypt/kms-message/src/kms_request_str.c" role="src" />
+ <file md5sum="888bf715d142e373232463eccf0dffcf" name="src/libmongocrypt/kms-message/src/kms_request_str.c" role="src" />
<file md5sum="7d8d321cf69c6316096ca2aab4c9728c" name="src/libmongocrypt/kms-message/src/kms_request_str.h" role="src" />
<file md5sum="ea5d236af2499b31ad2d6b8820376313" name="src/libmongocrypt/kms-message/src/kms_response.c" role="src" />
<file md5sum="2253d59b564ae589d7f0bc6c41626ec2" name="src/libmongocrypt/kms-message/src/kms_response_parser.c" role="src" />
<file md5sum="dff15b5018efb6269a2a0269c5ddb798" name="src/libmongocrypt/kms-message/src/sort.c" role="src" />
<file md5sum="18f9bd055f6a60e7702603b6b8bf07d5" name="src/libmongocrypt/kms-message/src/sort.h" role="src" />
<file md5sum="a791784364e86ef3029164fe8fafb4e7" name="src/libmongocrypt/src/crypto/cng.c" role="src" />
<file md5sum="53fc5575aff7106efd138447402987a0" name="src/libmongocrypt/src/crypto/commoncrypto.c" role="src" />
<file md5sum="977c2919c40b709e500db58b32cef614" name="src/libmongocrypt/src/crypto/libcrypto.c" role="src" />
<file md5sum="5f74a939598e843394ba5292069ace50" name="src/libmongocrypt/src/crypto/none.c" role="src" />
<file md5sum="39a4c1f631e35ead04f8ba13a11bba65" name="src/libmongocrypt/src/os_posix/os_mutex.c" role="src" />
<file md5sum="f36340408ed3b922617c53f5dc5570fb" name="src/libmongocrypt/src/os_posix/os_once.c" role="src" />
<file md5sum="f95d328d2484c7369dc938a5366cf846" name="src/libmongocrypt/src/os_win/os_mutex.c" role="src" />
<file md5sum="af647ade57dd876ee77cf5dd106035d4" name="src/libmongocrypt/src/os_win/os_once.c" role="src" />
<file md5sum="34e15d89ffa2a308ea86b1ae2cb0088f" name="src/libmongocrypt/src/mongocrypt-binary-private.h" role="src" />
<file md5sum="b81c6d7cb5e9526df940d94c813284e9" name="src/libmongocrypt/src/mongocrypt-binary.c" role="src" />
<file md5sum="109d64685929f58552226f26e709a3c8" name="src/libmongocrypt/src/mongocrypt-buffer-private.h" role="src" />
<file md5sum="4ac333f998d74213133f8bdc715f39ab" name="src/libmongocrypt/src/mongocrypt-buffer.c" role="src" />
<file md5sum="b5e9bc242b7d785f6c293d875c2d3c71" name="src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h" role="src" />
<file md5sum="48c5eb499d93bd2e230d38b78515deaa" name="src/libmongocrypt/src/mongocrypt-cache-collinfo.c" role="src" />
<file md5sum="1b4df4f22323d029c972086c956926d4" name="src/libmongocrypt/src/mongocrypt-cache-key-private.h" role="src" />
<file md5sum="21c432424e1a3160a71c8daa03a64cb5" name="src/libmongocrypt/src/mongocrypt-cache-key.c" role="src" />
<file md5sum="56a3c0f20b220f11a18965282facea22" name="src/libmongocrypt/src/mongocrypt-cache-private.h" role="src" />
<file md5sum="cf785575cca4c00c45dac5de2251c0c3" name="src/libmongocrypt/src/mongocrypt-cache.c" role="src" />
<file md5sum="3ee978103ce2a2f53b87f03b5bf9c12f" name="src/libmongocrypt/src/mongocrypt-ciphertext-private.h" role="src" />
<file md5sum="bdecd2c011f4f816c8660e3324115ca1" name="src/libmongocrypt/src/mongocrypt-ciphertext.c" role="src" />
<file md5sum="58273e221efb6ea6b1a05bb7fab3f2f3" name="src/libmongocrypt/src/mongocrypt-compat.h" role="src" />
<file md5sum="26ae605bd0f5b975033a17a545226496" name="src/libmongocrypt/src/mongocrypt-config.h" role="src" />
<file md5sum="6f51385c8021d849d4338bec0a8d0afc" name="src/libmongocrypt/src/mongocrypt-config.h.in" role="src" />
<file md5sum="aaa9e9a34de1a2b596666a81afc9b5fc" name="src/libmongocrypt/src/mongocrypt-crypto-private.h" role="src" />
<file md5sum="f06b1bc334578372191b07780ff6d64d" name="src/libmongocrypt/src/mongocrypt-crypto.c" role="src" />
<file md5sum="edb1d5aefa10337daf12dc05f1fb2d06" name="src/libmongocrypt/src/mongocrypt-ctx-datakey.c" role="src" />
<file md5sum="502f446a79814987c271a6baa18b50d2" name="src/libmongocrypt/src/mongocrypt-ctx-decrypt.c" role="src" />
<file md5sum="82a23ae6e1401c7f6cd75b2cb1325322" name="src/libmongocrypt/src/mongocrypt-ctx-encrypt.c" role="src" />
<file md5sum="969dfbc519ffcbf6b6f44f268559df61" name="src/libmongocrypt/src/mongocrypt-ctx-private.h" role="src" />
<file md5sum="d3b1ba157d5812d2d7e6b3718caf3464" name="src/libmongocrypt/src/mongocrypt-ctx.c" role="src" />
<file md5sum="6dd978a3c40bcd51b6ef191b147eab28" name="src/libmongocrypt/src/mongocrypt-key-broker-private.h" role="src" />
<file md5sum="082494b90330dcd1be7613de57533a81" name="src/libmongocrypt/src/mongocrypt-key-broker.c" role="src" />
<file md5sum="504951fc20640d67bf2d390e5d1623dc" name="src/libmongocrypt/src/mongocrypt-key-private.h" role="src" />
<file md5sum="57c011fdd62e96863c641159853de440" name="src/libmongocrypt/src/mongocrypt-key.c" role="src" />
<file md5sum="d68fa0e4ade2b9098f2d097d89513957" name="src/libmongocrypt/src/mongocrypt-kms-ctx-private.h" role="src" />
<file md5sum="bed3f500eed93e4b640436e779b1f861" name="src/libmongocrypt/src/mongocrypt-kms-ctx.c" role="src" />
<file md5sum="abb8c5d911a57713225517247cc9bd2a" name="src/libmongocrypt/src/mongocrypt-log-private.h" role="src" />
<file md5sum="791498257b4fc5601a91792bdc55c2cc" name="src/libmongocrypt/src/mongocrypt-log.c" role="src" />
<file md5sum="0453849c026e5fd24e80ad50c1aef528" name="src/libmongocrypt/src/mongocrypt-marking-private.h" role="src" />
<file md5sum="2993cd22ed2359e653f753f6a6c7ee16" name="src/libmongocrypt/src/mongocrypt-marking.c" role="src" />
<file md5sum="de4411fc003a25f9dbcc9d3f8fe80c2c" name="src/libmongocrypt/src/mongocrypt-mutex-private.h" role="src" />
<file md5sum="d80f92cec8266d12c3b174275b73bf10" name="src/libmongocrypt/src/mongocrypt-opts-private.h" role="src" />
<file md5sum="6560d217fe3b8418d7be07f8cd83896e" name="src/libmongocrypt/src/mongocrypt-opts.c" role="src" />
<file md5sum="3a8ee36ad63019ebde0f9c405d23aefd" name="src/libmongocrypt/src/mongocrypt-os-private.h" role="src" />
<file md5sum="23c4cfada727dd1d85574be5b0b4081f" name="src/libmongocrypt/src/mongocrypt-private.h" role="src" />
<file md5sum="24df0f363dcc87eb3e4e95b5b178133a" name="src/libmongocrypt/src/mongocrypt-status-private.h" role="src" />
<file md5sum="1c8e297a73ac824dd442ac3bfe2e06b3" name="src/libmongocrypt/src/mongocrypt-status.c" role="src" />
<file md5sum="c532c0d6ed2d0d97df2ac1b2bb01f469" name="src/libmongocrypt/src/mongocrypt-traverse-util-private.h" role="src" />
- <file md5sum="fcab1b2ca75d79386349bde7d4554bdb" name="src/libmongocrypt/src/mongocrypt-traverse-util.c" role="src" />
+ <file md5sum="93bf9b4cec817a1b527ddcaf1ee4f812" name="src/libmongocrypt/src/mongocrypt-traverse-util.c" role="src" />
<file md5sum="a1db2c8dfb2c724606562b2a26a26fa8" name="src/libmongocrypt/src/mongocrypt.c" role="src" />
- <file md5sum="b6e26705e9d048e726b48cc105300a69" name="src/libmongocrypt/src/mongocrypt.h" role="src" />
+ <file md5sum="47570a0d5dfb0d26bc49c526f020ac2c" name="src/libmongocrypt/src/mongocrypt.h" role="src" />
<file md5sum="b5a4f2ed22c33a7f2200eaecf835523a" name="src/libmongocrypt/src/mongocrypt.h.in" role="src" />
- <file md5sum="db007b32b16e26f01cae59f75e492284" name="src/LIBMONGOCRYPT_VERSION_CURRENT" role="src" />
- <file md5sum="474057a06282ce2dada2b47bed4fca65" name="src/LIBMONGOC_VERSION_CURRENT" role="src" />
- <file md5sum="9af123b4d9ee91e94d5670ea45f96591" name="src/bson-encode.c" role="src" />
- <file md5sum="a8e2fb06ebf696333431315af456bf0a" name="src/bson.c" role="src" />
+ <file md5sum="c0879261b3ffe363f27a5d1a6bb5ffcd" name="src/LIBMONGOCRYPT_VERSION_CURRENT" role="src" />
+ <file md5sum="6e8e7f4eecf00447cde2ef03edcd7a1c" name="src/LIBMONGOC_VERSION_CURRENT" role="src" />
+ <file md5sum="758ea1dc0add2812f22f8455cf81fbbe" name="src/bson-encode.c" role="src" />
+ <file md5sum="1faf61dc6c90ab73f9e1cd3bd43401f5" name="src/bson.c" role="src" />
<file md5sum="66af17011d592df54d55aaa7ff58e990" name="tests/apm/bug0950-001.phpt" role="test" />
<file md5sum="50f55a4c7b6155271ac7feb37e733ace" name="tests/apm/bug0950-002.phpt" role="test" />
<file md5sum="69974d01892202ee399bdf181549d07e" name="tests/apm/monitoring-addSubscriber-001.phpt" role="test" />
<file md5sum="8668c64512a5b32920ad2c87df9837ed" name="tests/apm/monitoring-addSubscriber-002.phpt" role="test" />
<file md5sum="e3b6beac60751e5ba7f48fc281e27f02" name="tests/apm/monitoring-addSubscriber-003.phpt" role="test" />
<file md5sum="c4e170d9acb0601c93e6112acd58792c" name="tests/apm/monitoring-addSubscriber-004.phpt" role="test" />
- <file md5sum="a818dba5765832b5c25eea95516bc7ca" name="tests/apm/monitoring-commandFailed-001.phpt" role="test" />
+ <file md5sum="03763298999547b395da7846105548dc" name="tests/apm/monitoring-commandFailed-001.phpt" role="test" />
<file md5sum="4cbdad41408461b054ba05df30cbacd5" name="tests/apm/monitoring-commandFailed-002.phpt" role="test" />
<file md5sum="0c0b354d9a505d05f74afa927375e3cc" name="tests/apm/monitoring-commandFailed-003.phpt" role="test" />
<file md5sum="9852e55216b755f2c800d8b7858aaae0" name="tests/apm/monitoring-commandStarted-001.phpt" role="test" />
- <file md5sum="f271860a62de00d560b06082e0cf6c4a" name="tests/apm/monitoring-commandSucceeded-001.phpt" role="test" />
+ <file md5sum="4b17b33c0b87a7f3e4878de244e426cb" name="tests/apm/monitoring-commandSucceeded-001.phpt" role="test" />
<file md5sum="4ce57a2990551547600ff91a3e15b6bd" name="tests/apm/monitoring-commandSucceeded-002.phpt" role="test" />
<file md5sum="aa99e776d1102681cac9b13ce84069ea" name="tests/apm/monitoring-removeSubscriber-001.phpt" role="test" />
<file md5sum="837f04a6157bf2dac297467b3a3a3590" name="tests/apm/monitoring-removeSubscriber-002.phpt" role="test" />
<file md5sum="b6ee01ca55973b188b7d83d79884c946" name="tests/bson-corpus/array-decodeError-001.phpt" role="test" />
<file md5sum="83f8434bb60797b4c6de3a675082b2ee" name="tests/bson-corpus/array-decodeError-002.phpt" role="test" />
<file md5sum="a185b9e13f33a7a5e33deed198aa5c56" name="tests/bson-corpus/array-decodeError-003.phpt" role="test" />
<file md5sum="5f7904f3ebaf38bb540b0b17e5ecd4d1" name="tests/bson-corpus/array-valid-001.phpt" role="test" />
<file md5sum="e664e3621ec2bad95c47047ce680b611" name="tests/bson-corpus/array-valid-002.phpt" role="test" />
<file md5sum="f2f189d6d98d8f54890c7a34c1ace17e" name="tests/bson-corpus/array-valid-003.phpt" role="test" />
<file md5sum="2e5d6afbb5e696585540ea681e5233a5" name="tests/bson-corpus/array-valid-004.phpt" role="test" />
<file md5sum="a9ff631ef6d197c1882bbbeaeb3e9e5e" name="tests/bson-corpus/array-valid-005.phpt" role="test" />
<file md5sum="8e413f5cb807cde854a34cb13b3386fc" name="tests/bson-corpus/binary-decodeError-001.phpt" role="test" />
<file md5sum="634976ba21553985d6ad1b33c3c7a94d" name="tests/bson-corpus/binary-decodeError-002.phpt" role="test" />
<file md5sum="c3d1081f87b20c7eccc634cc1fbe64dc" name="tests/bson-corpus/binary-decodeError-003.phpt" role="test" />
<file md5sum="029e9562d5745fcc40f68fa1f418ec3b" name="tests/bson-corpus/binary-decodeError-004.phpt" role="test" />
<file md5sum="4b2fb55983642f27a35f5044b0636d91" name="tests/bson-corpus/binary-decodeError-005.phpt" role="test" />
<file md5sum="42973b41103468bfafd3066be4bb7b48" name="tests/bson-corpus/binary-valid-001.phpt" role="test" />
<file md5sum="f6e30233405b16c9b436ea008a85bfd6" name="tests/bson-corpus/binary-valid-002.phpt" role="test" />
<file md5sum="3b4b3909abda591b158dd45ebdbe166b" name="tests/bson-corpus/binary-valid-003.phpt" role="test" />
<file md5sum="7292866378520a3727a8e126bffa9ae3" name="tests/bson-corpus/binary-valid-004.phpt" role="test" />
<file md5sum="2d3ff45f820fbc5b9338b5459de97866" name="tests/bson-corpus/binary-valid-005.phpt" role="test" />
<file md5sum="11933cd51cd1cdcc3cd134464e0896cf" name="tests/bson-corpus/binary-valid-006.phpt" role="test" />
<file md5sum="44569d1c0bf30bce454994a195f7823e" name="tests/bson-corpus/binary-valid-007.phpt" role="test" />
<file md5sum="05a35df52abd6765a5189c128284fcb4" name="tests/bson-corpus/binary-valid-008.phpt" role="test" />
<file md5sum="f84598efb7037482b132ac4fca5857e3" name="tests/bson-corpus/binary-valid-009.phpt" role="test" />
<file md5sum="6c4f6905bb8e6863c96588bd3a645177" name="tests/bson-corpus/binary-valid-010.phpt" role="test" />
<file md5sum="9a5f5e5d38089aaff6164dbc671e2246" name="tests/bson-corpus/binary-valid-011.phpt" role="test" />
<file md5sum="6acf60b8609adcb02a080fc2f2742acb" name="tests/bson-corpus/boolean-decodeError-001.phpt" role="test" />
<file md5sum="1b94fe0b7a11495dceaff6d1d2076082" name="tests/bson-corpus/boolean-decodeError-002.phpt" role="test" />
<file md5sum="2e89a679f02e12daac8311602f83c58b" name="tests/bson-corpus/boolean-valid-001.phpt" role="test" />
<file md5sum="fd64b1f664576a8cb9d5a8e96f883cdb" name="tests/bson-corpus/boolean-valid-002.phpt" role="test" />
<file md5sum="cb2c63091ce618abb5033167e4759ad3" name="tests/bson-corpus/code-decodeError-001.phpt" role="test" />
<file md5sum="d31b0b0e2e4979a9b9ec4e4d5bbca6ab" name="tests/bson-corpus/code-decodeError-002.phpt" role="test" />
<file md5sum="def5a9221b25131693a1a53d31535fef" name="tests/bson-corpus/code-decodeError-003.phpt" role="test" />
<file md5sum="a5047a340325e20232ad5ed40afc870b" name="tests/bson-corpus/code-decodeError-004.phpt" role="test" />
<file md5sum="3b5e60f96e1a28845decd47a24d9e1c8" name="tests/bson-corpus/code-decodeError-005.phpt" role="test" />
<file md5sum="5a5f978ebc00be2e2fd3f05d3544ad78" name="tests/bson-corpus/code-decodeError-006.phpt" role="test" />
<file md5sum="67b521b59cf0cee700b27ad76ad3f97f" name="tests/bson-corpus/code-decodeError-007.phpt" role="test" />
<file md5sum="4dd62a2936dc0d2a8b89d1e11727071c" name="tests/bson-corpus/code-valid-001.phpt" role="test" />
<file md5sum="fbbeca71baad82db682358fe22b40f92" name="tests/bson-corpus/code-valid-002.phpt" role="test" />
<file md5sum="39db4713192b7cf86eafaa9abc7fa35d" name="tests/bson-corpus/code-valid-003.phpt" role="test" />
<file md5sum="d56a95f4ddc720c825a8af0a14e65112" name="tests/bson-corpus/code-valid-004.phpt" role="test" />
<file md5sum="2fdd4dedb78278d264e22c3a059bae09" name="tests/bson-corpus/code-valid-005.phpt" role="test" />
<file md5sum="72e0600d4fa803ed685315248b0f864d" name="tests/bson-corpus/code-valid-006.phpt" role="test" />
<file md5sum="7e7b00cd6ae321cd06b04696558b93f9" name="tests/bson-corpus/code_w_scope-decodeError-001.phpt" role="test" />
<file md5sum="f0cba92ca6f26e073d988f2748d8e776" name="tests/bson-corpus/code_w_scope-decodeError-002.phpt" role="test" />
<file md5sum="eb2b50f7a920cc3442398f8e19f67119" name="tests/bson-corpus/code_w_scope-decodeError-003.phpt" role="test" />
<file md5sum="589dbd0b51bbc31700dd9a2edfef75c3" name="tests/bson-corpus/code_w_scope-decodeError-004.phpt" role="test" />
<file md5sum="7a02aa94adfd1007367d25ad001455a7" name="tests/bson-corpus/code_w_scope-decodeError-005.phpt" role="test" />
<file md5sum="2f8df9fe573147aa9b4e8416ce52b678" name="tests/bson-corpus/code_w_scope-decodeError-006.phpt" role="test" />
<file md5sum="8c9dbdc9c9b15b05859e87fc720483e9" name="tests/bson-corpus/code_w_scope-decodeError-007.phpt" role="test" />
<file md5sum="1b538522ec683297f76a6f53d9bfc559" name="tests/bson-corpus/code_w_scope-decodeError-008.phpt" role="test" />
<file md5sum="722497f92c19465fef10be41e1cbe89e" name="tests/bson-corpus/code_w_scope-decodeError-009.phpt" role="test" />
<file md5sum="7122940f8a8170b4129a8cb164bdd069" name="tests/bson-corpus/code_w_scope-decodeError-010.phpt" role="test" />
<file md5sum="1d1e085d1b768af338c0820be8b11078" name="tests/bson-corpus/code_w_scope-decodeError-011.phpt" role="test" />
<file md5sum="e51d958466aeeb7dbfd76347c3ac21e8" name="tests/bson-corpus/code_w_scope-valid-001.phpt" role="test" />
<file md5sum="27bc43506ee0a8112ccebf1e6020eb17" name="tests/bson-corpus/code_w_scope-valid-002.phpt" role="test" />
<file md5sum="a921c315930c5e272c2cd0ef6767bba2" name="tests/bson-corpus/code_w_scope-valid-003.phpt" role="test" />
<file md5sum="841870f527f9a55d8b49271fe6fd1c59" name="tests/bson-corpus/code_w_scope-valid-004.phpt" role="test" />
<file md5sum="5f945ba46fa191c856e73b76fd5ff451" name="tests/bson-corpus/code_w_scope-valid-005.phpt" role="test" />
<file md5sum="ce7213c4e3aae833d56812e57ca28cfa" name="tests/bson-corpus/datetime-decodeError-001.phpt" role="test" />
<file md5sum="f7bfa0b5340ca943ff152c50b0e1bf04" name="tests/bson-corpus/datetime-valid-001.phpt" role="test" />
<file md5sum="7b4a43c6d6f90fef8b7bca0a8c9a61e0" name="tests/bson-corpus/datetime-valid-002.phpt" role="test" />
<file md5sum="471939bcb3717b9d784cbb41dff0b8b4" name="tests/bson-corpus/datetime-valid-003.phpt" role="test" />
<file md5sum="0f753526142aad6abed8345951f3f90f" name="tests/bson-corpus/datetime-valid-004.phpt" role="test" />
<file md5sum="395f1fa7b59716e26f51f7b2523f6115" name="tests/bson-corpus/datetime-valid-005.phpt" role="test" />
<file md5sum="093f74a124695331852c20f6ba4236ee" name="tests/bson-corpus/dbpointer-decodeError-001.phpt" role="test" />
<file md5sum="21c522b8b544870ad4982ca50dd1e7ae" name="tests/bson-corpus/dbpointer-decodeError-002.phpt" role="test" />
<file md5sum="0399ddebcb1fd2dd5764bd81425f6265" name="tests/bson-corpus/dbpointer-decodeError-003.phpt" role="test" />
<file md5sum="72e19565405e17ddd67b58a12f7fcde2" name="tests/bson-corpus/dbpointer-decodeError-004.phpt" role="test" />
<file md5sum="7579629d6cbaac8e1b3a0f5dddbea518" name="tests/bson-corpus/dbpointer-decodeError-005.phpt" role="test" />
<file md5sum="5f3222fe704bc140610288700005bbf1" name="tests/bson-corpus/dbpointer-decodeError-006.phpt" role="test" />
<file md5sum="4fe16bf89fe5df9ccc78fe065d635d97" name="tests/bson-corpus/dbpointer-valid-001.phpt" role="test" />
<file md5sum="2e8314da3bf0d89a6cc59aa05beab8d5" name="tests/bson-corpus/dbpointer-valid-002.phpt" role="test" />
<file md5sum="03f8c4c2d67c9836b2bea4f3e6e01878" name="tests/bson-corpus/dbpointer-valid-003.phpt" role="test" />
<file md5sum="f6a0d646f5f59227ab1a2a2d94fdf180" name="tests/bson-corpus/dbref-valid-001.phpt" role="test" />
<file md5sum="0a9d842217ab322bffa873e492687737" name="tests/bson-corpus/dbref-valid-002.phpt" role="test" />
<file md5sum="35045645543825eb1964601f4fe86cae" name="tests/bson-corpus/dbref-valid-003.phpt" role="test" />
<file md5sum="6d08c11b156e71399412d2271dcc31ae" name="tests/bson-corpus/dbref-valid-004.phpt" role="test" />
<file md5sum="c8bea39a89b0a90b84842ad6d3a96a11" name="tests/bson-corpus/dbref-valid-005.phpt" role="test" />
<file md5sum="1be9664e30513a74507db5a31493d6ab" name="tests/bson-corpus/decimal128-1-valid-001.phpt" role="test" />
<file md5sum="6211d74f1ce5b93637cb0a0649071866" name="tests/bson-corpus/decimal128-1-valid-002.phpt" role="test" />
<file md5sum="6c3cc1a8b4342f226e53614aee46c850" name="tests/bson-corpus/decimal128-1-valid-003.phpt" role="test" />
<file md5sum="1258eedd19348a86ddd31f21d1115d9c" name="tests/bson-corpus/decimal128-1-valid-004.phpt" role="test" />
<file md5sum="ba2b9cf011c89650faa41c46503d6201" name="tests/bson-corpus/decimal128-1-valid-005.phpt" role="test" />
<file md5sum="13646f18b50308a4816c3a2adb583433" name="tests/bson-corpus/decimal128-1-valid-006.phpt" role="test" />
<file md5sum="e61f4ac46d6d11c7ff1e3eff3fead1bb" name="tests/bson-corpus/decimal128-1-valid-007.phpt" role="test" />
<file md5sum="ed121eaa293ae98345e2632ce931d87e" name="tests/bson-corpus/decimal128-1-valid-008.phpt" role="test" />
<file md5sum="38799d1515616bb61426710833d27a33" name="tests/bson-corpus/decimal128-1-valid-009.phpt" role="test" />
<file md5sum="675915a04d0ccbe5e33c8cd191c49009" name="tests/bson-corpus/decimal128-1-valid-010.phpt" role="test" />
<file md5sum="da13a23d8a366f64173469a48d34bf75" name="tests/bson-corpus/decimal128-1-valid-011.phpt" role="test" />
<file md5sum="e53db0b3304cf22b40bd88648905b8b0" name="tests/bson-corpus/decimal128-1-valid-012.phpt" role="test" />
<file md5sum="e0ea8c1c0af2018097e277766178af4d" name="tests/bson-corpus/decimal128-1-valid-013.phpt" role="test" />
<file md5sum="683e01fbd575c916cf8318f79abe3e24" name="tests/bson-corpus/decimal128-1-valid-014.phpt" role="test" />
<file md5sum="14e8fd8b30319c05b7b11bb36ca1d653" name="tests/bson-corpus/decimal128-1-valid-015.phpt" role="test" />
<file md5sum="75c92b5d14312891ab5c3e16055743fa" name="tests/bson-corpus/decimal128-1-valid-016.phpt" role="test" />
<file md5sum="8a7fa49d165fda74aa161fe86a462b76" name="tests/bson-corpus/decimal128-1-valid-017.phpt" role="test" />
<file md5sum="ac80ba6121ddaa84a249b30ca2ea1872" name="tests/bson-corpus/decimal128-1-valid-018.phpt" role="test" />
<file md5sum="5d01624977a5c30b7d119314f3aff184" name="tests/bson-corpus/decimal128-1-valid-019.phpt" role="test" />
<file md5sum="8c3fcbbc3a7aa1640fe397c67a5cf899" name="tests/bson-corpus/decimal128-1-valid-020.phpt" role="test" />
<file md5sum="53f02848dfab7990fd60b1e9d38b67ad" name="tests/bson-corpus/decimal128-1-valid-021.phpt" role="test" />
<file md5sum="4361a2779601eba39c3636fe4083e6aa" name="tests/bson-corpus/decimal128-1-valid-022.phpt" role="test" />
<file md5sum="aa5c274f7340aa5640db649637a2b598" name="tests/bson-corpus/decimal128-1-valid-023.phpt" role="test" />
<file md5sum="cd2d62f86eefa21ed3515cf7331abebc" name="tests/bson-corpus/decimal128-1-valid-024.phpt" role="test" />
<file md5sum="5bc00004cb90af3b3c96d94f874ee0d2" name="tests/bson-corpus/decimal128-1-valid-025.phpt" role="test" />
<file md5sum="fcb960fc23592fae8d2ab1f043fe6d96" name="tests/bson-corpus/decimal128-1-valid-026.phpt" role="test" />
<file md5sum="7b4e7a0b389b795a77b30f955488581d" name="tests/bson-corpus/decimal128-1-valid-027.phpt" role="test" />
<file md5sum="03e0925896672089326dccfb5cdf3bb7" name="tests/bson-corpus/decimal128-1-valid-028.phpt" role="test" />
<file md5sum="7e4e2525f124be41a89a73d26b7918a0" name="tests/bson-corpus/decimal128-1-valid-029.phpt" role="test" />
<file md5sum="975e4fae01096e30dd2f99d8fae7e5ba" name="tests/bson-corpus/decimal128-1-valid-030.phpt" role="test" />
<file md5sum="9082185cf22808c7e69dcb1da3c423d9" name="tests/bson-corpus/decimal128-1-valid-031.phpt" role="test" />
<file md5sum="434f43477c58954f210d1af1fb6588c1" name="tests/bson-corpus/decimal128-1-valid-032.phpt" role="test" />
<file md5sum="a052b5e7678dd60a7c7e7de744c87017" name="tests/bson-corpus/decimal128-1-valid-033.phpt" role="test" />
<file md5sum="613ab4ac14503406b50607c19d273cb8" name="tests/bson-corpus/decimal128-1-valid-034.phpt" role="test" />
<file md5sum="5c0d2131e7acbfaedc525a8f4c4f2d45" name="tests/bson-corpus/decimal128-1-valid-035.phpt" role="test" />
<file md5sum="3fe40e8d661ebc168a849a2c45472477" name="tests/bson-corpus/decimal128-1-valid-036.phpt" role="test" />
<file md5sum="ed25faa820a283907a32e179616f5334" name="tests/bson-corpus/decimal128-1-valid-037.phpt" role="test" />
<file md5sum="8b29111ce0810339305ebb10f2bef961" name="tests/bson-corpus/decimal128-1-valid-038.phpt" role="test" />
<file md5sum="b7a91a4e418cad9b65d56549fadbadc1" name="tests/bson-corpus/decimal128-1-valid-039.phpt" role="test" />
<file md5sum="6bd56aaf565aa7aad486a0c6dd65e65a" name="tests/bson-corpus/decimal128-1-valid-040.phpt" role="test" />
<file md5sum="e676d6b392e18ca3c128e53fcef060d7" name="tests/bson-corpus/decimal128-1-valid-041.phpt" role="test" />
<file md5sum="442a9f5586ada55d3f140dffa1877de6" name="tests/bson-corpus/decimal128-1-valid-042.phpt" role="test" />
<file md5sum="84ea678317f307cb585a66b5cc692a02" name="tests/bson-corpus/decimal128-1-valid-043.phpt" role="test" />
<file md5sum="95d97fe1c10db4b55b011c14eef8a39d" name="tests/bson-corpus/decimal128-1-valid-044.phpt" role="test" />
<file md5sum="403ac53597d14f2ccdede8493c078d2e" name="tests/bson-corpus/decimal128-1-valid-045.phpt" role="test" />
<file md5sum="820b7afdb1489889b589672526912ba4" name="tests/bson-corpus/decimal128-1-valid-046.phpt" role="test" />
<file md5sum="80ee524599f9f7e0642c7b37fd897e09" name="tests/bson-corpus/decimal128-1-valid-047.phpt" role="test" />
<file md5sum="d8f2a7e25e4008b5d7819cd8b678fcb9" name="tests/bson-corpus/decimal128-1-valid-048.phpt" role="test" />
<file md5sum="c238495574eeedc4cf8fd00573ea905e" name="tests/bson-corpus/decimal128-1-valid-049.phpt" role="test" />
<file md5sum="0b0973d7ea834026c163a2011fbeb080" name="tests/bson-corpus/decimal128-1-valid-050.phpt" role="test" />
<file md5sum="ec24828ca55a2bda0a2d66505b64936d" name="tests/bson-corpus/decimal128-1-valid-051.phpt" role="test" />
<file md5sum="729441ba04ae3012c56930d4096717c5" name="tests/bson-corpus/decimal128-1-valid-052.phpt" role="test" />
<file md5sum="8f95866d1d16ab43e97c7f2faa57ea28" name="tests/bson-corpus/decimal128-1-valid-053.phpt" role="test" />
<file md5sum="c37788e500a3ffd5e4fe9de2c7beb8d2" name="tests/bson-corpus/decimal128-1-valid-054.phpt" role="test" />
<file md5sum="75284b0772f6c51e3ddfac7b54b690fc" name="tests/bson-corpus/decimal128-1-valid-055.phpt" role="test" />
<file md5sum="195bb4db3fe142ea2a5c18f42511fb98" name="tests/bson-corpus/decimal128-1-valid-056.phpt" role="test" />
<file md5sum="ee3b5cfa0a47ab7816934bb3d910f865" name="tests/bson-corpus/decimal128-2-valid-001.phpt" role="test" />
<file md5sum="5e408cdeb8c9bd64821c2036e297074b" name="tests/bson-corpus/decimal128-2-valid-002.phpt" role="test" />
<file md5sum="14d41a31977b7f3f3117846057ba2601" name="tests/bson-corpus/decimal128-2-valid-003.phpt" role="test" />
<file md5sum="b18a1b7373ede0724f2419af2589ba2c" name="tests/bson-corpus/decimal128-2-valid-004.phpt" role="test" />
<file md5sum="66ff234efe9a92930a955012376426a8" name="tests/bson-corpus/decimal128-2-valid-005.phpt" role="test" />
<file md5sum="2ebc1553235eb6940c8eb52511ffaa20" name="tests/bson-corpus/decimal128-2-valid-006.phpt" role="test" />
<file md5sum="5b3c244258cc82c1518d8921c5968629" name="tests/bson-corpus/decimal128-2-valid-007.phpt" role="test" />
<file md5sum="37c5c0137ab212c29589fbc3f933b6e8" name="tests/bson-corpus/decimal128-2-valid-008.phpt" role="test" />
<file md5sum="0161b23d856375b66b5c609a0c11ab40" name="tests/bson-corpus/decimal128-2-valid-009.phpt" role="test" />
<file md5sum="b9a07e0062873f860c2bc4883ef61bea" name="tests/bson-corpus/decimal128-2-valid-010.phpt" role="test" />
<file md5sum="0d2c193c752e22363784d7f3fe8223cd" name="tests/bson-corpus/decimal128-2-valid-011.phpt" role="test" />
<file md5sum="2bbf62a4f860531f268664ccc1ff04a7" name="tests/bson-corpus/decimal128-2-valid-012.phpt" role="test" />
<file md5sum="8c7793815244ce46beb792fff2d5d9b2" name="tests/bson-corpus/decimal128-2-valid-013.phpt" role="test" />
<file md5sum="a018ded9ca70adae810dd2a6e1e73ac0" name="tests/bson-corpus/decimal128-2-valid-014.phpt" role="test" />
<file md5sum="33c3d1896d9a523f0dc3a6d17c7cd672" name="tests/bson-corpus/decimal128-2-valid-015.phpt" role="test" />
<file md5sum="cee62aa6daacce199f4bcff29baaa770" name="tests/bson-corpus/decimal128-2-valid-016.phpt" role="test" />
<file md5sum="8fb1a596f198f8dca07ad897ba785c44" name="tests/bson-corpus/decimal128-2-valid-017.phpt" role="test" />
<file md5sum="0446235e9a03299e5056cc02af33710c" name="tests/bson-corpus/decimal128-2-valid-018.phpt" role="test" />
<file md5sum="18f5d9e1b47d4a616382b538a8c96748" name="tests/bson-corpus/decimal128-2-valid-019.phpt" role="test" />
<file md5sum="7687301937038736b52fabce10c4318d" name="tests/bson-corpus/decimal128-2-valid-020.phpt" role="test" />
<file md5sum="f4e793063b75e6bdc63417fda9693333" name="tests/bson-corpus/decimal128-2-valid-021.phpt" role="test" />
<file md5sum="9402b1bb065a1cd7e86b4926bf66b465" name="tests/bson-corpus/decimal128-2-valid-022.phpt" role="test" />
<file md5sum="419293525c66ae26d2b20bb543814df4" name="tests/bson-corpus/decimal128-2-valid-023.phpt" role="test" />
<file md5sum="2175c57d8e8cb92126c4c92b0ccfc488" name="tests/bson-corpus/decimal128-2-valid-024.phpt" role="test" />
<file md5sum="0b1133406d9c82e15b84b85237be2bed" name="tests/bson-corpus/decimal128-2-valid-025.phpt" role="test" />
<file md5sum="d466e879d9363723795783b4c4eb47ff" name="tests/bson-corpus/decimal128-2-valid-026.phpt" role="test" />
<file md5sum="af2cd17bc30e18cbf53f942d8f362b47" name="tests/bson-corpus/decimal128-2-valid-027.phpt" role="test" />
<file md5sum="6fbbd48bb5eb9f930e85fad5bead1519" name="tests/bson-corpus/decimal128-2-valid-028.phpt" role="test" />
<file md5sum="15798456fa5e0d6452f1083b1fc5807b" name="tests/bson-corpus/decimal128-2-valid-029.phpt" role="test" />
<file md5sum="de2f22e66df859f1013a9cfadfd6ba98" name="tests/bson-corpus/decimal128-2-valid-030.phpt" role="test" />
<file md5sum="7eea0cf3baacbf61664f9d4daebcaba0" name="tests/bson-corpus/decimal128-2-valid-031.phpt" role="test" />
<file md5sum="8854ca1f4536973749715dd8fc29c9da" name="tests/bson-corpus/decimal128-2-valid-032.phpt" role="test" />
<file md5sum="7804c313c8e262224e2786cd658c5dfb" name="tests/bson-corpus/decimal128-2-valid-033.phpt" role="test" />
<file md5sum="ecfcceb6d572ecc43d8f51f7b461052a" name="tests/bson-corpus/decimal128-2-valid-034.phpt" role="test" />
<file md5sum="795cb7a559a455790f48b8d7099657e2" name="tests/bson-corpus/decimal128-2-valid-035.phpt" role="test" />
<file md5sum="5294b8700c5b184ceeab7e3fdac9ac09" name="tests/bson-corpus/decimal128-2-valid-036.phpt" role="test" />
<file md5sum="fa8c1f8e2471b1e88f70494e3d43a2a3" name="tests/bson-corpus/decimal128-2-valid-037.phpt" role="test" />
<file md5sum="b26ceb09c9c9fb679ce2ae070b46e440" name="tests/bson-corpus/decimal128-2-valid-038.phpt" role="test" />
<file md5sum="930c0a170ba388984e21ccc62befaa17" name="tests/bson-corpus/decimal128-2-valid-039.phpt" role="test" />
<file md5sum="1fc738e64b9cadd5508a6eef087e9e6a" name="tests/bson-corpus/decimal128-2-valid-040.phpt" role="test" />
<file md5sum="fd7e38aa78b293c936e6e30916154be2" name="tests/bson-corpus/decimal128-2-valid-041.phpt" role="test" />
<file md5sum="f1a6c263b9f19ca118927987a3a3e960" name="tests/bson-corpus/decimal128-2-valid-042.phpt" role="test" />
<file md5sum="dce7e447bd22e0e1b6ca368a0126f6c9" name="tests/bson-corpus/decimal128-2-valid-043.phpt" role="test" />
<file md5sum="5250c400c16366276e85dd3a84a68464" name="tests/bson-corpus/decimal128-2-valid-044.phpt" role="test" />
<file md5sum="d8ed4f32c9f21737c3db57d2ff9f517d" name="tests/bson-corpus/decimal128-2-valid-045.phpt" role="test" />
<file md5sum="8da310bcd5248f1a4c788e57292fcbf3" name="tests/bson-corpus/decimal128-2-valid-046.phpt" role="test" />
<file md5sum="b78100f032f9b07917f03f6f43b27032" name="tests/bson-corpus/decimal128-2-valid-047.phpt" role="test" />
<file md5sum="fb9958f291c703f5c29a7f5572db3bcc" name="tests/bson-corpus/decimal128-2-valid-048.phpt" role="test" />
<file md5sum="39f6a9f651550909f54aba9ce62ee4c5" name="tests/bson-corpus/decimal128-2-valid-049.phpt" role="test" />
<file md5sum="de192bf93dc79e402aa334f45ba18b1e" name="tests/bson-corpus/decimal128-2-valid-050.phpt" role="test" />
<file md5sum="3d67788e6781992107655e299446eddb" name="tests/bson-corpus/decimal128-2-valid-051.phpt" role="test" />
<file md5sum="6e480e0a1b326ce956f40b40fb5ed094" name="tests/bson-corpus/decimal128-2-valid-052.phpt" role="test" />
<file md5sum="b41ce0b1219941d0432219f37a710aa5" name="tests/bson-corpus/decimal128-2-valid-053.phpt" role="test" />
<file md5sum="91b106e513924c9a611bc7a27919ce4b" name="tests/bson-corpus/decimal128-2-valid-054.phpt" role="test" />
<file md5sum="4dfbe9e6347d72e4ba4403e722314b53" name="tests/bson-corpus/decimal128-2-valid-055.phpt" role="test" />
<file md5sum="caf747e3fd2e28b322612199074487dd" name="tests/bson-corpus/decimal128-2-valid-056.phpt" role="test" />
<file md5sum="30424dfa94cdaf355ca52920a787fd10" name="tests/bson-corpus/decimal128-2-valid-057.phpt" role="test" />
<file md5sum="cf94d76866c57ff87907cafeb8fbe7e8" name="tests/bson-corpus/decimal128-2-valid-058.phpt" role="test" />
<file md5sum="48e42590a32c360bb1861b691884c2a0" name="tests/bson-corpus/decimal128-2-valid-059.phpt" role="test" />
<file md5sum="5eb9b793969b6fbf7adc222f285ad250" name="tests/bson-corpus/decimal128-2-valid-060.phpt" role="test" />
<file md5sum="2365af956b837469db89cdbdc8778421" name="tests/bson-corpus/decimal128-2-valid-061.phpt" role="test" />
<file md5sum="91d59d84d2ba39e6ba24ff68221d74f6" name="tests/bson-corpus/decimal128-2-valid-062.phpt" role="test" />
<file md5sum="753a7e1af8e0a2d9975335e8ea3f140a" name="tests/bson-corpus/decimal128-2-valid-063.phpt" role="test" />
<file md5sum="944e77c82029d92d3ff7140cf5dc5018" name="tests/bson-corpus/decimal128-2-valid-064.phpt" role="test" />
<file md5sum="ea6e3558be75757726e0dd2e970c023c" name="tests/bson-corpus/decimal128-2-valid-065.phpt" role="test" />
<file md5sum="ab5c5c8d5cdf13c31212a8b122a1f7d6" name="tests/bson-corpus/decimal128-2-valid-066.phpt" role="test" />
<file md5sum="76a085cd5533ccb41e25c04ce208404d" name="tests/bson-corpus/decimal128-2-valid-067.phpt" role="test" />
<file md5sum="4c038c0004299008f8530ee1905db50a" name="tests/bson-corpus/decimal128-2-valid-068.phpt" role="test" />
<file md5sum="3f5cc49cc6ba45b816028b3cc92d264f" name="tests/bson-corpus/decimal128-2-valid-069.phpt" role="test" />
<file md5sum="a7e88590454ce68e11ae15005f23082e" name="tests/bson-corpus/decimal128-2-valid-070.phpt" role="test" />
<file md5sum="5bae02a95b54fd348d174eb3d85f04eb" name="tests/bson-corpus/decimal128-2-valid-071.phpt" role="test" />
<file md5sum="ebd162d6f711b331e7accc7fa5c1d835" name="tests/bson-corpus/decimal128-2-valid-072.phpt" role="test" />
<file md5sum="d235b6936bfecf314267d9c14953a7d4" name="tests/bson-corpus/decimal128-2-valid-073.phpt" role="test" />
<file md5sum="c5ec17d328828052df60b7584bf38757" name="tests/bson-corpus/decimal128-2-valid-074.phpt" role="test" />
<file md5sum="9ba36e27db6ecb0a0aa936a5b492b0b9" name="tests/bson-corpus/decimal128-2-valid-075.phpt" role="test" />
<file md5sum="fb767d85a2edeae3c8bffa7d5760c10b" name="tests/bson-corpus/decimal128-2-valid-076.phpt" role="test" />
<file md5sum="c6957d607d662ed2cc67330eb10f2402" name="tests/bson-corpus/decimal128-2-valid-077.phpt" role="test" />
<file md5sum="681b2a2936c14f2004c7dec85d01b2e2" name="tests/bson-corpus/decimal128-2-valid-078.phpt" role="test" />
<file md5sum="1b1f27774210373d6afcf151bbb07bca" name="tests/bson-corpus/decimal128-2-valid-079.phpt" role="test" />
<file md5sum="e22ea399a7e6b673efbd0dc4c0888699" name="tests/bson-corpus/decimal128-2-valid-080.phpt" role="test" />
<file md5sum="2788019eba5db7c958a9a1f2535c8c0d" name="tests/bson-corpus/decimal128-2-valid-081.phpt" role="test" />
<file md5sum="e26769d5a2bde67c35f09c10a9de9dbf" name="tests/bson-corpus/decimal128-2-valid-082.phpt" role="test" />
<file md5sum="5dcc949efe0bd05699a5600c8c7171b0" name="tests/bson-corpus/decimal128-2-valid-083.phpt" role="test" />
<file md5sum="0c0e987a3230f753fe95372c7f90a32b" name="tests/bson-corpus/decimal128-2-valid-084.phpt" role="test" />
<file md5sum="66c6528d392928c73aaee101bab0d4e7" name="tests/bson-corpus/decimal128-2-valid-085.phpt" role="test" />
<file md5sum="4b4c6033d1cc69584ddc02d2cb61679c" name="tests/bson-corpus/decimal128-2-valid-086.phpt" role="test" />
<file md5sum="9fef33369778b3b31af02f918bc940d1" name="tests/bson-corpus/decimal128-2-valid-087.phpt" role="test" />
<file md5sum="83571d78ab83eb7d6f26039c06392f61" name="tests/bson-corpus/decimal128-2-valid-088.phpt" role="test" />
<file md5sum="6f3abc25b06b28dd814748aefe26fbee" name="tests/bson-corpus/decimal128-2-valid-089.phpt" role="test" />
<file md5sum="4bdd4a38167e036b0edc16fef1d0d7c0" name="tests/bson-corpus/decimal128-2-valid-090.phpt" role="test" />
<file md5sum="f70773da403b020c400324ad86a7cef0" name="tests/bson-corpus/decimal128-2-valid-091.phpt" role="test" />
<file md5sum="3b10869e9ebff2e3fe99adeb0932fb1c" name="tests/bson-corpus/decimal128-2-valid-092.phpt" role="test" />
<file md5sum="0341f9cca69ca88f914acfa9c0b11dcd" name="tests/bson-corpus/decimal128-2-valid-093.phpt" role="test" />
<file md5sum="5dd6ebcbd16e2d783fb924bc0168ced7" name="tests/bson-corpus/decimal128-2-valid-094.phpt" role="test" />
<file md5sum="be4a8b9bec6e5e94d77ff089ff1d0ee1" name="tests/bson-corpus/decimal128-2-valid-095.phpt" role="test" />
<file md5sum="442195cc8ef85c91e2fbef49122e628e" name="tests/bson-corpus/decimal128-2-valid-096.phpt" role="test" />
<file md5sum="7b92d8695368b4974328d3bf221e46be" name="tests/bson-corpus/decimal128-2-valid-097.phpt" role="test" />
<file md5sum="2e3ff697a3a2abd7b9ec13e52358ebb3" name="tests/bson-corpus/decimal128-2-valid-098.phpt" role="test" />
<file md5sum="ec685a2e20a0ec15f6bf3ff73f360d85" name="tests/bson-corpus/decimal128-2-valid-099.phpt" role="test" />
<file md5sum="4201a63bfd136d7e662938f67dd05254" name="tests/bson-corpus/decimal128-2-valid-100.phpt" role="test" />
<file md5sum="2d08081f184061e053ebc445e5b8cd24" name="tests/bson-corpus/decimal128-2-valid-101.phpt" role="test" />
<file md5sum="3a6ff963db42fcf64206e2de4ee780cc" name="tests/bson-corpus/decimal128-2-valid-102.phpt" role="test" />
<file md5sum="540d5b91603c7357e8d89824d5719737" name="tests/bson-corpus/decimal128-2-valid-103.phpt" role="test" />
<file md5sum="796fc26fd08560613f19d9083e020338" name="tests/bson-corpus/decimal128-2-valid-104.phpt" role="test" />
<file md5sum="49df24fb744715760e55787d0957b5de" name="tests/bson-corpus/decimal128-2-valid-105.phpt" role="test" />
<file md5sum="66855ccf81d802eb68391b0807feedaf" name="tests/bson-corpus/decimal128-2-valid-106.phpt" role="test" />
<file md5sum="bbba9d352a373a719ccbe406d96ca835" name="tests/bson-corpus/decimal128-2-valid-107.phpt" role="test" />
<file md5sum="52d7e75eec143dd82f2c90ef5d20dd73" name="tests/bson-corpus/decimal128-2-valid-108.phpt" role="test" />
<file md5sum="b111889617eac3398d98dc2847efa454" name="tests/bson-corpus/decimal128-2-valid-109.phpt" role="test" />
<file md5sum="25202c94a851caaa78be7cc01d338083" name="tests/bson-corpus/decimal128-2-valid-110.phpt" role="test" />
<file md5sum="ac6afaac7a362f5418c78734fd34e8c0" name="tests/bson-corpus/decimal128-2-valid-111.phpt" role="test" />
<file md5sum="b5900c5ed1adec986f86fa21bd0da84f" name="tests/bson-corpus/decimal128-2-valid-112.phpt" role="test" />
<file md5sum="9cefd97e411d3ca7612875f1dc156f90" name="tests/bson-corpus/decimal128-2-valid-113.phpt" role="test" />
<file md5sum="8aae5fee09f7e8a17a69c47bd1fee75e" name="tests/bson-corpus/decimal128-2-valid-114.phpt" role="test" />
<file md5sum="e65ebb960f782a5013d39baaed48d41e" name="tests/bson-corpus/decimal128-2-valid-115.phpt" role="test" />
<file md5sum="cac712953a826fb899b728b30e3cea8d" name="tests/bson-corpus/decimal128-2-valid-116.phpt" role="test" />
<file md5sum="eff59a7472ca181c00839c6c7d87bd82" name="tests/bson-corpus/decimal128-2-valid-117.phpt" role="test" />
<file md5sum="9320d637ed82864d61562da53a374d0a" name="tests/bson-corpus/decimal128-2-valid-118.phpt" role="test" />
<file md5sum="5850b1ff7d5c26da1468534752e98ea3" name="tests/bson-corpus/decimal128-2-valid-119.phpt" role="test" />
<file md5sum="5dcf443d0ccc15b32aa834069fa6c412" name="tests/bson-corpus/decimal128-2-valid-120.phpt" role="test" />
<file md5sum="f85faa8be07f8d8173eb072a0570dc0e" name="tests/bson-corpus/decimal128-2-valid-121.phpt" role="test" />
<file md5sum="573c4ccdfad6c9f0f59360c986ebd2c9" name="tests/bson-corpus/decimal128-2-valid-122.phpt" role="test" />
<file md5sum="82c51a7042011e90499bf8170f28952d" name="tests/bson-corpus/decimal128-2-valid-123.phpt" role="test" />
<file md5sum="b0d78129713054d1c026f070c1ba0dad" name="tests/bson-corpus/decimal128-2-valid-124.phpt" role="test" />
<file md5sum="971f60d5191b863bd465b8cfe99fbb81" name="tests/bson-corpus/decimal128-2-valid-125.phpt" role="test" />
<file md5sum="008c8b511828b32f4345e74f432f57a1" name="tests/bson-corpus/decimal128-2-valid-126.phpt" role="test" />
<file md5sum="84014477bceff0f8d732a34e91400663" name="tests/bson-corpus/decimal128-2-valid-127.phpt" role="test" />
<file md5sum="aa3df20a486284805f6633f613f4ff9c" name="tests/bson-corpus/decimal128-2-valid-128.phpt" role="test" />
<file md5sum="8a0bb497bfac2faa7cee23cdc8d8a2c3" name="tests/bson-corpus/decimal128-2-valid-129.phpt" role="test" />
<file md5sum="e880542c707e7fc3a0bb82ff519213ac" name="tests/bson-corpus/decimal128-2-valid-130.phpt" role="test" />
<file md5sum="553bf9e872800102f95acd398629af64" name="tests/bson-corpus/decimal128-2-valid-131.phpt" role="test" />
<file md5sum="77a7bcbcba9bd363342d9c7b830fae34" name="tests/bson-corpus/decimal128-2-valid-132.phpt" role="test" />
<file md5sum="cff1328a6288da15f9350b68f8c5d489" name="tests/bson-corpus/decimal128-2-valid-133.phpt" role="test" />
<file md5sum="0ee8ae38952b950651a7b43a57b8c60b" name="tests/bson-corpus/decimal128-2-valid-134.phpt" role="test" />
<file md5sum="1ea5f4d4114b0706a6b8bd4ad46179c6" name="tests/bson-corpus/decimal128-2-valid-135.phpt" role="test" />
<file md5sum="6330096fc3283f7ef5136caafa57b1bd" name="tests/bson-corpus/decimal128-2-valid-136.phpt" role="test" />
<file md5sum="e6c4f50ff19a3e501ca6b573f3f47825" name="tests/bson-corpus/decimal128-2-valid-137.phpt" role="test" />
<file md5sum="e3a7756627e40c90117bbd3e7e8d17a2" name="tests/bson-corpus/decimal128-2-valid-138.phpt" role="test" />
<file md5sum="ba8acc01b63d6e8dd109c4c7997e2c6c" name="tests/bson-corpus/decimal128-2-valid-139.phpt" role="test" />
<file md5sum="7fab66eb8d2f53b33375a0013a955d26" name="tests/bson-corpus/decimal128-2-valid-140.phpt" role="test" />
<file md5sum="9f169b5e4371cbe24c056973cde84831" name="tests/bson-corpus/decimal128-2-valid-141.phpt" role="test" />
<file md5sum="d5dfc064d6f4e5e448f42bd730fed054" name="tests/bson-corpus/decimal128-2-valid-142.phpt" role="test" />
<file md5sum="fe97ba097b1d594eb1a09cd106a11854" name="tests/bson-corpus/decimal128-2-valid-143.phpt" role="test" />
<file md5sum="867c2c7530dd452ba36f0fa0d7022d91" name="tests/bson-corpus/decimal128-2-valid-144.phpt" role="test" />
<file md5sum="0bbc6e5d9a03298d265a72bddb8076b0" name="tests/bson-corpus/decimal128-2-valid-145.phpt" role="test" />
<file md5sum="b4ba690f01910bca2af1d00954d80a9d" name="tests/bson-corpus/decimal128-2-valid-146.phpt" role="test" />
<file md5sum="ea231b7006051408759096f712705fd7" name="tests/bson-corpus/decimal128-2-valid-147.phpt" role="test" />
<file md5sum="df997d34321d8620ff8a35d810fd9b02" name="tests/bson-corpus/decimal128-2-valid-148.phpt" role="test" />
<file md5sum="d4479dfa2cc526a133799b5e625181c3" name="tests/bson-corpus/decimal128-2-valid-149.phpt" role="test" />
<file md5sum="a6a1e66f9c931b707885f8d094500ac9" name="tests/bson-corpus/decimal128-2-valid-150.phpt" role="test" />
<file md5sum="3c92721f8d215a7c3fea8ac667706fba" name="tests/bson-corpus/decimal128-2-valid-151.phpt" role="test" />
<file md5sum="8fd7c1533b61fe6eca0e58ea4a017cab" name="tests/bson-corpus/decimal128-2-valid-152.phpt" role="test" />
<file md5sum="9748fe4d36fc0ceb9e72eb929748d760" name="tests/bson-corpus/decimal128-2-valid-153.phpt" role="test" />
<file md5sum="8d6cb5244dd36b26cf92648de850307b" name="tests/bson-corpus/decimal128-2-valid-154.phpt" role="test" />
<file md5sum="d9f95167b0f45e34bf472a405bb2cf11" name="tests/bson-corpus/decimal128-2-valid-155.phpt" role="test" />
<file md5sum="d8a54fba958ab819f07e0addec0b977f" name="tests/bson-corpus/decimal128-2-valid-156.phpt" role="test" />
<file md5sum="070b469361b80b8229357d23555aaf63" name="tests/bson-corpus/decimal128-2-valid-157.phpt" role="test" />
<file md5sum="34ce63d06e50aa4944679b48de0de335" name="tests/bson-corpus/decimal128-3-valid-001.phpt" role="test" />
<file md5sum="df328c1d2158b658942dce1a4c5bdfce" name="tests/bson-corpus/decimal128-3-valid-002.phpt" role="test" />
<file md5sum="9bcf947760c6bb9a958234bc41afd4f4" name="tests/bson-corpus/decimal128-3-valid-003.phpt" role="test" />
<file md5sum="180a4302dd151247a9a37cb5ce9d5d47" name="tests/bson-corpus/decimal128-3-valid-004.phpt" role="test" />
<file md5sum="54b812360f1de0b104455a39c8889c9e" name="tests/bson-corpus/decimal128-3-valid-005.phpt" role="test" />
<file md5sum="9f7c80841aacca871904857d6710cfa3" name="tests/bson-corpus/decimal128-3-valid-006.phpt" role="test" />
<file md5sum="0293d8c4c2123f53c819c27730d86197" name="tests/bson-corpus/decimal128-3-valid-007.phpt" role="test" />
<file md5sum="60e423b7c4a59f10532f6e10caf6e0ac" name="tests/bson-corpus/decimal128-3-valid-008.phpt" role="test" />
<file md5sum="e19c736e10533f9fe6998ae25081d21c" name="tests/bson-corpus/decimal128-3-valid-009.phpt" role="test" />
<file md5sum="965acf5ad70ef683da051811f71ad0bd" name="tests/bson-corpus/decimal128-3-valid-010.phpt" role="test" />
<file md5sum="628c029a7d5c3d51b9d669f11741703e" name="tests/bson-corpus/decimal128-3-valid-011.phpt" role="test" />
<file md5sum="05198752b5da78889234ed05f1be6993" name="tests/bson-corpus/decimal128-3-valid-012.phpt" role="test" />
<file md5sum="2a19fe2d928be479d4da0d7b5fe8005f" name="tests/bson-corpus/decimal128-3-valid-013.phpt" role="test" />
<file md5sum="3af90adbafbaa424d7b9f9318ff6db94" name="tests/bson-corpus/decimal128-3-valid-014.phpt" role="test" />
<file md5sum="52114773cfeb41974cefc54e33ffa9fa" name="tests/bson-corpus/decimal128-3-valid-015.phpt" role="test" />
<file md5sum="7076c929dbc5f535627e251811cb7187" name="tests/bson-corpus/decimal128-3-valid-016.phpt" role="test" />
<file md5sum="e17cda3744c02f6a62114f0b9227ab49" name="tests/bson-corpus/decimal128-3-valid-017.phpt" role="test" />
<file md5sum="61c8d58565c8d1224a9c0676d5513b4b" name="tests/bson-corpus/decimal128-3-valid-018.phpt" role="test" />
<file md5sum="3baacae5cfebaa97ea82b6b86ca7f67f" name="tests/bson-corpus/decimal128-3-valid-019.phpt" role="test" />
<file md5sum="6f0d7886b289c38462f5d73bab69429d" name="tests/bson-corpus/decimal128-3-valid-020.phpt" role="test" />
<file md5sum="31733bfe4a02fd610b308f6ec295e011" name="tests/bson-corpus/decimal128-3-valid-021.phpt" role="test" />
<file md5sum="848c7632ba9b923bf87fc62bd9f7d950" name="tests/bson-corpus/decimal128-3-valid-022.phpt" role="test" />
<file md5sum="318f52f20af58648b597e5a0a84cb502" name="tests/bson-corpus/decimal128-3-valid-023.phpt" role="test" />
<file md5sum="601d7464591e31244bf866bb08ed22b7" name="tests/bson-corpus/decimal128-3-valid-024.phpt" role="test" />
<file md5sum="e8fff68562159a22cb3dd1cc18da37ae" name="tests/bson-corpus/decimal128-3-valid-025.phpt" role="test" />
<file md5sum="1b3494487358e1a4f21d63a246e4d1d1" name="tests/bson-corpus/decimal128-3-valid-026.phpt" role="test" />
<file md5sum="890ab1774515db8761dc156430f8d85c" name="tests/bson-corpus/decimal128-3-valid-027.phpt" role="test" />
<file md5sum="e3eadea00725f55269ffca85c5f8c008" name="tests/bson-corpus/decimal128-3-valid-028.phpt" role="test" />
<file md5sum="8fbb4f5ca491b489e81a7ce09d3949cb" name="tests/bson-corpus/decimal128-3-valid-029.phpt" role="test" />
<file md5sum="f47494ab7e679e8818e1d6859bd5f127" name="tests/bson-corpus/decimal128-3-valid-030.phpt" role="test" />
<file md5sum="2684997e4eb6f61274bf887accfeed4a" name="tests/bson-corpus/decimal128-3-valid-031.phpt" role="test" />
<file md5sum="994338eb57c4179dd912901548d1f8ec" name="tests/bson-corpus/decimal128-3-valid-032.phpt" role="test" />
<file md5sum="819721414a29a06d9955b0cad0f2125d" name="tests/bson-corpus/decimal128-3-valid-033.phpt" role="test" />
<file md5sum="365a51312afc80e0fb501150c29e6459" name="tests/bson-corpus/decimal128-3-valid-034.phpt" role="test" />
<file md5sum="e7a0116a4a1cc5505da6a5d9b57dabac" name="tests/bson-corpus/decimal128-3-valid-035.phpt" role="test" />
<file md5sum="367042b8bc7cbc069a12e467b4ee808f" name="tests/bson-corpus/decimal128-3-valid-036.phpt" role="test" />
<file md5sum="81a942f5107c4ff31de391acb675238a" name="tests/bson-corpus/decimal128-3-valid-037.phpt" role="test" />
<file md5sum="18a0462849355e6152bfe9730c85bd62" name="tests/bson-corpus/decimal128-3-valid-038.phpt" role="test" />
<file md5sum="9ac0dbafb449b20c8d4577134b3426b6" name="tests/bson-corpus/decimal128-3-valid-039.phpt" role="test" />
<file md5sum="90ebcac3ae67c235aeb5238e1f4ec133" name="tests/bson-corpus/decimal128-3-valid-040.phpt" role="test" />
<file md5sum="6251fd1a5f9e2c7fd74dfa63bbd62d7a" name="tests/bson-corpus/decimal128-3-valid-041.phpt" role="test" />
<file md5sum="cca47ea381a8738e7b0099f460f2f8c0" name="tests/bson-corpus/decimal128-3-valid-042.phpt" role="test" />
<file md5sum="f637d2f9517908f27030e3660196515b" name="tests/bson-corpus/decimal128-3-valid-043.phpt" role="test" />
<file md5sum="bde96730654b79fd7b4078b07d282eef" name="tests/bson-corpus/decimal128-3-valid-044.phpt" role="test" />
<file md5sum="ee71d0f43cd2f467813ca6a77dcf2d30" name="tests/bson-corpus/decimal128-3-valid-045.phpt" role="test" />
<file md5sum="ff0e3aad7b641672842c802c49a958d6" name="tests/bson-corpus/decimal128-3-valid-046.phpt" role="test" />
<file md5sum="94b54b1fb76f4b0eff34f4eb0e9f4405" name="tests/bson-corpus/decimal128-3-valid-047.phpt" role="test" />
<file md5sum="52044d796ece83c2352f65673b6c1350" name="tests/bson-corpus/decimal128-3-valid-048.phpt" role="test" />
<file md5sum="9ce69dba579892069c0e85917a7c8974" name="tests/bson-corpus/decimal128-3-valid-049.phpt" role="test" />
<file md5sum="d8e88496d162ff5715f5501ef3c18b83" name="tests/bson-corpus/decimal128-3-valid-050.phpt" role="test" />
<file md5sum="bac8d2811e73164fb379d31c0f913247" name="tests/bson-corpus/decimal128-3-valid-051.phpt" role="test" />
<file md5sum="9e5fa37875831ef40eadf3c56ce823f2" name="tests/bson-corpus/decimal128-3-valid-052.phpt" role="test" />
<file md5sum="798796c56a13185581d5ae58a64dbd46" name="tests/bson-corpus/decimal128-3-valid-053.phpt" role="test" />
<file md5sum="29745eb4e3008772f3eb96a8eb9cee74" name="tests/bson-corpus/decimal128-3-valid-054.phpt" role="test" />
<file md5sum="0d53d0dca5f8ef56e07f74b9961c9de5" name="tests/bson-corpus/decimal128-3-valid-055.phpt" role="test" />
<file md5sum="369f39cc9176e7e5bf7771a5f41ee635" name="tests/bson-corpus/decimal128-3-valid-056.phpt" role="test" />
<file md5sum="a5755fd2f1fd412503a52a8e71822f58" name="tests/bson-corpus/decimal128-3-valid-057.phpt" role="test" />
<file md5sum="e70940764cd396ac7ba9ceca6869ae6c" name="tests/bson-corpus/decimal128-3-valid-058.phpt" role="test" />
<file md5sum="81f941b52e9fb46279be381b17cd3382" name="tests/bson-corpus/decimal128-3-valid-059.phpt" role="test" />
<file md5sum="34a9bfac2faf455c77e2eacff967eeac" name="tests/bson-corpus/decimal128-3-valid-060.phpt" role="test" />
<file md5sum="359126abd17081eff11ce85b77b520f7" name="tests/bson-corpus/decimal128-3-valid-061.phpt" role="test" />
<file md5sum="a648faf4b3d80ba1cfdc9babc6d1f2f4" name="tests/bson-corpus/decimal128-3-valid-062.phpt" role="test" />
<file md5sum="ca9b3b5c19c652c7458b47d5d31d993c" name="tests/bson-corpus/decimal128-3-valid-063.phpt" role="test" />
<file md5sum="476611f8de079cfd73a8ad165827b1e3" name="tests/bson-corpus/decimal128-3-valid-064.phpt" role="test" />
<file md5sum="bb4d8b42a95eeff6952cf123aa8c50f7" name="tests/bson-corpus/decimal128-3-valid-065.phpt" role="test" />
<file md5sum="1e49a8bddd4fb5d856a8946bfddedc72" name="tests/bson-corpus/decimal128-3-valid-066.phpt" role="test" />
<file md5sum="63b3f358f5e98d0b14d8533570b94fbe" name="tests/bson-corpus/decimal128-3-valid-067.phpt" role="test" />
<file md5sum="d7c9b5b0837ed0c9072a43c23f0ea79d" name="tests/bson-corpus/decimal128-3-valid-068.phpt" role="test" />
<file md5sum="91642a109e973cb5ae8a6e73b8b383e5" name="tests/bson-corpus/decimal128-3-valid-069.phpt" role="test" />
<file md5sum="2315a5f9acac305bd8c5b95b3e0504f1" name="tests/bson-corpus/decimal128-3-valid-070.phpt" role="test" />
<file md5sum="d9d4d7744a2f7fd8a1503a3052db4ced" name="tests/bson-corpus/decimal128-3-valid-071.phpt" role="test" />
<file md5sum="bf0656069ff0056699c12f9efafd1fdc" name="tests/bson-corpus/decimal128-3-valid-072.phpt" role="test" />
<file md5sum="43fdb9db13d73a584253c80048aca85e" name="tests/bson-corpus/decimal128-3-valid-073.phpt" role="test" />
<file md5sum="7f01cc48402ce9aa550f47f0085f5be6" name="tests/bson-corpus/decimal128-3-valid-074.phpt" role="test" />
<file md5sum="56e888b90bb6d68d36a3420ab40fa2a2" name="tests/bson-corpus/decimal128-3-valid-075.phpt" role="test" />
<file md5sum="c4747e234d72b0e9cf83de75e6e4596b" name="tests/bson-corpus/decimal128-3-valid-076.phpt" role="test" />
<file md5sum="253e370c0292e398e2e2df3722030754" name="tests/bson-corpus/decimal128-3-valid-077.phpt" role="test" />
<file md5sum="09da81d16a25a265188a09240668d394" name="tests/bson-corpus/decimal128-3-valid-078.phpt" role="test" />
<file md5sum="9cf3e496ab05c2adfc02c39330a7445a" name="tests/bson-corpus/decimal128-3-valid-079.phpt" role="test" />
<file md5sum="0518d4e8c881748990645a167f4f36cf" name="tests/bson-corpus/decimal128-3-valid-080.phpt" role="test" />
<file md5sum="08eb0d3cad6adbb15a79456bfb2f026b" name="tests/bson-corpus/decimal128-3-valid-081.phpt" role="test" />
<file md5sum="d6cb12e7bda8e841448e93b789b52dd6" name="tests/bson-corpus/decimal128-3-valid-082.phpt" role="test" />
<file md5sum="bac369bafd38e7fafa2ba592e5d30489" name="tests/bson-corpus/decimal128-3-valid-083.phpt" role="test" />
<file md5sum="7a48888dc58dbf811db159d2c10c843c" name="tests/bson-corpus/decimal128-3-valid-084.phpt" role="test" />
<file md5sum="8e23f78cdac0b401de8262c3af50e356" name="tests/bson-corpus/decimal128-3-valid-085.phpt" role="test" />
<file md5sum="be50c0aebd85dcbef025970c46cd913d" name="tests/bson-corpus/decimal128-3-valid-086.phpt" role="test" />
<file md5sum="6751c5d768d4d52661269ece902566e1" name="tests/bson-corpus/decimal128-3-valid-087.phpt" role="test" />
<file md5sum="9878d291035d1dc914bc82e1b5d5c584" name="tests/bson-corpus/decimal128-3-valid-088.phpt" role="test" />
<file md5sum="0542decc55be115b2398094ae114ccc8" name="tests/bson-corpus/decimal128-3-valid-089.phpt" role="test" />
<file md5sum="11e1ae724b83903286609d49928fd9d2" name="tests/bson-corpus/decimal128-3-valid-090.phpt" role="test" />
<file md5sum="69676108995b60008c71a704eede26ce" name="tests/bson-corpus/decimal128-3-valid-091.phpt" role="test" />
<file md5sum="73e811163a049f29878895044bc62a9d" name="tests/bson-corpus/decimal128-3-valid-092.phpt" role="test" />
<file md5sum="f6ac7fd403b04684561c9fad043fc8ea" name="tests/bson-corpus/decimal128-3-valid-093.phpt" role="test" />
<file md5sum="a8313d3d58d2d86ba3bc65e6ce8a4d26" name="tests/bson-corpus/decimal128-3-valid-094.phpt" role="test" />
<file md5sum="2b5f4bf73e72166bdeeeadee235524c4" name="tests/bson-corpus/decimal128-3-valid-095.phpt" role="test" />
<file md5sum="702c6144e3119b48c504f400434b9937" name="tests/bson-corpus/decimal128-3-valid-096.phpt" role="test" />
<file md5sum="f1956970c8ad095e2121cababaad4374" name="tests/bson-corpus/decimal128-3-valid-097.phpt" role="test" />
<file md5sum="c0d39b7a047fb6e79db8e8499acf7975" name="tests/bson-corpus/decimal128-3-valid-098.phpt" role="test" />
<file md5sum="cd6605d45f8b50e1b912601c225b5aaa" name="tests/bson-corpus/decimal128-3-valid-099.phpt" role="test" />
<file md5sum="3ae675145aa2e4fab775942feee47abd" name="tests/bson-corpus/decimal128-3-valid-100.phpt" role="test" />
<file md5sum="3b464a872ae34247bdc420a98e8b0ed0" name="tests/bson-corpus/decimal128-3-valid-101.phpt" role="test" />
<file md5sum="9ad48a9a8204c467f69b4513974b424d" name="tests/bson-corpus/decimal128-3-valid-102.phpt" role="test" />
<file md5sum="ad81004f6f6dde066f37f2518d4276ad" name="tests/bson-corpus/decimal128-3-valid-103.phpt" role="test" />
<file md5sum="8605780af705eed39e0a63687fbfabf8" name="tests/bson-corpus/decimal128-3-valid-104.phpt" role="test" />
<file md5sum="03bd099aae2cd95304891a2024078d95" name="tests/bson-corpus/decimal128-3-valid-105.phpt" role="test" />
<file md5sum="9b8753f1a0c682afc798e26f9bb7438c" name="tests/bson-corpus/decimal128-3-valid-106.phpt" role="test" />
<file md5sum="287d867a9177b14f4a79675fe7de3a63" name="tests/bson-corpus/decimal128-3-valid-107.phpt" role="test" />
<file md5sum="1fe640b7c1ce4fb9f1434668f924d291" name="tests/bson-corpus/decimal128-3-valid-108.phpt" role="test" />
<file md5sum="04f4c79344465d3b97bf06af70f50fc9" name="tests/bson-corpus/decimal128-3-valid-109.phpt" role="test" />
<file md5sum="135e27eb2013c1020a281dc274b5c5ad" name="tests/bson-corpus/decimal128-3-valid-110.phpt" role="test" />
<file md5sum="b5b913cd09fa92954ef0f733ea75d034" name="tests/bson-corpus/decimal128-3-valid-111.phpt" role="test" />
<file md5sum="5450dae06e8644a656e50f63aca7a59d" name="tests/bson-corpus/decimal128-3-valid-112.phpt" role="test" />
<file md5sum="95d5dd6366600afad79399eadbf02d45" name="tests/bson-corpus/decimal128-3-valid-113.phpt" role="test" />
<file md5sum="804eefe67a94dc093096379149d830ef" name="tests/bson-corpus/decimal128-3-valid-114.phpt" role="test" />
<file md5sum="b2216f79aa2963b8125dc9255c216e9c" name="tests/bson-corpus/decimal128-3-valid-115.phpt" role="test" />
<file md5sum="bcb72d39f0bbf6be1232811ada8b5452" name="tests/bson-corpus/decimal128-3-valid-116.phpt" role="test" />
<file md5sum="9294200386f7d81ade24785c6adc6a4e" name="tests/bson-corpus/decimal128-3-valid-117.phpt" role="test" />
<file md5sum="c2bba821bc6d48e512d277a8f9641e4e" name="tests/bson-corpus/decimal128-3-valid-118.phpt" role="test" />
<file md5sum="6d0de9a32d83136fc3a6db0ca8783c6f" name="tests/bson-corpus/decimal128-3-valid-119.phpt" role="test" />
<file md5sum="f870f22e48817f120623476ff39a9d5c" name="tests/bson-corpus/decimal128-3-valid-120.phpt" role="test" />
<file md5sum="2b71fd8e044c4aa5874e789b4f8cacb6" name="tests/bson-corpus/decimal128-3-valid-121.phpt" role="test" />
<file md5sum="4edc5e6640c225b79832bc2e0f48c726" name="tests/bson-corpus/decimal128-3-valid-122.phpt" role="test" />
<file md5sum="d660ff8273614aaa01123cb5319d2fce" name="tests/bson-corpus/decimal128-3-valid-123.phpt" role="test" />
<file md5sum="76ed3bc8e675cc584d1ecfd81874f0da" name="tests/bson-corpus/decimal128-3-valid-124.phpt" role="test" />
<file md5sum="0e118b247fe378b22933eabce71addd5" name="tests/bson-corpus/decimal128-3-valid-125.phpt" role="test" />
<file md5sum="ea4a57092893d65ebc6c10bd845f73da" name="tests/bson-corpus/decimal128-3-valid-126.phpt" role="test" />
<file md5sum="033bd199b375c8d8edfc99557efb664c" name="tests/bson-corpus/decimal128-3-valid-127.phpt" role="test" />
<file md5sum="b39431446dd3024d4586c5ee7a53a9c7" name="tests/bson-corpus/decimal128-3-valid-128.phpt" role="test" />
<file md5sum="a5c5465e913593e71ebbdb9ddda2b7e0" name="tests/bson-corpus/decimal128-3-valid-129.phpt" role="test" />
<file md5sum="48e9c801bc4e85c1b645c337484969dc" name="tests/bson-corpus/decimal128-3-valid-130.phpt" role="test" />
<file md5sum="ff1fd438092fec37c43f5581074a8654" name="tests/bson-corpus/decimal128-3-valid-131.phpt" role="test" />
<file md5sum="7a49e15bbe61c0f44f77032a0590dd08" name="tests/bson-corpus/decimal128-3-valid-132.phpt" role="test" />
<file md5sum="41b5c0a8d472f19f445f18b1d2415103" name="tests/bson-corpus/decimal128-3-valid-133.phpt" role="test" />
<file md5sum="ceedef671302bcfb2139ce9ec6f3d76d" name="tests/bson-corpus/decimal128-3-valid-134.phpt" role="test" />
<file md5sum="102f119348c5131e67511ca4a826958f" name="tests/bson-corpus/decimal128-3-valid-135.phpt" role="test" />
<file md5sum="93a232d6dd61f6b9c4c8385393ebdef4" name="tests/bson-corpus/decimal128-3-valid-136.phpt" role="test" />
<file md5sum="f01d124d3b1b4174de15fa782ed5a8a6" name="tests/bson-corpus/decimal128-3-valid-137.phpt" role="test" />
<file md5sum="919ce4fdde473d6479e43e9dfdb0e186" name="tests/bson-corpus/decimal128-3-valid-138.phpt" role="test" />
<file md5sum="53b86c3935f6cd6af126b8218d94e160" name="tests/bson-corpus/decimal128-3-valid-139.phpt" role="test" />
<file md5sum="7bd66fd3bffdeff24d9dd3ccd5b877a8" name="tests/bson-corpus/decimal128-3-valid-140.phpt" role="test" />
<file md5sum="b6b0407bba7493ada8641c3ea20cb0f3" name="tests/bson-corpus/decimal128-3-valid-141.phpt" role="test" />
<file md5sum="1f753ad00b8f28fbc904442a4a1c00d2" name="tests/bson-corpus/decimal128-3-valid-142.phpt" role="test" />
<file md5sum="9c56975628864c07cdb1a987d32af308" name="tests/bson-corpus/decimal128-3-valid-143.phpt" role="test" />
<file md5sum="46e1f60aea42cb626a6a8c6e2e8aed24" name="tests/bson-corpus/decimal128-3-valid-144.phpt" role="test" />
<file md5sum="dfb1c9f2a6677a54b38e15a00a076206" name="tests/bson-corpus/decimal128-3-valid-145.phpt" role="test" />
<file md5sum="483b6f3b8adbdffe6b2822d45ac27fdd" name="tests/bson-corpus/decimal128-3-valid-146.phpt" role="test" />
<file md5sum="34280ee40ad731d5fd74e2896627bcfa" name="tests/bson-corpus/decimal128-3-valid-147.phpt" role="test" />
<file md5sum="f50691f53242893865a5e7e8167efdf3" name="tests/bson-corpus/decimal128-3-valid-148.phpt" role="test" />
<file md5sum="6caa2f259d2a4d4fec8bfae1c189cd29" name="tests/bson-corpus/decimal128-3-valid-149.phpt" role="test" />
<file md5sum="a174e644ef93e3bbf40b9b1b22de211f" name="tests/bson-corpus/decimal128-3-valid-150.phpt" role="test" />
<file md5sum="d5cdcd6aa65dff7129d65080a273b28d" name="tests/bson-corpus/decimal128-3-valid-151.phpt" role="test" />
<file md5sum="aa21bd5fb048c7dcd081e666b2658a32" name="tests/bson-corpus/decimal128-3-valid-152.phpt" role="test" />
<file md5sum="06d138aad451e764f3c5160374acc456" name="tests/bson-corpus/decimal128-3-valid-153.phpt" role="test" />
<file md5sum="60ed7e43676c63a4f05eed0e23b97f21" name="tests/bson-corpus/decimal128-3-valid-154.phpt" role="test" />
<file md5sum="698c194680b1a261a9040d05bcfdb6f0" name="tests/bson-corpus/decimal128-3-valid-155.phpt" role="test" />
<file md5sum="8fca768c3428aea430c5307c80e72d7d" name="tests/bson-corpus/decimal128-3-valid-156.phpt" role="test" />
<file md5sum="7ccffdab18207ff6ac931876e8819158" name="tests/bson-corpus/decimal128-3-valid-157.phpt" role="test" />
<file md5sum="ff3d7be550b35a00d313cb74a1d2ae94" name="tests/bson-corpus/decimal128-3-valid-158.phpt" role="test" />
<file md5sum="6313e9b84336ea9a22034df9f5ae4278" name="tests/bson-corpus/decimal128-3-valid-159.phpt" role="test" />
<file md5sum="af457cac1c796d177c0ddced3cb7b507" name="tests/bson-corpus/decimal128-3-valid-160.phpt" role="test" />
<file md5sum="5a3c16d9b930348d2f25feb9174b630d" name="tests/bson-corpus/decimal128-3-valid-161.phpt" role="test" />
<file md5sum="78af9a90018a3174bd3225f806abc98c" name="tests/bson-corpus/decimal128-3-valid-162.phpt" role="test" />
<file md5sum="bab6fe8749117af054525b4b3148b59b" name="tests/bson-corpus/decimal128-3-valid-163.phpt" role="test" />
<file md5sum="e80be94522fe70a126623c4e347439fc" name="tests/bson-corpus/decimal128-3-valid-164.phpt" role="test" />
<file md5sum="b1c1243a7a52aea8e15f685d03afefad" name="tests/bson-corpus/decimal128-3-valid-165.phpt" role="test" />
<file md5sum="74d49b5f3409db69768e4daa20da44c6" name="tests/bson-corpus/decimal128-3-valid-166.phpt" role="test" />
<file md5sum="12fc4d315fddfc77dac54e611710e35c" name="tests/bson-corpus/decimal128-3-valid-167.phpt" role="test" />
<file md5sum="cf310a36aae9825fdd782acf3c16ba8a" name="tests/bson-corpus/decimal128-3-valid-168.phpt" role="test" />
<file md5sum="453122b2d589ce01ad556a47bf49c83b" name="tests/bson-corpus/decimal128-3-valid-169.phpt" role="test" />
<file md5sum="d741c0b4b531ca79835fbe40ac29f274" name="tests/bson-corpus/decimal128-3-valid-170.phpt" role="test" />
<file md5sum="bb0ce34b58847ffa1c78d4146f7418a0" name="tests/bson-corpus/decimal128-3-valid-171.phpt" role="test" />
<file md5sum="69f67ca42b68a6de8f8c3b1d40646dfc" name="tests/bson-corpus/decimal128-3-valid-172.phpt" role="test" />
<file md5sum="b65a2e3284509b9c5e462a264627bcb9" name="tests/bson-corpus/decimal128-3-valid-173.phpt" role="test" />
<file md5sum="c9bd868906728cabd730205804a164ab" name="tests/bson-corpus/decimal128-3-valid-174.phpt" role="test" />
<file md5sum="b305dcd7417ad764dd2957e1027287c5" name="tests/bson-corpus/decimal128-3-valid-175.phpt" role="test" />
<file md5sum="d5af17d98c8c607b0d5282bbf6182920" name="tests/bson-corpus/decimal128-3-valid-176.phpt" role="test" />
<file md5sum="ea5fc2dd9f80691d17cac7f090f71d90" name="tests/bson-corpus/decimal128-3-valid-177.phpt" role="test" />
<file md5sum="7952b43a5122c26a8ca2246fad1bb2ba" name="tests/bson-corpus/decimal128-3-valid-178.phpt" role="test" />
<file md5sum="d85eb123995adc0d78b1740884ef2685" name="tests/bson-corpus/decimal128-3-valid-179.phpt" role="test" />
<file md5sum="c728812d21d551ab4dff6408af92be0f" name="tests/bson-corpus/decimal128-3-valid-180.phpt" role="test" />
<file md5sum="c76e2b2c5bdfe687573356e00a97fbdf" name="tests/bson-corpus/decimal128-3-valid-181.phpt" role="test" />
<file md5sum="829e8f36fa61407de01d27bd9eeef27c" name="tests/bson-corpus/decimal128-3-valid-182.phpt" role="test" />
<file md5sum="d3ccc5c3981cd94f355639c378e4677b" name="tests/bson-corpus/decimal128-3-valid-183.phpt" role="test" />
<file md5sum="9504c6aa7b80b8db9184cb52474f6c85" name="tests/bson-corpus/decimal128-3-valid-184.phpt" role="test" />
<file md5sum="2a9eeffd0beef95d467064de10f02de9" name="tests/bson-corpus/decimal128-3-valid-185.phpt" role="test" />
<file md5sum="f47be02dfa343467cb9e6ee3417c3dd7" name="tests/bson-corpus/decimal128-3-valid-186.phpt" role="test" />
<file md5sum="96d35bfcaa77ef683578e6c270758790" name="tests/bson-corpus/decimal128-3-valid-187.phpt" role="test" />
<file md5sum="47e5c49caf081b6129518717e0963882" name="tests/bson-corpus/decimal128-3-valid-188.phpt" role="test" />
<file md5sum="7a90df09c7c531d3faf54764b9033ccb" name="tests/bson-corpus/decimal128-3-valid-189.phpt" role="test" />
<file md5sum="2564d7a605f7c459b57ed68b6e9a4fe0" name="tests/bson-corpus/decimal128-3-valid-190.phpt" role="test" />
<file md5sum="164acbaf5bd1fb0285b44c1bbf869cf3" name="tests/bson-corpus/decimal128-3-valid-191.phpt" role="test" />
<file md5sum="69f2c6581d8069f7eec36c31ee852d9c" name="tests/bson-corpus/decimal128-3-valid-192.phpt" role="test" />
<file md5sum="347b7859ac548820b806f92a9baac4d8" name="tests/bson-corpus/decimal128-3-valid-193.phpt" role="test" />
<file md5sum="6cace49760bbafb3fb3741e3e0de8b46" name="tests/bson-corpus/decimal128-3-valid-194.phpt" role="test" />
<file md5sum="7d54c24b910eae152d58eb12fa151c32" name="tests/bson-corpus/decimal128-3-valid-195.phpt" role="test" />
<file md5sum="429a273911a483c2c57755ad8e001d7b" name="tests/bson-corpus/decimal128-3-valid-196.phpt" role="test" />
<file md5sum="2832812b1b6ce8d2fd9b5daac398ee49" name="tests/bson-corpus/decimal128-3-valid-197.phpt" role="test" />
<file md5sum="27874826657d1ba50af6b3a8fffca76c" name="tests/bson-corpus/decimal128-3-valid-198.phpt" role="test" />
<file md5sum="8b71ad45296b088c0dd63330a23ecd4f" name="tests/bson-corpus/decimal128-3-valid-199.phpt" role="test" />
<file md5sum="92f0aa39dc57b06ac3c3ce0ce7ad610e" name="tests/bson-corpus/decimal128-3-valid-200.phpt" role="test" />
<file md5sum="3d152e470dfc642c980ad1a432d0349f" name="tests/bson-corpus/decimal128-3-valid-201.phpt" role="test" />
<file md5sum="c6f013f11312804349500ecc1e8a3351" name="tests/bson-corpus/decimal128-3-valid-202.phpt" role="test" />
<file md5sum="6848f1bc8eca604b55c47fc8aa38fe75" name="tests/bson-corpus/decimal128-3-valid-203.phpt" role="test" />
<file md5sum="d3caea6474c2e1bd8f654955fc64aa2e" name="tests/bson-corpus/decimal128-3-valid-204.phpt" role="test" />
<file md5sum="0f8fc5ab722aa03bc3fc7e3860c9a077" name="tests/bson-corpus/decimal128-3-valid-205.phpt" role="test" />
<file md5sum="8e24ccc73ba8342df00c84d031148604" name="tests/bson-corpus/decimal128-3-valid-206.phpt" role="test" />
<file md5sum="ec75b7a5cffe375b83dd42d27a9e2d1b" name="tests/bson-corpus/decimal128-3-valid-207.phpt" role="test" />
<file md5sum="f7c54531b297db29bb31515d63682bc1" name="tests/bson-corpus/decimal128-3-valid-208.phpt" role="test" />
<file md5sum="a7f1b30a6a5b7c66173a83d7ee961929" name="tests/bson-corpus/decimal128-3-valid-209.phpt" role="test" />
<file md5sum="c7684068a7e28cb83f38fbe8fa839817" name="tests/bson-corpus/decimal128-3-valid-210.phpt" role="test" />
<file md5sum="f4b13a599e9a1472afc2e8d3fa9024ec" name="tests/bson-corpus/decimal128-3-valid-211.phpt" role="test" />
<file md5sum="00958f5dc092ab03b9416901f2ca420f" name="tests/bson-corpus/decimal128-3-valid-212.phpt" role="test" />
<file md5sum="bf9dad19e8fa0f2d0263a882a7bd8ff0" name="tests/bson-corpus/decimal128-3-valid-213.phpt" role="test" />
<file md5sum="b56f4a4785368c98157a59d654511b09" name="tests/bson-corpus/decimal128-3-valid-214.phpt" role="test" />
<file md5sum="ce4fdc35eb9250c5b9393f6bb8f3a1df" name="tests/bson-corpus/decimal128-3-valid-215.phpt" role="test" />
<file md5sum="4f5f37a624b349a30d5d7db07bd7f8f1" name="tests/bson-corpus/decimal128-3-valid-216.phpt" role="test" />
<file md5sum="0cc395f87f42a8aa0dcc4b12815d2be9" name="tests/bson-corpus/decimal128-3-valid-217.phpt" role="test" />
<file md5sum="b930c8c6c6e6585035a1c66e22aa93eb" name="tests/bson-corpus/decimal128-3-valid-218.phpt" role="test" />
<file md5sum="25b18102a0465f8eb725d60ed7804aae" name="tests/bson-corpus/decimal128-3-valid-219.phpt" role="test" />
<file md5sum="9cdc0a1bae62b587da3359e7835df88c" name="tests/bson-corpus/decimal128-3-valid-220.phpt" role="test" />
<file md5sum="e7507fadc34ba39c785caf3afb433124" name="tests/bson-corpus/decimal128-3-valid-221.phpt" role="test" />
<file md5sum="e051c0f931bc32024c89135fd968a1eb" name="tests/bson-corpus/decimal128-3-valid-222.phpt" role="test" />
<file md5sum="1323db4f58f17eff6aa0ed1d3e00fb30" name="tests/bson-corpus/decimal128-3-valid-223.phpt" role="test" />
<file md5sum="45bdd12b7abcb5f8f89a63777da88f43" name="tests/bson-corpus/decimal128-3-valid-224.phpt" role="test" />
<file md5sum="4396d4763a727c77b2f9a0b0863346b2" name="tests/bson-corpus/decimal128-3-valid-225.phpt" role="test" />
<file md5sum="99b4a3961fbf77dc7acd6800ebca9c75" name="tests/bson-corpus/decimal128-3-valid-226.phpt" role="test" />
<file md5sum="2369608b5fed1db23661d54259da490b" name="tests/bson-corpus/decimal128-3-valid-227.phpt" role="test" />
<file md5sum="947d659f83807f67e858859a6b033ec4" name="tests/bson-corpus/decimal128-3-valid-228.phpt" role="test" />
<file md5sum="30ae76f8a7f60a2398c3f510cb207f25" name="tests/bson-corpus/decimal128-3-valid-229.phpt" role="test" />
<file md5sum="86f36843eca5e1ced0ef3444694aef0b" name="tests/bson-corpus/decimal128-3-valid-230.phpt" role="test" />
<file md5sum="664bbaa8c107f0fce2767a088a12b791" name="tests/bson-corpus/decimal128-3-valid-231.phpt" role="test" />
<file md5sum="0c4f8fb0b5c2a24119261dd8cb7c611c" name="tests/bson-corpus/decimal128-3-valid-232.phpt" role="test" />
<file md5sum="d75b88a50714e5b2dde675bbecb5af67" name="tests/bson-corpus/decimal128-3-valid-233.phpt" role="test" />
<file md5sum="50031e356b25cc6bcdc6ec6feabdbaaa" name="tests/bson-corpus/decimal128-3-valid-234.phpt" role="test" />
<file md5sum="a25eb0e75c2af7bd90aada71bddd9320" name="tests/bson-corpus/decimal128-3-valid-235.phpt" role="test" />
<file md5sum="89482d2a83c13c53346f59a5b5694125" name="tests/bson-corpus/decimal128-3-valid-236.phpt" role="test" />
<file md5sum="4c9877820e4836a88496db7de7321f33" name="tests/bson-corpus/decimal128-3-valid-237.phpt" role="test" />
<file md5sum="67cd9f43beb81a49ec625d536a271127" name="tests/bson-corpus/decimal128-3-valid-238.phpt" role="test" />
<file md5sum="75cf91ed5d8caa16a200f8471c468f0f" name="tests/bson-corpus/decimal128-3-valid-239.phpt" role="test" />
<file md5sum="1862658ccdb34e863796b317ce135d5d" name="tests/bson-corpus/decimal128-3-valid-240.phpt" role="test" />
<file md5sum="95d2c1258eda3145275a8f042232d821" name="tests/bson-corpus/decimal128-3-valid-241.phpt" role="test" />
<file md5sum="6f2a12b7c3346e02d8d9df70dbf24443" name="tests/bson-corpus/decimal128-3-valid-242.phpt" role="test" />
<file md5sum="ca041a60616750c6fd631e785aecf06a" name="tests/bson-corpus/decimal128-3-valid-243.phpt" role="test" />
<file md5sum="182f0e57202ed38f3b52deba31b7830a" name="tests/bson-corpus/decimal128-3-valid-244.phpt" role="test" />
<file md5sum="8a00aadf85b1dd97fb7d432886d045aa" name="tests/bson-corpus/decimal128-3-valid-245.phpt" role="test" />
<file md5sum="0461bbc97f686051b08e6a5bbb53b959" name="tests/bson-corpus/decimal128-3-valid-246.phpt" role="test" />
<file md5sum="a4621259bd5fa3d8799066a099f83ee8" name="tests/bson-corpus/decimal128-3-valid-247.phpt" role="test" />
<file md5sum="02d0781517ee131ac6824feda1ee3d06" name="tests/bson-corpus/decimal128-3-valid-248.phpt" role="test" />
<file md5sum="70e8b607541f4be7e319abc6e7851d23" name="tests/bson-corpus/decimal128-3-valid-249.phpt" role="test" />
<file md5sum="87ed40582612e5fb716b79cb35f4fd3f" name="tests/bson-corpus/decimal128-3-valid-250.phpt" role="test" />
<file md5sum="8df6fd7da9c803f09e2123d8e908cf6f" name="tests/bson-corpus/decimal128-3-valid-251.phpt" role="test" />
<file md5sum="303eca9da56f6fc952c57a349886a047" name="tests/bson-corpus/decimal128-3-valid-252.phpt" role="test" />
<file md5sum="d5219e0fe85d9e20ee278e8b0df66164" name="tests/bson-corpus/decimal128-3-valid-253.phpt" role="test" />
<file md5sum="c392834bd6a188890ca34ba35e3d1da5" name="tests/bson-corpus/decimal128-3-valid-254.phpt" role="test" />
<file md5sum="74bff884a0f11350fda93122266b47de" name="tests/bson-corpus/decimal128-3-valid-255.phpt" role="test" />
<file md5sum="a8aae300a1bbea5a59f982dd1d04a7d8" name="tests/bson-corpus/decimal128-3-valid-256.phpt" role="test" />
<file md5sum="64d3badff7261c4f8c396180228e9263" name="tests/bson-corpus/decimal128-3-valid-257.phpt" role="test" />
<file md5sum="72863a6b340184d2efc06bec4b0b1b52" name="tests/bson-corpus/decimal128-3-valid-258.phpt" role="test" />
<file md5sum="1a18988ad9f4645ec716c5728de5123d" name="tests/bson-corpus/decimal128-3-valid-259.phpt" role="test" />
<file md5sum="217fb1e340d68c7ebeed3b1812e75007" name="tests/bson-corpus/decimal128-3-valid-260.phpt" role="test" />
<file md5sum="479050beb76594438da5e46d5b11ab1f" name="tests/bson-corpus/decimal128-3-valid-261.phpt" role="test" />
<file md5sum="642266524c9f30a9883d406db25f962f" name="tests/bson-corpus/decimal128-3-valid-262.phpt" role="test" />
<file md5sum="90c6819ad16d227ddc9bd08874a1a38f" name="tests/bson-corpus/decimal128-3-valid-263.phpt" role="test" />
<file md5sum="9edb6624bcfcee4ab0ab3c70861e6429" name="tests/bson-corpus/decimal128-3-valid-264.phpt" role="test" />
<file md5sum="865052b3dc114e727e94fe3ea35fe374" name="tests/bson-corpus/decimal128-3-valid-265.phpt" role="test" />
<file md5sum="db8cedb3eb82fe29bbaa90e1971380ee" name="tests/bson-corpus/decimal128-3-valid-266.phpt" role="test" />
<file md5sum="9f466e601b029010cc581ff0b5f6611b" name="tests/bson-corpus/decimal128-3-valid-267.phpt" role="test" />
<file md5sum="390e8afe134fee7238646a72d5984ba1" name="tests/bson-corpus/decimal128-3-valid-268.phpt" role="test" />
<file md5sum="a26942ae9397497efc6645fec446948f" name="tests/bson-corpus/decimal128-3-valid-269.phpt" role="test" />
<file md5sum="73f302c571efdfa0718b66c8f0586e49" name="tests/bson-corpus/decimal128-3-valid-270.phpt" role="test" />
<file md5sum="788c2ae67bbb0fe0ac1f184b2fad9b8f" name="tests/bson-corpus/decimal128-3-valid-271.phpt" role="test" />
<file md5sum="a96eef0690ad802e3fd7055ce15dc8f2" name="tests/bson-corpus/decimal128-3-valid-272.phpt" role="test" />
<file md5sum="670c9c570cd11238d78939b84fd3495d" name="tests/bson-corpus/decimal128-3-valid-273.phpt" role="test" />
<file md5sum="d087bd4fb582aaf15cac1f6487e85f1b" name="tests/bson-corpus/decimal128-3-valid-274.phpt" role="test" />
<file md5sum="bffaad4ce838bd0f05572805f4a792b3" name="tests/bson-corpus/decimal128-3-valid-275.phpt" role="test" />
<file md5sum="69df3124a8fc7c86f5d6a8872a9ea53b" name="tests/bson-corpus/decimal128-3-valid-276.phpt" role="test" />
<file md5sum="8c5513d50689ca1d35d1fb2c9df7bf2f" name="tests/bson-corpus/decimal128-3-valid-277.phpt" role="test" />
<file md5sum="ee2b602524107eff28c4d72402773ba4" name="tests/bson-corpus/decimal128-3-valid-278.phpt" role="test" />
<file md5sum="03db443213b04fa200cf3b7507796f32" name="tests/bson-corpus/decimal128-3-valid-279.phpt" role="test" />
<file md5sum="ca8fbc712096a759a73bf075780e647f" name="tests/bson-corpus/decimal128-3-valid-280.phpt" role="test" />
<file md5sum="5385fc73f83bbcfa4201c7783f496b72" name="tests/bson-corpus/decimal128-3-valid-281.phpt" role="test" />
<file md5sum="a816d6cbd31c7707200bdf7eb936bff7" name="tests/bson-corpus/decimal128-3-valid-282.phpt" role="test" />
<file md5sum="2f4497bacc3ff1d2b02833b0a295eaf4" name="tests/bson-corpus/decimal128-3-valid-283.phpt" role="test" />
<file md5sum="5c661b0156dc44a6b91f314c4b0f2509" name="tests/bson-corpus/decimal128-3-valid-284.phpt" role="test" />
<file md5sum="009d8193db88b5b9d866d712847fc389" name="tests/bson-corpus/decimal128-3-valid-285.phpt" role="test" />
<file md5sum="f528d64653839930b2725b0295074e3d" name="tests/bson-corpus/decimal128-3-valid-286.phpt" role="test" />
<file md5sum="e08f16db3d1d683b3e42f8b719c9a3ec" name="tests/bson-corpus/decimal128-3-valid-287.phpt" role="test" />
<file md5sum="a2723797d475df77bfa469aafcd1c23f" name="tests/bson-corpus/decimal128-3-valid-288.phpt" role="test" />
<file md5sum="7adc561fcc55c39f9b3952c1e642bc35" name="tests/bson-corpus/decimal128-3-valid-289.phpt" role="test" />
<file md5sum="d9e1e6515ace82b87d62155d6f690302" name="tests/bson-corpus/decimal128-3-valid-290.phpt" role="test" />
<file md5sum="56dc7d83c6e060c7b4307d0b7b9a6c0a" name="tests/bson-corpus/decimal128-3-valid-291.phpt" role="test" />
<file md5sum="92c4a118b61e0f354fe29e2e3a190a30" name="tests/bson-corpus/decimal128-3-valid-292.phpt" role="test" />
<file md5sum="74385ffc43126c1f584a31d022803ecf" name="tests/bson-corpus/decimal128-3-valid-293.phpt" role="test" />
<file md5sum="6d7e8945e86aa6f43e34849ae7ca019f" name="tests/bson-corpus/decimal128-3-valid-294.phpt" role="test" />
<file md5sum="19cc48ff2f3d7c0ac7463d051d546e5d" name="tests/bson-corpus/decimal128-3-valid-295.phpt" role="test" />
<file md5sum="046aea2e28cffc3c5ebc17d570c93303" name="tests/bson-corpus/decimal128-3-valid-296.phpt" role="test" />
<file md5sum="4a82366da632db80ae0d4ce74967849e" name="tests/bson-corpus/decimal128-3-valid-297.phpt" role="test" />
<file md5sum="9be11a5077f99d2e967124da5be6966d" name="tests/bson-corpus/decimal128-3-valid-298.phpt" role="test" />
<file md5sum="b952249c6ff1df0a12cf97167dea0761" name="tests/bson-corpus/decimal128-3-valid-299.phpt" role="test" />
<file md5sum="1dbd6aa53f3fd22835c60700d768cc64" name="tests/bson-corpus/decimal128-3-valid-300.phpt" role="test" />
<file md5sum="4a4333c5beba793ea2f9da8f3eead9cb" name="tests/bson-corpus/decimal128-3-valid-301.phpt" role="test" />
<file md5sum="504ce3bd1b863d0a304e1bec32b16964" name="tests/bson-corpus/decimal128-3-valid-302.phpt" role="test" />
<file md5sum="ddaef1de98c84dc697ebd60ee31d7c01" name="tests/bson-corpus/decimal128-3-valid-303.phpt" role="test" />
<file md5sum="1b84be6a6b81415243b515b8606f38b4" name="tests/bson-corpus/decimal128-3-valid-304.phpt" role="test" />
<file md5sum="1582fb1c5fcdeb152698567ce67c598e" name="tests/bson-corpus/decimal128-3-valid-305.phpt" role="test" />
<file md5sum="18db5afa1316af3b9de7d839153df780" name="tests/bson-corpus/decimal128-3-valid-306.phpt" role="test" />
<file md5sum="e66e488feb111d4d69ce77360329c898" name="tests/bson-corpus/decimal128-3-valid-307.phpt" role="test" />
<file md5sum="ef802778b9b3518610ace5dd8ea6b74c" name="tests/bson-corpus/decimal128-3-valid-308.phpt" role="test" />
<file md5sum="9ec3b1d0453a41981144d85b0f3eb575" name="tests/bson-corpus/decimal128-4-parseError-001.phpt" role="test" />
<file md5sum="506cd6ad521dacb23091429867c77f69" name="tests/bson-corpus/decimal128-4-parseError-002.phpt" role="test" />
<file md5sum="4d1c8bb08975e5f5689fddaeec8e8402" name="tests/bson-corpus/decimal128-4-parseError-003.phpt" role="test" />
<file md5sum="09a3731b634372e305ab1d20459a38b1" name="tests/bson-corpus/decimal128-4-parseError-004.phpt" role="test" />
<file md5sum="e6c661208cdfce2b594b7e438a5cb586" name="tests/bson-corpus/decimal128-4-parseError-005.phpt" role="test" />
<file md5sum="7abd53b9fd4b63103042469f1e712c51" name="tests/bson-corpus/decimal128-4-parseError-006.phpt" role="test" />
<file md5sum="a414cd52ef74a681a04bd08d174e07a4" name="tests/bson-corpus/decimal128-4-parseError-007.phpt" role="test" />
<file md5sum="93f7b286ece0c2cdc8ca80fb6deb3c29" name="tests/bson-corpus/decimal128-4-parseError-008.phpt" role="test" />
<file md5sum="a48bd5fa08ac0fd11524f9ed4349ea00" name="tests/bson-corpus/decimal128-4-parseError-009.phpt" role="test" />
<file md5sum="59db6e06cb969d386d2c4aff43789350" name="tests/bson-corpus/decimal128-4-parseError-010.phpt" role="test" />
<file md5sum="d5e93f9615e8a86ebb8406a5f06554d3" name="tests/bson-corpus/decimal128-4-parseError-011.phpt" role="test" />
<file md5sum="da29e2793f0f33cde882297f3ad93d16" name="tests/bson-corpus/decimal128-4-parseError-012.phpt" role="test" />
<file md5sum="bfa1678cd7627d4ffb33da8a97bc3291" name="tests/bson-corpus/decimal128-4-parseError-013.phpt" role="test" />
<file md5sum="e5ceaa080a31506dc370cb4eb584e5ce" name="tests/bson-corpus/decimal128-4-parseError-014.phpt" role="test" />
<file md5sum="7cc0cb86e19dacbd5a1950a36253bb9e" name="tests/bson-corpus/decimal128-4-parseError-015.phpt" role="test" />
<file md5sum="a0b16a86367ed7b6b0e708145d800cdf" name="tests/bson-corpus/decimal128-4-parseError-016.phpt" role="test" />
<file md5sum="fea774bacaf0b19b966a1cbf4eb7e495" name="tests/bson-corpus/decimal128-4-parseError-017.phpt" role="test" />
<file md5sum="0769502b551a8f55b21986d410a89bc4" name="tests/bson-corpus/decimal128-4-parseError-018.phpt" role="test" />
<file md5sum="f700e859506a827495b206157d0e79c1" name="tests/bson-corpus/decimal128-4-parseError-019.phpt" role="test" />
<file md5sum="15c4a2681de9e3e17634e0456dbb81f9" name="tests/bson-corpus/decimal128-4-parseError-020.phpt" role="test" />
<file md5sum="3d6c296dd577cf2f6d2d6fe52a07be20" name="tests/bson-corpus/decimal128-4-valid-001.phpt" role="test" />
<file md5sum="3b1e53207bff49057a875a76ceab1058" name="tests/bson-corpus/decimal128-4-valid-002.phpt" role="test" />
<file md5sum="c32fa8265ce7a165b28270e91c6afcbb" name="tests/bson-corpus/decimal128-4-valid-003.phpt" role="test" />
<file md5sum="fdcd72b9eed2a19ebbcdda5ffc0d3df6" name="tests/bson-corpus/decimal128-4-valid-004.phpt" role="test" />
<file md5sum="1306105e2f10e6f78d184b092a953020" name="tests/bson-corpus/decimal128-4-valid-005.phpt" role="test" />
<file md5sum="3d26a89dbcb3e20d41bbc7c4ea88bf18" name="tests/bson-corpus/decimal128-4-valid-006.phpt" role="test" />
<file md5sum="564b1167b72d3ac047170a0055b63026" name="tests/bson-corpus/decimal128-4-valid-007.phpt" role="test" />
<file md5sum="035a85fee0cd8c911c489b8e2d0d934e" name="tests/bson-corpus/decimal128-4-valid-008.phpt" role="test" />
<file md5sum="4b7270c06d321789031e4ffd0339134d" name="tests/bson-corpus/decimal128-4-valid-009.phpt" role="test" />
<file md5sum="12008e294dc7a4e60bbdbc86db43ef9a" name="tests/bson-corpus/decimal128-4-valid-010.phpt" role="test" />
<file md5sum="36af20079f691c94fd97142c9db41f77" name="tests/bson-corpus/decimal128-4-valid-011.phpt" role="test" />
<file md5sum="65841643c7443e84ee055d8fccff8fbe" name="tests/bson-corpus/decimal128-4-valid-012.phpt" role="test" />
<file md5sum="59d23c843f648bd0c2f389758d9b966e" name="tests/bson-corpus/decimal128-4-valid-013.phpt" role="test" />
<file md5sum="ae3f4157e8809fc7c378dad169f4b9f3" name="tests/bson-corpus/decimal128-5-valid-001.phpt" role="test" />
<file md5sum="dff889d4075849339476305219f5a236" name="tests/bson-corpus/decimal128-5-valid-002.phpt" role="test" />
<file md5sum="ba14ba6c016fdc18ff66f6db048fb0a3" name="tests/bson-corpus/decimal128-5-valid-003.phpt" role="test" />
<file md5sum="ba9a44b79affe27f730a7ec433352389" name="tests/bson-corpus/decimal128-5-valid-004.phpt" role="test" />
<file md5sum="5d5fcaa84d28796febd9b624c4ceced2" name="tests/bson-corpus/decimal128-5-valid-005.phpt" role="test" />
<file md5sum="cac2941094fc213e304e669388f6de42" name="tests/bson-corpus/decimal128-5-valid-006.phpt" role="test" />
<file md5sum="108213814aeceb9da7dae49085066aa9" name="tests/bson-corpus/decimal128-5-valid-007.phpt" role="test" />
<file md5sum="6e3802a9c28479151b815ae05ffedf4a" name="tests/bson-corpus/decimal128-5-valid-008.phpt" role="test" />
<file md5sum="e3a4f86c70897a071c52b8b63bd1ca72" name="tests/bson-corpus/decimal128-5-valid-009.phpt" role="test" />
<file md5sum="b050d4ec02398e8937444491e2008168" name="tests/bson-corpus/decimal128-5-valid-010.phpt" role="test" />
<file md5sum="b682adf6c7c93c0eb5ffe2482cbc86bb" name="tests/bson-corpus/decimal128-5-valid-011.phpt" role="test" />
<file md5sum="f86b59299c66649e186813f5efef88bc" name="tests/bson-corpus/decimal128-5-valid-012.phpt" role="test" />
<file md5sum="6a111849778a50875bb58ff1c139b78c" name="tests/bson-corpus/decimal128-5-valid-013.phpt" role="test" />
<file md5sum="d437c772800f78e1ef3469753641bdbd" name="tests/bson-corpus/decimal128-5-valid-014.phpt" role="test" />
<file md5sum="b3e546fc577e3d4eb0e148e9b7ebf07e" name="tests/bson-corpus/decimal128-5-valid-015.phpt" role="test" />
<file md5sum="c760575aae19fc8c536c30d7242a6779" name="tests/bson-corpus/decimal128-5-valid-016.phpt" role="test" />
<file md5sum="120f3057821b1a1ef4571c5d24f7a852" name="tests/bson-corpus/decimal128-5-valid-017.phpt" role="test" />
<file md5sum="ff5f2fd4dd075787ee81fd9e5bb3d8af" name="tests/bson-corpus/decimal128-5-valid-018.phpt" role="test" />
<file md5sum="972cbb598b739fe1e21d8b7058228c9e" name="tests/bson-corpus/decimal128-5-valid-019.phpt" role="test" />
<file md5sum="3d202b50c8a32d0f8d37ca43d5d93614" name="tests/bson-corpus/decimal128-5-valid-020.phpt" role="test" />
<file md5sum="e01b14a2a78c53e3a7b5a7eb4e4e8388" name="tests/bson-corpus/decimal128-5-valid-021.phpt" role="test" />
<file md5sum="02246aa93b1389373755099887155461" name="tests/bson-corpus/decimal128-5-valid-022.phpt" role="test" />
<file md5sum="ebed7e1c9008b272c3975fec979316ea" name="tests/bson-corpus/decimal128-5-valid-023.phpt" role="test" />
<file md5sum="148ee3caa80bb3e2c6016fa26490dd9d" name="tests/bson-corpus/decimal128-5-valid-024.phpt" role="test" />
<file md5sum="96915be6c733911d940e78b75da95d20" name="tests/bson-corpus/decimal128-5-valid-025.phpt" role="test" />
<file md5sum="978fecb824df0768511946b796cde1a8" name="tests/bson-corpus/decimal128-5-valid-026.phpt" role="test" />
<file md5sum="5e4607edd84ed63a80f860dd3a14a7a9" name="tests/bson-corpus/decimal128-5-valid-027.phpt" role="test" />
<file md5sum="0a35f861c451aaeb7b6ac51791e991b0" name="tests/bson-corpus/decimal128-5-valid-028.phpt" role="test" />
<file md5sum="c98cb2f14e20a5269154e87b51fc70bf" name="tests/bson-corpus/decimal128-5-valid-029.phpt" role="test" />
<file md5sum="dbb0dcd9dcddbe13dad3ebad0313583e" name="tests/bson-corpus/decimal128-5-valid-030.phpt" role="test" />
<file md5sum="365ca1ab11f99b25cb6429d7378edb56" name="tests/bson-corpus/decimal128-5-valid-031.phpt" role="test" />
<file md5sum="93942e13b80c76e95467b9366f606feb" name="tests/bson-corpus/decimal128-5-valid-032.phpt" role="test" />
<file md5sum="87f28f7c56eda1038b64ed8399c2e5ec" name="tests/bson-corpus/decimal128-5-valid-033.phpt" role="test" />
<file md5sum="5771eda7663092952f6813ebb215215a" name="tests/bson-corpus/decimal128-5-valid-034.phpt" role="test" />
<file md5sum="f17274f6b5d5a99ad0c967e95d22fa46" name="tests/bson-corpus/decimal128-5-valid-035.phpt" role="test" />
<file md5sum="b4881b4d619085b5653467fde9421fd5" name="tests/bson-corpus/decimal128-5-valid-036.phpt" role="test" />
<file md5sum="23c639715ea3612e866cf83d70d42ad9" name="tests/bson-corpus/decimal128-5-valid-037.phpt" role="test" />
<file md5sum="cba440a1b64840a63c71396c610682f2" name="tests/bson-corpus/decimal128-5-valid-038.phpt" role="test" />
<file md5sum="7a100539ca4b0e15127e30856ef8c472" name="tests/bson-corpus/decimal128-5-valid-039.phpt" role="test" />
<file md5sum="3b531bd1f338838a6bbb73a57fc9427b" name="tests/bson-corpus/decimal128-5-valid-040.phpt" role="test" />
<file md5sum="1df369ca39dc66acd2307b51f02391c7" name="tests/bson-corpus/decimal128-5-valid-041.phpt" role="test" />
<file md5sum="29a4582d8e5df180ccb4cf39077ade55" name="tests/bson-corpus/decimal128-5-valid-042.phpt" role="test" />
<file md5sum="9b6eefcc8964252e142dece5934c4b82" name="tests/bson-corpus/decimal128-5-valid-043.phpt" role="test" />
<file md5sum="2488859070570a442172d73831d15c36" name="tests/bson-corpus/decimal128-5-valid-044.phpt" role="test" />
<file md5sum="912be2cfedca3826ab13d326008a5e5f" name="tests/bson-corpus/decimal128-5-valid-045.phpt" role="test" />
<file md5sum="20f9f115f762cf2b8892c93036f29ffc" name="tests/bson-corpus/decimal128-5-valid-046.phpt" role="test" />
<file md5sum="209f1af4e3df9af67b83202cedddbcf1" name="tests/bson-corpus/decimal128-5-valid-047.phpt" role="test" />
<file md5sum="e83ed0b68f24e69f71cc9a9edfd93baa" name="tests/bson-corpus/decimal128-5-valid-048.phpt" role="test" />
<file md5sum="d984bf34b0053f704324c9ec0b9550cc" name="tests/bson-corpus/decimal128-5-valid-049.phpt" role="test" />
<file md5sum="534a913c9076f73604d69aa89a3e2b7f" name="tests/bson-corpus/decimal128-5-valid-050.phpt" role="test" />
<file md5sum="7fcc1d601ac8bb4f319d3013b2ff8d6f" name="tests/bson-corpus/decimal128-5-valid-051.phpt" role="test" />
<file md5sum="52f3ec367d8b1fdc14ea55a024633eeb" name="tests/bson-corpus/decimal128-5-valid-052.phpt" role="test" />
<file md5sum="6389fc0885e1671a6f4124876d7833b3" name="tests/bson-corpus/decimal128-5-valid-053.phpt" role="test" />
<file md5sum="0353aefe4f579411272f1db12cb9fb3c" name="tests/bson-corpus/decimal128-5-valid-054.phpt" role="test" />
<file md5sum="3259ba4a4500d16ed417c510ae39fb12" name="tests/bson-corpus/decimal128-5-valid-055.phpt" role="test" />
<file md5sum="ec6605e6c62dcfa8b40755dc6a68d4b7" name="tests/bson-corpus/decimal128-5-valid-056.phpt" role="test" />
<file md5sum="a80b45d66bb1b199ce676562aed98c8c" name="tests/bson-corpus/decimal128-5-valid-057.phpt" role="test" />
<file md5sum="8be00241652618fafc467ee5f0921c21" name="tests/bson-corpus/decimal128-5-valid-058.phpt" role="test" />
<file md5sum="69ecad834fe150b6af057e247f57d1ad" name="tests/bson-corpus/decimal128-5-valid-059.phpt" role="test" />
<file md5sum="5ef10e88062b5e8db6d57f2b3e9189cd" name="tests/bson-corpus/decimal128-5-valid-060.phpt" role="test" />
<file md5sum="e9b480a2bbb5a0840cef3a5c3b5b91c2" name="tests/bson-corpus/decimal128-5-valid-061.phpt" role="test" />
<file md5sum="5dc42a6bf54856a4184eff9cf0c093c5" name="tests/bson-corpus/decimal128-5-valid-062.phpt" role="test" />
<file md5sum="897f1d812ca47a431cf3bc5c17418290" name="tests/bson-corpus/decimal128-5-valid-063.phpt" role="test" />
<file md5sum="f127d0bfefd67c56f891896b37a76d8b" name="tests/bson-corpus/decimal128-5-valid-064.phpt" role="test" />
<file md5sum="221826b0f6273fb3f0858e521e0fe37e" name="tests/bson-corpus/decimal128-5-valid-065.phpt" role="test" />
<file md5sum="7ee3050a25a8743e9ce67691d997d190" name="tests/bson-corpus/decimal128-5-valid-066.phpt" role="test" />
<file md5sum="661f0ef7137987581e5fa6b93cdc06bb" name="tests/bson-corpus/decimal128-5-valid-067.phpt" role="test" />
<file md5sum="97fe7865f6b77af9761a310343fba415" name="tests/bson-corpus/decimal128-6-parseError-001.phpt" role="test" />
<file md5sum="9f575f6daff291e442343d44a3cac10a" name="tests/bson-corpus/decimal128-6-parseError-002.phpt" role="test" />
<file md5sum="4a66430c6a6a2f1a937f6eaab10f1f2c" name="tests/bson-corpus/decimal128-6-parseError-003.phpt" role="test" />
<file md5sum="6530b59f6a323ed20f911f87c0d6d5b9" name="tests/bson-corpus/decimal128-6-parseError-004.phpt" role="test" />
<file md5sum="b587d7e022d5ee929306a44f5e8f3666" name="tests/bson-corpus/decimal128-6-parseError-005.phpt" role="test" />
<file md5sum="1ce11e7590e301fe8cff91baf7f27299" name="tests/bson-corpus/decimal128-6-parseError-006.phpt" role="test" />
<file md5sum="f394f82562d15f669d1de267689cc95a" name="tests/bson-corpus/decimal128-6-parseError-007.phpt" role="test" />
<file md5sum="87032ec278bb9a13827a5b62cc2f21fc" name="tests/bson-corpus/decimal128-6-parseError-008.phpt" role="test" />
<file md5sum="e7ee4b1b929964e5ba5978dba60e098f" name="tests/bson-corpus/decimal128-6-parseError-009.phpt" role="test" />
<file md5sum="283726e643d46cbefb0b3641047756d4" name="tests/bson-corpus/decimal128-6-parseError-010.phpt" role="test" />
<file md5sum="4996d80b5d21cc5decb6036e0bcdc6ed" name="tests/bson-corpus/decimal128-6-parseError-011.phpt" role="test" />
<file md5sum="a9b27777c25778d465ab062981e80a46" name="tests/bson-corpus/decimal128-6-parseError-012.phpt" role="test" />
<file md5sum="d34cc4951df6044ca57808d9a7681b8e" name="tests/bson-corpus/decimal128-6-parseError-013.phpt" role="test" />
<file md5sum="539c801052840e099b620e31abb265e7" name="tests/bson-corpus/decimal128-6-parseError-014.phpt" role="test" />
<file md5sum="3f5e3afbd9eaceaf15480ec29c33e05e" name="tests/bson-corpus/decimal128-6-parseError-015.phpt" role="test" />
<file md5sum="c9bd1f761f82e17d1cad1a5e333c4d87" name="tests/bson-corpus/decimal128-6-parseError-016.phpt" role="test" />
<file md5sum="53493d03e0efa89d433e111d9e5b2c97" name="tests/bson-corpus/decimal128-6-parseError-017.phpt" role="test" />
<file md5sum="bac21d79cf24233a381256126e570e33" name="tests/bson-corpus/decimal128-6-parseError-018.phpt" role="test" />
<file md5sum="6f5805f1fdee72e416dcf3d6a2992407" name="tests/bson-corpus/decimal128-6-parseError-019.phpt" role="test" />
<file md5sum="3e2b85ba531690fb2e861dac542caccb" name="tests/bson-corpus/decimal128-6-parseError-020.phpt" role="test" />
<file md5sum="14bd678420d73ad4979dce95c78a1dcf" name="tests/bson-corpus/decimal128-6-parseError-021.phpt" role="test" />
<file md5sum="27966c70fc7cf6d78e2db4f1396c2f73" name="tests/bson-corpus/decimal128-6-parseError-022.phpt" role="test" />
<file md5sum="1f7d2bb1681215e34d5194410641de91" name="tests/bson-corpus/decimal128-6-parseError-023.phpt" role="test" />
<file md5sum="35ff6b7fde08867fd9585786b824a0d6" name="tests/bson-corpus/decimal128-6-parseError-024.phpt" role="test" />
<file md5sum="eb7fd03b97b7d1902619f4ddb2d432b8" name="tests/bson-corpus/decimal128-6-parseError-025.phpt" role="test" />
<file md5sum="e01b09664d43504f4edc73e33bfba3ca" name="tests/bson-corpus/decimal128-6-parseError-026.phpt" role="test" />
<file md5sum="deacc3d8fdfe797641fe0fe362404765" name="tests/bson-corpus/decimal128-6-parseError-027.phpt" role="test" />
<file md5sum="a0e8ac91c41ecf1eca07fb065f02d3ec" name="tests/bson-corpus/decimal128-6-parseError-028.phpt" role="test" />
<file md5sum="0bbefc7e842bfe89be81e8bf399d7d8a" name="tests/bson-corpus/decimal128-6-parseError-029.phpt" role="test" />
<file md5sum="d979bc87fec742e764e705eed2fed45b" name="tests/bson-corpus/decimal128-6-parseError-030.phpt" role="test" />
<file md5sum="f00357ca24f8844d4d7b22b3160e5e71" name="tests/bson-corpus/decimal128-6-parseError-031.phpt" role="test" />
<file md5sum="53f9d995d67a3762195fd07bb5f653d0" name="tests/bson-corpus/decimal128-7-parseError-001.phpt" role="test" />
<file md5sum="d29ed9186006eea15d635a9bacce926e" name="tests/bson-corpus/decimal128-7-parseError-002.phpt" role="test" />
<file md5sum="64d47b499c5cd564dd71d73cb85bb414" name="tests/bson-corpus/decimal128-7-parseError-003.phpt" role="test" />
<file md5sum="948ae3e82929bf3e4d0c997788a83900" name="tests/bson-corpus/decimal128-7-parseError-004.phpt" role="test" />
<file md5sum="94be2fca3acf9155613abc3e1310223c" name="tests/bson-corpus/decimal128-7-parseError-005.phpt" role="test" />
<file md5sum="d1f9e7f057df208e36759707aec45d3a" name="tests/bson-corpus/decimal128-7-parseError-006.phpt" role="test" />
<file md5sum="af5cb840cb6e880b7f4866225fb3ab8c" name="tests/bson-corpus/decimal128-7-parseError-007.phpt" role="test" />
<file md5sum="7c4945290e91d7d4ef142cd179866a72" name="tests/bson-corpus/decimal128-7-parseError-008.phpt" role="test" />
<file md5sum="ef3f78b87943a3af440e58adf83e762e" name="tests/bson-corpus/decimal128-7-parseError-009.phpt" role="test" />
<file md5sum="92b4275158b073a14953d9cd322a2202" name="tests/bson-corpus/decimal128-7-parseError-010.phpt" role="test" />
<file md5sum="a2d18ad0fdb146b6f2a142a8ea111ad5" name="tests/bson-corpus/decimal128-7-parseError-011.phpt" role="test" />
<file md5sum="535a7f455b7a9cbaaad113d915eae2ad" name="tests/bson-corpus/decimal128-7-parseError-012.phpt" role="test" />
<file md5sum="940f13a74a37c831f7b50e51ce03cb48" name="tests/bson-corpus/decimal128-7-parseError-013.phpt" role="test" />
<file md5sum="ee518aa3cd335ea1340cd660ac46c397" name="tests/bson-corpus/decimal128-7-parseError-014.phpt" role="test" />
<file md5sum="a18bb75fa65ab4364d3310dbc64b2d42" name="tests/bson-corpus/decimal128-7-parseError-015.phpt" role="test" />
<file md5sum="cdbb9254e8b5a8c2b61f0793e075bc21" name="tests/bson-corpus/decimal128-7-parseError-016.phpt" role="test" />
<file md5sum="e7c465fab5e7af09100cc0f2270e5ad4" name="tests/bson-corpus/decimal128-7-parseError-017.phpt" role="test" />
<file md5sum="ad9bded5d2d29d2f4cd40f3a98ad58ea" name="tests/bson-corpus/decimal128-7-parseError-018.phpt" role="test" />
<file md5sum="4fbef3e62555a42ecd78b5cd66c81569" name="tests/bson-corpus/decimal128-7-parseError-019.phpt" role="test" />
<file md5sum="d81d5065897fdef90dcad7be488f3188" name="tests/bson-corpus/decimal128-7-parseError-020.phpt" role="test" />
<file md5sum="db41dd01251ce000a5ecf40f762cf769" name="tests/bson-corpus/decimal128-7-parseError-021.phpt" role="test" />
<file md5sum="7f12e7dd1c939e2527470b1de6d34942" name="tests/bson-corpus/decimal128-7-parseError-022.phpt" role="test" />
<file md5sum="cd7219ff47cbc9fb57804486a944262f" name="tests/bson-corpus/decimal128-7-parseError-023.phpt" role="test" />
<file md5sum="bf34c189b0d7194e08307f081a1ffc10" name="tests/bson-corpus/decimal128-7-parseError-024.phpt" role="test" />
<file md5sum="b658af20fef19c777f878c7832b6a679" name="tests/bson-corpus/decimal128-7-parseError-025.phpt" role="test" />
<file md5sum="73a24ca42c6ae756ba56a06777610ef2" name="tests/bson-corpus/decimal128-7-parseError-026.phpt" role="test" />
<file md5sum="9a6d5b86647f571c6d4c89f96fa1f555" name="tests/bson-corpus/decimal128-7-parseError-027.phpt" role="test" />
<file md5sum="fd4263ac5a5a1dbdea4d02d607971c45" name="tests/bson-corpus/decimal128-7-parseError-028.phpt" role="test" />
<file md5sum="2b6d0739f6c91b9bad32353e19ac4db0" name="tests/bson-corpus/decimal128-7-parseError-029.phpt" role="test" />
<file md5sum="ec2592d9cf55680d54bda911b7237265" name="tests/bson-corpus/decimal128-7-parseError-030.phpt" role="test" />
<file md5sum="2c88d698f5abce5affb51f40c56cd79c" name="tests/bson-corpus/decimal128-7-parseError-031.phpt" role="test" />
<file md5sum="a1b55267e1f040cd47f234054fbd2bbc" name="tests/bson-corpus/decimal128-7-parseError-032.phpt" role="test" />
<file md5sum="ed2107f9aa466b5de70f274e7f4e9a50" name="tests/bson-corpus/decimal128-7-parseError-033.phpt" role="test" />
<file md5sum="131713b2aba97d35bb405f7c6e19f49f" name="tests/bson-corpus/decimal128-7-parseError-034.phpt" role="test" />
<file md5sum="23dd38e8a785335a2e580cb9cbd7f373" name="tests/bson-corpus/decimal128-7-parseError-035.phpt" role="test" />
<file md5sum="61c1fbba48138e7aa95dc619f1217e03" name="tests/bson-corpus/decimal128-7-parseError-036.phpt" role="test" />
<file md5sum="73448b46f4ebcfb371c3df67ffa25d70" name="tests/bson-corpus/decimal128-7-parseError-037.phpt" role="test" />
<file md5sum="ff7d44b3efcebe092a5be22db7500f93" name="tests/bson-corpus/decimal128-7-parseError-038.phpt" role="test" />
<file md5sum="958a9bc10f56cd9dabdae6b5382648be" name="tests/bson-corpus/decimal128-7-parseError-039.phpt" role="test" />
<file md5sum="a39fca304ccd2549988060852b9c2b60" name="tests/bson-corpus/decimal128-7-parseError-040.phpt" role="test" />
<file md5sum="21bcf3ea88275becb09488ce676ba256" name="tests/bson-corpus/decimal128-7-parseError-041.phpt" role="test" />
<file md5sum="a41810a881fd56479d50d1a2f10e4e15" name="tests/bson-corpus/decimal128-7-parseError-042.phpt" role="test" />
<file md5sum="b352d47eee76795c6d9cef4c1d42639a" name="tests/bson-corpus/decimal128-7-parseError-043.phpt" role="test" />
<file md5sum="0a6925324970b9215c46d629dc2ad648" name="tests/bson-corpus/decimal128-7-parseError-044.phpt" role="test" />
<file md5sum="7fd640f689e3b25e589449ce51762438" name="tests/bson-corpus/decimal128-7-parseError-045.phpt" role="test" />
<file md5sum="8965fa643c3177ba677b0a338c43935c" name="tests/bson-corpus/decimal128-7-parseError-046.phpt" role="test" />
<file md5sum="b89d1125f54520819d4780bb407751b1" name="tests/bson-corpus/decimal128-7-parseError-047.phpt" role="test" />
<file md5sum="29a49b24ce427755d4a5643a01f1e45e" name="tests/bson-corpus/decimal128-7-parseError-048.phpt" role="test" />
<file md5sum="15026f957644968579b0033b741ad521" name="tests/bson-corpus/decimal128-7-parseError-049.phpt" role="test" />
<file md5sum="bc10ad81fb524afbad5eb9f7e9354a24" name="tests/bson-corpus/decimal128-7-parseError-050.phpt" role="test" />
<file md5sum="a690c91d87cab939fd2c4b152e3d5a1f" name="tests/bson-corpus/decimal128-7-parseError-051.phpt" role="test" />
<file md5sum="cdfb6d264322fbd94013be733e93b7e2" name="tests/bson-corpus/decimal128-7-parseError-052.phpt" role="test" />
<file md5sum="b48b0f7abcdaef499f8dd6391a9e73be" name="tests/bson-corpus/decimal128-7-parseError-053.phpt" role="test" />
<file md5sum="51a21d680cf93ca8e61054d1798f3a6d" name="tests/bson-corpus/decimal128-7-parseError-054.phpt" role="test" />
<file md5sum="2fa0d96cc6ca037e731e8d73359254a1" name="tests/bson-corpus/decimal128-7-parseError-055.phpt" role="test" />
<file md5sum="3cb79692a3fff1a2965d633f583ffda1" name="tests/bson-corpus/decimal128-7-parseError-056.phpt" role="test" />
<file md5sum="31668df0a6ae44cd4b8c201b391b3c05" name="tests/bson-corpus/decimal128-7-parseError-057.phpt" role="test" />
<file md5sum="291870eebd18c55b40dd774a1250e6f2" name="tests/bson-corpus/decimal128-7-parseError-058.phpt" role="test" />
<file md5sum="8c8282547270d94ab76310662de33c5f" name="tests/bson-corpus/decimal128-7-parseError-059.phpt" role="test" />
<file md5sum="0a785c54b0e5874555867da3046d0544" name="tests/bson-corpus/decimal128-7-parseError-060.phpt" role="test" />
<file md5sum="8b00ab977fa43482b20fc6cc88923560" name="tests/bson-corpus/decimal128-7-parseError-061.phpt" role="test" />
<file md5sum="87b858d1e87a14f0f3f074a30bc428f4" name="tests/bson-corpus/decimal128-7-parseError-062.phpt" role="test" />
<file md5sum="93c4597cbcf092b83effe458587cab42" name="tests/bson-corpus/decimal128-7-parseError-063.phpt" role="test" />
<file md5sum="5604b3c00d90f38326b2caf587b75d39" name="tests/bson-corpus/decimal128-7-parseError-064.phpt" role="test" />
<file md5sum="7698f35a879199cc6cfbe2975766609a" name="tests/bson-corpus/decimal128-7-parseError-065.phpt" role="test" />
<file md5sum="8c780164635efc163d9e92df2b5fd778" name="tests/bson-corpus/decimal128-7-parseError-066.phpt" role="test" />
<file md5sum="f82b3d0a1e0617ede4d6516f1c34f63e" name="tests/bson-corpus/decimal128-7-parseError-067.phpt" role="test" />
<file md5sum="46d018c7f78ebd672e61f5761327f79e" name="tests/bson-corpus/decimal128-7-parseError-068.phpt" role="test" />
<file md5sum="c39afed94ddc79eacb39bcfde732e058" name="tests/bson-corpus/decimal128-7-parseError-069.phpt" role="test" />
<file md5sum="779aa919b0c83011517a57eb4c677c0a" name="tests/bson-corpus/decimal128-7-parseError-070.phpt" role="test" />
<file md5sum="4d74f03527230857d81b7b22c3a37091" name="tests/bson-corpus/decimal128-7-parseError-071.phpt" role="test" />
<file md5sum="678cdc4e6e63ef31974353cd80fb96b3" name="tests/bson-corpus/decimal128-7-parseError-072.phpt" role="test" />
<file md5sum="7ff4eeca58923e636f37286aea06224f" name="tests/bson-corpus/decimal128-7-parseError-073.phpt" role="test" />
<file md5sum="06cc4c867376e6ff2a138d94d839e521" name="tests/bson-corpus/decimal128-7-parseError-074.phpt" role="test" />
<file md5sum="b207d585456f86a2ff1fbc9934fafc65" name="tests/bson-corpus/decimal128-7-parseError-075.phpt" role="test" />
<file md5sum="e6eb3226d4e334bf082a32beb6f4640e" name="tests/bson-corpus/decimal128-7-parseError-076.phpt" role="test" />
<file md5sum="fc9d86339d2ec2a1fdccd6e13efdccdd" name="tests/bson-corpus/decimal128-7-parseError-077.phpt" role="test" />
<file md5sum="9ff5ca747749d6dd2cad6512ff0ba502" name="tests/bson-corpus/decimal128-7-parseError-078.phpt" role="test" />
<file md5sum="90fb79370f2b72ed1563d30b9015736f" name="tests/bson-corpus/decimal128-7-parseError-079.phpt" role="test" />
<file md5sum="2c7374986d5f75a2c14c2ff7b195a543" name="tests/bson-corpus/decimal128-7-parseError-080.phpt" role="test" />
<file md5sum="b4f5cfd8c1af72e086fcf2f53f911580" name="tests/bson-corpus/document-decodeError-001.phpt" role="test" />
<file md5sum="42b26e9ea5c826cd63b5a4ba2e01152e" name="tests/bson-corpus/document-decodeError-002.phpt" role="test" />
<file md5sum="3c60f26d3ab45610a6e214ca12926b57" name="tests/bson-corpus/document-decodeError-003.phpt" role="test" />
<file md5sum="b71432e20fecfbbd136675551156717b" name="tests/bson-corpus/document-valid-001.phpt" role="test" />
<file md5sum="b0b4b9c4d1d6ecd30899942cb293ffec" name="tests/bson-corpus/document-valid-002.phpt" role="test" />
<file md5sum="b070130d8fcfe008b8b5fe72754e4b9e" name="tests/bson-corpus/document-valid-003.phpt" role="test" />
<file md5sum="5785f63d468dd3d263b6959d2d2f3231" name="tests/bson-corpus/double-decodeError-001.phpt" role="test" />
<file md5sum="c25d9dd31322b620a29376e89b470b3e" name="tests/bson-corpus/double-valid-001.phpt" role="test" />
<file md5sum="e27a84a58acd3483ceea6e8598f5e569" name="tests/bson-corpus/double-valid-002.phpt" role="test" />
<file md5sum="3f094dfb468145dd39698d7008ade9b2" name="tests/bson-corpus/double-valid-003.phpt" role="test" />
<file md5sum="37b83b39bfb17e9e6bbb9263c47b76b4" name="tests/bson-corpus/double-valid-004.phpt" role="test" />
<file md5sum="176b1e8434a4c8319d7a9efe9023ae9a" name="tests/bson-corpus/double-valid-005.phpt" role="test" />
<file md5sum="11650a7fffae73c77db77cc43da70156" name="tests/bson-corpus/double-valid-006.phpt" role="test" />
<file md5sum="50d446cbe8475bbe34b3e3d60b6417b3" name="tests/bson-corpus/double-valid-007.phpt" role="test" />
<file md5sum="7bc4cb4dbf62717fbc354069f6fc9243" name="tests/bson-corpus/double-valid-008.phpt" role="test" />
<file md5sum="71ab6661b8790895c443b7c647bb53af" name="tests/bson-corpus/double-valid-009.phpt" role="test" />
<file md5sum="93b5c5f2636dee82f24ffd42f2a74bee" name="tests/bson-corpus/double-valid-010.phpt" role="test" />
<file md5sum="7a93dcfb31a7f1cc8b538a2b679153d5" name="tests/bson-corpus/double-valid-011.phpt" role="test" />
<file md5sum="59f568be5cd5b412f61907013d0f64e9" name="tests/bson-corpus/double-valid-012.phpt" role="test" />
<file md5sum="0da998151b70c18c67a96d8bc28a01ce" name="tests/bson-corpus/int32-decodeError-001.phpt" role="test" />
<file md5sum="5f47f37ecf54e332d98dd7f005d8bac7" name="tests/bson-corpus/int32-valid-001.phpt" role="test" />
<file md5sum="8e71156bc821c7912aad8061dfae7fab" name="tests/bson-corpus/int32-valid-002.phpt" role="test" />
<file md5sum="b6c5b826eca41d0ee00461d1992963f3" name="tests/bson-corpus/int32-valid-003.phpt" role="test" />
<file md5sum="ce5cfdb10be3feb8adcee2f5edd557c1" name="tests/bson-corpus/int32-valid-004.phpt" role="test" />
<file md5sum="b3d82bf44e3e6be968f38078e460a9ae" name="tests/bson-corpus/int32-valid-005.phpt" role="test" />
<file md5sum="d72c859a13ce93310c4f69b31e58e57e" name="tests/bson-corpus/int64-decodeError-001.phpt" role="test" />
<file md5sum="a3f1a8c46052df6030a22b4268159e5b" name="tests/bson-corpus/int64-valid-001.phpt" role="test" />
<file md5sum="b3cab1e750ec07ecca05dec4b0264cf2" name="tests/bson-corpus/int64-valid-002.phpt" role="test" />
<file md5sum="9007c33064a22e5bfef713a954530c7a" name="tests/bson-corpus/int64-valid-003.phpt" role="test" />
<file md5sum="84237b507c3cd8adad64bc33952689ab" name="tests/bson-corpus/int64-valid-004.phpt" role="test" />
<file md5sum="09e51f0ab0b8ee6c11177b9bb198b14e" name="tests/bson-corpus/int64-valid-005.phpt" role="test" />
<file md5sum="e20137603c2a90305bd4742f03ec48a1" name="tests/bson-corpus/maxkey-valid-001.phpt" role="test" />
<file md5sum="9aac546a028d88f2044b49833eb210d5" name="tests/bson-corpus/minkey-valid-001.phpt" role="test" />
<file md5sum="95c489156077919b60d71ea9641d3e9e" name="tests/bson-corpus/multi-type-deprecated-valid-001.phpt" role="test" />
<file md5sum="bd81777656d4aa81d5d3f25175e9a920" name="tests/bson-corpus/multi-type-valid-001.phpt" role="test" />
<file md5sum="b1333fa4f91e784ef53ccbf077c5dc42" name="tests/bson-corpus/null-valid-001.phpt" role="test" />
<file md5sum="042a55fe8b49061f91ac3f21c9720886" name="tests/bson-corpus/oid-decodeError-001.phpt" role="test" />
<file md5sum="50101edf5a54969a5a8cf70253b50cb1" name="tests/bson-corpus/oid-valid-001.phpt" role="test" />
<file md5sum="700450049438b9bd06520bf6a17c7788" name="tests/bson-corpus/oid-valid-002.phpt" role="test" />
<file md5sum="f3546b078c40a068b7c250da016f9113" name="tests/bson-corpus/oid-valid-003.phpt" role="test" />
<file md5sum="6d2bbf0542ddfb10dbc00c5c9fef742f" name="tests/bson-corpus/regex-decodeError-001.phpt" role="test" />
<file md5sum="0aec7965ead30a0e9bb1d6a9aac6073a" name="tests/bson-corpus/regex-decodeError-002.phpt" role="test" />
<file md5sum="e2a22519ed22c6fd51a15f07cfea6574" name="tests/bson-corpus/regex-valid-001.phpt" role="test" />
<file md5sum="ff971b74a615f126d1683ac064afb486" name="tests/bson-corpus/regex-valid-002.phpt" role="test" />
<file md5sum="e032a9da471e7b8b7b6e214fdc502464" name="tests/bson-corpus/regex-valid-003.phpt" role="test" />
<file md5sum="e32ff0d63d4e978140415c1ee00ec943" name="tests/bson-corpus/regex-valid-004.phpt" role="test" />
<file md5sum="4d3c27a8c2a4f0d00d3bea4dd8fb1845" name="tests/bson-corpus/regex-valid-005.phpt" role="test" />
<file md5sum="dff8cac5463447779eab36cca3dae8d1" name="tests/bson-corpus/regex-valid-006.phpt" role="test" />
<file md5sum="2bab1b2abf90c557456afa3979c3e127" name="tests/bson-corpus/regex-valid-007.phpt" role="test" />
<file md5sum="87257a9e6683539f0234ed1ae77bd366" name="tests/bson-corpus/regex-valid-008.phpt" role="test" />
<file md5sum="dbf6860f5b827b502e1449d4184229e4" name="tests/bson-corpus/regex-valid-009.phpt" role="test" />
<file md5sum="0240e21ac7208bd577ad206545d9079b" name="tests/bson-corpus/string-decodeError-001.phpt" role="test" />
<file md5sum="1b49383dcd31b2fcfd08605d1e11224d" name="tests/bson-corpus/string-decodeError-002.phpt" role="test" />
<file md5sum="b9851ba430d845aa0d0cfbec06986420" name="tests/bson-corpus/string-decodeError-003.phpt" role="test" />
<file md5sum="c5c3e28b1702a4a526998998b65ae2b6" name="tests/bson-corpus/string-decodeError-004.phpt" role="test" />
<file md5sum="09e45dc9b3831b90438d42967d98e81f" name="tests/bson-corpus/string-decodeError-005.phpt" role="test" />
<file md5sum="aef88e1ff7d5b21c715f00a4ca3d44ff" name="tests/bson-corpus/string-decodeError-006.phpt" role="test" />
<file md5sum="d208f92291581f7319ecc9af5f3a0fb7" name="tests/bson-corpus/string-decodeError-007.phpt" role="test" />
<file md5sum="b96f96eac724e666d73f4c7ce146e6d3" name="tests/bson-corpus/string-valid-001.phpt" role="test" />
<file md5sum="c86edeb94cd259c3771c69cfccfe88ff" name="tests/bson-corpus/string-valid-002.phpt" role="test" />
<file md5sum="b69c5ddf7866f0de81d3aaa9923452ba" name="tests/bson-corpus/string-valid-003.phpt" role="test" />
<file md5sum="a09d1c006787d42d982e0a80f80a75e1" name="tests/bson-corpus/string-valid-004.phpt" role="test" />
<file md5sum="f004f57e1908394a0f9d0018c177755c" name="tests/bson-corpus/string-valid-005.phpt" role="test" />
<file md5sum="658c6b0e16fd679f5e7ef30c920e5da3" name="tests/bson-corpus/string-valid-006.phpt" role="test" />
<file md5sum="b9263c54d0a92357a336ab5ff9544911" name="tests/bson-corpus/string-valid-007.phpt" role="test" />
<file md5sum="3d11be58c91b9a1f8d42c2fc4c264733" name="tests/bson-corpus/symbol-decodeError-001.phpt" role="test" />
<file md5sum="8b260ed51ddca45a69acc54bc10d767c" name="tests/bson-corpus/symbol-decodeError-002.phpt" role="test" />
<file md5sum="738ac24d3ec20630f7d29f904bae2209" name="tests/bson-corpus/symbol-decodeError-003.phpt" role="test" />
<file md5sum="35e3562d24a6378a65ce3d3de6b2091b" name="tests/bson-corpus/symbol-decodeError-004.phpt" role="test" />
<file md5sum="2211c7745a5ac3e3c4febf63b4dc827c" name="tests/bson-corpus/symbol-decodeError-005.phpt" role="test" />
<file md5sum="a44e30922c7764b57afff5395bbca126" name="tests/bson-corpus/symbol-decodeError-006.phpt" role="test" />
<file md5sum="097146230f60960a210ca20db243d8d8" name="tests/bson-corpus/symbol-decodeError-007.phpt" role="test" />
<file md5sum="c91d5c1d3f675a8b77155c4863ae31d8" name="tests/bson-corpus/symbol-valid-001.phpt" role="test" />
<file md5sum="d94d8b7c069f4707a0b5850a73c82bbd" name="tests/bson-corpus/symbol-valid-002.phpt" role="test" />
<file md5sum="56dc191f2e7e6e54683fd8e06264e459" name="tests/bson-corpus/symbol-valid-003.phpt" role="test" />
<file md5sum="77217526b5bc90ae8f1a0b7cf85128e0" name="tests/bson-corpus/symbol-valid-004.phpt" role="test" />
<file md5sum="9813119cb30ddfdc73e4e34c9e0c3f12" name="tests/bson-corpus/symbol-valid-005.phpt" role="test" />
<file md5sum="4ea56490f75638b65382afb9372f08f3" name="tests/bson-corpus/symbol-valid-006.phpt" role="test" />
<file md5sum="267928a71cfe6e336a82eef0d3f5b239" name="tests/bson-corpus/timestamp-decodeError-001.phpt" role="test" />
<file md5sum="5469f32d4d42a0d4f9ff2c5bed56a387" name="tests/bson-corpus/timestamp-valid-001.phpt" role="test" />
<file md5sum="3fca07533f08d2fe9821b980afa8a2be" name="tests/bson-corpus/timestamp-valid-002.phpt" role="test" />
<file md5sum="c93eb857dfeb49bf70a7bcc9c0f9a425" name="tests/bson-corpus/timestamp-valid-003.phpt" role="test" />
<file md5sum="17ce094686cb362b80cfe1bca51b7088" name="tests/bson-corpus/top-decodeError-001.phpt" role="test" />
<file md5sum="600cb83eacf159a50fce8ac90cdf74ad" name="tests/bson-corpus/top-decodeError-002.phpt" role="test" />
<file md5sum="05031bb2a71b66c4f7ddee2b6a28ddeb" name="tests/bson-corpus/top-decodeError-003.phpt" role="test" />
<file md5sum="9e10c5ae6ec32276e1fa8a1a4ee892fb" name="tests/bson-corpus/top-decodeError-004.phpt" role="test" />
<file md5sum="68283e51bd216fa7e1b2eb437c3e76d9" name="tests/bson-corpus/top-decodeError-005.phpt" role="test" />
<file md5sum="797ce39fad54934b9b0c0bd6b13511cd" name="tests/bson-corpus/top-decodeError-006.phpt" role="test" />
<file md5sum="ad427d8fe90a3a37af730cb6ed0ca872" name="tests/bson-corpus/top-decodeError-007.phpt" role="test" />
<file md5sum="cf6d4a73c4741f76969251dd6254ef75" name="tests/bson-corpus/top-decodeError-008.phpt" role="test" />
<file md5sum="3d9b849acd268ae10a2cc1658f7fdfed" name="tests/bson-corpus/top-decodeError-009.phpt" role="test" />
<file md5sum="249c629abd447efec58954be6d0bfd90" name="tests/bson-corpus/top-decodeError-010.phpt" role="test" />
<file md5sum="d86a4178bced6e0fc406be05e232f56b" name="tests/bson-corpus/top-decodeError-011.phpt" role="test" />
<file md5sum="6272048144f54d1c61e6dcc2a54577a0" name="tests/bson-corpus/top-decodeError-012.phpt" role="test" />
<file md5sum="e0c5a2f46b6bb5043b0b95a56c7bfc6b" name="tests/bson-corpus/top-decodeError-013.phpt" role="test" />
<file md5sum="bbe865333f4d9917795b2d097bbb2114" name="tests/bson-corpus/top-decodeError-014.phpt" role="test" />
<file md5sum="f4b30ed02746f3520b83c6c680e849cf" name="tests/bson-corpus/top-parseError-001.phpt" role="test" />
<file md5sum="91ff115679200da2479742be4c591690" name="tests/bson-corpus/top-parseError-002.phpt" role="test" />
<file md5sum="6d9d8365254b5cc40f2bfdf0b474b614" name="tests/bson-corpus/top-parseError-003.phpt" role="test" />
<file md5sum="43e86b1dceb98cf74b2e55153cdb9198" name="tests/bson-corpus/top-parseError-004.phpt" role="test" />
<file md5sum="2c97ee609289adb8f2f9a474c562ad14" name="tests/bson-corpus/top-parseError-005.phpt" role="test" />
<file md5sum="2b8b22e19e96a1fce188857b269e80db" name="tests/bson-corpus/top-parseError-006.phpt" role="test" />
<file md5sum="63b0e2d0d4aca2dedadd7c77110b7472" name="tests/bson-corpus/top-parseError-007.phpt" role="test" />
<file md5sum="e8150597fe010182fc52036df6cfda73" name="tests/bson-corpus/top-parseError-008.phpt" role="test" />
<file md5sum="a4216bb01781440e2d893563d2a3e1fe" name="tests/bson-corpus/top-parseError-009.phpt" role="test" />
<file md5sum="23c04f804d78b680143362608b120559" name="tests/bson-corpus/top-parseError-010.phpt" role="test" />
<file md5sum="7aa72cf9cac3c52466857d9f06be03e6" name="tests/bson-corpus/top-parseError-011.phpt" role="test" />
<file md5sum="cf0d10a7ccb9b3cf057bfaf1155c7fe7" name="tests/bson-corpus/top-parseError-012.phpt" role="test" />
<file md5sum="f743225a927233df16827f1b284ec947" name="tests/bson-corpus/top-parseError-013.phpt" role="test" />
<file md5sum="3a3b29d65c4a35d5f27c78043701eff9" name="tests/bson-corpus/top-parseError-014.phpt" role="test" />
<file md5sum="6476201c23012606cc5741b93cdf3a98" name="tests/bson-corpus/top-parseError-015.phpt" role="test" />
<file md5sum="683bf02ff22e94e6b445b2184973bd61" name="tests/bson-corpus/top-parseError-016.phpt" role="test" />
<file md5sum="d08cb48900875f44cc0edcae2d367f54" name="tests/bson-corpus/top-parseError-017.phpt" role="test" />
<file md5sum="325077497c93dfd8f05868675a11156a" name="tests/bson-corpus/top-parseError-018.phpt" role="test" />
<file md5sum="3728e5b380d1342efe7509e86d831d99" name="tests/bson-corpus/top-parseError-019.phpt" role="test" />
<file md5sum="c8912c33f65fca26063d9fc102573667" name="tests/bson-corpus/top-parseError-020.phpt" role="test" />
<file md5sum="cc552f5c94e9381bfe83a2c69c9055e7" name="tests/bson-corpus/top-parseError-021.phpt" role="test" />
<file md5sum="e5c8182e3897dceb743012ceb7d53078" name="tests/bson-corpus/top-parseError-022.phpt" role="test" />
<file md5sum="2ae68a06cd5e15375bac8ba27f320b84" name="tests/bson-corpus/top-parseError-023.phpt" role="test" />
<file md5sum="5fb8365ce1e7c8cc9ae704f1f3e09a49" name="tests/bson-corpus/top-parseError-024.phpt" role="test" />
<file md5sum="182e2b40f8b1258916cab85e9f3b07ed" name="tests/bson-corpus/top-parseError-025.phpt" role="test" />
<file md5sum="7d6ee218b88c852721423dd332a6d5c7" name="tests/bson-corpus/top-parseError-026.phpt" role="test" />
<file md5sum="6b3cb7b036b3bdd2f096a06467321d84" name="tests/bson-corpus/top-parseError-027.phpt" role="test" />
<file md5sum="2475d1436b8e3f8abbf8810d0c9cf20d" name="tests/bson-corpus/top-parseError-028.phpt" role="test" />
<file md5sum="aa111516293dd649fbaf4422d45a7a50" name="tests/bson-corpus/top-parseError-029.phpt" role="test" />
<file md5sum="03a9219928cfc54e7ba0740c5b6da4da" name="tests/bson-corpus/top-parseError-030.phpt" role="test" />
<file md5sum="6ece98f8da86545a67fb6b746bf4bc0f" name="tests/bson-corpus/top-parseError-031.phpt" role="test" />
<file md5sum="be3927befbcc2741e4063f6ad5b85b8a" name="tests/bson-corpus/top-parseError-032.phpt" role="test" />
<file md5sum="0f9ab539216d28503c0e5e964f8ecf5a" name="tests/bson-corpus/top-parseError-033.phpt" role="test" />
<file md5sum="39bc682fadb62d8600396ee6e7964442" name="tests/bson-corpus/top-parseError-034.phpt" role="test" />
<file md5sum="73cc7317c62a4006f0eafeaaa512eda0" name="tests/bson-corpus/top-parseError-035.phpt" role="test" />
<file md5sum="dea2b127c4421799656ac90ac5a8a19a" name="tests/bson-corpus/top-parseError-036.phpt" role="test" />
<file md5sum="cd0ee19e16182cc19bc392cd9828753d" name="tests/bson-corpus/top-parseError-037.phpt" role="test" />
<file md5sum="fa78aa1ba539ffb2af3554812ed1b89c" name="tests/bson-corpus/top-parseError-038.phpt" role="test" />
<file md5sum="de6cb2dae694a93abcd0c55dd1e7e131" name="tests/bson-corpus/top-parseError-039.phpt" role="test" />
<file md5sum="0bc5affa8185d39910c7210cec956be7" name="tests/bson-corpus/top-parseError-040.phpt" role="test" />
<file md5sum="1898e62ad427e74c8ea17da283b99194" name="tests/bson-corpus/top-parseError-041.phpt" role="test" />
<file md5sum="0065bb9e2c526be10241d62820459405" name="tests/bson-corpus/top-valid-001.phpt" role="test" />
<file md5sum="5ec152da957dd51d5ee3fb6a719c2600" name="tests/bson-corpus/undefined-valid-001.phpt" role="test" />
<file md5sum="3d80c1cedf3c4a5efa3796dd674c572f" name="tests/bson/bson-binary-001.phpt" role="test" />
<file md5sum="ed2ceadc61f469667f684a3156043661" name="tests/bson/bson-binary-clone-001.phpt" role="test" />
<file md5sum="78c016cd924e363fb8433ce673a76b6a" name="tests/bson/bson-binary-compare-001.phpt" role="test" />
<file md5sum="6eb6c83707dd7be5c718fa13b0427d6c" name="tests/bson/bson-binary-compare-002.phpt" role="test" />
<file md5sum="58e5df014bd86dd8f1313b3fb734a7ce" name="tests/bson/bson-binary-get_properties-001.phpt" role="test" />
<file md5sum="c61e1c8e4c5327f87674314fde6b5d2f" name="tests/bson/bson-binary-get_properties-002.phpt" role="test" />
<file md5sum="a89324b72c9dbfffca5008d9563565c8" name="tests/bson/bson-binary-jsonserialize-001.phpt" role="test" />
<file md5sum="ba515183a779c4ce6740ba3fb1e46f77" name="tests/bson/bson-binary-jsonserialize-002.phpt" role="test" />
<file md5sum="94deed355325f66c567309e6074cfe7a" name="tests/bson/bson-binary-serialization-001.phpt" role="test" />
<file md5sum="f487c59192b7df686475bfe0be84c3e6" name="tests/bson/bson-binary-serialization_error-001.phpt" role="test" />
<file md5sum="2ebc7a07dd945df1922ca274d04478a8" name="tests/bson/bson-binary-serialization_error-002.phpt" role="test" />
<file md5sum="325c3d210bfa4eb571a36ffa5f75c347" name="tests/bson/bson-binary-serialization_error-003.phpt" role="test" />
<file md5sum="4a4275ac852b7457302ddcb2fdce7544" name="tests/bson/bson-binary-set_state-001.phpt" role="test" />
<file md5sum="bfee0375bac0c0e1a26a34dda9814eb0" name="tests/bson/bson-binary-set_state_error-001.phpt" role="test" />
<file md5sum="b88eb23a9a107c5300863e1dc5a780b0" name="tests/bson/bson-binary-set_state_error-002.phpt" role="test" />
<file md5sum="df1ccfb1bbd3562866bc851709320cd4" name="tests/bson/bson-binary-set_state_error-003.phpt" role="test" />
<file md5sum="2079c2a8ebed8e51c12a0fab40e42ab3" name="tests/bson/bson-binary-tostring-001.phpt" role="test" />
<file md5sum="b347f8c2d418ca38cf19983ec7aa4f9d" name="tests/bson/bson-binary_error-001.phpt" role="test" />
<file md5sum="a9d13886ed7bad49396fe58fb69728dc" name="tests/bson/bson-binary_error-002.phpt" role="test" />
<file md5sum="c52d47c59fa41f83989f99d3b509bc4b" name="tests/bson/bson-binary_error-003.phpt" role="test" />
<file md5sum="47b5df8e7129de482422f2eda5f15be7" name="tests/bson/bson-binary_error-004.phpt" role="test" />
<file md5sum="fe638f713510cf803847a14a9109e6e7" name="tests/bson/bson-binaryinterface-001.phpt" role="test" />
<file md5sum="ccecb42fcff7a5c5ac18f3049f869367" name="tests/bson/bson-dbpointer-001.phpt" role="test" />
<file md5sum="a9eb173b6168b52f6f36a3c1ad230e03" name="tests/bson/bson-dbpointer-002.phpt" role="test" />
<file md5sum="9d2f5ce5b252da2c222cec4f2c9848e8" name="tests/bson/bson-dbpointer-clone-001.phpt" role="test" />
<file md5sum="d583aaa6c756bd85fbc18a1aea0c8375" name="tests/bson/bson-dbpointer-compare-001.phpt" role="test" />
<file md5sum="54a92286eef293b765b118e13c4c35c6" name="tests/bson/bson-dbpointer-get_properties-001.phpt" role="test" />
<file md5sum="7eb0a24e6d9fdb5ba682ed5b56d4e903" name="tests/bson/bson-dbpointer-get_properties-002.phpt" role="test" />
<file md5sum="080fc12205c5e3b7faac905c1492d430" name="tests/bson/bson-dbpointer-jsonserialize-001.phpt" role="test" />
<file md5sum="e5e353372466bdf22c21a2cf2b9d4b7e" name="tests/bson/bson-dbpointer-jsonserialize-003.phpt" role="test" />
<file md5sum="8f81f1d20a38681c86091496d0fbf318" name="tests/bson/bson-dbpointer-serialization-001.phpt" role="test" />
<file md5sum="2edafeb76539e7a390372cfabc097c69" name="tests/bson/bson-dbpointer-serialization_error-001.phpt" role="test" />
<file md5sum="3cc4a7fdb023213b9528558497fe03d4" name="tests/bson/bson-dbpointer-serialization_error-002.phpt" role="test" />
<file md5sum="9967c68c7c6be7228d00469feb0a1a44" name="tests/bson/bson-dbpointer-tostring-001.phpt" role="test" />
<file md5sum="b014e534e95c2a043f33d4e65fb876df" name="tests/bson/bson-dbpointer_error-002.phpt" role="test" />
<file md5sum="1b07dc40c0327eaa948a01415e80156e" name="tests/bson/bson-decimal128-001.phpt" role="test" />
<file md5sum="aa1a54f32962e51878159b0b3f25a83a" name="tests/bson/bson-decimal128-002.phpt" role="test" />
<file md5sum="b17b174c54b38e37a407f8fb35aff65e" name="tests/bson/bson-decimal128-003.phpt" role="test" />
<file md5sum="b6d96feed66dfb73e8220e48e58337a1" name="tests/bson/bson-decimal128-004.phpt" role="test" />
<file md5sum="0f6988e90559d6d9f1a55d433bd02e8a" name="tests/bson/bson-decimal128-clone-001.phpt" role="test" />
<file md5sum="49024c33887fe583b96d02a37d826015" name="tests/bson/bson-decimal128-get_properties-001.phpt" role="test" />
<file md5sum="2078cc54b51b316910e7724a9fd6a346" name="tests/bson/bson-decimal128-get_properties-002.phpt" role="test" />
<file md5sum="b82e77c47a326ab042f1e35ec4725e51" name="tests/bson/bson-decimal128-jsonserialize-001.phpt" role="test" />
<file md5sum="afbe9023c707b866dcc078d3b126ba0a" name="tests/bson/bson-decimal128-jsonserialize-002.phpt" role="test" />
<file md5sum="4c603508bb6b9838066286014832c97f" name="tests/bson/bson-decimal128-serialization-001.phpt" role="test" />
<file md5sum="18bcb6a21e50d2bbdfc8f05dd81ea095" name="tests/bson/bson-decimal128-serialization_error-001.phpt" role="test" />
<file md5sum="105c568368afe25b76a7f4d2cbc8ab32" name="tests/bson/bson-decimal128-serialization_error-002.phpt" role="test" />
<file md5sum="3a8bcad13be933556fd0967a643293ac" name="tests/bson/bson-decimal128-set_state-001.phpt" role="test" />
<file md5sum="db934fbaaeca32c3461ca5a0e3924b3c" name="tests/bson/bson-decimal128-set_state_error-001.phpt" role="test" />
<file md5sum="cc39b9bf030108cc2e36cec032c3e021" name="tests/bson/bson-decimal128-set_state_error-002.phpt" role="test" />
<file md5sum="d8f8e22c20591565326ca9049c000bd9" name="tests/bson/bson-decimal128_error-001.phpt" role="test" />
<file md5sum="c551b87ae2e2987ba8e5518c73aed1f6" name="tests/bson/bson-decimal128_error-002.phpt" role="test" />
<file md5sum="a7dbd531a5dace1341acdf77d3821da3" name="tests/bson/bson-decimal128interface-001.phpt" role="test" />
<file md5sum="d9e66d3693c33a70a8f302b285d6a017" name="tests/bson/bson-decode-001.phpt" role="test" />
<file md5sum="72c9ae0b2a63b4734b4242634b26d838" name="tests/bson/bson-decode-002.phpt" role="test" />
<file md5sum="c537992ae377109995cc650def0fbe31" name="tests/bson/bson-encode-001.phpt" role="test" />
<file md5sum="7d63ae8f6ffe1c3723de519a28c518a8" name="tests/bson/bson-encode-002.phpt" role="test" />
<file md5sum="d550fc4626346715c42734b53530214c" name="tests/bson/bson-encode-003.phpt" role="test" />
<file md5sum="3522dbb44d2bd025ab4af336ceedb5be" name="tests/bson/bson-encode-004.phpt" role="test" />
<file md5sum="9b2c1fb3ece5c67bf2593e78ebd4481d" name="tests/bson/bson-encode-005.phpt" role="test" />
<file md5sum="9f2c849e9e4d87c63fee4591fc4c3e3f" name="tests/bson/bson-fromJSON-001.phpt" role="test" />
<file md5sum="08a8c4233a4a4d3d5216bbc289189e79" name="tests/bson/bson-fromJSON-002.phpt" role="test" />
<file md5sum="729e16c01e1318e6a3e74c1a28139e5e" name="tests/bson/bson-fromJSON_error-001.phpt" role="test" />
<file md5sum="ef65020cde3e656d01e8dd4b70f5211e" name="tests/bson/bson-fromPHP-001.phpt" role="test" />
<file md5sum="06ede31fb02f0b324a717cadb4265039" name="tests/bson/bson-fromPHP-002.phpt" role="test" />
<file md5sum="5cd6e5efd2648c553440a51f3ad3598d" name="tests/bson/bson-fromPHP-003.phpt" role="test" />
<file md5sum="cdee70ad41d06ebf5433f0c123d8b473" name="tests/bson/bson-fromPHP-005.phpt" role="test" />
<file md5sum="fb00e3c73770eaa72d2c4042438a698a" name="tests/bson/bson-fromPHP-006.phpt" role="test" />
<file md5sum="37da86a86d36cd1daed3a9bfa248f70e" name="tests/bson/bson-fromPHP_error-001.phpt" role="test" />
<file md5sum="ef68d2538f8ba276e2c1f5d2cf2ddfc9" name="tests/bson/bson-fromPHP_error-002.phpt" role="test" />
<file md5sum="f993198bf3a01d40aa7b99bdde1ffdc5" name="tests/bson/bson-fromPHP_error-003.phpt" role="test" />
<file md5sum="1c04d76289edca5f11debc932a34d41a" name="tests/bson/bson-fromPHP_error-004.phpt" role="test" />
<file md5sum="25c8a2dce3c0bf744ea7299af0ec7566" name="tests/bson/bson-fromPHP_error-005.phpt" role="test" />
<file md5sum="770dc582943380506e71373bf2b7a26e" name="tests/bson/bson-fromPHP_error-006.phpt" role="test" />
<file md5sum="a2e0a4b52f68269b2438cd87a6f9cf60" name="tests/bson/bson-fromPHP_error-007.phpt" role="test" />
<file md5sum="b064e9510af10fb5bbd0ca9e8de7c17a" name="tests/bson/bson-fromPHP_error-008.phpt" role="test" />
<file md5sum="f6d0cd61c063f7a75cd28fb2532b3f23" name="tests/bson/bson-generate-document-id.phpt" role="test" />
<file md5sum="734a26320f6c21f4843d6b91bd986c92" name="tests/bson/bson-int64-001.phpt" role="test" />
<file md5sum="bb10023184831709486f50af335da27d" name="tests/bson/bson-int64-002.phpt" role="test" />
<file md5sum="a1a1f85b23be0c1715e8ec4144208ed9" name="tests/bson/bson-int64-003.phpt" role="test" />
<file md5sum="bc8258611a29335e873c4f9e2e071a5c" name="tests/bson/bson-int64-clone-001.phpt" role="test" />
<file md5sum="3e9447dc7f3c1f1d40741b8585fe7807" name="tests/bson/bson-int64-compare-001.phpt" role="test" />
<file md5sum="c213fa3095e2825c4743677d746b1439" name="tests/bson/bson-int64-debug-001.phpt" role="test" />
<file md5sum="9cf48adc54bdbcbcecb5a2d9fd7c83c5" name="tests/bson/bson-int64-get_properties-001.phpt" role="test" />
<file md5sum="4900dd4d57070508e00217e51f470024" name="tests/bson/bson-int64-get_properties-002.phpt" role="test" />
<file md5sum="3e267e9d9f2bd1c6e3cf496dc153291c" name="tests/bson/bson-int64-jsonserialize-001.phpt" role="test" />
<file md5sum="7ce34a4fb651813d599dc770d61ef203" name="tests/bson/bson-int64-jsonserialize-002.phpt" role="test" />
<file md5sum="2b72562264c5a073b5013b0a48bb36c5" name="tests/bson/bson-int64-serialization-001.phpt" role="test" />
<file md5sum="05cbed2ca31e86e60e51c93f5e008379" name="tests/bson/bson-int64-serialization_error-001.phpt" role="test" />
<file md5sum="b742b905af55fa62956722bc4ca9f3af" name="tests/bson/bson-int64-serialization_error-002.phpt" role="test" />
<file md5sum="d3d5527a1ed2efe91fa1772c9f4b9698" name="tests/bson/bson-int64-tostring-001.phpt" role="test" />
<file md5sum="bfc1487b2aaa119d7da844a767f76487" name="tests/bson/bson-int64_error-001.phpt" role="test" />
<file md5sum="3ee11e5db8d124bc21663bb2f306b983" name="tests/bson/bson-javascript-001.phpt" role="test" />
<file md5sum="9c91bd749fd0ab27a36d14394a5e424b" name="tests/bson/bson-javascript-002.phpt" role="test" />
<file md5sum="7251917701d3bbf22a6caba54c332bd4" name="tests/bson/bson-javascript-clone-001.phpt" role="test" />
<file md5sum="97e60e9d937e0545fdd93efbc9f78c7f" name="tests/bson/bson-javascript-compare-001.phpt" role="test" />
<file md5sum="6fa03185f5a88f493df843621065aeb9" name="tests/bson/bson-javascript-compare-002.phpt" role="test" />
<file md5sum="3567bceb79c30dfd50838a0267a69c62" name="tests/bson/bson-javascript-getCode-001.phpt" role="test" />
<file md5sum="540de5d9a88362eb9f00555a1fb35597" name="tests/bson/bson-javascript-getScope-001.phpt" role="test" />
<file md5sum="e25c7ca28f41bf8785962a44c62b2159" name="tests/bson/bson-javascript-get_properties-001.phpt" role="test" />
<file md5sum="d422d8249db5a52a19a9fb2bf3e2b631" name="tests/bson/bson-javascript-get_properties-002.phpt" role="test" />
<file md5sum="b56136e8638788b0e72210ae82293c4a" name="tests/bson/bson-javascript-jsonserialize-001.phpt" role="test" />
<file md5sum="08155bf6625a0317d0daebba81670fcc" name="tests/bson/bson-javascript-jsonserialize-002.phpt" role="test" />
<file md5sum="50f282c4901a3e1640c94fc927f714f0" name="tests/bson/bson-javascript-jsonserialize-003.phpt" role="test" />
<file md5sum="8b577cf09bca8e3fc9614d616c19860e" name="tests/bson/bson-javascript-jsonserialize-004.phpt" role="test" />
<file md5sum="6715a176827be6b7f3ef2226d9599063" name="tests/bson/bson-javascript-serialization-001.phpt" role="test" />
<file md5sum="3b734b3672e2fb7c22d631e30a668572" name="tests/bson/bson-javascript-serialization_error-001.phpt" role="test" />
<file md5sum="aad55f29fc2f8cb29fbe24be4f8e3f45" name="tests/bson/bson-javascript-serialization_error-002.phpt" role="test" />
<file md5sum="71105272974df96fcc305b2c19b3055f" name="tests/bson/bson-javascript-serialization_error-003.phpt" role="test" />
<file md5sum="8b7ae41cc5888baaa121061c665ba301" name="tests/bson/bson-javascript-set_state-001.phpt" role="test" />
<file md5sum="b1ca12563c821779cb762995b0eb72c1" name="tests/bson/bson-javascript-set_state_error-001.phpt" role="test" />
<file md5sum="abb0c3c2cb58a5b2ee28849a5fdebcc8" name="tests/bson/bson-javascript-set_state_error-002.phpt" role="test" />
<file md5sum="23f1dcb1ec478e1ccad03999c2f7a023" name="tests/bson/bson-javascript-set_state_error-003.phpt" role="test" />
<file md5sum="4a853962f168d677f3e9c2087766fa29" name="tests/bson/bson-javascript-tostring-001.phpt" role="test" />
<file md5sum="7f3d6e574efcc98b4db1fbe543bdb12e" name="tests/bson/bson-javascript_error-001.phpt" role="test" />
<file md5sum="3c848a8651ccfeddeb8a6c2d60a986f3" name="tests/bson/bson-javascript_error-002.phpt" role="test" />
<file md5sum="02fba91408fc0f350a204bc8b1d3f04c" name="tests/bson/bson-javascript_error-003.phpt" role="test" />
<file md5sum="91e37d158699b239d09f45bac8b3a237" name="tests/bson/bson-javascriptinterface-001.phpt" role="test" />
<file md5sum="726fe1860dfb685818b14c5a6be825ea" name="tests/bson/bson-maxkey-001.phpt" role="test" />
<file md5sum="99b4187d536dc839066a926b7d672f7a" name="tests/bson/bson-maxkey-clone-001.phpt" role="test" />
<file md5sum="1640c877e8ffab77ca2a49939721f325" name="tests/bson/bson-maxkey-compare-001.phpt" role="test" />
<file md5sum="4314312c271b5c33f53a4d3887a683b0" name="tests/bson/bson-maxkey-jsonserialize-001.phpt" role="test" />
<file md5sum="a57e651d344bd32f6ac3f820a222bfa2" name="tests/bson/bson-maxkey-jsonserialize-002.phpt" role="test" />
<file md5sum="6e74674e084b8fb81f31e9863a87079d" name="tests/bson/bson-maxkey-serialization-001.phpt" role="test" />
<file md5sum="ea86c16672ce4ca92a750eb7de2837e5" name="tests/bson/bson-maxkey-set_state-001.phpt" role="test" />
<file md5sum="101130436ace2c1418413a1cdd3cc5a5" name="tests/bson/bson-maxkey_error-001.phpt" role="test" />
<file md5sum="d9a42b06a0a7d9b8103ffee8a638c7b5" name="tests/bson/bson-maxkeyinterface-001.phpt" role="test" />
<file md5sum="62d2b76e5ddf5a724d21ae546b7561b1" name="tests/bson/bson-minkey-001.phpt" role="test" />
<file md5sum="5d69570131fe8a1649287c0369d31599" name="tests/bson/bson-minkey-clone-001.phpt" role="test" />
<file md5sum="cab9d17b350f7ff0fb3930aa298f626a" name="tests/bson/bson-minkey-compare-001.phpt" role="test" />
<file md5sum="6b2c6c29ac2dbc4f91392779b99d562c" name="tests/bson/bson-minkey-jsonserialize-001.phpt" role="test" />
<file md5sum="ee6731f161e2de2523764a03c4693783" name="tests/bson/bson-minkey-jsonserialize-002.phpt" role="test" />
<file md5sum="37fe1c3d8e22afe72cdbb2b6c445eba4" name="tests/bson/bson-minkey-serialization-001.phpt" role="test" />
<file md5sum="74201982485a724a0822cc2f2093cb75" name="tests/bson/bson-minkey-set_state-001.phpt" role="test" />
<file md5sum="910f6541ade6c03374170c097907a8b2" name="tests/bson/bson-minkey_error-001.phpt" role="test" />
<file md5sum="0a45023579316c69f78806f230ba106c" name="tests/bson/bson-minkeyinterface-001.phpt" role="test" />
<file md5sum="6a98e167419823a2ae98732fbcdc16ef" name="tests/bson/bson-objectid-001.phpt" role="test" />
<file md5sum="d1eae72097de3d1e1bd0ef60f4e35cd6" name="tests/bson/bson-objectid-002.phpt" role="test" />
<file md5sum="c994597716974e44d2586b1fd6abe4a8" name="tests/bson/bson-objectid-003.phpt" role="test" />
<file md5sum="b9a3a09dd645ff06e975d192c34ad587" name="tests/bson/bson-objectid-004.phpt" role="test" />
<file md5sum="bde3597cc2da978c6f610be4f4e0af99" name="tests/bson/bson-objectid-clone-001.phpt" role="test" />
<file md5sum="a777ad1f36f9f3ab61a31848e29fbda3" name="tests/bson/bson-objectid-compare-001.phpt" role="test" />
<file md5sum="45a5c909f831527ec527dc6dff83a41d" name="tests/bson/bson-objectid-compare-002.phpt" role="test" />
<file md5sum="5f4fc31b72fbf2946cabfbe801e1f8e5" name="tests/bson/bson-objectid-getTimestamp-001.phpt" role="test" />
<file md5sum="04c2bfef7d149d82b796f8257ae8d1ee" name="tests/bson/bson-objectid-getTimestamp-002.phpt" role="test" />
<file md5sum="cae2d6ff62f134db503c739f79da7516" name="tests/bson/bson-objectid-get_properties-001.phpt" role="test" />
<file md5sum="ce20450b15ec7489bc67392e0af50231" name="tests/bson/bson-objectid-get_properties-002.phpt" role="test" />
<file md5sum="2927bb3a1e8581dada0e53f8c701f30d" name="tests/bson/bson-objectid-jsonserialize-001.phpt" role="test" />
<file md5sum="d64b11cf175f975ebe964b1dd1684d52" name="tests/bson/bson-objectid-jsonserialize-002.phpt" role="test" />
<file md5sum="5e8370c65ccd9bd3af9268acbc0b2d32" name="tests/bson/bson-objectid-serialization-001.phpt" role="test" />
<file md5sum="147723e5365c43ef3947319b75374d05" name="tests/bson/bson-objectid-serialization_error-001.phpt" role="test" />
<file md5sum="30c5ef0be71cb20a6d59055090d4c360" name="tests/bson/bson-objectid-serialization_error-002.phpt" role="test" />
<file md5sum="5d2fd4b95c5120b2f79599dab1d8611f" name="tests/bson/bson-objectid-set_state-001.phpt" role="test" />
<file md5sum="1bd644e702a2bbd2524899eee772ec0c" name="tests/bson/bson-objectid-set_state_error-001.phpt" role="test" />
<file md5sum="67d3e6886da704de351a6aa49b256c74" name="tests/bson/bson-objectid-set_state_error-002.phpt" role="test" />
<file md5sum="53f896b8b17ed91961848044f0c9a67f" name="tests/bson/bson-objectid_error-001.phpt" role="test" />
<file md5sum="d89e2fd1b54762f478872976049633ec" name="tests/bson/bson-objectid_error-002.phpt" role="test" />
<file md5sum="51145ee580d4b4dced0c2f23f0fbbfca" name="tests/bson/bson-objectid_error-003.phpt" role="test" />
<file md5sum="94512cbf7a26273ee3b7191601600674" name="tests/bson/bson-objectidinterface-001.phpt" role="test" />
<file md5sum="36f88ff62e81bfc544a0f70a055a301b" name="tests/bson/bson-regex-001.phpt" role="test" />
<file md5sum="c6d502bd80b12b49bb86ca15cd80cb5d" name="tests/bson/bson-regex-002.phpt" role="test" />
<file md5sum="986da81902669ff49dd126f04122b14e" name="tests/bson/bson-regex-003.phpt" role="test" />
<file md5sum="511347e513bdf3bc2ae37aa34b146c01" name="tests/bson/bson-regex-004.phpt" role="test" />
<file md5sum="c5aeef20912e9660c5b9b9916e6061ed" name="tests/bson/bson-regex-005.phpt" role="test" />
<file md5sum="343c27a913b443e296a90286b9da70e6" name="tests/bson/bson-regex-clone-001.phpt" role="test" />
<file md5sum="6f0accb9c2f47fd13f287b115e1fdb69" name="tests/bson/bson-regex-compare-001.phpt" role="test" />
<file md5sum="78e0fcaa87dc451f34f9ef119e1bd274" name="tests/bson/bson-regex-compare-002.phpt" role="test" />
<file md5sum="7b006f20fc2ac164fb4bdce2846da38b" name="tests/bson/bson-regex-get_properties-001.phpt" role="test" />
<file md5sum="6324a488905bb05b3d2e75375c69d88a" name="tests/bson/bson-regex-get_properties-002.phpt" role="test" />
<file md5sum="6fa2a0677b01b0c63ac9e75d7189de73" name="tests/bson/bson-regex-jsonserialize-001.phpt" role="test" />
<file md5sum="b74df13ee5230ede71e1c6dab4439d2f" name="tests/bson/bson-regex-jsonserialize-002.phpt" role="test" />
<file md5sum="f2443282d9f3e636c68051904febb3e7" name="tests/bson/bson-regex-jsonserialize-003.phpt" role="test" />
<file md5sum="3e8cea9be0207736f5f1a57b7f3f985a" name="tests/bson/bson-regex-jsonserialize-004.phpt" role="test" />
<file md5sum="66647e53b95c6eafb52d98e2d9196c7f" name="tests/bson/bson-regex-serialization-001.phpt" role="test" />
<file md5sum="f5eca804b8710b015d2f90c8d8c71368" name="tests/bson/bson-regex-serialization-002.phpt" role="test" />
<file md5sum="e42ec5b985814f1dd3c3ce3acbcbc00f" name="tests/bson/bson-regex-serialization-003.phpt" role="test" />
<file md5sum="07c7662c6b8dcc5723693077eae6c9fd" name="tests/bson/bson-regex-serialization_error-001.phpt" role="test" />
<file md5sum="733b4696d0d9e1b0da751510a761acc5" name="tests/bson/bson-regex-serialization_error-002.phpt" role="test" />
<file md5sum="1761af9218ff1583f51133d4f0cdcb19" name="tests/bson/bson-regex-set_state-001.phpt" role="test" />
<file md5sum="ab56bd68ecf9ea5717facbaa141db1b5" name="tests/bson/bson-regex-set_state-002.phpt" role="test" />
<file md5sum="22816419e87ffa591bfb03a921ea750c" name="tests/bson/bson-regex-set_state_error-001.phpt" role="test" />
<file md5sum="377e4b051a65dd08a16966cbd92f413c" name="tests/bson/bson-regex-set_state_error-002.phpt" role="test" />
<file md5sum="3d8f867dcd7ff6f50b6d34aefd27b656" name="tests/bson/bson-regex_error-001.phpt" role="test" />
<file md5sum="3422fde80d9b7e49dc5d430a10fa9862" name="tests/bson/bson-regex_error-002.phpt" role="test" />
<file md5sum="cdfaa1039a4cd0da222c476c1b6760ac" name="tests/bson/bson-regex_error-003.phpt" role="test" />
<file md5sum="b3c02b3eb309f7bbf5a33523a120b43f" name="tests/bson/bson-regexinterface-001.phpt" role="test" />
<file md5sum="049265745d1c20d6a527d5ddb093e987" name="tests/bson/bson-symbol-001.phpt" role="test" />
<file md5sum="f9fa29cc20bb17cada126b73688f61ad" name="tests/bson/bson-symbol-clone-001.phpt" role="test" />
<file md5sum="a55dbbc77a3a9221810c032f38d25005" name="tests/bson/bson-symbol-compare-001.phpt" role="test" />
<file md5sum="e0b90e25e3507d77a97b7463ab76c0d4" name="tests/bson/bson-symbol-get_properties-001.phpt" role="test" />
<file md5sum="0648e9bf022072d2eb9343fb99f30a0a" name="tests/bson/bson-symbol-get_properties-002.phpt" role="test" />
<file md5sum="218eba280d32b6bbe135d24fb530ecb1" name="tests/bson/bson-symbol-jsonserialize-001.phpt" role="test" />
<file md5sum="380d842bbdea45f6a8582ec563d2b64e" name="tests/bson/bson-symbol-jsonserialize-002.phpt" role="test" />
<file md5sum="55905512f51a5e7e449576456797c704" name="tests/bson/bson-symbol-serialization-001.phpt" role="test" />
<file md5sum="e0b13e8d18c0df3daa074afa7586758f" name="tests/bson/bson-symbol-serialization_error-001.phpt" role="test" />
<file md5sum="d409f086553d6059c65972228ba02b9e" name="tests/bson/bson-symbol-serialization_error-002.phpt" role="test" />
<file md5sum="5753cdf389e2e3cb769eaa272f4a285e" name="tests/bson/bson-symbol-tostring-001.phpt" role="test" />
<file md5sum="660786fbe39ddfa70e3d471a551fc52b" name="tests/bson/bson-symbol_error-001.phpt" role="test" />
<file md5sum="fd6921fa653d75593cebefdee44f3a37" name="tests/bson/bson-timestamp-001.phpt" role="test" />
<file md5sum="94cee14f3d06ab8085f06c241a976589" name="tests/bson/bson-timestamp-002.phpt" role="test" />
<file md5sum="a0763909d65abab501df3471d9cf0009" name="tests/bson/bson-timestamp-003.phpt" role="test" />
<file md5sum="3932a3692389d969ee55de22034324b1" name="tests/bson/bson-timestamp-004.phpt" role="test" />
<file md5sum="db926cded84f832c39e527d5fcdadcbb" name="tests/bson/bson-timestamp-005.phpt" role="test" />
<file md5sum="7a9928568f2b6519cca73c412800c549" name="tests/bson/bson-timestamp-clone-001.phpt" role="test" />
<file md5sum="bf27f37b85d838f7f3601f1733674ebe" name="tests/bson/bson-timestamp-compare-001.phpt" role="test" />
<file md5sum="8d390960f78a0d4c874f1a9bea6f60e1" name="tests/bson/bson-timestamp-getIncrement-001.phpt" role="test" />
<file md5sum="dbc98d4c863f2edbd470a744569b8ebc" name="tests/bson/bson-timestamp-getTimestamp-001.phpt" role="test" />
<file md5sum="70cbe569659d4cd104ded6f0b3954697" name="tests/bson/bson-timestamp-get_properties-001.phpt" role="test" />
<file md5sum="1cb51102b60c196d34c7c1588b91ae78" name="tests/bson/bson-timestamp-get_properties-002.phpt" role="test" />
<file md5sum="4ff5e264bb118d99302fb918e2b54ea4" name="tests/bson/bson-timestamp-jsonserialize-001.phpt" role="test" />
<file md5sum="b3c0547739e7996b33b49eddf15ca4bf" name="tests/bson/bson-timestamp-jsonserialize-002.phpt" role="test" />
<file md5sum="5bfc985572b0eae61c2e3e7afe46588b" name="tests/bson/bson-timestamp-serialization-001.phpt" role="test" />
<file md5sum="89ee88f82bd68012d2ab0d7cec057add" name="tests/bson/bson-timestamp-serialization-002.phpt" role="test" />
<file md5sum="29db1408dde1310afa8066e7233c3db6" name="tests/bson/bson-timestamp-serialization_error-001.phpt" role="test" />
<file md5sum="546931ee801ed3c60e649573cddf813f" name="tests/bson/bson-timestamp-serialization_error-002.phpt" role="test" />
<file md5sum="3623cb6f0ef62c302ced4b3acf1f1b3f" name="tests/bson/bson-timestamp-serialization_error-003.phpt" role="test" />
<file md5sum="f7d7dd2398c27c27def6cb8dab685315" name="tests/bson/bson-timestamp-serialization_error-004.phpt" role="test" />
<file md5sum="7a13dad169f79e7cda4ab3c7a8e2dc1f" name="tests/bson/bson-timestamp-set_state-001.phpt" role="test" />
<file md5sum="2137458362aca8c1a3d8f6224c438d9e" name="tests/bson/bson-timestamp-set_state-002.phpt" role="test" />
<file md5sum="effc86aba9ebac7be6f37ace2f24fc66" name="tests/bson/bson-timestamp-set_state_error-001.phpt" role="test" />
<file md5sum="4bd04c958a1ed842374aec323736bb00" name="tests/bson/bson-timestamp-set_state_error-002.phpt" role="test" />
<file md5sum="9a74bed31b0456757323dd297e0cf7d6" name="tests/bson/bson-timestamp-set_state_error-003.phpt" role="test" />
<file md5sum="e8957247a4043fc91f223da4ed9ec84e" name="tests/bson/bson-timestamp-set_state_error-004.phpt" role="test" />
<file md5sum="793354e47905c97cc4294d1b4be471e1" name="tests/bson/bson-timestamp_error-001.phpt" role="test" />
<file md5sum="82668bc9b4f77d46a5e32b9117fb355e" name="tests/bson/bson-timestamp_error-002.phpt" role="test" />
<file md5sum="22a4db204fc36bb46ac9ec53c494bc8b" name="tests/bson/bson-timestamp_error-003.phpt" role="test" />
<file md5sum="490199683c8657f10b662d5987abf546" name="tests/bson/bson-timestamp_error-004.phpt" role="test" />
<file md5sum="e10ea28f50dcdf86978919777ed5c74e" name="tests/bson/bson-timestamp_error-005.phpt" role="test" />
<file md5sum="f46e2440763b6497ffa907b66cf47752" name="tests/bson/bson-timestamp_error-006.phpt" role="test" />
<file md5sum="304b9fe634cafb1fb611d793197f60ec" name="tests/bson/bson-timestampinterface-001.phpt" role="test" />
<file md5sum="2473a1824e9801db25f815431426ca16" name="tests/bson/bson-toCanonicalJSON-001.phpt" role="test" />
<file md5sum="e39ea45b387e39515b840ec5b8a3135d" name="tests/bson/bson-toCanonicalJSON-002.phpt" role="test" />
<file md5sum="5c6650a3f73652dc05f756362b2447c2" name="tests/bson/bson-toCanonicalJSON_error-001.phpt" role="test" />
<file md5sum="e43ad22bbd940468212c5f138deedc2b" name="tests/bson/bson-toCanonicalJSON_error-002.phpt" role="test" />
<file md5sum="44685227625e78d0cc329a9c7f6e9c50" name="tests/bson/bson-toCanonicalJSON_error-003.phpt" role="test" />
<file md5sum="b3c4355b7d9dc5f2bd5897262e7f6072" name="tests/bson/bson-toJSON-001.phpt" role="test" />
<file md5sum="85790d6c33597dbc5185a551a6683141" name="tests/bson/bson-toJSON-002.phpt" role="test" />
<file md5sum="0a2207ba503d14dd271697e38ff60cbe" name="tests/bson/bson-toJSON_error-001.phpt" role="test" />
<file md5sum="9ddc7084c84ee21a184dc666a023049d" name="tests/bson/bson-toJSON_error-002.phpt" role="test" />
<file md5sum="177c53c68054489653d433bf0143a15e" name="tests/bson/bson-toJSON_error-003.phpt" role="test" />
<file md5sum="852eed0a106c82c454a8b567e01018bc" name="tests/bson/bson-toPHP-001.phpt" role="test" />
<file md5sum="2eb4b1aa39d8e6029fe79a7d87cb1101" name="tests/bson/bson-toPHP-002.phpt" role="test" />
<file md5sum="196ffa4a0c9763794b77551fc1114f79" name="tests/bson/bson-toPHP-003.phpt" role="test" />
<file md5sum="ee0bf59df01713d93b9efcc51b3a5edd" name="tests/bson/bson-toPHP-004.phpt" role="test" />
<file md5sum="4ccc17d46eda70ad34118644e960f18a" name="tests/bson/bson-toPHP-006.phpt" role="test" />
<file md5sum="a0b49d8b87a293efe7aa38950455b894" name="tests/bson/bson-toPHP-007.phpt" role="test" />
<file md5sum="ee6e525749af76f2ae9c761385ab330a" name="tests/bson/bson-toPHP-008.phpt" role="test" />
<file md5sum="6133bbf84603ad85a47a0c12990fc18e" name="tests/bson/bson-toPHP-009.phpt" role="test" />
<file md5sum="0f876fb762849183f99bf566dc0ac541" name="tests/bson/bson-toPHP-010.phpt" role="test" />
<file md5sum="021c453d17946caa7884add32eaef589" name="tests/bson/bson-toPHP-011.phpt" role="test" />
<file md5sum="365a4c9626dec315f8eddf0140c5b2e2" name="tests/bson/bson-toPHP_error-001.phpt" role="test" />
<file md5sum="7d296259645fb541f47952e8d528eba7" name="tests/bson/bson-toPHP_error-002.phpt" role="test" />
<file md5sum="e4204cc33475f1a76d9670b9de1f2d50" name="tests/bson/bson-toPHP_error-003.phpt" role="test" />
<file md5sum="ce74e8344d7e39ed56440643690aba00" name="tests/bson/bson-toPHP_error-004.phpt" role="test" />
<file md5sum="81f3916c20e89abdd32906b543a343ef" name="tests/bson/bson-toPHP_error-005.phpt" role="test" />
<file md5sum="70da79d6ebc4f973f5a39740c46d1530" name="tests/bson/bson-toPHP_error-006.phpt" role="test" />
<file md5sum="a9e58db0748ac3208b802941b30a389e" name="tests/bson/bson-toRelaxedJSON-001.phpt" role="test" />
<file md5sum="403af2cffe3eec241affea1737dd93f0" name="tests/bson/bson-toRelaxedJSON-002.phpt" role="test" />
<file md5sum="6a318442df977699b54c48460d713f4e" name="tests/bson/bson-toRelaxedJSON_error-001.phpt" role="test" />
<file md5sum="0d5c5385c5e6e52c3551503ad33cf19c" name="tests/bson/bson-toRelaxedJSON_error-002.phpt" role="test" />
<file md5sum="7bdb79435458303d103ea1f55c6fe7ad" name="tests/bson/bson-toRelaxedJSON_error-003.phpt" role="test" />
<file md5sum="f598ba4224ca96027f18c20bcf037b19" name="tests/bson/bson-undefined-001.phpt" role="test" />
<file md5sum="99d067198e5658f553c210a3785148b2" name="tests/bson/bson-undefined-clone-001.phpt" role="test" />
<file md5sum="dc74e078f67345758dbb837e9d1f0f6e" name="tests/bson/bson-undefined-compare-001.phpt" role="test" />
<file md5sum="286eaff5b548beb827ac4e7641bf0cf8" name="tests/bson/bson-undefined-jsonserialize-001.phpt" role="test" />
<file md5sum="afa7092fad05aa85063b74c4761670c1" name="tests/bson/bson-undefined-jsonserialize-002.phpt" role="test" />
<file md5sum="e48cf56855e1cb5778de9be4afb9db70" name="tests/bson/bson-undefined-serialization-001.phpt" role="test" />
<file md5sum="efc4ba473c747b5b0dc5b5ac7fbeb8c4" name="tests/bson/bson-undefined-tostring-001.phpt" role="test" />
<file md5sum="16fc8af65414cc3910a0d05478fbfeca" name="tests/bson/bson-undefined_error-001.phpt" role="test" />
<file md5sum="bb1d4baf6117f3219afe0f2dfafb6437" name="tests/bson/bson-unknown-001.phpt" role="test" />
<file md5sum="28b1517c06aad34ce7dd88be5aa80846" name="tests/bson/bson-utcdatetime-001.phpt" role="test" />
<file md5sum="de22f1e3d63048ab3db3b3514ce45bf2" name="tests/bson/bson-utcdatetime-002.phpt" role="test" />
<file md5sum="cb6b0009b8dfc770c489cd76f168f875" name="tests/bson/bson-utcdatetime-003.phpt" role="test" />
<file md5sum="de4188f960c7fd6debed280d2ce4da02" name="tests/bson/bson-utcdatetime-004.phpt" role="test" />
<file md5sum="ebcbd881098aeef861090012f341282d" name="tests/bson/bson-utcdatetime-005.phpt" role="test" />
<file md5sum="982f7f8d65d0f7f222f9b2512786dc4c" name="tests/bson/bson-utcdatetime-006.phpt" role="test" />
<file md5sum="322715ac6f412974a9dacb1dc7a1ebc9" name="tests/bson/bson-utcdatetime-007.phpt" role="test" />
<file md5sum="d254384c4d47ea4242c61ded0e391d66" name="tests/bson/bson-utcdatetime-clone-001.phpt" role="test" />
<file md5sum="6728e628d6cd1def65b21b5d58c477b4" name="tests/bson/bson-utcdatetime-compare-001.phpt" role="test" />
<file md5sum="8272da2bda9a4289184e655f6822550c" name="tests/bson/bson-utcdatetime-get_properties-001.phpt" role="test" />
<file md5sum="334df91a905a2ca36f77b385271e77ab" name="tests/bson/bson-utcdatetime-get_properties-002.phpt" role="test" />
<file md5sum="87a0dfcedd4205a3da922c2f10a05e7e" name="tests/bson/bson-utcdatetime-int-size-001.phpt" role="test" />
<file md5sum="56191c433baac3e51c249dec24a34a5e" name="tests/bson/bson-utcdatetime-int-size-002.phpt" role="test" />
<file md5sum="a93b633b97ec16f0b7707205f4709d12" name="tests/bson/bson-utcdatetime-jsonserialize-001.phpt" role="test" />
<file md5sum="1ac1ca2d4db3d5f77ccc59a3a48076c9" name="tests/bson/bson-utcdatetime-jsonserialize-002.phpt" role="test" />
<file md5sum="2bc0c3ddf3167bc788ced0582a2cd157" name="tests/bson/bson-utcdatetime-serialization-001.phpt" role="test" />
<file md5sum="3a575abb63e282591e1f150ca5ebb61a" name="tests/bson/bson-utcdatetime-serialization-002.phpt" role="test" />
<file md5sum="ac49747cfa5295c81d6e0271f827d59c" name="tests/bson/bson-utcdatetime-serialization_error-001.phpt" role="test" />
<file md5sum="a90aec321df162e83202ebabbc4248f1" name="tests/bson/bson-utcdatetime-serialization_error-002.phpt" role="test" />
<file md5sum="5f4ac622d87e508604308b21ae43f835" name="tests/bson/bson-utcdatetime-set_state-001.phpt" role="test" />
<file md5sum="cdbb4d6a6cd72816568163b8f54a0b9f" name="tests/bson/bson-utcdatetime-set_state-002.phpt" role="test" />
<file md5sum="8292f7be7a23f1afe04101f2e57f95b6" name="tests/bson/bson-utcdatetime-set_state_error-001.phpt" role="test" />
<file md5sum="d18b948a39fdb4a68f97209c48b2a846" name="tests/bson/bson-utcdatetime-set_state_error-002.phpt" role="test" />
<file md5sum="1b9dd88668a06f402a8567d13d47dea7" name="tests/bson/bson-utcdatetime-todatetime-001.phpt" role="test" />
<file md5sum="8a6c7f3a7120a6135e4d8153da1fe675" name="tests/bson/bson-utcdatetime-todatetime-002.phpt" role="test" />
<file md5sum="71574612145585e471c5777f97b4721e" name="tests/bson/bson-utcdatetime-tostring-001.phpt" role="test" />
<file md5sum="01ff429024e70923880b7000d904f95f" name="tests/bson/bson-utcdatetime_error-001.phpt" role="test" />
<file md5sum="77b84eee9de2aa927194d1e7699de1a4" name="tests/bson/bson-utcdatetime_error-002.phpt" role="test" />
<file md5sum="b9c3f3108a0ecf7fe4f58f0c6cbc0d68" name="tests/bson/bson-utcdatetime_error-003.phpt" role="test" />
<file md5sum="af38799ce8a8fdd05b703ba3c2a6f77d" name="tests/bson/bson-utcdatetime_error-004.phpt" role="test" />
<file md5sum="a67824badfe3e9a6cfb5aea0577edaad" name="tests/bson/bson-utcdatetimeinterface-001.phpt" role="test" />
<file md5sum="74978df74e164c08a7e98b2b00a850a6" name="tests/bson/bug0274.phpt" role="test" />
<file md5sum="9a2d16556ac49c2fa06a8dc043e45c47" name="tests/bson/bug0325.phpt" role="test" />
<file md5sum="5f838703ed88cbe9bfb826f6d606db67" name="tests/bson/bug0334-001.phpt" role="test" />
<file md5sum="decfd02f9f77ba7f2b7698bc2e9b1993" name="tests/bson/bug0334-002.phpt" role="test" />
<file md5sum="a65cb3e46f03654beb1cf483341abcea" name="tests/bson/bug0341.phpt" role="test" />
<file md5sum="4066bd0654a8969c42d6313aa8dca106" name="tests/bson/bug0347.phpt" role="test" />
<file md5sum="2888441736b763719632b0c3ab4d4288" name="tests/bson/bug0528.phpt" role="test" />
<file md5sum="f3533e9c7ff66e5288f9261921b01dba" name="tests/bson/bug0531-001.phpt" role="test" />
<file md5sum="98df395abbaf09fe313a1ccc6d5ed0a2" name="tests/bson/bug0544.phpt" role="test" />
<file md5sum="31d39a3e234f3a74213c42121098e6f4" name="tests/bson/bug0592.phpt" role="test" />
<file md5sum="a07657032dc64d3586c3a87c62edcc9c" name="tests/bson/bug0623.phpt" role="test" />
<file md5sum="e71fb1adaa9a59504527a072b8f0e971" name="tests/bson/bug0631.phpt" role="test" />
<file md5sum="3c0b0a89a373da7ef34ff8bd72a81b59" name="tests/bson/bug0672.phpt" role="test" />
<file md5sum="9264b5948771b436ed31cf559ade001a" name="tests/bson/bug0894-001.phpt" role="test" />
<file md5sum="5008b223eb1545f5ae7d3d83d929f853" name="tests/bson/bug0923-001.phpt" role="test" />
<file md5sum="ec260ee6e229062d86c0bd19b0b142f4" name="tests/bson/bug0923-002.phpt" role="test" />
<file md5sum="ebc9dd229bc5c7091808835c1dfa2b7c" name="tests/bson/bug0939-001.phpt" role="test" />
<file md5sum="6b3b90dfccbbd0107ef9233270f80ad7" name="tests/bson/bug0974-001.phpt" role="test" />
<file md5sum="99a8ae579b019a928d9a0885c2a1a85d" name="tests/bson/bug1006-001.phpt" role="test" />
<file md5sum="e352907224c2510f5b7c8bbebba323a3" name="tests/bson/bug1006-002.phpt" role="test" />
<file md5sum="22c30ca9d73e86406d2d6f74861366b7" name="tests/bson/bug1053.phpt" role="test" />
<file md5sum="b32de2d6a5a540a853ad9ae92b466e63" name="tests/bson/bug1067.phpt" role="test" />
<file md5sum="6e4cd77ba6ba82ebf68c6a366733094e" name="tests/bson/bug1266.phpt" role="test" />
+ <file md5sum="2cf98072672acfd21d0da25bad891ac6" name="tests/bson/bug1598-001.phpt" role="test" />
+ <file md5sum="14399bc891511ef249b27b2a377e7319" name="tests/bson/bug1598-002.phpt" role="test" />
<file md5sum="b5dddc9aa831f655bd6b3f948d469d9f" name="tests/bson/typemap-001.phpt" role="test" />
<file md5sum="265a8a0020cfa67f4b100d782e018821" name="tests/bson/typemap-002.phpt" role="test" />
<file md5sum="37cff187fd6fd685320304087a72b4c9" name="tests/bson/typemap-003.phpt" role="test" />
<file md5sum="2fc8da280efe2f7a6719a86c9f80b273" name="tests/bson/typemap-004.phpt" role="test" />
<file md5sum="dae81cf2389ecd32be4343cb445df533" name="tests/bson/typemap-005.phpt" role="test" />
<file md5sum="cbc87188adb0e9671a028a23b99ade23" name="tests/bson/typemap-006.phpt" role="test" />
<file md5sum="0fac0215f1a7d97e619aef2bf974c18e" name="tests/bson/typemap-007.phpt" role="test" />
<file md5sum="55f4be2106b3f9222216570cb4e53df8" name="tests/bulk/bug0667.phpt" role="test" />
<file md5sum="e64d115fba82e356ad50e008520a491f" name="tests/bulk/bulkwrite-count-001.phpt" role="test" />
<file md5sum="0a96053f6e2e81ba25f21c62ab6512fa" name="tests/bulk/bulkwrite-countable-001.phpt" role="test" />
<file md5sum="a47d92a55b6eb204c1de84d6d5f239b1" name="tests/bulk/bulkwrite-debug-001.phpt" role="test" />
<file md5sum="9689a2f68b62e23bc88cad87154f8912" name="tests/bulk/bulkwrite-delete-001.phpt" role="test" />
- <file md5sum="ff6efa6a61b517b9813c5b6f3b34a36f" name="tests/bulk/bulkwrite-delete_error-001.phpt" role="test" />
+ <file md5sum="da2e239725bacb438803aaabcb719dc4" name="tests/bulk/bulkwrite-delete-002.phpt" role="test" />
+ <file md5sum="e07f420ce5e7461ecf81bb60d7447943" name="tests/bulk/bulkwrite-delete_error-001.phpt" role="test" />
<file md5sum="2133bfa253805676feebf8b31b6488d4" name="tests/bulk/bulkwrite-delete_error-002.phpt" role="test" />
<file md5sum="2b697d8fc672fa4805bd218596d6839f" name="tests/bulk/bulkwrite-delete_error-003.phpt" role="test" />
<file md5sum="bea544612dcafa65a6c84720ceb27835" name="tests/bulk/bulkwrite-delete_error-004.phpt" role="test" />
+ <file md5sum="984a979319b95deb972e9c8b1fa66f09" name="tests/bulk/bulkwrite-delete_error-005.phpt" role="test" />
<file md5sum="2f31966f55b8d5f3140c3782d9c4578a" name="tests/bulk/bulkwrite-insert-001.phpt" role="test" />
<file md5sum="ca45e311267cfea1113089a50fb3e04a" name="tests/bulk/bulkwrite-insert-004.phpt" role="test" />
<file md5sum="68bcb0c4b874d1811af6e2c61f617b2a" name="tests/bulk/bulkwrite-insert_error-001.phpt" role="test" />
<file md5sum="886ba3ce266bbcd113232102b279a94c" name="tests/bulk/bulkwrite-insert_error-002.phpt" role="test" />
<file md5sum="371b44e7e9d22b7e74af719efdf39055" name="tests/bulk/bulkwrite-insert_error-003.phpt" role="test" />
<file md5sum="6eead56305c7efe949257787c48d13ff" name="tests/bulk/bulkwrite-update-001.phpt" role="test" />
<file md5sum="1ee69820fd6409210a1c9b15aa8b9bda" name="tests/bulk/bulkwrite-update-002.phpt" role="test" />
<file md5sum="09cd3b0145171df68d665a0bb798b4b9" name="tests/bulk/bulkwrite-update-003.phpt" role="test" />
<file md5sum="7ae783892615695e8c8f20739d089400" name="tests/bulk/bulkwrite-update-004.phpt" role="test" />
<file md5sum="bac4712bf1be74448b06b24fd19b14c1" name="tests/bulk/bulkwrite-update_error-001.phpt" role="test" />
<file md5sum="ad132ab85eaf886f513e0a378b095056" name="tests/bulk/bulkwrite-update_error-002.phpt" role="test" />
<file md5sum="0a7d9b81f777ee493aea7b2032e1701a" name="tests/bulk/bulkwrite-update_error-003.phpt" role="test" />
<file md5sum="6fca01de682f0aefeaa62cd2b8c6c840" name="tests/bulk/bulkwrite-update_error-004.phpt" role="test" />
<file md5sum="79f2ddb11b24ed4982a42ae45a824888" name="tests/bulk/bulkwrite-update_error-005.phpt" role="test" />
<file md5sum="876f91f66ea9eb35065748e11baf1b11" name="tests/bulk/bulkwrite-update_error-006.phpt" role="test" />
<file md5sum="3cabc5ebfa8cb23fc2b41b91ea752d44" name="tests/bulk/bulkwrite-update_error-007.phpt" role="test" />
- <file md5sum="ed2f3819523338f81bf1dd47c29d1e69" name="tests/bulk/bulkwrite-update_error-008.phpt" role="test" />
+ <file md5sum="48826e05adbbce2e2c9c6810890141d9" name="tests/bulk/bulkwrite-update_error-008.phpt" role="test" />
<file md5sum="c117f84081a29441f2df90bf68b36308" name="tests/bulk/bulkwrite_error-001.phpt" role="test" />
<file md5sum="3c06f753a692d3a7dbfe22a1e8aaa697" name="tests/bulk/bulkwrite_error-002.phpt" role="test" />
<file md5sum="5701ee82e28b2d1a30c5737744014ee9" name="tests/bulk/write-0001.phpt" role="test" />
<file md5sum="1773338cd648c0370249748964a6c751" name="tests/bulk/write-0002.phpt" role="test" />
<file md5sum="901a76b67b727866c0ee7797468000a4" name="tests/causal-consistency/causal-consistency-001.phpt" role="test" />
<file md5sum="0db8fc24fbf4581335bf9906c9e639ad" name="tests/causal-consistency/causal-consistency-002.phpt" role="test" />
<file md5sum="acc424159afbf9abd819e6f4b3dc1cb9" name="tests/causal-consistency/causal-consistency-003.phpt" role="test" />
<file md5sum="bc9d7634f7ba40dece6b9eb5fcf8e6df" name="tests/causal-consistency/causal-consistency-004.phpt" role="test" />
<file md5sum="4a49856d3dab5e3459e776f4c033cc5d" name="tests/causal-consistency/causal-consistency-005.phpt" role="test" />
<file md5sum="5d924415516a9f4b80744494f77a33e1" name="tests/causal-consistency/causal-consistency-006.phpt" role="test" />
<file md5sum="5945124d0f7050059f05f703cc01942a" name="tests/causal-consistency/causal-consistency-007.phpt" role="test" />
<file md5sum="62769bf3d23ad4930c8b07eaa863fa84" name="tests/causal-consistency/causal-consistency-008.phpt" role="test" />
<file md5sum="0a4e806029bc07f088185ec716194deb" name="tests/causal-consistency/causal-consistency-009.phpt" role="test" />
<file md5sum="7caa537c84e59dbdf0ceff238530a1e6" name="tests/causal-consistency/causal-consistency-010.phpt" role="test" />
<file md5sum="4a16403162937ca8f6661599ec7ea191" name="tests/causal-consistency/causal-consistency-011.phpt" role="test" />
<file md5sum="366cfeafbe04d6e914dcd3302e0e05c3" name="tests/causal-consistency/causal-consistency-012.phpt" role="test" />
<file md5sum="f4f472cc8b013465c3fbb600ceaecc53" name="tests/clientEncryption/clientEncryption-constants.phpt" role="test" />
<file md5sum="2a43f19c7a0a438a0e8676b39f0edd5d" name="tests/clientEncryption/clientEncryption-createDataKey-001.phpt" role="test" />
<file md5sum="af475caa7ace9d5b5c95327412707ebe" name="tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt" role="test" />
<file md5sum="2b11e1c7c28c96aa6f19761e139a1ef5" name="tests/clientEncryption/clientEncryption-decrypt-001.phpt" role="test" />
<file md5sum="057fab341de20c8057ee1b5063d8c5f6" name="tests/clientEncryption/clientEncryption-encrypt-001.phpt" role="test" />
<file md5sum="2fcc843a96b5a7017f141ea4eaef601d" name="tests/command/command-ctor-001.phpt" role="test" />
<file md5sum="1a71256d8141d7150c3efbb97e1a524a" name="tests/command/command_error-001.phpt" role="test" />
<file md5sum="0cccef5075f48d56e22cd86580093dbf" name="tests/command/cursor-batchsize-001.phpt" role="test" />
<file md5sum="f7a7fe65cf10a5360ca3a2d3a234f0c5" name="tests/command/cursor-batchsize-002.phpt" role="test" />
<file md5sum="60324bb545475e5d6f1a288085af6b24" name="tests/command/cursor-tailable-001.phpt" role="test" />
<file md5sum="f14cf22ea8f75cc0800a7cc080caed71" name="tests/command/findAndModify-001.phpt" role="test" />
<file md5sum="b2f0e323e8823b98306884f398a159be" name="tests/command/update-001.phpt" role="test" />
<file md5sum="fedfd02407ffbe2825b612aa84e84562" name="tests/connect/bug0720.phpt" role="test" />
<file md5sum="8c1dd350b0bcf69173885a169ded376f" name="tests/connect/bug1015.phpt" role="test" />
<file md5sum="6e4ba6c6e30d836b9495f200dd5ab3c7" name="tests/connect/bug1045.phpt" role="test" />
<file md5sum="d3e2b9f04909791abbd6bafba559896a" name="tests/connect/compression_error-001.phpt" role="test" />
<file md5sum="f94f489e2c3d2e51d39a057b8215616a" name="tests/connect/compression_error-002.phpt" role="test" />
<file md5sum="09cadd7b529ac15592d48c72aa33828b" name="tests/connect/replicaset-seedlist-001.phpt" role="test" />
<file md5sum="bda55d6aae7f3fbee4a1914b4ef0738f" name="tests/connect/replicaset-seedlist-002.phpt" role="test" />
<file md5sum="26a61cb56c97cd8427510647db36fd95" name="tests/connect/standalone-auth-001.phpt" role="test" />
<file md5sum="123a6ec334879b549877a8330bd632fe" name="tests/connect/standalone-auth_error-001.phpt" role="test" />
<file md5sum="f26f328b141d13db8c11ff637f64c432" name="tests/connect/standalone-plain-0001.phpt" role="test" />
<file md5sum="298d127e2589ac4a31d05ad1863466a2" name="tests/connect/standalone-plain-0002.phpt" role="test" />
<file md5sum="cfda03907f75ad8e518d55618162126c" name="tests/connect/standalone-ssl-no_verify-001.phpt" role="test" />
<file md5sum="3093aeb28dfc5873a97ace15d9d5e3d1" name="tests/connect/standalone-ssl-no_verify-002.phpt" role="test" />
<file md5sum="6d522fea1bfa02e93238078690a205fb" name="tests/connect/standalone-ssl-verify_cert-001.phpt" role="test" />
<file md5sum="f9c9becc920540043433aa090b537a44" name="tests/connect/standalone-ssl-verify_cert-002.phpt" role="test" />
<file md5sum="c863b3ba18aeb7675e8a2bd6dd5e2b22" name="tests/connect/standalone-ssl-verify_cert-error-001.phpt" role="test" />
<file md5sum="e7934eee9e58b70c85e1e03a996e9ab4" name="tests/connect/standalone-ssl-verify_cert-error-002.phpt" role="test" />
<file md5sum="d67dded952b5f36db36d003a13f61190" name="tests/connect/standalone-x509-auth-001.phpt" role="test" />
<file md5sum="ebe16753709665720793e887cdbe531c" name="tests/connect/standalone-x509-auth-002.phpt" role="test" />
<file md5sum="fd5baf924fc715cd7f2c1c77415c5077" name="tests/connect/standalone-x509-error-0001.phpt" role="test" />
<file md5sum="69179c043fbbff16bc7427f854cc4c93" name="tests/connect/standalone-x509-extract_username-001.phpt" role="test" />
<file md5sum="24f8c393372a78faf418ead494cf7642" name="tests/connect/standalone-x509-extract_username-002.phpt" role="test" />
<file md5sum="4b3ec023465d6f599dc6812e26f16ad2" name="tests/cursor/bug0671-001.phpt" role="test" />
<file md5sum="524244d50b3588736868d9d2f135ab33" name="tests/cursor/bug0732-001.phpt" role="test" />
<file md5sum="bbe3fa4ce74ef94ad5e9aca6dc351a6f" name="tests/cursor/bug0849-001.phpt" role="test" />
<file md5sum="56c27d634fe1a1d97be99671624f25f6" name="tests/cursor/bug0924-001.phpt" role="test" />
<file md5sum="eec44586301a9b8cd083fd8701925732" name="tests/cursor/bug0924-002.phpt" role="test" />
<file md5sum="8e2e22ab7f136805e6605c6ccbf8b9f7" name="tests/cursor/bug1050-001.phpt" role="test" />
<file md5sum="876563d42d69bd3ff8153cc17227f707" name="tests/cursor/bug1050-002.phpt" role="test" />
<file md5sum="474ef5823553b4484818d5bfd5cd21fa" name="tests/cursor/bug1151-001.phpt" role="test" />
<file md5sum="51ad1108e7a66e00267ef09991c5724a" name="tests/cursor/bug1151-002.phpt" role="test" />
<file md5sum="5ff240192903529edc723f6a58524ce7" name="tests/cursor/bug1151-003.phpt" role="test" />
<file md5sum="1db156ec62b98f4ed41815b8bf8ffbd9" name="tests/cursor/bug1151-004.phpt" role="test" />
<file md5sum="23feaaa3649e8ffbe642fde83f565f3f" name="tests/cursor/bug1152-001.phpt" role="test" />
<file md5sum="2320a6aa115b05ffc94bc03c3d80a80e" name="tests/cursor/bug1152-002.phpt" role="test" />
<file md5sum="eceedecd3662d1e1ca8004b07d9153df" name="tests/cursor/bug1162-001.phpt" role="test" />
<file md5sum="dc520ea2df1b82313c24a0d6f268dd47" name="tests/cursor/bug1274-001.phpt" role="test" />
<file md5sum="c3a2e319e6c79251918a8da4c3003280" name="tests/cursor/bug1274-002.phpt" role="test" />
<file md5sum="4a2e018800cf0cdfa7a48efd7ba422dc" name="tests/cursor/bug1274-003.phpt" role="test" />
<file md5sum="a65a7ac32a7e8f13ffefa43beef84b60" name="tests/cursor/bug1419-001.phpt" role="test" />
<file md5sum="03bc65d514988acceecd8b830c41f152" name="tests/cursor/cursor-001.phpt" role="test" />
<file md5sum="7c0410ba5a6e41fe743d9982cd6d02e0" name="tests/cursor/cursor-IteratorIterator-001.phpt" role="test" />
<file md5sum="bb0d309916633938dfa05d9f3af864da" name="tests/cursor/cursor-IteratorIterator-002.phpt" role="test" />
<file md5sum="0ed7eec3383fbae9cf671561b26899bd" name="tests/cursor/cursor-IteratorIterator-003.phpt" role="test" />
<file md5sum="7fba13f507848315e8e6e254e900ca24" name="tests/cursor/cursor-IteratorIterator-004.phpt" role="test" />
<file md5sum="9efe615e5928c3309c668f022239474e" name="tests/cursor/cursor-NoRewindIterator-001.phpt" role="test" />
<file md5sum="939767ddea3315dd68cbc737fb4941f1" name="tests/cursor/cursor-destruct-001.phpt" role="test" />
<file md5sum="c229b405181889a015f169b6e43692e2" name="tests/cursor/cursor-get_iterator-001.phpt" role="test" />
<file md5sum="0c5bcf30b509cbd02ec40b08a05728bd" name="tests/cursor/cursor-get_iterator-002.phpt" role="test" />
<file md5sum="6b23937a3d2036d340d57a0d020b4619" name="tests/cursor/cursor-get_iterator-003.phpt" role="test" />
<file md5sum="5aa3b3c35507a9ab338f04e825c4f477" name="tests/cursor/cursor-getmore-001.phpt" role="test" />
<file md5sum="70b15d8f85e88d8347daa29e77b0a44e" name="tests/cursor/cursor-getmore-002.phpt" role="test" />
<file md5sum="7ce1dd001788a037780a27751f6e6316" name="tests/cursor/cursor-getmore-003.phpt" role="test" />
<file md5sum="d2634f26a6137197255118f5f7d9b110" name="tests/cursor/cursor-getmore-004.phpt" role="test" />
<file md5sum="3223830f882a253d05b2d7a0b3c71e9a" name="tests/cursor/cursor-getmore-005.phpt" role="test" />
<file md5sum="0d455054f75e9b7a6304688ef38792b9" name="tests/cursor/cursor-getmore-006.phpt" role="test" />
<file md5sum="c23542434327940c5c6d0355873c2070" name="tests/cursor/cursor-getmore-007.phpt" role="test" />
<file md5sum="bc396ff3c3029772f445eb8b7da637e8" name="tests/cursor/cursor-getmore-008.phpt" role="test" />
<file md5sum="db16c429ebdb76d3b753f0ae5bb7fd83" name="tests/cursor/cursor-isDead-001.phpt" role="test" />
<file md5sum="c7ca93a7828140200b4a04015a687104" name="tests/cursor/cursor-isDead-002.phpt" role="test" />
<file md5sum="035a777de95a979b6d7c2073e3733198" name="tests/cursor/cursor-isDead-003.phpt" role="test" />
<file md5sum="0e1be952d398b2d171bd06dae306c78f" name="tests/cursor/cursor-isDead-004.phpt" role="test" />
<file md5sum="fc0bd8479123c749a38ef0adcbebf3de" name="tests/cursor/cursor-iterator_handlers-001.phpt" role="test" />
<file md5sum="eb64a093d4088a07f989fb0e91322073" name="tests/cursor/cursor-rewind-001.phpt" role="test" />
<file md5sum="36e439ec289e714153e9ff58beaefd00" name="tests/cursor/cursor-session-001.phpt" role="test" />
<file md5sum="fcd89096cff4d61e660f598711aaf99d" name="tests/cursor/cursor-session-002.phpt" role="test" />
<file md5sum="1cb4aee3dd92582dde10f6cf55090161" name="tests/cursor/cursor-session-003.phpt" role="test" />
<file md5sum="40d880c42f27636bc1682bf02a654798" name="tests/cursor/cursor-session-004.phpt" role="test" />
<file md5sum="3cdc16f34a7e79dd63b192a3245349d5" name="tests/cursor/cursor-setTypeMap_error-001.phpt" role="test" />
<file md5sum="bd71fa980d79b8c89ea4af9a363c9f82" name="tests/cursor/cursor-setTypeMap_error-002.phpt" role="test" />
<file md5sum="d4fdb84e9efd4d8853cb8a8e9c25b541" name="tests/cursor/cursor-setTypeMap_error-003.phpt" role="test" />
<file md5sum="883cdb6d9684d4f4a75778d8aa641875" name="tests/cursor/cursor-setTypeMap_error-004.phpt" role="test" />
<file md5sum="a13fe8aa5f454d3c9a84b0f3b1238c1e" name="tests/cursor/cursor-tailable-001.phpt" role="test" />
<file md5sum="4798d1df7ac09fde475b9551d5d6cdba" name="tests/cursor/cursor-tailable-002.phpt" role="test" />
<file md5sum="219b719f4a6b5a00d25bbbba851718d2" name="tests/cursor/cursor-tailable-003.phpt" role="test" />
<file md5sum="df7250832938a3a7204d59688552d590" name="tests/cursor/cursor-tailable_error-001.phpt" role="test" />
<file md5sum="8b85e4c9583b80963a1a7739448698a5" name="tests/cursor/cursor-tailable_error-002.phpt" role="test" />
<file md5sum="41f0d76fe5c1d5bf7ed874a5aed1a36b" name="tests/cursor/cursor-toArray-001.phpt" role="test" />
<file md5sum="52f7368b650deecf36d6f782f9d66534" name="tests/cursor/cursor-toArray-002.phpt" role="test" />
<file md5sum="98ab429a6b6a19ea5848c83119784a3b" name="tests/cursor/cursor_error-001.phpt" role="test" />
<file md5sum="44738ce88a60fbb2fa2a1a7a426e5c2c" name="tests/cursor/cursorinterface-001.phpt" role="test" />
<file md5sum="d35e1eff5ad7b32efb76838dd4345d0e" name="tests/cursor/cursorinterface-002.phpt" role="test" />
<file md5sum="d79faab763a82a123c7ee9affb0321f3" name="tests/cursorid/cursorid-001.phpt" role="test" />
<file md5sum="e1c6552db05d0f32390dab6953a63399" name="tests/cursorid/cursorid-002.phpt" role="test" />
<file md5sum="754d7f2c950a695011824b6d48ad6bdc" name="tests/cursorid/cursorid-serialization-001.phpt" role="test" />
<file md5sum="c72707601edf6dd9e41b2c67b05d92ae" name="tests/cursorid/cursorid_error-001.phpt" role="test" />
<file md5sum="e9d41f8bd860cf7bc7aecf888a6e5f03" name="tests/exception/bulkwriteexception-getwriteresult-001.phpt" role="test" />
<file md5sum="0c742d44e6e7d6cc44043ff7c7d52dfd" name="tests/exception/bulkwriteexception-haserrorlabel-001.phpt" role="test" />
+ <file md5sum="559013f8d14f022aa69821f0b96fc21d" name="tests/exception/bulkwriteexception-haserrorlabel-002.phpt" role="test" />
<file md5sum="9affde6e5226e248967e3ee33a5feef0" name="tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt" role="test" />
<file md5sum="9b577a17a9a125ab32ad48010d3b7909" name="tests/exception/commandexception-getresultdocument-001.phpt" role="test" />
<file md5sum="f517ae8a8ad62e3fa2fe69d282367ea4" name="tests/exception/commandexception-haserrorlabel-001.phpt" role="test" />
<file md5sum="69b64eec21ec54c479dfe557269598ab" name="tests/exception/commandexception-haserrorlabel_error-001.phpt" role="test" />
<file md5sum="6bcc1ed27df3ddbe16f549c82803d0cf" name="tests/exception/exception-001.phpt" role="test" />
<file md5sum="0f64ba7a9c355b2ee9a30d5f3f2241b8" name="tests/exception/runtimeexception-haserrorlabel-001.phpt" role="test" />
<file md5sum="98fe8f2b6fc815b91199a9d9fb9320f3" name="tests/exception/runtimeexception-haserrorlabel_error-001.phpt" role="test" />
<file md5sum="3dd7d094e945216ab896611686cf15e9" name="tests/functional/cursor-001.phpt" role="test" />
<file md5sum="4ffb80e523858bcb53cc938fe4e9f0d5" name="tests/functional/cursorid-001.phpt" role="test" />
<file md5sum="cf458375411ca8026f40990bcca820fe" name="tests/functional/phpinfo-1.phpt" role="test" />
- <file md5sum="22b8fb519337d30e92157b6ae14660be" name="tests/functional/phpinfo-2.phpt" role="test" />
+ <file md5sum="d77ed62417811ccf6d2d7feb0972bfc3" name="tests/functional/phpinfo-2.phpt" role="test" />
<file md5sum="27cf53aba7bbf1e22c32fb6b691c048d" name="tests/functional/query-sort-001.phpt" role="test" />
<file md5sum="b4a504f5f5be61568c645e307cfba097" name="tests/functional/query-sort-002.phpt" role="test" />
<file md5sum="b2cfb45cfca7ef52c97823c088cfa470" name="tests/functional/query-sort-003.phpt" role="test" />
<file md5sum="590e9fc57ad23f3b22c80017ae44c470" name="tests/functional/query-sort-004.phpt" role="test" />
<file md5sum="c1195325dce8f3e5fed51fa4cca7939a" name="tests/manager/bug0572.phpt" role="test" />
<file md5sum="f0346e6cd2ba9520eef5021167879c4e" name="tests/manager/bug0851-001.phpt" role="test" />
<file md5sum="d5af337dd2aa7220b61b71deacb2a0ef" name="tests/manager/bug0851-002.phpt" role="test" />
<file md5sum="36ca061b4e0eef92165a1150909f5293" name="tests/manager/bug0912-001.phpt" role="test" />
<file md5sum="28f893fc2a6942725c70ec36c4a4f066" name="tests/manager/bug0913-001.phpt" role="test" />
<file md5sum="581f3f676bb14c8f81e76890e69864f4" name="tests/manager/bug0940-001.phpt" role="test" />
<file md5sum="4a8161bfdfd6cc6611c33d7c22323e35" name="tests/manager/bug0940-002.phpt" role="test" />
<file md5sum="0772851b9d33b0cf98ca7574a9c9c8cf" name="tests/manager/bug1163-001.phpt" role="test" />
<file md5sum="2787ed29d23447eead4f2e5b5fcbf3f5" name="tests/manager/manager-createClientEncryption-001.phpt" role="test" />
<file md5sum="8da08fb4b7677bf2029f7c304ef52901" name="tests/manager/manager-createClientEncryption-error-001.phpt" role="test" />
<file md5sum="32c86b6d904954e456d28eb593565877" name="tests/manager/manager-createClientEncryption-error-002.phpt" role="test" />
<file md5sum="d582d6ff744cdbf6f65a37e63faac924" name="tests/manager/manager-ctor-001.phpt" role="test" />
<file md5sum="ddb6ad56c0bddfdcddc28eac459c2ec7" name="tests/manager/manager-ctor-002.phpt" role="test" />
<file md5sum="bf482d24f1467be19b603557a6cb8e6c" name="tests/manager/manager-ctor-003.phpt" role="test" />
<file md5sum="cd62592a5c1c3b6c855b698735a1b9eb" name="tests/manager/manager-ctor-004.phpt" role="test" />
<file md5sum="fc9c0aeba95b987c080b27740bc4807f" name="tests/manager/manager-ctor-005.phpt" role="test" />
<file md5sum="1317f0fb54d0f321cb566484a347cfaf" name="tests/manager/manager-ctor-006.phpt" role="test" />
<file md5sum="9971491b14eee35b683cafca4df93f69" name="tests/manager/manager-ctor-appname-001.phpt" role="test" />
<file md5sum="61b8d5978585fc2a3f031c4f37d2d611" name="tests/manager/manager-ctor-appname_error-001.phpt" role="test" />
- <file md5sum="6f1a0e56af62c11b78c82ebce370031e" name="tests/manager/manager-ctor-auth_mechanism-001.phpt" role="test" />
+ <file md5sum="0f29f362757476ecaa36f936d16a7c20" name="tests/manager/manager-ctor-auth_mechanism-001.phpt" role="test" />
<file md5sum="7e334d9c4f17adc4ec5be12d461207b6" name="tests/manager/manager-ctor-auth_mechanism-002.phpt" role="test" />
- <file md5sum="033396c12259f9fa9b23ae1c1459ebaf" name="tests/manager/manager-ctor-auth_mechanism-error-001.phpt" role="test" />
- <file md5sum="bd5361d34cc5c27092d5ed70b2d10aab" name="tests/manager/manager-ctor-auto_encryption-001.phpt" role="test" />
+ <file md5sum="90c734296f99cf087690ce5b3c971842" name="tests/manager/manager-ctor-auth_mechanism-error-001.phpt" role="test" />
+ <file md5sum="b36422d0897ec7f315fdb5f3391d7341" name="tests/manager/manager-ctor-auth_source-001.phpt" role="test" />
+ <file md5sum="85b83ea4ac48a57132906b006c01d8de" name="tests/manager/manager-ctor-auto_encryption-001.phpt" role="test" />
<file md5sum="e731e03841e0883f4ee751c7032513cf" name="tests/manager/manager-ctor-auto_encryption-error-001.phpt" role="test" />
<file md5sum="55231e67734f454c0d611e83e3eb223f" name="tests/manager/manager-ctor-auto_encryption-error-002.phpt" role="test" />
<file md5sum="765c62e3361c84850c07ab0ecf4022c4" name="tests/manager/manager-ctor-auto_encryption-error-003.phpt" role="test" />
+ <file md5sum="9097547b2339ca142d1c322666fd376d" name="tests/manager/manager-ctor-directconnection-001.phpt" role="test" />
+ <file md5sum="19d7f6abca6dd2cd228a14d469e16343" name="tests/manager/manager-ctor-directconnection-error-001.phpt" role="test" />
+ <file md5sum="cf82ac686119977b53c28c06884e74a2" name="tests/manager/manager-ctor-directconnection-error-002.phpt" role="test" />
+ <file md5sum="7914802b3c64e680dce7a36fb46fce50" name="tests/manager/manager-ctor-driver-metadata-001.phpt" role="test" />
<file md5sum="620dd66d04240a1cbfbc33373117085c" name="tests/manager/manager-ctor-duplicate-option-001.phpt" role="test" />
<file md5sum="9311bb62f8740436ef91ef7a0fe5c97a" name="tests/manager/manager-ctor-duplicate-option-002.phpt" role="test" />
<file md5sum="d6b52ffcafa9ceaf363ebdb07c10cc75" name="tests/manager/manager-ctor-duplicate-option-003.phpt" role="test" />
<file md5sum="7538039ec421e2ae634e91ba24999408" name="tests/manager/manager-ctor-duplicate-option-004.phpt" role="test" />
<file md5sum="ee7822e3b58b7abb5ccee0a87dc86e4d" name="tests/manager/manager-ctor-read_concern-001.phpt" role="test" />
<file md5sum="e0f1aac391b3a951064df7cae6234cb6" name="tests/manager/manager-ctor-read_concern-error-001.phpt" role="test" />
<file md5sum="79e97d46bf35dde168a2b2c8b304d259" name="tests/manager/manager-ctor-read_preference-001.phpt" role="test" />
<file md5sum="a68f0249fa21dc829486e9b349d5835a" name="tests/manager/manager-ctor-read_preference-002.phpt" role="test" />
<file md5sum="f79bc0bb4c539b3ca7d92289c5799928" name="tests/manager/manager-ctor-read_preference-004.phpt" role="test" />
<file md5sum="d34478e19a06621ab48134ad3e921cb5" name="tests/manager/manager-ctor-read_preference-error-001.phpt" role="test" />
<file md5sum="41eed52f397fb36e3fb504e9f56d7322" name="tests/manager/manager-ctor-read_preference-error-002.phpt" role="test" />
<file md5sum="33c909db248b8926649d82d481106abd" name="tests/manager/manager-ctor-read_preference-error-003.phpt" role="test" />
<file md5sum="cd42434868d062400d1acc99236c62a2" name="tests/manager/manager-ctor-read_preference-error-004.phpt" role="test" />
<file md5sum="d7708745e5025122ef406cd0782defee" name="tests/manager/manager-ctor-server.phpt" role="test" />
<file md5sum="0f5384a769df66ede31e0c1bcd91db3b" name="tests/manager/manager-ctor-ssl-001.phpt" role="test" />
<file md5sum="1fdfd08d1e55f063b61f2d885a761054" name="tests/manager/manager-ctor-ssl-002.phpt" role="test" />
<file md5sum="49e47e03ae62edbc4d1930a0f344f554" name="tests/manager/manager-ctor-ssl-003.phpt" role="test" />
<file md5sum="154a35441fb15f215da538454af5bc6d" name="tests/manager/manager-ctor-ssl-deprecated-001.phpt" role="test" />
<file md5sum="44edb9adf6690a82c276fd88671eb7b3" name="tests/manager/manager-ctor-ssl-deprecated-002.phpt" role="test" />
- <file md5sum="727c9f21a5504ad664cc53cc32078089" name="tests/manager/manager-ctor-tls-error-001.phpt" role="test" />
- <file md5sum="32d6ed4bec04871a437d283bbb7e1868" name="tests/manager/manager-ctor-tls-error-002.phpt" role="test" />
+ <file md5sum="fb412e73099879b0e80c876bcbfcc696" name="tests/manager/manager-ctor-tls-error-001.phpt" role="test" />
<file md5sum="ac19b3dbd632af113caa63ea3736e778" name="tests/manager/manager-ctor-wireversion.phpt" role="test" />
<file md5sum="f5f725515b3e0d3000a190ca90a48902" name="tests/manager/manager-ctor-write_concern-001.phpt" role="test" />
<file md5sum="f57f8e8063d723e1cd9e01a7e65cdcf6" name="tests/manager/manager-ctor-write_concern-002.phpt" role="test" />
<file md5sum="a795c0a05f3f14eee39dc899c6b8b353" name="tests/manager/manager-ctor-write_concern-003.phpt" role="test" />
<file md5sum="243320fdfc028f0156dab89e0a4111fd" name="tests/manager/manager-ctor-write_concern-004.phpt" role="test" />
<file md5sum="3082087d08245cfd506d8e9c065552eb" name="tests/manager/manager-ctor-write_concern-005.phpt" role="test" />
<file md5sum="19a3af22d908692a494ff19407488831" name="tests/manager/manager-ctor-write_concern-006.phpt" role="test" />
<file md5sum="930d34ab034a874b0d1bfdfb359f57a2" name="tests/manager/manager-ctor-write_concern-error-001.phpt" role="test" />
<file md5sum="961a3b93ec15395bf57bcc55c42af238" name="tests/manager/manager-ctor-write_concern-error-002.phpt" role="test" />
<file md5sum="ca05908ad81b3b535edd8da9a28227b4" name="tests/manager/manager-ctor-write_concern-error-003.phpt" role="test" />
<file md5sum="4ceba0f9bddd41670eafafcb2cdcf036" name="tests/manager/manager-ctor-write_concern-error-005.phpt" role="test" />
<file md5sum="d5375e39c52cfe38e226f28a72de528b" name="tests/manager/manager-ctor-write_concern-error-006.phpt" role="test" />
<file md5sum="327b953424cc1b3453185431059c50ff" name="tests/manager/manager-ctor-write_concern-error-007.phpt" role="test" />
<file md5sum="dd2c31375156083cadd617d2f01a01cf" name="tests/manager/manager-ctor_error-001.phpt" role="test" />
<file md5sum="bc5dbc3dac6898f0ee0d6baccd0a7866" name="tests/manager/manager-ctor_error-002.phpt" role="test" />
<file md5sum="07074b4ac6d148d2c45fd2c6cf23f427" name="tests/manager/manager-ctor_error-003.phpt" role="test" />
<file md5sum="8e860028e777c320122fd32b8e674e4d" name="tests/manager/manager-ctor_error-004.phpt" role="test" />
+ <file md5sum="fe609749b9120c60524e70f35d434a16" name="tests/manager/manager-ctor_error-005.phpt" role="test" />
<file md5sum="be738dc790fc658a6ce32235b04b1d4b" name="tests/manager/manager-debug-001.phpt" role="test" />
<file md5sum="fed182f4305d260702f56990d7977c91" name="tests/manager/manager-debug-002.phpt" role="test" />
<file md5sum="b99cf3e782d7e1fba6a320e7815305f5" name="tests/manager/manager-debug-003.phpt" role="test" />
<file md5sum="be82f864c923bc9bff1156270aa6d4c4" name="tests/manager/manager-destruct-001.phpt" role="test" />
<file md5sum="37a4fd602a24f5a72289e451f192b492" name="tests/manager/manager-executeBulkWrite-001.phpt" role="test" />
<file md5sum="d02cd524c7f3bc05b51b7a2ccc778ea7" name="tests/manager/manager-executeBulkWrite-002.phpt" role="test" />
<file md5sum="4600431b5b3ad77bf8bceec091e5940f" name="tests/manager/manager-executeBulkWrite-003.phpt" role="test" />
<file md5sum="115cfabb0f82ccd4915ef27d57eba2c5" name="tests/manager/manager-executeBulkWrite-004.phpt" role="test" />
<file md5sum="193b327bd8996dca2f31780fcd00db02" name="tests/manager/manager-executeBulkWrite-005.phpt" role="test" />
<file md5sum="95879a94e1994a3166591ab8a9bdc0f8" name="tests/manager/manager-executeBulkWrite-006.phpt" role="test" />
<file md5sum="6ac99ac40f172cfe91bebb3b680d17fb" name="tests/manager/manager-executeBulkWrite-007.phpt" role="test" />
<file md5sum="99aab4ef28819e1ee25831b778306672" name="tests/manager/manager-executeBulkWrite-008.phpt" role="test" />
<file md5sum="ca20571d844c13b6715e29a9c2a3c56a" name="tests/manager/manager-executeBulkWrite-009.phpt" role="test" />
<file md5sum="5ab058d19d4282a2e40f2e93e07f8392" name="tests/manager/manager-executeBulkWrite-010.phpt" role="test" />
<file md5sum="f5594d4af26be91375b2b0c3359a9d99" name="tests/manager/manager-executeBulkWrite-011.phpt" role="test" />
<file md5sum="38bcd67bf01142405204cf785fa39a50" name="tests/manager/manager-executeBulkWrite-012.phpt" role="test" />
<file md5sum="f6888d16a579ba70fbc2699355d18d9f" name="tests/manager/manager-executeBulkWrite-013.phpt" role="test" />
<file md5sum="50b50e510349d45121bb8693025c289b" name="tests/manager/manager-executeBulkWrite_error-001.phpt" role="test" />
<file md5sum="d432f702c365f82c27120254c5e9b240" name="tests/manager/manager-executeBulkWrite_error-002.phpt" role="test" />
- <file md5sum="2b1c509ef99f7ff7d3e4d120ed4e9748" name="tests/manager/manager-executeBulkWrite_error-003.phpt" role="test" />
+ <file md5sum="ad64ea876a6959cea64eb486feb556fa" name="tests/manager/manager-executeBulkWrite_error-003.phpt" role="test" />
<file md5sum="a6d4e1528ad9aee1f9d1870b8d854fd5" name="tests/manager/manager-executeBulkWrite_error-004.phpt" role="test" />
<file md5sum="5ff3bc58c098a387b12dd1f43642caa2" name="tests/manager/manager-executeBulkWrite_error-005.phpt" role="test" />
<file md5sum="2c180c572d2672f86d902952cc512339" name="tests/manager/manager-executeBulkWrite_error-006.phpt" role="test" />
<file md5sum="52db00924a47b5eaf3786570f1752e37" name="tests/manager/manager-executeBulkWrite_error-007.phpt" role="test" />
<file md5sum="76c87f395ccde1404e4d95d59c72daa2" name="tests/manager/manager-executeBulkWrite_error-008.phpt" role="test" />
<file md5sum="779777e6596fdf0ac60ef82cb456bdfe" name="tests/manager/manager-executeBulkWrite_error-009.phpt" role="test" />
<file md5sum="fda28235360691d16827ef93432069db" name="tests/manager/manager-executeBulkWrite_error-010.phpt" role="test" />
<file md5sum="f2cb4ea7930edd02193127d2e7ba906c" name="tests/manager/manager-executeBulkWrite_error-011.phpt" role="test" />
<file md5sum="aafb8b95f6c1bbd150bccb6dd7e3bc57" name="tests/manager/manager-executeCommand-001.phpt" role="test" />
<file md5sum="6dbcf61d66a0493d6d8df6bdd7578965" name="tests/manager/manager-executeCommand-002.phpt" role="test" />
<file md5sum="a7591fdbe2aa5ef921e1003927004968" name="tests/manager/manager-executeCommand-003.phpt" role="test" />
<file md5sum="41ce44fa9e3a2884805a6ffc25152ff5" name="tests/manager/manager-executeCommand-004.phpt" role="test" />
<file md5sum="5741b0a6160bcd5e02ec54644396e751" name="tests/manager/manager-executeCommand-005.phpt" role="test" />
+ <file md5sum="218be15aa69e000d88283b45328550b4" name="tests/manager/manager-executeCommand-006.phpt" role="test" />
<file md5sum="54226b358783e1456d9ad86905ac68e9" name="tests/manager/manager-executeCommand_error-001.phpt" role="test" />
<file md5sum="893e7be482ea85b53fef7df7c420af96" name="tests/manager/manager-executeCommand_error-002.phpt" role="test" />
<file md5sum="e93a51f896f2d28e4a790aeb83edbf84" name="tests/manager/manager-executeCommand_error-003.phpt" role="test" />
<file md5sum="ebf6a1268b5819c8364d20cfd543a1e2" name="tests/manager/manager-executeCommand_error-004.phpt" role="test" />
<file md5sum="d20a3cc04c2e2e084b62d7574b97f959" name="tests/manager/manager-executeCommand_error-005.phpt" role="test" />
<file md5sum="2447fcf2f5dc9e1592ab26b14cf095f5" name="tests/manager/manager-executeQuery-001.phpt" role="test" />
<file md5sum="6645785c68bb34b8194c88ca1b784ad5" name="tests/manager/manager-executeQuery-002.phpt" role="test" />
<file md5sum="84473ebdaf73e71bd85ede11bb8e93b4" name="tests/manager/manager-executeQuery-003.phpt" role="test" />
<file md5sum="cca51ff672d601588ebac850c1a93d88" name="tests/manager/manager-executeQuery-004.phpt" role="test" />
<file md5sum="c92462fb5fbb4676e46cc229ee8023c9" name="tests/manager/manager-executeQuery-005.phpt" role="test" />
<file md5sum="40a85322815629155580859956bd1bf6" name="tests/manager/manager-executeQuery-006.phpt" role="test" />
<file md5sum="f42311575c9bcbfbc67b8dbd10dbbaa7" name="tests/manager/manager-executeQuery_error-001.phpt" role="test" />
<file md5sum="7b31d0c0d68ba02a2faceb693af677b9" name="tests/manager/manager-executeQuery_error-002.phpt" role="test" />
<file md5sum="2425a02eeab9cbf1e1c9bf992092dd09" name="tests/manager/manager-executeQuery_error-003.phpt" role="test" />
<file md5sum="adb41c1b6c560be32f1f67bea783435b" name="tests/manager/manager-executeReadCommand-001.phpt" role="test" />
<file md5sum="257032820b00d61ddd946ac7d9eed5ec" name="tests/manager/manager-executeReadCommand-002.phpt" role="test" />
<file md5sum="af698c727b61a0580ce66a08e625c8d1" name="tests/manager/manager-executeReadCommand_error-001.phpt" role="test" />
<file md5sum="9ef55f95e1a5d536163ddd8be039d617" name="tests/manager/manager-executeReadWriteCommand-001.phpt" role="test" />
<file md5sum="07a665f5fef5cbd9a52bbf01b7dd50be" name="tests/manager/manager-executeReadWriteCommand-002.phpt" role="test" />
<file md5sum="2d92dfe9aea73ef5f5fb2c3d37df7be1" name="tests/manager/manager-executeReadWriteCommand_error-001.phpt" role="test" />
<file md5sum="472adf24949ec9cea47cc86ac4e834e7" name="tests/manager/manager-executeReadWriteCommand_error-002.phpt" role="test" />
<file md5sum="49d1f29f49e7f5a179c510e7987d9c71" name="tests/manager/manager-executeWriteCommand-001.phpt" role="test" />
<file md5sum="a306a2a66e27ae315c48dc8ba180e509" name="tests/manager/manager-executeWriteCommand-002.phpt" role="test" />
<file md5sum="223884a8c7d9d23e943fd9003fb41bd8" name="tests/manager/manager-executeWriteCommand_error-001.phpt" role="test" />
<file md5sum="1b8dc81a302c4025b33497363f463920" name="tests/manager/manager-executeWriteCommand_error-002.phpt" role="test" />
<file md5sum="721dc0ae6eb5cb397918b2f8a64faa5d" name="tests/manager/manager-executeWriteCommand_error-003.phpt" role="test" />
<file md5sum="5eedfce5f915c4b30a25bc4eb1accfea" name="tests/manager/manager-executeWriteCommand_error-004.phpt" role="test" />
- <file md5sum="f7ca35a24f44f8117591743db2060984" name="tests/manager/manager-getreadconcern-001.phpt" role="test" />
- <file md5sum="5dffa436262af8c4da1c91b261d624b3" name="tests/manager/manager-getreadpreference-001.phpt" role="test" />
+ <file md5sum="0c869cc5b61b1891fb9860b5c631797f" name="tests/manager/manager-getreadconcern-001.phpt" role="test" />
+ <file md5sum="f01ca8d5ec0497d3c83c20fbfbd78df9" name="tests/manager/manager-getreadpreference-001.phpt" role="test" />
<file md5sum="e47864f13ca7fe25e35f9e8baaa2cdb4" name="tests/manager/manager-getservers-001.phpt" role="test" />
<file md5sum="39c56a7a7608e2ab54aed5430c199a33" name="tests/manager/manager-getservers-002.phpt" role="test" />
- <file md5sum="eb3d87882c6ec387276cb1135c9f4f9f" name="tests/manager/manager-getwriteconcern-001.phpt" role="test" />
+ <file md5sum="5cb96f5b8c994e360692ef80b430085d" name="tests/manager/manager-getwriteconcern-001.phpt" role="test" />
<file md5sum="316c963c709d2798c952d1f26ecfdcaf" name="tests/manager/manager-invalidnamespace.phpt" role="test" />
<file md5sum="594abcad7988e7af8992b58564c3053d" name="tests/manager/manager-selectserver-001.phpt" role="test" />
<file md5sum="a8165780917ad1de3e6b62a9d50893de" name="tests/manager/manager-selectserver_error-001.phpt" role="test" />
<file md5sum="c0a9cabc0b65b3d2148beb6a3647dabc" name="tests/manager/manager-set-uri-options-001.phpt" role="test" />
<file md5sum="3267666e2c1ec85975664d8db24d40f1" name="tests/manager/manager-set-uri-options-002.phpt" role="test" />
<file md5sum="0cf275d98e263adead46d915d4212d88" name="tests/manager/manager-set-uri-options-003.phpt" role="test" />
<file md5sum="78450543d70ac4092db50f3f34a0066c" name="tests/manager/manager-var-dump-001.phpt" role="test" />
<file md5sum="f888f59a3fe5f9fdf3697f1424aaf38d" name="tests/manager/manager-wakeup.phpt" role="test" />
<file md5sum="d9723d6bfe30a7e2691ecea5b69c2c13" name="tests/manager/manager_error-001.phpt" role="test" />
<file md5sum="2dd9863434c753dd55242243d48091c9" name="tests/query/bug0430-001.phpt" role="test" />
<file md5sum="6cfbe0ca5de33e4402bf779a44d64b4e" name="tests/query/bug0430-002.phpt" role="test" />
<file md5sum="6004d177d8ffc04a0a295eb824697e4a" name="tests/query/bug0430-003.phpt" role="test" />
<file md5sum="6a3a4c5c33296d0c57bf99eafdd2eac0" name="tests/query/bug0705-001.phpt" role="test" />
<file md5sum="760272a446ac993f8e97d21b6fe07667" name="tests/query/bug0705-002.phpt" role="test" />
<file md5sum="29108178991e9a305da2df846cf494b4" name="tests/query/query-ctor-001.phpt" role="test" />
- <file md5sum="76a56a3ca81f977881f02d4cf1e90f09" name="tests/query/query-ctor-002.phpt" role="test" />
+ <file md5sum="1cf3ecf0a05cc2c305042b47e712e351" name="tests/query/query-ctor-002.phpt" role="test" />
<file md5sum="739343c4dd6b03ab5c3dfec995fe6bff" name="tests/query/query-ctor-003.phpt" role="test" />
<file md5sum="c78b0601cac5a186e6e7c386f89ee4ef" name="tests/query/query-ctor-004.phpt" role="test" />
<file md5sum="71f1fa84dbf281b67d942863248f7e31" name="tests/query/query-ctor-005.phpt" role="test" />
<file md5sum="64bda823995da00efceed4b07627f18f" name="tests/query/query-ctor-006.phpt" role="test" />
<file md5sum="a8feb530a36c277f0c0e29bb9972f88c" name="tests/query/query-ctor_error-001.phpt" role="test" />
<file md5sum="1c2302cdb1b48a6c94776b928d27b68e" name="tests/query/query-ctor_error-002.phpt" role="test" />
<file md5sum="2238f34b7a0c1b93e6c1b1af5fc7b9b8" name="tests/query/query-ctor_error-003.phpt" role="test" />
<file md5sum="70af7d02949d0bfffa87729079871c74" name="tests/query/query-ctor_error-004.phpt" role="test" />
<file md5sum="21539cda062a422b388591fcda520ef3" name="tests/query/query-ctor_error-005.phpt" role="test" />
<file md5sum="07edfcf218e25dc4cf5fa8b677f6f636" name="tests/query/query-ctor_error-006.phpt" role="test" />
<file md5sum="8cf658f5cd18c7b5fc9b71e668699910" name="tests/query/query-debug-001.phpt" role="test" />
<file md5sum="623f5385c7016ba73c3be33c0e9a7b1e" name="tests/query/query_error-001.phpt" role="test" />
+ <file md5sum="a235c15b6d12006dd86cd3fc9d364abd" name="tests/readConcern/bug1598-001.phpt" role="test" />
+ <file md5sum="5b87f36784f6bfaf2d80fd5cd79c4571" name="tests/readConcern/bug1598-002.phpt" role="test" />
<file md5sum="dcbdfa9e8696be8baec22a8c09ec75d2" name="tests/readConcern/readconcern-bsonserialize-001.phpt" role="test" />
<file md5sum="e73ca4a826636a54ffe3ea853df7b0ef" name="tests/readConcern/readconcern-bsonserialize-002.phpt" role="test" />
<file md5sum="60e5d468a783ea7f28f43e261f9c4e15" name="tests/readConcern/readconcern-constants.phpt" role="test" />
<file md5sum="673f3d6d7729381139502491fd69dda4" name="tests/readConcern/readconcern-ctor-001.phpt" role="test" />
<file md5sum="cc84842cd29ca9b34ed7febc8f9a0bae" name="tests/readConcern/readconcern-ctor_error-001.phpt" role="test" />
<file md5sum="9a43b7910880283516d0594f881ca548" name="tests/readConcern/readconcern-ctor_error-002.phpt" role="test" />
<file md5sum="32d628a71d398bd65e13d2bbe6b63b6c" name="tests/readConcern/readconcern-debug-001.phpt" role="test" />
<file md5sum="c6ecab3439c2b4249bedd2c6dc299dcf" name="tests/readConcern/readconcern-getlevel-001.phpt" role="test" />
<file md5sum="7bc12b0529eef007f25068e8a410d755" name="tests/readConcern/readconcern-isdefault-001.phpt" role="test" />
<file md5sum="79b0f4db273686ee4ff10f2e89f17124" name="tests/readConcern/readconcern-serialization-001.phpt" role="test" />
<file md5sum="bd2a1f13b5cf85270aa8085f46e0e48c" name="tests/readConcern/readconcern-set_state-001.phpt" role="test" />
<file md5sum="3fbc3e10cec34871c930e36227d39733" name="tests/readConcern/readconcern-set_state_error-001.phpt" role="test" />
<file md5sum="086b0444ec258c33779027b4b58e38b1" name="tests/readConcern/readconcern-var_export-001.phpt" role="test" />
<file md5sum="f773914d83286e225a75016f89b6eba6" name="tests/readConcern/readconcern_error-001.phpt" role="test" />
<file md5sum="c8c3b1d561bf4f39184476a28c23556d" name="tests/readPreference/bug0146-001.phpt" role="test" />
<file md5sum="917e360edc3fa8ffe58140b1a745d28c" name="tests/readPreference/bug0146-002.phpt" role="test" />
<file md5sum="5bbbd73884d0d64989109201e7e1bf3f" name="tests/readPreference/bug0851-001.phpt" role="test" />
+ <file md5sum="bdc1634fe23391ae15928e87da27e5dc" name="tests/readPreference/bug1598-001.phpt" role="test" />
+ <file md5sum="fd65990a31032d72fd2a97e4d9425ea4" name="tests/readPreference/bug1598-002.phpt" role="test" />
<file md5sum="6677621b6743e8d5d17b3cf0d45283d3" name="tests/readPreference/readpreference-bsonserialize-001.phpt" role="test" />
<file md5sum="ff0ce5637f8b68e7cf7c1aa65bedf89f" name="tests/readPreference/readpreference-bsonserialize-002.phpt" role="test" />
<file md5sum="961998132bc79161663699fd64b369b2" name="tests/readPreference/readpreference-constants.phpt" role="test" />
- <file md5sum="f08d9809213c98acdf84fd9e656910e0" name="tests/readPreference/readpreference-ctor-001.phpt" role="test" />
+ <file md5sum="d8641784d6b9e66b8b44dfaa0328abd6" name="tests/readPreference/readpreference-ctor-001.phpt" role="test" />
<file md5sum="221ff341be838431d0b6aa95e1680e16" name="tests/readPreference/readpreference-ctor-002.phpt" role="test" />
<file md5sum="475a0c5eff5f7f7a211614819b886648" name="tests/readPreference/readpreference-ctor_error-001.phpt" role="test" />
<file md5sum="a0cdfd5d545b800d979e6610fa8f417a" name="tests/readPreference/readpreference-ctor_error-002.phpt" role="test" />
<file md5sum="ecc2c2b630fc509b9cc13cbaa180071e" name="tests/readPreference/readpreference-ctor_error-003.phpt" role="test" />
<file md5sum="2ecac9178a92b919e2a3d744386b308d" name="tests/readPreference/readpreference-ctor_error-004.phpt" role="test" />
<file md5sum="67904c50feea14b362824470d04a73ea" name="tests/readPreference/readpreference-ctor_error-005.phpt" role="test" />
<file md5sum="7f4fccdf7d3913833ddcb7c7a04feafd" name="tests/readPreference/readpreference-ctor_error-006.phpt" role="test" />
- <file md5sum="4708202d52455d5454a03b70d029b97f" name="tests/readPreference/readpreference-debug-001.phpt" role="test" />
+ <file md5sum="151872a7a99973fc6c29b11d10bfd26f" name="tests/readPreference/readpreference-ctor_error-007.phpt" role="test" />
+ <file md5sum="611c1c5b2794b57db557b7eccdd602ce" name="tests/readPreference/readpreference-debug-001.phpt" role="test" />
+ <file md5sum="39dc737e5086a3eb1cffac1a5960fa58" name="tests/readPreference/readpreference-getHedge-001.phpt" role="test" />
<file md5sum="4a4e16d677e9a242b8e2429def65e565" name="tests/readPreference/readpreference-getMaxStalenessMS-001.phpt" role="test" />
<file md5sum="23c503e166045f34625abc42506b80db" name="tests/readPreference/readpreference-getMaxStalenessMS-002.phpt" role="test" />
<file md5sum="2300bc05051a0d0dc183ebe1d699190a" name="tests/readPreference/readpreference-getMode-001.phpt" role="test" />
<file md5sum="8114a801f07aafd9330c9143bb02672a" name="tests/readPreference/readpreference-getModeString-001.phpt" role="test" />
<file md5sum="2a58ca560ca933e763397fdecd6e1c22" name="tests/readPreference/readpreference-getTagSets-001.phpt" role="test" />
<file md5sum="74a95fd229d950e7116b5ff0fd78db56" name="tests/readPreference/readpreference-getTagSets-002.phpt" role="test" />
- <file md5sum="5a0b15d993ed753872c632ff4b988fcf" name="tests/readPreference/readpreference-serialization-001.phpt" role="test" />
+ <file md5sum="0518414983b7662cada85c7815bd3a0b" name="tests/readPreference/readpreference-serialization-001.phpt" role="test" />
<file md5sum="50ed95b7fd36ec4aaa810ff93843733b" name="tests/readPreference/readpreference-set_state-001.phpt" role="test" />
- <file md5sum="89cbffd1437261dbe4447e490d7cce79" name="tests/readPreference/readpreference-set_state_error-001.phpt" role="test" />
+ <file md5sum="469960c5dbe3d362997a7498ceffe957" name="tests/readPreference/readpreference-set_state_error-001.phpt" role="test" />
<file md5sum="211bbe4ed835c63572432551b13e2bce" name="tests/readPreference/readpreference-set_state_error-002.phpt" role="test" />
<file md5sum="fdad20125292e0c2bde2ef25b61e7c28" name="tests/readPreference/readpreference-var_export-001.phpt" role="test" />
<file md5sum="56df736cc8af42557ae036e2eef910a8" name="tests/readPreference/readpreference_error-001.phpt" role="test" />
- <file md5sum="21aeae983faa900d2c675138183ed7c4" name="tests/replicaset/bug0155.phpt" role="test" />
+ <file md5sum="3cf1afee6206f9de195b4791a6605123" name="tests/replicaset/bug0155.phpt" role="test" />
<file md5sum="96b4ca171bfa4d6e67c70f134dfd69ce" name="tests/replicaset/bug0898-001.phpt" role="test" />
<file md5sum="fe8e45640380677089d99101b5883978" name="tests/replicaset/bug0898-002.phpt" role="test" />
<file md5sum="8cf05460fd402ac17258be1326a0682a" name="tests/replicaset/manager-getservers-001.phpt" role="test" />
<file md5sum="42ae774904c6cb84873619f90d479999" name="tests/replicaset/manager-selectserver-001.phpt" role="test" />
<file md5sum="46383074e49b79c3ae027314d6df7d89" name="tests/replicaset/readconcern-001.phpt" role="test" />
<file md5sum="5dae0a9293aabc3c656349304a74ab46" name="tests/replicaset/readconcern-002.phpt" role="test" />
<file md5sum="3db976328d75135e29f81a749b3f11b4" name="tests/replicaset/server-001.phpt" role="test" />
<file md5sum="feafa6c44b637790e099b118027c7478" name="tests/replicaset/server-002.phpt" role="test" />
<file md5sum="05c06feede9e23ae255c3712812f4122" name="tests/replicaset/writeconcernerror-001.phpt" role="test" />
<file md5sum="efdbacd7538ec6dc9850d80a377f82d3" name="tests/replicaset/writeconcernerror-002.phpt" role="test" />
<file md5sum="880126db315e70c22a172ca3b82ab718" name="tests/replicaset/writeresult-getserver-001.phpt" role="test" />
<file md5sum="a4b61fd2d3ff6c2218c25506fa519cc8" name="tests/replicaset/writeresult-getserver-002.phpt" role="test" />
<file md5sum="f604c05218049fcf317d960d16c2b2cc" name="tests/retryable-reads/retryable-reads-001.phpt" role="test" />
<file md5sum="de129bc602ec27318658568eed322416" name="tests/retryable-reads/retryable-reads-002.phpt" role="test" />
<file md5sum="ea30a6e0fe482be5c9f4428b7f475d70" name="tests/retryable-reads/retryable-reads_error-001.phpt" role="test" />
<file md5sum="3b8aa211bff63115d7995c888befac0a" name="tests/retryable-reads/retryable-reads_error-002.phpt" role="test" />
<file md5sum="fc5c93b3587f7a38aa8bccc266ad0ef5" name="tests/retryable-writes/retryable-writes-001.phpt" role="test" />
<file md5sum="1e94c0321bb27b1e51244529dbd5a200" name="tests/retryable-writes/retryable-writes-002.phpt" role="test" />
<file md5sum="e233372e47b2f6885fbb93f321a47663" name="tests/retryable-writes/retryable-writes-003.phpt" role="test" />
<file md5sum="8ac30a3b5e2432c6b5b38d64c035b405" name="tests/retryable-writes/retryable-writes-004.phpt" role="test" />
<file md5sum="e612122e12f41490d3093d588ec24000" name="tests/retryable-writes/retryable-writes-005.phpt" role="test" />
<file md5sum="6e1a9844ce8b3040279040533ddc3fb2" name="tests/retryable-writes/retryable-writes_error-001.phpt" role="test" />
<file md5sum="2b8a8659f4a505c3677a747de6de7ec8" name="tests/server/bug0671-002.phpt" role="test" />
<file md5sum="ff8f474af054f3b378d6f5fd4b6b9000" name="tests/server/server-constants.phpt" role="test" />
<file md5sum="f6d00397b693b9e3f524369083d14ad5" name="tests/server/server-construct-001.phpt" role="test" />
<file md5sum="c2acd0e7641f5a35911b60891b6d7e67" name="tests/server/server-debug.phpt" role="test" />
<file md5sum="f3abb90943c0c59f61897f0a20a8aae3" name="tests/server/server-errors.phpt" role="test" />
<file md5sum="63806ee59d45516b6dc5d882fd8bbb8e" name="tests/server/server-executeBulkWrite-001.phpt" role="test" />
<file md5sum="64fe8867060b08da59fbce6e48d019da" name="tests/server/server-executeBulkWrite-002.phpt" role="test" />
<file md5sum="5df32910418b393b9acacb7f15efebdf" name="tests/server/server-executeBulkWrite-003.phpt" role="test" />
<file md5sum="4a2b33ad1d412a6afd184fa2f1501e80" name="tests/server/server-executeBulkWrite-004.phpt" role="test" />
<file md5sum="40a8ba3033c7ffc43b4021932fe3f783" name="tests/server/server-executeBulkWrite-005.phpt" role="test" />
<file md5sum="17d83387a16ae669e77129acb0916695" name="tests/server/server-executeBulkWrite-006.phpt" role="test" />
<file md5sum="624b24797c3d1cb8d54cd9e9cf405b22" name="tests/server/server-executeBulkWrite-007.phpt" role="test" />
<file md5sum="76ceeabf514f6a5f4adf15803005a69f" name="tests/server/server-executeBulkWrite-008.phpt" role="test" />
<file md5sum="7bf168cb673fbcd4180a9b2f845a5488" name="tests/server/server-executeBulkWrite_error-001.phpt" role="test" />
<file md5sum="79244553626ae88124f93c5a5affb3a5" name="tests/server/server-executeBulkWrite_error-002.phpt" role="test" />
<file md5sum="e4271a12b01bdd5ea8aaf4b55cd44593" name="tests/server/server-executeCommand-001.phpt" role="test" />
<file md5sum="dc66ce61035c76ca671de5953da7b2a9" name="tests/server/server-executeCommand-002.phpt" role="test" />
<file md5sum="c42f82129f878752f19e5f75a852c225" name="tests/server/server-executeCommand-003.phpt" role="test" />
<file md5sum="cefa45c0633900d06eb8e76994a3fc29" name="tests/server/server-executeCommand-004.phpt" role="test" />
<file md5sum="81551df9208318dadb031c4076ffbd95" name="tests/server/server-executeCommand-005.phpt" role="test" />
<file md5sum="b7044ff1bcfade95c76418cada0e56f5" name="tests/server/server-executeCommand-006.phpt" role="test" />
<file md5sum="33c673f0982b40672eb5eade7eb49c81" name="tests/server/server-executeCommand-007.phpt" role="test" />
<file md5sum="4338862033ecb05c842a3bd331036578" name="tests/server/server-executeCommand-008.phpt" role="test" />
<file md5sum="29ee7b6f5a03852428a471fab21db52d" name="tests/server/server-executeCommand-009.phpt" role="test" />
<file md5sum="d3ecf35db4eee7f0019a9233b0b5b38e" name="tests/server/server-executeCommand_error-001.phpt" role="test" />
<file md5sum="80252724c53b8372b9ebe2e264ec7a58" name="tests/server/server-executeQuery-001.phpt" role="test" />
<file md5sum="8dfbcb094d44c59a17bc1d04cf239c2f" name="tests/server/server-executeQuery-002.phpt" role="test" />
<file md5sum="acde1eea432e4daf349f6f8a2339e573" name="tests/server/server-executeQuery-003.phpt" role="test" />
<file md5sum="391cb0318ab4bdb40d83e28e8d9951c9" name="tests/server/server-executeQuery-004.phpt" role="test" />
<file md5sum="e6b67a9a31145112f7796532006cc296" name="tests/server/server-executeQuery-005.phpt" role="test" />
<file md5sum="1f1cdc714fb4fc09a54c41efd785d366" name="tests/server/server-executeQuery-006.phpt" role="test" />
<file md5sum="8bbe2939e84d878696c64ff145e411f0" name="tests/server/server-executeQuery-007.phpt" role="test" />
<file md5sum="c3ba3846c961874e121c7171a80573d3" name="tests/server/server-executeQuery-008.phpt" role="test" />
<file md5sum="6eb6da9e63a1c00481498887f6743bfb" name="tests/server/server-executeQuery-009.phpt" role="test" />
<file md5sum="3d65377e8d570aaf0ffb95a1a85ddf96" name="tests/server/server-executeQuery-010.phpt" role="test" />
<file md5sum="113b6723ee01ef2bd9fa620693c30ab3" name="tests/server/server-executeQuery-011.phpt" role="test" />
<file md5sum="c31c549e66c9d8f3c8a4756265f9690d" name="tests/server/server-executeQuery-012.phpt" role="test" />
<file md5sum="f43cf4e01f89d67bcf211244385d1100" name="tests/server/server-executeQuery_error-001.phpt" role="test" />
<file md5sum="2b47225cdf8e0f9e68dbffa882c481b5" name="tests/server/server-executeReadCommand-001.phpt" role="test" />
<file md5sum="022e8daf9bfeec99d765cc41e8d03504" name="tests/server/server-executeReadCommand-002.phpt" role="test" />
<file md5sum="05e98dbeb736c1ed965e3f460ea5df64" name="tests/server/server-executeReadCommand_error-001.phpt" role="test" />
<file md5sum="0db31d3ee522f2013ce0e3a83b2a8c53" name="tests/server/server-executeReadWriteCommand-001.phpt" role="test" />
<file md5sum="cf783828d11acca6e25557ee048a0e3d" name="tests/server/server-executeReadWriteCommand-002.phpt" role="test" />
<file md5sum="90eb8548a78789f802d23e009e813917" name="tests/server/server-executeReadWriteCommand_error-001.phpt" role="test" />
<file md5sum="a7fbf14b06d151ff4ff2c7710846ef27" name="tests/server/server-executeWriteCommand-001.phpt" role="test" />
<file md5sum="0254f26bf9a337814293064204ee6da9" name="tests/server/server-executeWriteCommand-002.phpt" role="test" />
<file md5sum="2d4077a32f65cc4721d04d10a0a323c8" name="tests/server/server-executeWriteCommand_error-001.phpt" role="test" />
<file md5sum="560a414d45da81e5f0ab181f81492638" name="tests/server/server-getInfo-001.phpt" role="test" />
<file md5sum="fa45738e0a372064a1e977cce5e098a7" name="tests/server/server-getTags-001.phpt" role="test" />
<file md5sum="ed4ba9169d7b8395d1c1ff1196ca067b" name="tests/server/server-getTags-002.phpt" role="test" />
<file md5sum="9aefd9967eed1cb334069bc28d435b71" name="tests/server/server_error-001.phpt" role="test" />
<file md5sum="ad46a7559a26c836567ddd44773de48b" name="tests/session/bug1274-001.phpt" role="test" />
<file md5sum="f714efea637da9bad3c0c6db972f8607" name="tests/session/bug1274-002.phpt" role="test" />
<file md5sum="dc283d6d0443c19aae30034b23fa7cf7" name="tests/session/bug1274-003.phpt" role="test" />
- <file md5sum="aa3f58ea51533673c06e2382dc553f15" name="tests/session/session-001.phpt" role="test" />
+ <file md5sum="0fe9e9e9f4b22afb422cc73cf167df5d" name="tests/session/session-001.phpt" role="test" />
<file md5sum="7af7d6e79d92d1c96e49264e7ed033ed" name="tests/session/session-002.phpt" role="test" />
<file md5sum="882e75a08e382e51293cb93e7c338174" name="tests/session/session-003.phpt" role="test" />
<file md5sum="e2254f346cd7ae8ca11c3c6d0e923060" name="tests/session/session-advanceClusterTime-001.phpt" role="test" />
<file md5sum="a01993c77c1c241f3ccd23673d2a525c" name="tests/session/session-advanceOperationTime-001.phpt" role="test" />
<file md5sum="24e3cb8b13c5e1bd1227632b4b03839c" name="tests/session/session-advanceOperationTime-002.phpt" role="test" />
<file md5sum="627fae666642fe3e289c0ef2b569e11e" name="tests/session/session-advanceOperationTime-003.phpt" role="test" />
<file md5sum="47952ec7d197bb4ccc1fa2c41be6ab23" name="tests/session/session-advanceOperationTime_error-001.phpt" role="test" />
<file md5sum="65a1d6097e9a4b68a8a154b0176c7e74" name="tests/session/session-commitTransaction-001.phpt" role="test" />
<file md5sum="ae4075d8629d54ce74448dc56562af31" name="tests/session/session-constants.phpt" role="test" />
<file md5sum="d7d63d2f3a6a7eb838dfb0e6c9d52322" name="tests/session/session-debug-001.phpt" role="test" />
<file md5sum="3fcb23362cb2338d1e849febc02aa471" name="tests/session/session-debug-002.phpt" role="test" />
<file md5sum="7e9a3d5e7b740ea24af65fe8c08ed7c9" name="tests/session/session-debug-003.phpt" role="test" />
<file md5sum="62849f5a965ef2d2ca3cf2e12e24d4e9" name="tests/session/session-debug-004.phpt" role="test" />
<file md5sum="06cd05293d3d6cfa7341be647f998d7c" name="tests/session/session-debug-005.phpt" role="test" />
<file md5sum="4f5dcd685ab878798f0ad74dbdbab1be" name="tests/session/session-endSession-001.phpt" role="test" />
<file md5sum="6268cff15cfd8eeb0f96f00616812eca" name="tests/session/session-endSession-002.phpt" role="test" />
<file md5sum="4727641df2caa42900b2c3e78132276c" name="tests/session/session-getClusterTime-001.phpt" role="test" />
<file md5sum="80cf8d773cba1a17908b07ce7161c3bc" name="tests/session/session-getLogicalSessionId-001.phpt" role="test" />
<file md5sum="96a41fd301fb5aa28135abeefb9def5c" name="tests/session/session-getOperationTime-001.phpt" role="test" />
<file md5sum="c8ba6dba60f1ae46cba7f71360c55ed6" name="tests/session/session-getTransactionOptions-001.phpt" role="test" />
<file md5sum="d54de85742d6e5a1fef859f295eb3c07" name="tests/session/session-getTransactionState-001.phpt" role="test" />
<file md5sum="a0b3fffee98888621ca138b1077958a8" name="tests/session/session-isInTransaction-001.phpt" role="test" />
<file md5sum="2e266404ac1f83d906fa47302fddc4f6" name="tests/session/session-startTransaction-001.phpt" role="test" />
<file md5sum="b1f793dfdf9538a37f2e4e4aea83f89b" name="tests/session/session-startTransaction_error-001.phpt" role="test" />
<file md5sum="1d5eacd6b5d32fcd27cc4504f9078fe3" name="tests/session/session-startTransaction_error-002.phpt" role="test" />
- <file md5sum="af1eaddfe7a4087760e3827a099bad1d" name="tests/session/session-startTransaction_error-003.phpt" role="test" />
- <file md5sum="b8258f2d3da8a9ee25998ce77cb36285" name="tests/session/session-startTransaction_error-004.phpt" role="test" />
+ <file md5sum="1ddbf1f3f69d92eedb67ec1c7df5f9e0" name="tests/session/session-startTransaction_error-004.phpt" role="test" />
<file md5sum="40fea178eed89f96155406e7454e66ae" name="tests/session/session-startTransaction_error-005.phpt" role="test" />
<file md5sum="8083d8a3439a1bb5077c773179bf2bac" name="tests/session/session-startTransaction_error-006.phpt" role="test" />
<file md5sum="99efcb91c29c3173d76d965eecff97f0" name="tests/session/session-startTransaction_error-007.phpt" role="test" />
<file md5sum="45e56e8802f0a23f022af36821045a87" name="tests/session/session_error-001.phpt" role="test" />
<file md5sum="418a31e693d99470550772bb393c0195" name="tests/session/transaction-integration-001.phpt" role="test" />
<file md5sum="f0bd641948afbbc7e61a337723d39d5b" name="tests/session/transaction-integration-002.phpt" role="test" />
<file md5sum="dfadd390104f59283051fe0beb2e3925" name="tests/session/transaction-integration-003.phpt" role="test" />
<file md5sum="a7c9e16b70f3b8d3d9718984800c5377" name="tests/session/transaction-integration_error-001.phpt" role="test" />
<file md5sum="7def4e71fa83b9f89acce1282b4073c8" name="tests/session/transaction-integration_error-002.phpt" role="test" />
<file md5sum="b6e68398a74801cb94d85772a1896a8b" name="tests/session/transaction-integration_error-003.phpt" role="test" />
<file md5sum="bb21f9b365f3248f121541ae6578d3cc" name="tests/session/transaction-integration_error-004.phpt" role="test" />
<file md5sum="940383190d64230873ed7d5fd0ea4e83" name="tests/standalone/bug0166.phpt" role="test" />
<file md5sum="6663da2bef4308dda70d7e5536358fc0" name="tests/standalone/bug0231.phpt" role="test" />
<file md5sum="e960210e5b8a123f06b5b2f0f5dc9b1f" name="tests/standalone/bug0357.phpt" role="test" />
<file md5sum="895c0c02119818d6085e5d4b965284ce" name="tests/standalone/bug0545.phpt" role="test" />
<file md5sum="8e078a15babcfcd350ac6208da20858a" name="tests/standalone/bug0655.phpt" role="test" />
<file md5sum="c0e1dafb0b6072b56625cb46a9e8db8d" name="tests/standalone/command-aggregate-001.phpt" role="test" />
<file md5sum="30a58f9aae77077a886309ddaf4f5599" name="tests/standalone/connectiontimeoutexception-001.phpt" role="test" />
<file md5sum="bd525b744a97ecc68c9dcc25c49436ee" name="tests/standalone/executiontimeoutexception-001.phpt" role="test" />
<file md5sum="aba1a96e301df77d3f5b17b6954d5569" name="tests/standalone/executiontimeoutexception-002.phpt" role="test" />
<file md5sum="c25d1cb79ff39fc6ff20fac6ba555e05" name="tests/standalone/manager-as-singleton.phpt" role="test" />
<file md5sum="54dc16a86c37e04384e2c6454ef056b7" name="tests/standalone/query-errors.phpt" role="test" />
<file md5sum="12028d3707db221c7ab5089f0cb1b865" name="tests/standalone/update-multi-001.phpt" role="test" />
<file md5sum="ee76e8fbed51422613ea238569c1876e" name="tests/standalone/write-error-001.phpt" role="test" />
<file md5sum="fde81b755ba7215a4508686b93cd1d0c" name="tests/standalone/writeresult-isacknowledged-001.phpt" role="test" />
<file md5sum="6c5c3c9f27c366857c03bc0e2c1d1a86" name="tests/standalone/writeresult-isacknowledged-002.phpt" role="test" />
<file md5sum="cc33d3dbb588b0218ae6801d4598b448" name="tests/standalone/writeresult-isacknowledged-003.phpt" role="test" />
<file md5sum="59adebd29ef983f00c4d55cfc4b2d10d" name="tests/utils/PHONGO-FIXTURES.json.gz" role="test" />
<file md5sum="20bcdb186e464bebff08400730d55afd" name="tests/utils/basic-skipif.inc" role="test" />
<file md5sum="06d6c225875e223552130cd59da13350" name="tests/utils/basic.inc" role="test" />
<file md5sum="d45f34ff6fd0f526099f3131d5d17b11" name="tests/utils/classes.inc" role="test" />
<file md5sum="4134acafdc5eb51800213b41043116ba" name="tests/utils/observer.php" role="test" />
- <file md5sum="d00e03ac86d81e826f45bafb82fcccf1" name="tests/utils/skipif.php" role="test" />
+ <file md5sum="017ec7dc3174e863cf94ece68093e26a" name="tests/utils/skipif.php" role="test" />
<file md5sum="ca818bdd97304f37d99a0af4a165c5b1" name="tests/utils/tools.php" role="test" />
+ <file md5sum="64ee8e2ef24e46d681df686739aa4e69" name="tests/writeConcern/bug1598-001.phpt" role="test" />
+ <file md5sum="2627d7f0df83428223b79249b0223243" name="tests/writeConcern/bug1598-002.phpt" role="test" />
<file md5sum="cf5ae403507aa8f399bc6aeb35ed5b70" name="tests/writeConcern/writeconcern-bsonserialize-001.phpt" role="test" />
<file md5sum="073e73d11253900ad6d1e3e1b0656d20" name="tests/writeConcern/writeconcern-bsonserialize-002.phpt" role="test" />
<file md5sum="a02e1015d4bc797ff8a68613342f28c5" name="tests/writeConcern/writeconcern-bsonserialize-003.phpt" role="test" />
<file md5sum="64c7fb44e466938561d753546b82c22f" name="tests/writeConcern/writeconcern-bsonserialize-004.phpt" role="test" />
<file md5sum="08cc65bfe3d89314eca5a43616e12202" name="tests/writeConcern/writeconcern-constants.phpt" role="test" />
<file md5sum="3dbbdae846359bf00358aad47b0b7ae6" name="tests/writeConcern/writeconcern-ctor-001.phpt" role="test" />
<file md5sum="1f9f66d9446fa0f5ce954d88abe56e70" name="tests/writeConcern/writeconcern-ctor-002.phpt" role="test" />
<file md5sum="14ed39149705e115f25a9e1fc0660e7f" name="tests/writeConcern/writeconcern-ctor_error-001.phpt" role="test" />
<file md5sum="c2e8f1ec966e7bea7506086d3b078b0c" name="tests/writeConcern/writeconcern-ctor_error-002.phpt" role="test" />
<file md5sum="c2060d2d434822651642407ea58f43de" name="tests/writeConcern/writeconcern-ctor_error-003.phpt" role="test" />
<file md5sum="fe0f02fd98455f53bf423043f6d92925" name="tests/writeConcern/writeconcern-ctor_error-004.phpt" role="test" />
+ <file md5sum="95bb856337bc64ff047555b00549eaae" name="tests/writeConcern/writeconcern-ctor_error-005.phpt" role="test" />
<file md5sum="22dfaec3917fe798f71c15d857a36921" name="tests/writeConcern/writeconcern-debug-001.phpt" role="test" />
<file md5sum="56555f30c1e42233cb65ef12a0fb870b" name="tests/writeConcern/writeconcern-debug-002.phpt" role="test" />
<file md5sum="7feb66ce332c7b57016aa3f40e157480" name="tests/writeConcern/writeconcern-debug-003.phpt" role="test" />
<file md5sum="544bc7904161390cd99e1603b71eb0c6" name="tests/writeConcern/writeconcern-getjournal-001.phpt" role="test" />
<file md5sum="c64faac6dd9eeb55bb27b2d82acb7d86" name="tests/writeConcern/writeconcern-getw-001.phpt" role="test" />
<file md5sum="9ec2c850fc6202678ea402e96a56e530" name="tests/writeConcern/writeconcern-getwtimeout-001.phpt" role="test" />
<file md5sum="e4a511f7c2e842768495c5ebefa824e1" name="tests/writeConcern/writeconcern-getwtimeout-002.phpt" role="test" />
<file md5sum="7ac2556e20b9fda6524d291b695f9241" name="tests/writeConcern/writeconcern-isdefault-001.phpt" role="test" />
<file md5sum="c455191cb343f16c2e707eb067ac09a9" name="tests/writeConcern/writeconcern-serialization-001.phpt" role="test" />
+ <file md5sum="3929df39414066a6b692810915cf65d1" name="tests/writeConcern/writeconcern-serialization_error-001.phpt" role="test" />
<file md5sum="d114d86a919cd387a4f16d9c2f1308db" name="tests/writeConcern/writeconcern-set_state-001.phpt" role="test" />
<file md5sum="c75a8d672c6e6eddc31470b73e2234c5" name="tests/writeConcern/writeconcern-set_state_error-001.phpt" role="test" />
<file md5sum="898c846d82ef5860cad45d52ff82e31c" name="tests/writeConcern/writeconcern-var_export-001.phpt" role="test" />
<file md5sum="14ec52ea19befdf082e3ee270fa7d8ea" name="tests/writeConcern/writeconcern_error-001.phpt" role="test" />
<file md5sum="007f673dcf21440bc71f0d2cd160dc06" name="tests/writeConcernError/writeconcernerror-debug-001.phpt" role="test" />
<file md5sum="b6a48538944c72c534c810fa88029c26" name="tests/writeConcernError/writeconcernerror-debug-002.phpt" role="test" />
<file md5sum="4f11045704555562d06c761ea2743c3b" name="tests/writeConcernError/writeconcernerror-getcode-001.phpt" role="test" />
<file md5sum="8ad20b0efa584722e3fc5c7fbd368026" name="tests/writeConcernError/writeconcernerror-getinfo-001.phpt" role="test" />
<file md5sum="b072dec51460af51750d092810e6933b" name="tests/writeConcernError/writeconcernerror-getinfo-002.phpt" role="test" />
<file md5sum="31455bca8a9201347154b00f301e7090" name="tests/writeConcernError/writeconcernerror-getmessage-001.phpt" role="test" />
<file md5sum="69820b84c701fe8480e6e8014a14189c" name="tests/writeConcernError/writeconcernerror_error-001.phpt" role="test" />
<file md5sum="49dec43862f3c94413d798af07744c48" name="tests/writeError/writeerror-debug-001.phpt" role="test" />
<file md5sum="dfd0eb23f183022e4c8e3b090412b92e" name="tests/writeError/writeerror-getCode-001.phpt" role="test" />
<file md5sum="13c878a368e78176a5cdc7332704883b" name="tests/writeError/writeerror-getIndex-001.phpt" role="test" />
<file md5sum="eeecb795c9cd519549fa486460bc7458" name="tests/writeError/writeerror-getInfo-001.phpt" role="test" />
<file md5sum="33a6c89310fee726c12dd0113ab3e45b" name="tests/writeError/writeerror-getMessage-001.phpt" role="test" />
<file md5sum="ba12ea26054c04774c4d6a3f35094c28" name="tests/writeError/writeerror_error-001.phpt" role="test" />
<file md5sum="e1659c0daaebbf2324739990c3b7ce23" name="tests/writeResult/bug0671-003.phpt" role="test" />
<file md5sum="cc04e32b67b25545a84b9b2c568a9a5f" name="tests/writeResult/writeresult-debug-001.phpt" role="test" />
- <file md5sum="c901d2965cc53ee9efc146bd7e1f9ba6" name="tests/writeResult/writeresult-debug-002.phpt" role="test" />
+ <file md5sum="99e759dc701153d6436484c106b33b20" name="tests/writeResult/writeresult-debug-002.phpt" role="test" />
<file md5sum="bea93768430dad4080e6dacfaf3d767d" name="tests/writeResult/writeresult-getdeletedcount-001.phpt" role="test" />
<file md5sum="8e98e22963c706d5dd639ad1ce7ce66f" name="tests/writeResult/writeresult-getdeletedcount-002.phpt" role="test" />
<file md5sum="d275cd76a8696ff44dbcd7b837f849bc" name="tests/writeResult/writeresult-getinsertedcount-001.phpt" role="test" />
<file md5sum="ae69602d2142ed4d45e63533f39836ac" name="tests/writeResult/writeresult-getinsertedcount-002.phpt" role="test" />
<file md5sum="daaf8b1c546b212e2fde05c2d8bb8b44" name="tests/writeResult/writeresult-getmatchedcount-001.phpt" role="test" />
<file md5sum="42e979f88d2f246953e9b6602a57c2f7" name="tests/writeResult/writeresult-getmatchedcount-002.phpt" role="test" />
<file md5sum="75c7961241c42185ce8d0d28fe9b521d" name="tests/writeResult/writeresult-getmodifiedcount-001.phpt" role="test" />
<file md5sum="774ba30e92e3ba4cd9783fd66739c669" name="tests/writeResult/writeresult-getmodifiedcount-002.phpt" role="test" />
<file md5sum="70e5f633cb3a6679cd2f336635d7d196" name="tests/writeResult/writeresult-getserver-001.phpt" role="test" />
<file md5sum="348f056b4388e6b1f8906b6d2b33f4b1" name="tests/writeResult/writeresult-getupsertedcount-001.phpt" role="test" />
<file md5sum="8a71a2cdf9c660c9bdce8472859ce7ed" name="tests/writeResult/writeresult-getupsertedcount-002.phpt" role="test" />
<file md5sum="dc301823a371a9844ad051f148e89540" name="tests/writeResult/writeresult-getupsertedids-001.phpt" role="test" />
<file md5sum="7f2a32e5a6fa6dccde7448ef0668e1bd" name="tests/writeResult/writeresult-getupsertedids-002.phpt" role="test" />
- <file md5sum="91fc62bff855fc49d7d2f9cede83344b" name="tests/writeResult/writeresult-getwriteconcernerror-001.phpt" role="test" />
+ <file md5sum="3c5ab26b8cf18f85ccbbe5ce5e8a5604" name="tests/writeResult/writeresult-getwriteconcernerror-001.phpt" role="test" />
<file md5sum="eb245af82b8e8845a85d63e2620feb9a" name="tests/writeResult/writeresult-getwriteerrors-001.phpt" role="test" />
<file md5sum="3f4f8053a660b2a575338e96b4badf2a" name="tests/writeResult/writeresult-getwriteerrors-002.phpt" role="test" />
<file md5sum="700423c4500dc42f08187c2fdd13422c" name="tests/writeResult/writeresult-isacknowledged-001.phpt" role="test" />
<file md5sum="fdd3ef0a514427c85fb91ff8a1cff3f6" name="tests/writeResult/writeresult_error-001.phpt" role="test" />
- <file md5sum="fce0c3612e0b5fbd45b6a0b7f8ccc82e" name="CREDITS" role="doc" />
+ <file md5sum="b3a933056b7c0bf6369b2cbbfb99d833" name="CONTRIBUTING.md" role="doc" />
+ <file md5sum="198d0ffaabbd88f77e9b9067b694ca10" name="CREDITS" role="doc" />
<file md5sum="b1e01b26bacfc2232046c90a330332b3" name="LICENSE" role="doc" />
<file md5sum="eacc64f242c8462914d179af5370b078" name="Makefile.frag" role="src" />
<file md5sum="52a347bc408e3b94f1fe5d7d6a78af3a" name="README.md" role="doc" />
+ <file md5sum="eadbe8ccffa540f5ac53ffc59e36a727" name="THIRD_PARTY_NOTICES" role="doc" />
<file md5sum="0962c850da28d6d16b471cc9e9c976d9" name="Vagrantfile" role="test" />
- <file md5sum="740e19b5e7cf8c53b6688246aa6c4bfa" name="config.m4" role="src" />
- <file md5sum="8a007e96a2d335921701c96116d80974" name="config.w32" role="src" />
- <file md5sum="718b96d994ef9f9094ded50768c51036" name="phongo_compat.c" role="src" />
- <file md5sum="c89cbd49d74902922d3c30a997d2faa2" name="phongo_compat.h" role="src" />
- <file md5sum="00c71eae83838a3de264262a55c58e5d" name="phongo_version.h" role="src" />
- <file md5sum="f6008935024021292fa57ea85585f54f" name="php_bson.h" role="src" />
- <file md5sum="3d3b278f3f9e5fbb54675b333ce3dabe" name="php_phongo.c" role="src" />
- <file md5sum="2dc3de67e1e6424659055b6be6d61433" name="php_phongo.h" role="src" />
- <file md5sum="f84ca19e12a0e1010b1f43bdad2b67aa" name="php_phongo_classes.h" role="src" />
- <file md5sum="e333728cdc4ab522396c5bb4066300cb" name="php_phongo_structs.h" role="src" />
+ <file md5sum="9da1a6110b74ccb6655cb70c75f262ba" name="config.m4" role="src" />
+ <file md5sum="4d9d117bb9889cf6d292ee737f9861c7" name="config.w32" role="src" />
+ <file md5sum="dda0618f33950b5b7613dc3af0aecc3c" name="phongo_compat.c" role="src" />
+ <file md5sum="3ba4b84d903f9d6bc17d87fdce7a6a96" name="phongo_compat.h" role="src" />
+ <file md5sum="5bc800c33eadb9a62afddaf6133c5d36" name="phongo_version.h" role="src" />
+ <file md5sum="3239fe58ab586acf0d942629fd210b90" name="php_bson.h" role="src" />
+ <file md5sum="ef6c986a54b10ad2b8e07026d5264e93" name="php_phongo.c" role="src" />
+ <file md5sum="e4c3b3d58237efbe2eff962cf224a971" name="php_phongo.h" role="src" />
+ <file md5sum="2a6d7e8c1627e96625a8e3d893a1a192" name="php_phongo_classes.h" role="src" />
+ <file md5sum="d4285f6453217854e078d39dab046ebf" name="php_phongo_structs.h" role="src" />
</dir>
</contents>
<dependencies>
<required>
<php>
- <min>5.6.0</min>
+ <min>7.0.0</min>
<max>7.99.99</max>
</php>
<pearinstaller>
<min>1.4.8</min>
</pearinstaller>
</required>
</dependencies>
<providesextension>mongodb</providesextension>
<extsrcrelease />
</package>

File Metadata

Mime Type
application/octet-stream
Expires
Sat, Sep 13, 4:27 AM (1 d, 23 h)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
X5RNlpW9VYsu
Default Alt Text
(4 MB)

Event Timeline