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()); } }
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); }
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); }
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(); } }
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(); } }
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; }
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); */ }
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); */ }
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); }
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; }
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); }
/* {{{ 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); } } /* }}} */
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); } }
/* 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); }
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); }
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; }