Пример #1
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);
}
void HHVM_METHOD(MongoDBDriverWriteConcern, __construct, const Variant &w, const Variant &w_timeout, const Variant &journal, const Variant &fsync)
{
	MongoDBDriverWriteConcernData* data = Native::data<MongoDBDriverWriteConcernData>(this_);
	data->m_write_concern = mongoc_write_concern_new();

	if (w.isInteger()) {
		mongoc_write_concern_set_w(data->m_write_concern, w.toInt64());
	} else if (w.isString()) {
		String w_str = w.toString();

		if (w_str.compare(s_MongoDriverWriteConcern_majority) == 0) {
			mongoc_write_concern_set_w(data->m_write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY);
		} else {
			mongoc_write_concern_set_wtag(data->m_write_concern, w_str.c_str());
		}
	}

	if (!w_timeout.isNull()) {
		int64_t w_int = w_timeout.toInt64();

		mongoc_write_concern_set_wtimeout(data->m_write_concern, w_int);
	}

	if (!journal.isNull()) {
		mongoc_write_concern_set_journal(data->m_write_concern, journal.toBoolean());
	}

	if (!fsync.isNull()) {
		mongoc_write_concern_set_fsync(data->m_write_concern, fsync.toBoolean());
	}
}
Пример #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;
}
static void
test_write_concern_basic (void)
{
    mongoc_write_concern_t *write_concern;
    const bson_t *b;
    bson_iter_t iter;

    write_concern = mongoc_write_concern_new();

    /*
     * Test defaults.
     */
    assert(write_concern);
    assert(!mongoc_write_concern_get_fsync(write_concern));
    assert(!mongoc_write_concern_get_journal(write_concern));
    assert(mongoc_write_concern_get_w(write_concern) == MONGOC_WRITE_CONCERN_W_DEFAULT);
    assert(!mongoc_write_concern_get_wtimeout(write_concern));
    assert(!mongoc_write_concern_get_wmajority(write_concern));

    mongoc_write_concern_set_fsync(write_concern, TRUE);
    assert(mongoc_write_concern_get_fsync(write_concern));
    mongoc_write_concern_set_fsync(write_concern, FALSE);
    assert(!mongoc_write_concern_get_fsync(write_concern));

    mongoc_write_concern_set_journal(write_concern, TRUE);
    assert(mongoc_write_concern_get_journal(write_concern));
    mongoc_write_concern_set_journal(write_concern, FALSE);
    assert(!mongoc_write_concern_get_journal(write_concern));

    /*
     * Test changes to w.
     */
    mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY);
    assert(mongoc_write_concern_get_wmajority(write_concern));
    mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT);
    assert(!mongoc_write_concern_get_wmajority(write_concern));
    mongoc_write_concern_set_wmajority(write_concern, 1000);
    assert(mongoc_write_concern_get_wmajority(write_concern));
    assert(mongoc_write_concern_get_wtimeout(write_concern) == 1000);
    mongoc_write_concern_set_wtimeout(write_concern, 0);
    assert(!mongoc_write_concern_get_wtimeout(write_concern));
    mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT);
    assert(mongoc_write_concern_get_w(write_concern) == MONGOC_WRITE_CONCERN_W_DEFAULT);
    mongoc_write_concern_set_w(write_concern, 3);
    assert(mongoc_write_concern_get_w(write_concern) == 3);

    /*
     * Check generated bson.
     */
    mongoc_write_concern_set_fsync(write_concern, TRUE);
    mongoc_write_concern_set_journal(write_concern, TRUE);
    b = _mongoc_write_concern_freeze(write_concern);
    assert(bson_iter_init_find(&iter, b, "fsync") && BSON_ITER_HOLDS_BOOL(&iter) && bson_iter_bool(&iter));
    assert(bson_iter_init_find(&iter, b, "j") && BSON_ITER_HOLDS_BOOL(&iter) && bson_iter_bool(&iter));
    assert(bson_iter_init_find(&iter, b, "w") && BSON_ITER_HOLDS_INT32(&iter) && bson_iter_int32(&iter) == 3);
    assert(b);

    mongoc_write_concern_destroy(write_concern);
}
Пример #6
0
static void
test_invalid_write_concern (void)
{
   mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
   mongoc_write_command_t command;
   mongoc_write_result_t result;
   mongoc_collection_t *collection;
   mongoc_client_t *client;
   mongoc_write_concern_t *write_concern;
   mongoc_server_stream_t *server_stream;
   bson_t *doc;
   bson_t reply = BSON_INITIALIZER;
   bson_error_t error;
   bool r;

   client = test_framework_client_new ();
   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));

   doc = BCON_NEW("_id", BCON_INT32(0));

   _mongoc_write_command_init_insert(&command, doc, write_flags,
                                     ++client->cluster.operation_id, true);
   _mongoc_write_result_init (&result);
   server_stream = mongoc_cluster_stream_for_writes (&client->cluster, &error);
   ASSERT_OR_PRINT (server_stream, error);
   _mongoc_write_command_execute (&command, client, server_stream,
                                  collection->db, collection->collection,
                                  write_concern, 0, &result);

   r = _mongoc_write_result_complete (&result, 2, collection->write_concern,
                                      &reply, &error);

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

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

   bson_destroy(doc);
   mongoc_server_stream_cleanup (server_stream);
   mongoc_collection_destroy(collection);
   mongoc_client_destroy(client);
   mongoc_write_concern_destroy(write_concern);
}
static void
test_find_and_modify_write_concern_wire_32_failure (void *context)
{
   mongoc_collection_t *collection;
   mongoc_client_t *client;
   bson_error_t error;
   mongoc_find_and_modify_opts_t *opts;
   bson_t reply;
   bson_t query = BSON_INITIALIZER;
   bson_t *update;
   bool success;
   mongoc_write_concern_t *wc;

   client = test_framework_client_new ();
   collection = get_test_collection (client, "writeFailure");
   wc = mongoc_write_concern_new ();

   mongoc_write_concern_set_w (wc, 42);
   mongoc_collection_set_write_concern (collection, wc);

   /* Find Zlatan Ibrahimovic, the striker */
   BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
   BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
   BSON_APPEND_UTF8 (&query, "profession", "Football player");
   BSON_APPEND_INT32 (&query, "age", 34);
   BSON_APPEND_INT32 (
      &query, "goals", (16 + 35 + 23 + 57 + 16 + 14 + 28 + 84) + (1 + 6 + 62));

   /* Add his football position */
   update = BCON_NEW ("$set", "{", "position", BCON_UTF8 ("striker"), "}");

   opts = mongoc_find_and_modify_opts_new ();

   mongoc_find_and_modify_opts_set_update (opts, update);

   /* Create the document if it didn't exist, and return the updated document */
   mongoc_find_and_modify_opts_set_flags (
      opts, MONGOC_FIND_AND_MODIFY_UPSERT | MONGOC_FIND_AND_MODIFY_RETURN_NEW);

   success = mongoc_collection_find_and_modify_with_opts (
      collection, &query, opts, &reply, &error);

   ASSERT (!success);
   ASSERT_ERROR_CONTAINS (
      error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:");

   bson_destroy (&reply);
   bson_destroy (update);
   bson_destroy (&query);
   mongoc_find_and_modify_opts_destroy (opts);
   mongoc_collection_drop (collection, NULL);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
}
static void
test_regex (void)
{
   mongoc_collection_t *collection;
   mongoc_database_t *database;
   mongoc_write_concern_t *wr;
   mongoc_client_t *client;
   bson_error_t error = { 0 };
   int64_t count;
   bson_t q = BSON_INITIALIZER;
   bson_t *doc;
   bool r;

   client = mongoc_client_new (gTestUri);
   ASSERT (client);

   database = get_test_database (client);
   ASSERT (database);

   collection = get_test_collection (client, "test_regex");
   ASSERT (collection);

   wr = mongoc_write_concern_new ();
   mongoc_write_concern_set_journal (wr, true);

   doc = BCON_NEW ("hello", "/world");
   r = mongoc_collection_insert (collection, MONGOC_INSERT_NONE, doc, wr, &error);
   ASSERT (r);

   BSON_APPEND_REGEX (&q, "hello", "^/wo", "i");

   count = mongoc_collection_count (collection,
                                    MONGOC_QUERY_NONE,
                                    &q,
                                    0,
                                    0,
                                    NULL,
                                    &error);

   ASSERT (count > 0);
   ASSERT (!error.domain);

   r = mongoc_collection_drop (collection, &error);
   ASSERT (r);

   mongoc_write_concern_destroy (wr);

   bson_destroy (&q);
   bson_destroy (doc);
   mongoc_collection_destroy (collection);
   mongoc_database_destroy(database);
   mongoc_client_destroy (client);
}
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);
}
Пример #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_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();
   }
}
Пример #12
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 ();
   }
}
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);
   }

   return ret;
}
Пример #15
0
    static Variant HHVM_METHOD(MongoCollection, insert, Variant a, Array options) {
        mongoc_collection_t *collection;
        bson_t doc;
        bson_error_t error;

        collection = get_collection(this_);

        Array& doc_array = a.toArrRef();
        if (!doc_array.exists(String("_id"))) {
            const StaticString s_MongoId("MongoId");
            char id[25];
            bson_oid_t oid;
            bson_oid_init(&oid, NULL);
            bson_oid_to_string(&oid, id);
            ObjectData * data = create_object(&s_MongoId, make_packed_array(String(id)));
            doc_array.add(String("_id"), data);
        }
        encodeToBSON(doc_array, &doc);




        int w_flag = MONGOC_WRITE_CONCERN_W_DEFAULT;
        //如果传递了参数
        
        mongoc_write_concern_t *write_concern;
        write_concern = mongoc_write_concern_new();
        mongoc_write_concern_set_w(write_concern, w_flag);
        
        bool ret = mongoc_collection_insert(collection, MONGOC_INSERT_NONE, &doc, write_concern, &error);
        if (!ret) {
            mongoThrow<MongoCursorException>((const char *) error.message);
        }
        mongoc_collection_destroy(collection);
        bson_destroy(&doc);
        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);
         */

    }
