Пример #1
0
mongoc_uri_t *
mongoc_uri_copy (const mongoc_uri_t *uri)
{
   mongoc_uri_t       *copy;
   mongoc_host_list_t *iter;

   BSON_ASSERT (uri);

   copy = (mongoc_uri_t *)bson_malloc0(sizeof (*copy));

   copy->str      = bson_strdup (uri->str);
   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);

   for (iter = uri->hosts; iter; iter = iter->next) {
      mongoc_uri_append_host (copy, iter->host, iter->port);
   }

   bson_copy_to (&uri->options, &copy->options);
   bson_copy_to (&uri->credentials, &copy->credentials);

   return copy;
}
Пример #2
0
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);

   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);

   RETURN(db);
}
Пример #3
0
mongoc_database_t *
_mongoc_database_new (mongoc_client_t              *client,
                      const char                   *name,
                      const mongoc_read_prefs_t    *read_prefs,
                      const mongoc_write_concern_t *write_concern)
{
   mongoc_database_t *db;

   ENTRY;

   bson_return_val_if_fail(client, NULL);
   bson_return_val_if_fail(name, NULL);

   db = bson_malloc0(sizeof *db);
   db->client = client;
   db->write_concern = write_concern ?
      mongoc_write_concern_copy(write_concern) :
      mongoc_write_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);

   RETURN(db);
}
static mongoc_write_concern_t *
create_commit_retry_wc (const mongoc_write_concern_t *existing_wc)
{
   mongoc_write_concern_t *wc;
   int32_t wtimeout;

   wc = existing_wc ? mongoc_write_concern_copy (existing_wc)
                    : mongoc_write_concern_new ();

   wtimeout = mongoc_write_concern_get_wtimeout (wc);

   /* 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 (wtimeout <= 0) {
      wtimeout = 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_wmajority (wc, wtimeout);

   return wc;
}
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);
}
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);
}
Пример #7
0
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);
}
Пример #8
0
Object HHVM_METHOD(MongoDBDriverManager, getWriteConcern)
{
	MongoDBDriverManagerData* data = Native::data<MongoDBDriverManagerData>(this_);

	Class *c_wc = Unit::lookupClass(s_MongoDriverWriteConcern_className.get());
	assert(c_wc);
	Object wc_obj = Object{c_wc};
	MongoDBDriverWriteConcernData* wc_data = Native::data<HPHP::MongoDBDriverWriteConcernData>(wc_obj.get());

	wc_data->m_write_concern = mongoc_write_concern_copy(mongoc_client_get_write_concern(data->m_client));

	return wc_obj;
}
mongoc_client_t *
mongoc_client_new (const char *uri_string)
{
   const mongoc_write_concern_t *write_concern;
   mongoc_client_t *client;
   mongoc_uri_t *uri;
   const bson_t *options;
   bson_iter_t iter;
   bool has_ssl = false;

   if (!uri_string) {
      uri_string = "mongodb://127.0.0.1/";
   }

   if (!(uri = mongoc_uri_new(uri_string))) {
      return NULL;
   }

   options = mongoc_uri_get_options (uri);

   if (bson_iter_init_find (&iter, options, "ssl") &&
       BSON_ITER_HOLDS_BOOL (&iter) &&
       bson_iter_bool (&iter)) {
      has_ssl = true;
   }

   client = bson_malloc0(sizeof *client);
   client->uri = uri;
   client->request_id = rand ();
   client->initiator = mongoc_client_default_stream_initiator;
   client->initiator_data = client;

   write_concern = mongoc_uri_get_write_concern (uri);
   client->write_concern = mongoc_write_concern_copy (write_concern);

   client->read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);

   _mongoc_cluster_init (&client->cluster, client->uri, client);

#ifdef MONGOC_ENABLE_SSL
   if (has_ssl) {
      mongoc_client_set_ssl_opts (client, mongoc_ssl_opt_get_default ());
   }
#endif

   mongoc_counter_clients_active_inc ();

   return client;
}
Пример #10
0
void
mongoc_client_set_write_concern (mongoc_client_t              *client,
                                 const mongoc_write_concern_t *write_concern)
{
   bson_return_if_fail(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();
   }
}
Пример #11
0
void
mongoc_database_set_write_concern (mongoc_database_t            *database,
                                   const mongoc_write_concern_t *write_concern)
{
   bson_return_if_fail(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);
   }
}
Пример #12
0
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();
   }
}
Пример #13
0
void
mongoc_database_set_write_concern (mongoc_database_t            *database,
                                   const mongoc_write_concern_t *write_concern)
{
   BSON_ASSERT (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);
   }
}
Пример #14
0
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 ();
   }
}
void
mongoc_bulk_operation_set_write_concern (mongoc_bulk_operation_t      *bulk,
                                         const mongoc_write_concern_t *write_concern)
{
   bson_return_if_fail (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 ();
   }
}
Пример #16
0
mongoc_client_t *
_mongoc_client_new_from_uri (const mongoc_uri_t *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;

   BSON_ASSERT (uri);

#ifndef MONGOC_ENABLE_SSL
   if (mongoc_uri_get_ssl (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 (uri);
   client->request_id = rand ();
   client->initiator = mongoc_client_default_stream_initiator;
   client->initiator_data = client;
   client->topology = topology;

   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);

   mongoc_cluster_init (&client->cluster, client->uri, client);

#ifdef MONGOC_ENABLE_SSL
   client->use_ssl = false;
   if (mongoc_uri_get_ssl (client->uri)) {
      /* sets use_ssl = true */
      mongoc_client_set_ssl_opts (client, mongoc_ssl_opt_get_default ());
   }
