mongoc_uri_t *
mongoc_uri_new (const char *uri_string)
{
   mongoc_uri_t *uri;

   uri = bson_malloc0(sizeof *uri);
   bson_init(&uri->options);
   bson_init(&uri->credentials);
   bson_init(&uri->read_prefs);

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

   if (!mongoc_uri_parse(uri, uri_string)) {
      mongoc_uri_destroy(uri);
      return NULL;
   }

   _mongoc_uri_build_write_concern (uri);

   if (!_mongoc_write_concern_is_valid(uri->write_concern)) {
      mongoc_uri_destroy(uri);
      return NULL;
   }

   uri->str = bson_strdup(uri_string);

   return uri;
}
static void
test_invalid_write_concern (void)
{
   mongoc_write_command_t command;
   mongoc_write_result_t result;
   mongoc_collection_t *collection;
   mongoc_client_t *client;
   mongoc_write_concern_t *write_concern;
   bson_t **docs;
   bson_t reply = BSON_INITIALIZER;
   bson_error_t error;
   bool r;

   client = test_framework_client_new (NULL);
   assert(client);

   collection = get_test_collection(client, "test_invalid_write_concern");
   assert(collection);

   write_concern = mongoc_write_concern_new();
   assert(write_concern);
   mongoc_write_concern_set_w(write_concern, 0);
   mongoc_write_concern_set_journal(write_concern, true);
   assert(!_mongoc_write_concern_is_valid(write_concern));

   docs = bson_malloc(sizeof(bson_t*));
   docs[0] = BCON_NEW("_id", BCON_INT32(0));

   _mongoc_write_command_init_insert(&command, (const bson_t * const *)docs, 1, true, true);
   _mongoc_write_result_init (&result);

   _mongoc_write_command_execute (&command, client, 0, collection->db,
                                  collection->collection, write_concern, 0,
                                  &result);

   r = _mongoc_write_result_complete (&result, &reply, &error);

   assert(!r);
   assert(error.domain = MONGOC_ERROR_COMMAND);
   assert(error.code = MONGOC_ERROR_COMMAND_INVALID_ARG);

   _mongoc_write_command_destroy (&command);
   _mongoc_write_result_destroy (&result);

   bson_destroy(docs[0]);
   bson_free(docs);

   mongoc_collection_destroy(collection);
   mongoc_client_destroy(client);
   mongoc_write_concern_destroy(write_concern);
}
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_write_result_t        *result)        /* OUT */
{
   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;
   }

   if (!command->hint) {
      command->hint = server_stream->sd->id;
   } else {
      BSON_ASSERT (command->hint == server_stream->sd->id);
   }

   if (server_stream->sd->max_wire_version >= WIRE_VERSION_WRITE_CMD) {
      _mongoc_write_command (command, client, server_stream, database,
                             collection, write_concern, offset,
                             result, &result->error);
   } else {
      gLegacyWriteOps[command->type] (command, client, server_stream, database,
                                      collection, write_concern, offset,
                                      result, &result->error);
   }

   EXIT;
}
Beispiel #4
0
mongoc_uri_t *
mongoc_uri_new (const char *uri_string)
{
   mongoc_uri_t *uri;

   uri = (mongoc_uri_t *)bson_malloc0(sizeof *uri);
   bson_init(&uri->options);
   bson_init(&uri->credentials);

   /* Initialize read_prefs since tag parsing may add to it */
   uri->read_prefs = mongoc_read_prefs_new(MONGOC_READ_PRIMARY);

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

   if (!mongoc_uri_parse(uri, uri_string)) {
      mongoc_uri_destroy(uri);
      return NULL;
   }

   uri->str = bson_strdup(uri_string);

   _mongoc_uri_assign_read_prefs_mode(uri);

   if (!mongoc_read_prefs_is_valid(uri->read_prefs)) {
      mongoc_uri_destroy(uri);
      return NULL;
   }
   
   _mongoc_uri_build_write_concern (uri);

   if (!_mongoc_write_concern_is_valid(uri->write_concern)) {
      mongoc_uri_destroy(uri);
      return NULL;
   }

   return uri;
}
static void
test_write_concern_fsync_and_journal_gle_and_validity (void)
{
    mongoc_write_concern_t *write_concern = mongoc_write_concern_new();

    /*
     * Journal and fsync should imply GLE regardless of w; however, journal and
     * fsync logically conflict with w=0 and w=-1, so a write concern with such
     * a combination of options will be considered invalid.
     */

    /* Default write concern needs GLE and is valid */
    ASSERT(write_concern);
    ASSERT(_mongoc_write_concern_needs_gle(write_concern));
    ASSERT(_mongoc_write_concern_is_valid(write_concern));

    /* w=0 does not need GLE and is valid */
    mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
    ASSERT(!_mongoc_write_concern_needs_gle(write_concern));
    ASSERT(_mongoc_write_concern_is_valid(write_concern));

    /* fsync=true needs GLE, but it conflicts with w=0 */
    mongoc_write_concern_set_fsync(write_concern, true);
    ASSERT(_mongoc_write_concern_needs_gle(write_concern));
    ASSERT(!_mongoc_write_concern_is_valid(write_concern));
    mongoc_write_concern_set_fsync(write_concern, false);

    /* journal=true needs GLE, but it conflicts with w=0 */
    mongoc_write_concern_set_journal(write_concern, true);
    ASSERT(_mongoc_write_concern_needs_gle(write_concern));
    ASSERT(!_mongoc_write_concern_is_valid(write_concern));
    mongoc_write_concern_set_journal(write_concern, false);

    /* w=-1 does not need GLE and is valid */
    mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED);
    ASSERT(!_mongoc_write_concern_needs_gle(write_concern));
    ASSERT(_mongoc_write_concern_is_valid(write_concern));

    /* fsync=true needs GLE, but it conflicts with w=-1 */
    mongoc_write_concern_set_fsync(write_concern, true);
    ASSERT(_mongoc_write_concern_needs_gle(write_concern));
    ASSERT(!_mongoc_write_concern_is_valid(write_concern));

    /* journal=true needs GLE, but it conflicts with w=-1 */
    mongoc_write_concern_set_fsync(write_concern, false);
    mongoc_write_concern_set_journal(write_concern, true);
    ASSERT(_mongoc_write_concern_needs_gle(write_concern));

    /* fsync=true with w=default needs GLE and is valid */
    mongoc_write_concern_set_journal(write_concern, false);
    mongoc_write_concern_set_fsync(write_concern, true);
    mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT);
    ASSERT(_mongoc_write_concern_needs_gle(write_concern));
    ASSERT(_mongoc_write_concern_is_valid(write_concern));

    /* journal=true with w=default needs GLE and is valid */
    mongoc_write_concern_set_journal(write_concern, false);
    mongoc_write_concern_set_fsync(write_concern, true);
    mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT);
    ASSERT(_mongoc_write_concern_needs_gle(write_concern));
    ASSERT(_mongoc_write_concern_is_valid(write_concern));

    mongoc_write_concern_destroy(write_concern);
}