Пример #16
0
    static Variant HHVM_METHOD(MongoCollection, remove, Array criteria, Array options) {
        mongoc_collection_t *collection;
        bson_t criteria_b;
        bson_error_t error;

        collection = get_collection(this_);

        encodeToBSON(criteria, &criteria_b);
        mongoc_delete_flags_t delete_flag = MONGOC_DELETE_NONE;
        int w_flag = MONGOC_WRITE_CONCERN_W_DEFAULT;
        //如果传递了参数
        if(!options.empty()){
            //printf("multiple = %s\r\n",options[String("multiple")].toBoolean() ? "true":"false");
            if(options[String("justOne")].toBoolean()==true){
                delete_flag = MONGOC_DELETE_SINGLE_REMOVE;
            }
            
        }
        mongoc_write_concern_t *write_concern;
        write_concern = mongoc_write_concern_new();
        mongoc_write_concern_set_w(write_concern, w_flag);
        bool ret = mongoc_collection_delete(collection, delete_flag, &criteria_b, write_concern, &error);

        if (!ret) {
            mongoThrow<MongoCursorException>((const char *) error.message);
        }
        mongoc_collection_destroy(collection);
        bson_destroy(&criteria_b);
        
        
        
        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);
         */
    }
Пример #17
0
static void
bulk4 (mongoc_collection_t *collection)
{
   mongoc_write_concern_t *wc;
   mongoc_bulk_operation_t *bulk;
   bson_error_t error;
   bson_t *doc;
   bson_t reply;
   char *str;
   bool ret;

   wc = mongoc_write_concern_new ();
   mongoc_write_concern_set_w (wc, 4);
   mongoc_write_concern_set_wtimeout (wc, 100);  /* milliseconds */

   bulk = mongoc_collection_create_bulk_operation (collection, true, wc);

   /* Two inserts */
   doc = BCON_NEW ("_id", BCON_INT32 (10));
   mongoc_bulk_operation_insert (bulk, doc);
   bson_destroy (doc);

   doc = BCON_NEW ("_id", BCON_INT32 (11));
   mongoc_bulk_operation_insert (bulk, doc);
   bson_destroy (doc);

   ret = mongoc_bulk_operation_execute (bulk, &reply, &error);

   str = bson_as_json (&reply, NULL);
   printf ("%s\n", str);
   bson_free (str);

   if (!ret) {
      printf ("Error: %s\n", error.message);
   }

   bson_destroy (&reply);
   mongoc_bulk_operation_destroy (bulk);
   mongoc_write_concern_destroy (wc);
}
Пример #18
0
static void
insert_test_docs (mongoc_collection_t *collection)
{
   mongoc_write_concern_t *write_concern;
   bson_error_t error;
   bson_oid_t oid;
   bson_t b;
   int i;

   write_concern = mongoc_write_concern_new();
   mongoc_write_concern_set_w(write_concern, 3);

   {
      const bson_t *wc;
      char *str;

      wc = _mongoc_write_concern_get_gle(write_concern);
      str = bson_as_json(wc, NULL);
      fprintf(stderr, "Write Concern: %s\n", str);
      bson_free(str);
   }

   for (i = 0; i < 200; i++) {
      bson_init(&b);
      bson_oid_init(&oid, NULL);
      bson_append_oid(&b, "_id", 3, &oid);

      ASSERT_OR_PRINT (mongoc_collection_insert(collection,
                                                MONGOC_INSERT_NONE,
                                                &b,
                                                write_concern,
                                                &error), error);
      bson_destroy(&b);
   }

   mongoc_write_concern_destroy(write_concern);
}
static void
test_write_concern_append (void)
{
   mongoc_write_concern_t *wc;
   bson_t *cmd;

   cmd = tmp_bson ("{'foo': 1}");
   capture_logs (true);

   /* cannot append invalid writeConcern */
   wc = NULL;
   assert (!mongoc_write_concern_append (wc, cmd));

   /* append valid writeConcern */
   wc = mongoc_write_concern_new ();
   mongoc_write_concern_set_w (wc, 1);
   assert (mongoc_write_concern_append (wc, cmd));

   ASSERT (match_bson (cmd,
                       tmp_bson ("{'foo': 1, 'writeConcern': {'w': 1}}"),
                       true));

   mongoc_write_concern_destroy (wc);
}
int
main ()
{
   bson_t empty = BSON_INITIALIZER;
   const bson_t *doc;
   bson_t *to_insert = BCON_NEW ("x", BCON_INT32 (1));
   const bson_t *err_doc;
   bson_error_t error;
   const char *uri_string;
   mongoc_uri_t *uri;
   mongoc_client_t *client;
   mongoc_collection_t *coll;
   mongoc_change_stream_t *stream;
   mongoc_write_concern_t *wc = mongoc_write_concern_new ();
   bson_t opts = BSON_INITIALIZER;
   bool r;

   mongoc_init ();

   uri_string = "mongodb://"
                "localhost:27017,localhost:27018,localhost:"
                "27019/db?replicaSet=rs0";

   uri = mongoc_uri_new_with_error (uri_string, &error);
   if (!uri) {
      fprintf (stderr,
               "failed to parse URI: %s\n"
               "error message:       %s\n",
               uri_string,
               error.message);
      return EXIT_FAILURE;
   }

   client = mongoc_client_new_from_uri (uri);
   if (!client) {
      return EXIT_FAILURE;
   }

   coll = mongoc_client_get_collection (client, "db", "coll");
   stream = mongoc_collection_watch (coll, &empty, NULL);

   mongoc_write_concern_set_wmajority (wc, 10000);
   mongoc_write_concern_append (wc, &opts);
   r = mongoc_collection_insert_one (coll, to_insert, &opts, NULL, &error);
   if (!r) {
      fprintf (stderr, "Error: %s\n", error.message);
      return EXIT_FAILURE;
   }

   while (mongoc_change_stream_next (stream, &doc)) {
      char *as_json = bson_as_relaxed_extended_json (doc, NULL);
      fprintf (stderr, "Got document: %s\n", as_json);
      bson_free (as_json);
   }

   if (mongoc_change_stream_error_document (stream, &error, &err_doc)) {
      if (!bson_empty (err_doc)) {
         fprintf (stderr,
                  "Server Error: %s\n",
                  bson_as_relaxed_extended_json (err_doc, NULL));
      } else {
         fprintf (stderr, "Client Error: %s\n", error.message);
      }
      return EXIT_FAILURE;
   }

   bson_destroy (to_insert);
   mongoc_write_concern_destroy (wc);
   bson_destroy (&opts);
   mongoc_change_stream_destroy (stream);
   mongoc_collection_destroy (coll);
   mongoc_uri_destroy (uri);
   mongoc_client_destroy (client);
   mongoc_cleanup ();

   return EXIT_SUCCESS;
}
Пример #21
0
static void
_mongoc_uri_build_write_concern (mongoc_uri_t *uri) /* IN */
{
   mongoc_write_concern_t *write_concern;
   const char *str;
   bson_iter_t iter;
   int32_t wtimeoutms = 0;
   int value;

   BSON_ASSERT (uri);

   write_concern = mongoc_write_concern_new ();

   if (bson_iter_init_find_case (&iter, &uri->options, "safe") &&
       BSON_ITER_HOLDS_BOOL (&iter) &&
       !bson_iter_bool (&iter)) {
      mongoc_write_concern_set_w (write_concern,
                                  MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
   }

   if (bson_iter_init_find_case (&iter, &uri->options, "wtimeoutms") &&
       BSON_ITER_HOLDS_INT32 (&iter)) {
      wtimeoutms = bson_iter_int32 (&iter);
   }

   if (bson_iter_init_find_case (&iter, &uri->options, "w")) {
      if (BSON_ITER_HOLDS_INT32 (&iter)) {
         value = bson_iter_int32 (&iter);

         switch (value) {
         case -1:
            mongoc_write_concern_set_w (write_concern,
                                        MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED);
            break;
         case 0:
            mongoc_write_concern_set_w (write_concern,
                                        MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
            break;
         case 1:
            mongoc_write_concern_set_w (write_concern,
                                        MONGOC_WRITE_CONCERN_W_DEFAULT);
            break;
         default:
            if (value > 1) {
               mongoc_write_concern_set_w (write_concern, value);
               break;
            }
            MONGOC_WARNING ("Unsupported w value [w=%d].", value);
            break;
         }
      } else if (BSON_ITER_HOLDS_UTF8 (&iter)) {
         str = bson_iter_utf8 (&iter, NULL);

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

   uri->write_concern = write_concern;
}
static void
test_exhaust_cursor (void)
{
    mongoc_write_concern_t *wr;
    mongoc_client_t *client;
    mongoc_collection_t *collection;
    mongoc_cursor_t *cursor;
    mongoc_cursor_t *cursor2;
    mongoc_stream_t *stream;
    mongoc_cluster_node_t *node;
    const bson_t *doc;
    bson_t q;
    bson_t b[10];
    bson_t *bptr[10];
    int i;
    bool r;
    bson_error_t error;
    bson_oid_t oid;

    client = mongoc_client_new (gTestUri);
    assert (client);

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

    mongoc_collection_drop(collection, &error);

    wr = mongoc_write_concern_new ();
    mongoc_write_concern_set_journal (wr, true);

    /* bulk insert some records to work on */
    {
        bson_init(&q);

        for (i = 0; i < 10; i++) {
            bson_init(&b[i]);
            bson_oid_init(&oid, NULL);
            bson_append_oid(&b[i], "_id", -1, &oid);
            bson_append_int32(&b[i], "n", -1, i % 2);
            bptr[i] = &b[i];
        }

        BEGIN_IGNORE_DEPRECATIONS;
        r = mongoc_collection_insert_bulk (collection, MONGOC_INSERT_NONE,
                                           (const bson_t **)bptr, 10, wr, &error);
        END_IGNORE_DEPRECATIONS;

        if (!r) {
            MONGOC_WARNING("Insert bulk failure: %s\n", error.message);
        }
        assert(r);
    }

    /* create a couple of cursors */
    {
        cursor = mongoc_collection_find (collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, &q,
                                         NULL, NULL);

        cursor2 = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, &q,
                                          NULL, NULL);
    }

    /* Read from the exhaust cursor, ensure that we're in exhaust where we
     * should be and ensure that an early destroy properly causes a disconnect
     * */
    {
        r = mongoc_cursor_next (cursor, &doc);
        assert (r);
        assert (doc);
        assert (cursor->in_exhaust);
        assert (client->in_exhaust);
        node = &client->cluster.nodes[cursor->hint - 1];
        stream = node->stream;

        mongoc_cursor_destroy (cursor);
        /* make sure a disconnect happened */
        assert (stream != node->stream);
        assert (! client->in_exhaust);
    }

    /* Grab a new exhaust cursor, then verify that reading from that cursor
     * (putting the client into exhaust), breaks a mid-stream read from a
     * regular cursor */
    {
        cursor = mongoc_collection_find (collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, &q,
                                         NULL, NULL);

        for (i = 0; i < 5; i++) {
            r = mongoc_cursor_next (cursor2, &doc);
            assert (r);
            assert (doc);
        }

        r = mongoc_cursor_next (cursor, &doc);
        assert (r);
        assert (doc);

        doc = NULL;
        r = mongoc_cursor_next (cursor2, &doc);
        assert (!r);
        assert (!doc);

        mongoc_cursor_error(cursor2, &error);
        assert (error.domain == MONGOC_ERROR_CLIENT);
        assert (error.code == MONGOC_ERROR_CLIENT_IN_EXHAUST);

        mongoc_cursor_destroy (cursor2);
    }

    /* make sure writes fail as well */
    {
        BEGIN_IGNORE_DEPRECATIONS;
        r = mongoc_collection_insert_bulk (collection, MONGOC_INSERT_NONE,
                                           (const bson_t **)bptr, 10, wr, &error);
        END_IGNORE_DEPRECATIONS;

        assert (!r);
        assert (error.domain == MONGOC_ERROR_CLIENT);
        assert (error.code == MONGOC_ERROR_CLIENT_IN_EXHAUST);
    }

    /* we're still in exhaust.
     *
     * 1. check that we can create a new cursor, as long as we don't read from it
     * 2. fully exhaust the exhaust cursor
     * 3. make sure that we don't disconnect at destroy
     * 4. make sure we can read the cursor we made during the exhuast
     */
    {
        cursor2 = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, &q,
                                          NULL, NULL);

        node = &client->cluster.nodes[cursor->hint - 1];
        stream = node->stream;

        for (i = 1; i < 10; i++) {
            r = mongoc_cursor_next (cursor, &doc);
            assert (r);
            assert (doc);
        }

        r = mongoc_cursor_next (cursor, &doc);
        assert (!r);
        assert (!doc);

        mongoc_cursor_destroy (cursor);

        assert (stream == node->stream);

        r = mongoc_cursor_next (cursor2, &doc);
        assert (r);
        assert (doc);
    }

    bson_destroy(&q);
    for (i = 0; i < 10; i++) {
        bson_destroy(&b[i]);
    }

    r = mongoc_collection_drop (collection, &error);
    assert (r);

    mongoc_write_concern_destroy (wr);
    mongoc_cursor_destroy (cursor2);
    mongoc_collection_destroy(collection);
    mongoc_client_destroy (client);
}
Пример #23
0
/* {{{ 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;
	SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)


	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
	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);
		return;
	}
	zend_restore_error_handling(&error_handling TSRMLS_CC);


	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));
			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", zend_get_type_by_const(Z_TYPE_P(w)));
		return;
	}

	switch(ZEND_NUM_ARGS()) {
		case 3:
			if (Z_TYPE_P(journal) != IS_NULL) {
#ifdef ZEND_ENGINE_3
				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);
				return;
			}

			if (wtimeout > INT32_MAX) {
				phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected wtimeout to be <= %" PRId32 ", %" PHONGO_LONG_FORMAT " given", INT32_MAX, wtimeout);
				return;
			}

			mongoc_write_concern_set_wtimeout(intern->write_concern, wtimeout);
	}
} /* }}} */
Пример #24
0
static void
test_exhaust_cursor (bool pooled)
{
   mongoc_stream_t *stream;
   mongoc_write_concern_t *wr;
   mongoc_client_t *client;
   mongoc_client_pool_t *pool = NULL;
   mongoc_collection_t *collection;
   mongoc_cursor_t *cursor;
   mongoc_cursor_t *cursor2;
   const bson_t *doc;
   bson_t q;
   bson_t b[10];
   bson_t *bptr[10];
   int i;
   bool r;
   uint32_t hint;
   bson_error_t error;
   bson_oid_t oid;
   int64_t timestamp1;

   if (pooled) {
      pool = test_framework_client_pool_new ();
      client = mongoc_client_pool_pop (pool);
   } else {
      client = test_framework_client_new ();
   }
   assert (client);

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

   mongoc_collection_drop(collection, &error);

   wr = mongoc_write_concern_new ();
   mongoc_write_concern_set_journal (wr, true);

   /* bulk insert some records to work on */
   {
      bson_init(&q);

      for (i = 0; i < 10; i++) {
         bson_init(&b[i]);
         bson_oid_init(&oid, NULL);
         bson_append_oid(&b[i], "_id", -1, &oid);
         bson_append_int32(&b[i], "n", -1, i % 2);
         bptr[i] = &b[i];
      }

      BEGIN_IGNORE_DEPRECATIONS;
      ASSERT_OR_PRINT (mongoc_collection_insert_bulk (
                          collection, MONGOC_INSERT_NONE,
                          (const bson_t **)bptr, 10, wr, &error),
                       error);
      END_IGNORE_DEPRECATIONS;
   }

   /* create a couple of cursors */
   {
      cursor = mongoc_collection_find (collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, &q,
                                       NULL, NULL);

      cursor2 = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, &q,
                                        NULL, NULL);
   }

   /* Read from the exhaust cursor, ensure that we're in exhaust where we
    * should be and ensure that an early destroy properly causes a disconnect
    * */
   {
      r = mongoc_cursor_next (cursor, &doc);
      if (!r) {
         mongoc_cursor_error (cursor, &error);
         fprintf (stderr, "cursor error: %s\n", error.message);
      }
      assert (r);
      assert (doc);
      assert (cursor->in_exhaust);
      assert (client->in_exhaust);

      /* destroy the cursor, make sure a disconnect happened */
      timestamp1 = get_timestamp (client, cursor);
      mongoc_cursor_destroy (cursor);
      assert (! client->in_exhaust);
   }

   /* Grab a new exhaust cursor, then verify that reading from that cursor
    * (putting the client into exhaust), breaks a mid-stream read from a
    * regular cursor */
   {
      cursor = mongoc_collection_find (collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, &q,
                                       NULL, NULL);

      r = mongoc_cursor_next (cursor2, &doc);
      if (!r) {
         mongoc_cursor_error (cursor2, &error);
         fprintf (stderr, "cursor error: %s\n", error.message);
      }
      assert (r);
      assert (doc);
      assert (timestamp1 < get_timestamp (client, cursor2));

      for (i = 0; i < 5; i++) {
         r = mongoc_cursor_next (cursor2, &doc);
         if (!r) {
            mongoc_cursor_error (cursor2, &error);
            fprintf (stderr, "cursor error: %s\n", error.message);
         }
         assert (r);
         assert (doc);
      }

      r = mongoc_cursor_next (cursor, &doc);
      assert (r);
      assert (doc);

      doc = NULL;
      r = mongoc_cursor_next (cursor2, &doc);
      assert (!r);
      assert (!doc);

      mongoc_cursor_error(cursor2, &error);
      assert (error.domain == MONGOC_ERROR_CLIENT);
      assert (error.code == MONGOC_ERROR_CLIENT_IN_EXHAUST);

      mongoc_cursor_destroy (cursor2);
   }

   /* make sure writes fail as well */
   {
      BEGIN_IGNORE_DEPRECATIONS;
      r = mongoc_collection_insert_bulk (collection, MONGOC_INSERT_NONE,
                                         (const bson_t **)bptr, 10, wr, &error);
      END_IGNORE_DEPRECATIONS;

      assert (!r);
      assert (error.domain == MONGOC_ERROR_CLIENT);
      assert (error.code == MONGOC_ERROR_CLIENT_IN_EXHAUST);
   }

   /* we're still in exhaust.
    *
    * 1. check that we can create a new cursor, as long as we don't read from it
    * 2. fully exhaust the exhaust cursor
    * 3. make sure that we don't disconnect at destroy
    * 4. make sure we can read the cursor we made during the exhuast
    */
   {
      cursor2 = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, &q,
                                        NULL, NULL);

      stream = (mongoc_stream_t *)mongoc_set_get(client->cluster.nodes, cursor->hint);
      hint = cursor->hint;

      for (i = 1; i < 10; i++) {
         r = mongoc_cursor_next (cursor, &doc);
         assert (r);
         assert (doc);
      }

      r = mongoc_cursor_next (cursor, &doc);
      assert (!r);
      assert (!doc);

      mongoc_cursor_destroy (cursor);

      assert (stream == (mongoc_stream_t *)mongoc_set_get(client->cluster.nodes, hint));

      r = mongoc_cursor_next (cursor2, &doc);
      assert (r);
      assert (doc);
   }

   bson_destroy(&q);
   for (i = 0; i < 10; i++) {
      bson_destroy(&b[i]);
   }

   ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error);

   mongoc_write_concern_destroy (wr);
   mongoc_cursor_destroy (cursor2);
   mongoc_collection_destroy(collection);

   if (pooled) {
      mongoc_client_pool_push (pool, client);
      mongoc_client_pool_destroy (pool);
   } else {
      mongoc_client_destroy (client);
   }
}
Пример #25
0
    /*
    public function update(array $criteria,
                             array $new_object,
                             array $options = array()): mixed;
     */
    static Variant HHVM_METHOD(MongoCollection, update, Array criteria, Array new_object, Array options) {
        mongoc_collection_t *collection;
        bson_t selector; //selector is the criteria (which document to update)
        bson_t update; //update is the new_object containing the new data 
        const bson_t * collection_error; //update is the new_object containing the new data 
        bson_error_t error;
        collection = get_collection(this_);

        encodeToBSON(criteria, &selector);
        encodeToBSON(new_object, &update);
        
        //先定义一些默认的参数
        mongoc_update_flags_t update_flag = MONGOC_UPDATE_NONE;
        //todo
        int w_flag = MONGOC_WRITE_CONCERN_W_DEFAULT;
        
        
        //如果传递了参数
        if(!options.empty()){
            //printf("multiple = %s\r\n",options[String("multiple")].toBoolean() ? "true":"false");
            if(options[String("multiple")].toBoolean()==true){
                update_flag = MONGOC_UPDATE_MULTI_UPDATE;
            }
            if(options[String("upsert")].toBoolean()==true){
                update_flag = MONGOC_UPDATE_UPSERT;
            }
        }
        mongoc_write_concern_t *write_concern;
        write_concern = mongoc_write_concern_new();
        mongoc_write_concern_set_w(write_concern, w_flag);
   
        bool ret = mongoc_collection_update(collection, update_flag, &selector, &update, write_concern, &error);
        bson_destroy(&update);
        bson_destroy(&selector);
        if (!ret) {
            mongoThrow<MongoCursorException>((const char *) error.message);
        }
        collection_error = mongoc_collection_get_last_error(collection);
        //char *str;
        //if (collection_error) {
            //for debug
            //str = bson_as_json(collection_error, NULL);
            //printf("debug = %s\r\n",str);
            //bson_free(str);
        //}
        Array collectionReturn = Array();
        Array ouput = Array();
        collectionReturn = cbson_loads(collection_error);
        mongoc_collection_destroy(collection);
        ouput.add(String("ok"),1);
        ouput.add(String("nModified"),collectionReturn[String("nModified")]);
        ouput.add(String("n"),collectionReturn[String("nMatched")]);
        ouput.add(String("updatedExisting"),collectionReturn[String("nMatched")].toInt64() > 0 ?true:false);//todo 
        
        ouput.add(String("err"),collectionReturn[String("writeErrors")]);
        ouput.add(String("errmsg"),collectionReturn[String("writeErrors")]);
        
        const StaticString s_MongoTimestamp("MongoTimestamp");
        Array mongotimestampParam = Array();
        ObjectData * data = create_object(&s_MongoTimestamp,mongotimestampParam);
        ouput.add(String("lastOp"), data);
        ouput.add(String("mongoRaw"),collectionReturn);
        
        
        return ouput;
        //return ret;

        
    }
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.
    */

   /* No write concern needs GLE, but not "valid" */
   ASSERT(mongoc_write_concern_is_acknowledged (NULL));
   ASSERT(!mongoc_write_concern_is_valid (NULL));

   /* Default write concern needs GLE and is valid */
   ASSERT(write_concern);
   ASSERT(mongoc_write_concern_is_acknowledged (write_concern));
   ASSERT(mongoc_write_concern_is_valid (write_concern));
   ASSERT(!mongoc_write_concern_journal_is_set (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_is_acknowledged (write_concern));
   ASSERT(mongoc_write_concern_is_valid (write_concern));
   ASSERT(!mongoc_write_concern_journal_is_set (write_concern));

   /* fsync=true needs GLE, but it conflicts with w=0 */
   mongoc_write_concern_set_fsync(write_concern, true);
   ASSERT(mongoc_write_concern_is_acknowledged (write_concern));
   ASSERT(!mongoc_write_concern_is_valid (write_concern));
   ASSERT(!mongoc_write_concern_journal_is_set (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_is_acknowledged (write_concern));
   ASSERT(!mongoc_write_concern_is_valid (write_concern));
   ASSERT(mongoc_write_concern_journal_is_set (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_is_acknowledged (write_concern));
   ASSERT(mongoc_write_concern_is_valid (write_concern));
   ASSERT(mongoc_write_concern_journal_is_set (write_concern));

   /* fsync=true needs GLE, but it conflicts with w=-1 */
   mongoc_write_concern_set_fsync(write_concern, true);
   ASSERT(mongoc_write_concern_is_acknowledged (write_concern));
   ASSERT(!mongoc_write_concern_is_valid (write_concern));
   ASSERT(mongoc_write_concern_journal_is_set (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_is_acknowledged (write_concern));
   ASSERT(mongoc_write_concern_journal_is_set (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_is_acknowledged (write_concern));
   ASSERT(mongoc_write_concern_is_valid (write_concern));
   ASSERT(mongoc_write_concern_journal_is_set (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_is_acknowledged (write_concern));
   ASSERT(mongoc_write_concern_is_valid (write_concern));
   ASSERT(mongoc_write_concern_journal_is_set (write_concern));

   mongoc_write_concern_destroy(write_concern);
}
static void
test_write_concern_basic (void)
{
   mongoc_write_concern_t *write_concern;
   const bson_t *gle;
   const bson_t *bson;
   bson_iter_t iter;

   write_concern = mongoc_write_concern_new();

BEGIN_IGNORE_DEPRECATIONS;

   /*
    * Test defaults.
    */
   ASSERT(write_concern);
   ASSERT(!mongoc_write_concern_get_fsync(write_concern));
   ASSERT(!mongoc_write_concern_get_journal(write_concern));
   ASSERT(mongoc_write_concern_get_w(write_concern) == MONGOC_WRITE_CONCERN_W_DEFAULT);
   ASSERT(!mongoc_write_concern_get_wtimeout(write_concern));
   ASSERT(!mongoc_write_concern_get_wmajority(write_concern));

   mongoc_write_concern_set_fsync(write_concern, true);
   ASSERT(mongoc_write_concern_get_fsync(write_concern));
   mongoc_write_concern_set_fsync(write_concern, false);
   ASSERT(!mongoc_write_concern_get_fsync(write_concern));

   mongoc_write_concern_set_journal(write_concern, true);
   ASSERT(mongoc_write_concern_get_journal(write_concern));
   mongoc_write_concern_set_journal(write_concern, false);
   ASSERT(!mongoc_write_concern_get_journal(write_concern));

   /*
    * Test changes to w.
    */
   mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY);
   ASSERT(mongoc_write_concern_get_wmajority(write_concern));
   mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT);
   ASSERT(!mongoc_write_concern_get_wmajority(write_concern));
   mongoc_write_concern_set_wmajority(write_concern, 1000);
   ASSERT(mongoc_write_concern_get_wmajority(write_concern));
   ASSERT(mongoc_write_concern_get_wtimeout(write_concern) == 1000);
   mongoc_write_concern_set_wtimeout(write_concern, 0);
   ASSERT(!mongoc_write_concern_get_wtimeout(write_concern));
   mongoc_write_concern_set_w(write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT);
   ASSERT(mongoc_write_concern_get_w(write_concern) == MONGOC_WRITE_CONCERN_W_DEFAULT);
   mongoc_write_concern_set_w(write_concern, 3);
   ASSERT(mongoc_write_concern_get_w(write_concern) == 3);

   /*
    * Check generated bson.
    */
   mongoc_write_concern_set_fsync(write_concern, true);
   mongoc_write_concern_set_journal(write_concern, true);
   gle = _mongoc_write_concern_get_gle(write_concern);
   ASSERT(bson_iter_init_find(&iter, gle, "getlasterror") && BSON_ITER_HOLDS_INT32(&iter) && bson_iter_int32(&iter) == 1);
   ASSERT(bson_iter_init_find(&iter, gle, "fsync") && BSON_ITER_HOLDS_BOOL(&iter) && bson_iter_bool(&iter));
   ASSERT(bson_iter_init_find(&iter, gle, "j") && BSON_ITER_HOLDS_BOOL(&iter) && bson_iter_bool(&iter));
   ASSERT(bson_iter_init_find(&iter, gle, "w") && BSON_ITER_HOLDS_INT32(&iter) && bson_iter_int32(&iter) == 3);
   ASSERT(gle);

   bson = _mongoc_write_concern_get_bson(write_concern);
   ASSERT(!bson_iter_init_find(&iter, bson, "getlasterror"));
   ASSERT(bson_iter_init_find(&iter, bson, "fsync") && BSON_ITER_HOLDS_BOOL(&iter) && bson_iter_bool(&iter));
   ASSERT(bson_iter_init_find(&iter, bson, "j") && BSON_ITER_HOLDS_BOOL(&iter) && bson_iter_bool(&iter));
   ASSERT(bson_iter_init_find(&iter, bson, "w") && BSON_ITER_HOLDS_INT32(&iter) && bson_iter_int32(&iter) == 3);
   ASSERT(bson);

   mongoc_write_concern_destroy(write_concern);

END_IGNORE_DEPRECATIONS;
}
static void
test_find_and_modify_write_concern (int wire_version)
{
   mongoc_collection_t *collection;
   mongoc_client_t *client;
   mock_server_t *server;
   request_t *request;
   future_t *future;
   bson_error_t error;
   bson_t *update;
   bson_t doc = BSON_INITIALIZER;
   bson_t reply;
   mongoc_find_and_modify_opts_t *opts;
   mongoc_write_concern_t *write_concern;

   server = mock_server_new ();
   mock_server_run (server);

   client = mongoc_client_new_from_uri (mock_server_get_uri (server));
   ASSERT (client);

   collection =
      mongoc_client_get_collection (client, "test", "test_find_and_modify");

   auto_ismaster (server,
                  wire_version, /* max_wire_version */
                  48000000,     /* max_message_size */
                  16777216,     /* max_bson_size */
                  1000);        /* max_write_batch_size */

   BSON_APPEND_INT32 (&doc, "superduper", 77889);

   update = BCON_NEW ("$set", "{", "superduper", BCON_INT32 (1234), "}");

   write_concern = mongoc_write_concern_new ();
   mongoc_write_concern_set_w (write_concern, 42);
   opts = mongoc_find_and_modify_opts_new ();
   mongoc_collection_set_write_concern (collection, write_concern);
   mongoc_find_and_modify_opts_set_update (opts, update);
   mongoc_find_and_modify_opts_set_flags (opts,
                                          MONGOC_FIND_AND_MODIFY_RETURN_NEW);

   future = future_collection_find_and_modify_with_opts (
      collection, &doc, opts, &reply, &error);

   if (wire_version >= 4) {
      request = mock_server_receives_command (
         server,
         "test",
         MONGOC_QUERY_NONE,
         "{ 'findAndModify' : 'test_find_and_modify', "
         "'query' : { 'superduper' : 77889 },"
         "'update' : { '$set' : { 'superduper' : 1234 } },"
         "'new' : true,"
         "'writeConcern' : { 'w' : 42 } }");
   } else {
      request = mock_server_receives_command (
         server,
         "test",
         MONGOC_QUERY_NONE,
         "{ 'findAndModify' : 'test_find_and_modify', "
         "'query' : { 'superduper' : 77889 },"
         "'update' : { '$set' : { 'superduper' : 1234 } },"
         "'new' : true }");
   }

   mock_server_replies_simple (request, "{ 'value' : null, 'ok' : 1 }");
   ASSERT_OR_PRINT (future_get_bool (future), error);

   future_destroy (future);

   mongoc_find_and_modify_opts_destroy (opts);
   bson_destroy (&reply);
   bson_destroy (update);

   mongoc_write_concern_destroy (write_concern);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   bson_destroy (&doc);
   mock_server_destroy (server);
}
Пример #29
0
static void
test_bypass_validation (void *context)
{
   mongoc_collection_t *collection;
   bson_t reply = BSON_INITIALIZER;
   mongoc_bulk_operation_t *bulk;
   mongoc_database_t *database;
   mongoc_write_concern_t *wr;
   mongoc_client_t *client;
   bson_error_t error;
   bson_t *options;
   char *collname;
   char *dbname;
   int r;
   int i;

   client = test_framework_client_new ();
   assert (client);

   dbname = gen_collection_name ("dbtest");
   collname = gen_collection_name ("bypass");
   database = mongoc_client_get_database (client, dbname);
   collection = mongoc_database_get_collection (database, collname);
   assert (collection);

   options = tmp_bson ("{'validator': {'number': {'$gte': 5}}, 'validationAction': 'error'}");
   ASSERT_OR_PRINT (mongoc_database_create_collection (database, collname, options, &error), error);

   /* {{{ Default fails validation */
   bulk = mongoc_collection_create_bulk_operation(collection, true, NULL);
   for (i = 0; i < 3; i++) {
      bson_t *doc = tmp_bson (bson_strdup_printf ("{'number': 3, 'high': %d }", i));

      mongoc_bulk_operation_insert (bulk, doc);
   }
   r = mongoc_bulk_operation_execute (bulk, &reply, &error);
   ASSERT(!r);

   ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_COMMAND, 121, "Document failed validation");
   mongoc_bulk_operation_destroy (bulk);
   /* }}} */

   /* {{{ bypass_document_validation=false Fails validation */
   bulk = mongoc_collection_create_bulk_operation(collection, true, NULL);
   mongoc_bulk_operation_set_bypass_document_validation (bulk, false);
   for (i = 0; i < 3; i++) {
      bson_t *doc = tmp_bson (bson_strdup_printf ("{'number': 3, 'high': %d }", i));

      mongoc_bulk_operation_insert (bulk, doc);
   }
   r = mongoc_bulk_operation_execute (bulk, &reply, &error);
   ASSERT(!r);

   ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_COMMAND, 121, "Document failed validation");
   mongoc_bulk_operation_destroy (bulk);
   /* }}} */

   /* {{{ bypass_document_validation=true ignores validation */
   bulk = mongoc_collection_create_bulk_operation(collection, true, NULL);
   mongoc_bulk_operation_set_bypass_document_validation (bulk, true);
   for (i = 0; i < 3; i++) {
      bson_t *doc = tmp_bson (bson_strdup_printf ("{'number': 3, 'high': %d }", i));

      mongoc_bulk_operation_insert (bulk, doc);
   }
   r = mongoc_bulk_operation_execute (bulk, &reply, &error);
   ASSERT_OR_PRINT(r, error);
   mongoc_bulk_operation_destroy (bulk);
   /* }}} */

   /* {{{ w=0 and bypass_document_validation=set fails */
   bulk = mongoc_collection_create_bulk_operation(collection, true, NULL);
   wr = mongoc_write_concern_new ();
   mongoc_write_concern_set_w (wr, 0);
   mongoc_bulk_operation_set_write_concern (bulk, wr);
   mongoc_bulk_operation_set_bypass_document_validation (bulk, true);
   for (i = 0; i < 3; i++) {
      bson_t *doc = tmp_bson (bson_strdup_printf ("{'number': 3, 'high': %d }", i));

      mongoc_bulk_operation_insert (bulk, doc);
   }
   r = mongoc_bulk_operation_execute (bulk, &reply, &error);
   ASSERT_OR_PRINT(!r, error);
   ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG,
         "Cannot set bypassDocumentValidation for unacknowledged writes");
   mongoc_bulk_operation_destroy (bulk);
   mongoc_write_concern_destroy (wr);
   /* }}} */

   ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error);

   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
}
Пример #30
0
static void
_mongoc_uri_build_write_concern (mongoc_uri_t *uri) /* IN */
{
   mongoc_write_concern_t *write_concern;
   const char *str;
   bson_iter_t iter;
   int32_t wtimeoutms;
   int value;

   BSON_ASSERT (uri);

   write_concern = mongoc_write_concern_new ();

   if (bson_iter_init_find_case (&iter, &uri->options, "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_int32(uri, "wtimeoutms", 0);

   if (bson_iter_init_find_case (&iter, &uri->options, "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, "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:
            /* Warn on conflict, since write concern will be validated later */
            if (mongoc_write_concern_get_journal(write_concern)) {
               MONGOC_WARNING("Journal conflicts with w value [w=%d].", value);
            }
            mongoc_write_concern_set_w(write_concern, value);
            break;
         default:
            if (value > 0) {
               mongoc_write_concern_set_w (write_concern, value);
               if (value > 1) {
                  mongoc_write_concern_set_wtimeout (write_concern, wtimeoutms);
               }
               break;
            }
            MONGOC_WARNING ("Unsupported w value [w=%d].", value);
            break;
         }
      } else if (BSON_ITER_HOLDS_UTF8 (&iter)) {
         str = bson_iter_utf8 (&iter, NULL);

         if (0 == strcasecmp ("majority", str)) {
            mongoc_write_concern_set_wmajority (write_concern, wtimeoutms);
         } else {
            mongoc_write_concern_set_wtag (write_concern, str);
            mongoc_write_concern_set_wtimeout (write_concern, wtimeoutms);
         }
      } else {
         BSON_ASSERT (false);
      }
   }

   uri->write_concern = write_concern;
}