#endif

   mongoc_counter_clients_active_inc ();

   return client;
}
Пример #17
0
mongoc_client_t *
_mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topology)
{
   mongoc_client_t *client;
   const mongoc_read_prefs_t *read_prefs;
   const mongoc_write_concern_t *write_concern;
#ifdef MONGOC_ENABLE_SSL
   const bson_t *options;
   bson_iter_t iter;
#endif

   BSON_ASSERT (uri);

   client = (mongoc_client_t *)bson_malloc0(sizeof *client);
   client->uri = mongoc_uri_copy (uri);
   client->request_id = rand ();
   client->initiator = mongoc_client_default_stream_initiator;
   client->initiator_data = client;
   client->topology = topology;

   write_concern = mongoc_uri_get_write_concern (client->uri);
   client->write_concern = mongoc_write_concern_copy (write_concern);

   read_prefs = mongoc_uri_get_read_prefs_t (client->uri);
   client->read_prefs = mongoc_read_prefs_copy (read_prefs);

   mongoc_cluster_init (&client->cluster, client->uri, client);

#ifdef MONGOC_ENABLE_SSL
   options = mongoc_uri_get_options (client->uri);

   if (bson_iter_init_find (&iter, options, "ssl") &&
       BSON_ITER_HOLDS_BOOL (&iter) &&
       bson_iter_bool (&iter)) {
         mongoc_client_set_ssl_opts (client, mongoc_ssl_opt_get_default ());
   }
#endif

   mongoc_counter_clients_active_inc ();

   return client;
}
mongoc_bulk_operation_t *
_mongoc_bulk_operation_new (mongoc_client_t              *client,        /* IN */
                            const char                   *database,      /* IN */
                            const char                   *collection,    /* IN */
                            uint32_t                      hint,          /* IN */
                            bool                          ordered,       /* 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 (ordered);
   bulk->client = client;
   bulk->database = bson_strdup (database);
   bulk->collection = bson_strdup (collection);
   bulk->hint = hint;
   bulk->write_concern = mongoc_write_concern_copy (write_concern);
   bulk->executed = false;

   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;
}
Пример #20
0
Object hippo_write_result_init(bson_t *reply, bson_error_t *error, mongoc_client_t *client, int server_id, int success, const mongoc_write_concern_t *write_concern)
{
	static Class* c_writeResult;

	c_writeResult = Unit::lookupClass(s_MongoDriverWriteResult_className.get());
	assert(c_writeResult);
	Object obj = Object{c_writeResult};

	MongoDBDriverWriteResultData* wr_data = Native::data<MongoDBDriverWriteResultData>(obj.get());
	wr_data->m_client = client;
	wr_data->m_server_id = server_id;
	wr_data->m_write_concern = mongoc_write_concern_copy(write_concern);

	/* Convert the whole BSON reply into a Variant */
	Variant v;
	Array a;
	hippo_bson_conversion_options_t options = HIPPO_TYPEMAP_DEBUG_INITIALIZER;

	BsonToVariantConverter convertor(bson_get_data(reply), reply->len, options);
	convertor.convert(&v);
	a = v.toArray();

	obj->o_set(s_nUpserted, Variant(a[s_nUpserted]), s_MongoDriverWriteResult_className);
	obj->o_set(s_nMatched, Variant(a[s_nMatched]), s_MongoDriverWriteResult_className);
	obj->o_set(s_nRemoved, Variant(a[s_nRemoved]), s_MongoDriverWriteResult_className);
	obj->o_set(s_nInserted, Variant(a[s_nInserted]), s_MongoDriverWriteResult_className);
	obj->o_set(s_nModified, Variant(a[s_nModified]), s_MongoDriverWriteResult_className);

	if (write_concern) {
		Array debugInfoResult = Array::Create();
		mongodb_driver_add_write_concern_debug((mongoc_write_concern_t*) write_concern, &debugInfoResult);

		obj->o_set(s_writeConcern, debugInfoResult, s_MongoDriverWriteConcern_className);
	} else {
		obj->o_set(s_writeConcern, Variant(), s_MongoDriverWriteConcern_className);
	}

	if (a.exists(s_upserted)) {
		obj->o_set(s_upsertedIds, a[s_upserted], s_MongoDriverWriteResult_className);
	} else {
		Array a = Array::Create();
		obj->o_set(s_upsertedIds, a, s_MongoDriverWriteResult_className);
	}

	if (a.exists(s_writeErrors)) {
		Array writeErrors = Array::Create();

		for (ArrayIter iter(a[s_writeErrors].toArray()); iter; ++iter) {
			const Variant& value = iter.second();
			static Class* c_writeError;

			Array a_we = value.toArray();

			c_writeError = Unit::lookupClass(s_MongoDriverWriteError_className.get());
			assert(c_writeError);
			Object we_obj = Object{c_writeError};

			if (a_we.exists(s_errmsg)) {
				we_obj->o_set(s_message, a_we[s_errmsg], s_MongoDriverWriteError_className);
			}
			if (a_we.exists(s_code)) {
				we_obj->o_set(s_code, a_we[s_code], s_MongoDriverWriteError_className);
			}
			if (a_we.exists(s_index)) {
				we_obj->o_set(s_index, a_we[s_index], s_MongoDriverWriteError_className);
			}
			if (a_we.exists(s_info)) {
				we_obj->o_set(s_info, a_we[s_info], s_MongoDriverWriteError_className);
			}

			writeErrors.append(we_obj);
		}

		obj->o_set(s_writeErrors, writeErrors, s_MongoDriverWriteResult_className);
	}

	if (a.exists(s_writeConcernErrors)) {
		Array a_v;

		a_v = a[s_writeConcernErrors].toArray();
	
		static Class* c_writeConcernError;

		c_writeConcernError = Unit::lookupClass(s_MongoDriverWriteConcernError_className.get());
		assert(c_writeConcernError);
		Object wce_obj = Object{c_writeConcernError};

		if (a_v.exists(0) && a_v[0].isArray()) {
			Array first_item = a_v[0].toArray();

			if (first_item.exists(s_errmsg)) {
				wce_obj->o_set(s_message, first_item[s_errmsg], s_MongoDriverWriteConcernError_className);
			}
			if (first_item.exists(s_code)) {
				wce_obj->o_set(s_code, first_item[s_code], s_MongoDriverWriteConcernError_className);
			}
			if (first_item.exists(s_info)) {
				wce_obj->o_set(s_info, first_item[s_info], s_MongoDriverWriteConcernError_className);
			} else {
				wce_obj->o_set(s_info, Variant(), s_MongoDriverWriteConcernError_className);
			}

			obj->o_set(s_writeConcernError, Variant(wce_obj), s_MongoDriverWriteResult_className);
		}
	}

	if (success == 0) {
		if ((error->domain == MONGOC_ERROR_COMMAND && error->code != MONGOC_ERROR_COMMAND_INVALID_ARG) || error->domain == MONGOC_ERROR_WRITE_CONCERN) {
			auto bw_exception = MongoDriver::Utils::throwBulkWriteException(error->message);
			bw_exception->o_set(s_MongoDriverExceptionBulkWriteException_writeResult, obj, MongoDriver::s_MongoDriverExceptionBulkWriteException_className);

			throw bw_exception;
		} else {
			throw MongoDriver::Utils::throwExceptionFromBsonError(error);
		}
	}

	return obj;
}
Пример #21
0
static bool hippo_mongo_driver_manager_apply_wc(mongoc_uri_t *uri, const Array options)
{
	int32_t wtimeoutms;
	mongoc_write_concern_t *new_wc;
	const mongoc_write_concern_t *old_wc;

	if (!(old_wc = mongoc_uri_get_write_concern(uri))) {
		throw MongoDriver::Utils::throwRunTimeException("mongoc_uri_t does not have a write concern");

		return false;
	}

	if (options.size() == 0) {
		return true;
	}

	if (
		!options.exists(s_MongoDBDriverManager_journal) &&
		!options.exists(s_MongoDBDriverManager_safe) &&
		!options.exists(s_MongoDBDriverManager_w) &&
		!options.exists(s_MongoDBDriverManager_wtimeoutms)
	) {
		return true;
	}

	wtimeoutms = mongoc_write_concern_get_wtimeout(old_wc);

	new_wc = mongoc_write_concern_copy(old_wc);

	if (options.exists(s_MongoDBDriverManager_safe) && options[s_MongoDBDriverManager_safe].isBoolean()) {
		mongoc_write_concern_set_w(new_wc, options[s_MongoDBDriverManager_safe].toBoolean() ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
	}

	if (options.exists(s_MongoDBDriverManager_wtimeoutms) && options[s_MongoDBDriverManager_wtimeoutms].isInteger()) {
		wtimeoutms = (int32_t) options[s_MongoDBDriverManager_wtimeoutms].toInt64();
	}

	if (options.exists(s_MongoDBDriverManager_journal) && options[s_MongoDBDriverManager_journal].isBoolean()) {
		mongoc_write_concern_set_journal(new_wc, !!options[s_MongoDBDriverManager_journal].toBoolean());
	}

	if (options.exists(s_MongoDBDriverManager_w)) {
		if (options[s_MongoDBDriverManager_w].isInteger()) {
			int32_t value = (int32_t) options[s_MongoDBDriverManager_w].toInt64();

			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;
					}
					throw MongoDriver::Utils::throwInvalidArgumentException("Unsupported w value: " + Variant(value).toString());
					mongoc_write_concern_destroy(new_wc);

					return false;
			}
		} else if (options[s_MongoDBDriverManager_w].isString()) {
			const char *str = options[s_MongoDBDriverManager_w].toString().c_str();

			if (0 == strcasecmp("majority", str)) {
				mongoc_write_concern_set_wmajority(new_wc, wtimeoutms);
			} else {
				mongoc_write_concern_set_wtag(new_wc, str);
			}
		}
	}

	/* Only set wtimeout if it's still applicable; otherwise, clear it. */
	if (mongoc_write_concern_get_w(new_wc) > 1 ||
		mongoc_write_concern_get_wmajority(new_wc) ||
		mongoc_write_concern_get_wtag(new_wc)) {
		mongoc_write_concern_set_wtimeout(new_wc, wtimeoutms);
	} else {
		mongoc_write_concern_set_wtimeout(new_wc, 0);
	}

	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) {
			throw MongoDriver::Utils::throwInvalidArgumentException("Journal conflicts with w value: " + Variant(w).toString());
			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)) {
		throw MongoDriver::Utils::throwInvalidArgumentException("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;
}