static void test_write_concern_wtimeout_validity (void) { mongoc_write_concern_t *write_concern = mongoc_write_concern_new(); /* Test defaults */ ASSERT(write_concern); ASSERT(mongoc_write_concern_get_w(write_concern) == MONGOC_WRITE_CONCERN_W_DEFAULT); ASSERT(mongoc_write_concern_get_wtimeout(write_concern) == 0); ASSERT(!mongoc_write_concern_get_wmajority(write_concern)); /* mongoc_write_concern_set_wtimeout() ignores invalid wtimeout */ mongoc_write_concern_set_wtimeout(write_concern, -1); ASSERT(mongoc_write_concern_get_w(write_concern) == MONGOC_WRITE_CONCERN_W_DEFAULT); ASSERT(mongoc_write_concern_get_wtimeout(write_concern) == 0); ASSERT(!mongoc_write_concern_get_wmajority(write_concern)); ASSERT(mongoc_write_concern_is_valid (write_concern)); /* mongoc_write_concern_set_wmajority() ignores invalid wtimeout */ mongoc_write_concern_set_wmajority(write_concern, -1); ASSERT(mongoc_write_concern_get_w(write_concern) == MONGOC_WRITE_CONCERN_W_MAJORITY); ASSERT(mongoc_write_concern_get_wtimeout(write_concern) == 0); ASSERT(mongoc_write_concern_get_wmajority(write_concern)); ASSERT(mongoc_write_concern_is_valid (write_concern)); /* Manually assigning a negative wtimeout will make the write concern invalid */ write_concern->wtimeout = -1; ASSERT(!mongoc_write_concern_is_valid (write_concern)); mongoc_write_concern_destroy(write_concern); }
/* {{{ proto string|integer|null MongoDB\Driver\WriteConcern::getW() Returns the WriteConcern "w" option */ static PHP_METHOD(WriteConcern, getW) { php_phongo_writeconcern_t *intern; const char *wtag; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITECONCERN_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } wtag = mongoc_write_concern_get_wtag(intern->write_concern); if (wtag) { PHONGO_RETURN_STRING(wtag); } if (mongoc_write_concern_get_wmajority(intern->write_concern)) { PHONGO_RETURN_STRING(PHONGO_WRITE_CONCERN_W_MAJORITY); } if (mongoc_write_concern_get_w(intern->write_concern) != MONGOC_WRITE_CONCERN_W_DEFAULT) { RETURN_LONG(mongoc_write_concern_get_w(intern->write_concern)); } RETURN_NULL(); } /* }}} */
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); }
bson_bool_t _mongoc_rpc_needs_gle (mongoc_rpc_t *rpc, const mongoc_write_concern_t *write_concern) { bson_return_val_if_fail(rpc, FALSE); switch (rpc->header.opcode) { case MONGOC_OPCODE_REPLY: case MONGOC_OPCODE_QUERY: case MONGOC_OPCODE_MSG: case MONGOC_OPCODE_GET_MORE: case MONGOC_OPCODE_KILL_CURSORS: return FALSE; case MONGOC_OPCODE_INSERT: case MONGOC_OPCODE_UPDATE: case MONGOC_OPCODE_DELETE: default: break; } if (!write_concern || !mongoc_write_concern_get_w(write_concern)) { return FALSE; } return TRUE; }
Array HHVM_METHOD(MongoDBDriverWriteConcern, __debugInfo) { MongoDBDriverWriteConcernData* data = Native::data<MongoDBDriverWriteConcernData>(this_); const char *wtag = mongoc_write_concern_get_wtag(data->m_write_concern); const int32_t w = mongoc_write_concern_get_w(data->m_write_concern); Array retval = Array::Create(); if (wtag) { retval.set(s_MongoDriverWriteConcern_w, (char*)wtag); } else if (mongoc_write_concern_get_wmajority(data->m_write_concern)) { retval.set(s_MongoDriverWriteConcern_w, "majority"); } else if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) { retval.set(s_MongoDriverWriteConcern_w, w); } retval.set(s_MongoDriverWriteConcern_wmajority, mongoc_write_concern_get_wmajority(data->m_write_concern)); retval.set(s_MongoDriverWriteConcern_wtimeout, mongoc_write_concern_get_wtimeout(data->m_write_concern)); if (data->m_write_concern->fsync_ != MONGOC_WRITE_CONCERN_FSYNC_DEFAULT) { retval.set(s_MongoDriverWriteConcern_fsync, mongoc_write_concern_get_fsync(data->m_write_concern)); } else { retval.set(s_MongoDriverWriteConcern_fsync, Variant()); } if (data->m_write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT) { retval.set(s_MongoDriverWriteConcern_journal, mongoc_write_concern_get_journal(data->m_write_concern)); } else { retval.set(s_MongoDriverWriteConcern_journal, Variant()); } return retval; }
static void test_mongoc_uri_write_concern (void) { const mongoc_write_concern_t *wr; mongoc_uri_t *uri; const write_concern_test *t; int i; static const write_concern_test tests [] = { { "mongodb://localhost/?safe=false", true, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED }, { "mongodb://localhost/?safe=true", true, 1 }, { "mongodb://localhost/?w=-1", true, MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED }, { "mongodb://localhost/?w=0", true, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED }, { "mongodb://localhost/?w=1", true, 1 }, { "mongodb://localhost/?w=2", true, 2 }, { "mongodb://localhost/?w=majority", true, MONGOC_WRITE_CONCERN_W_MAJORITY }, { "mongodb://localhost/?w=10", true, 10 }, { "mongodb://localhost/?w=", true, MONGOC_WRITE_CONCERN_W_DEFAULT }, { "mongodb://localhost/?w=mytag", true, MONGOC_WRITE_CONCERN_W_TAG, "mytag" }, { "mongodb://localhost/?w=mytag&safe=false", true, MONGOC_WRITE_CONCERN_W_TAG, "mytag" }, { "mongodb://localhost/?w=1&safe=false", true, 1 }, { "mongodb://localhost/?journal=true", true, MONGOC_WRITE_CONCERN_W_DEFAULT }, { "mongodb://localhost/?w=0&journal=true", false, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED }, { "mongodb://localhost/?w=-1&journal=true", false, MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED }, { "mongodb://localhost/?w=1&journal=true", true, 1 }, { NULL } }; /* Suppress warnings from two invalid URIs ("journal" and "w" conflict) */ suppress_one_message(); suppress_one_message(); for (i = 0; tests [i].uri; i++) { t = &tests [i]; uri = mongoc_uri_new (t->uri); if (t->parses) { assert (uri); } else { assert (!uri); continue; } wr = mongoc_uri_get_write_concern (uri); assert (wr); assert (t->w == mongoc_write_concern_get_w (wr)); if (t->wtag) { assert (0 == strcmp (t->wtag, mongoc_write_concern_get_wtag (wr))); } mongoc_uri_destroy (uri); } }
bool _mongoc_rpc_needs_gle (mongoc_rpc_t *rpc, const mongoc_write_concern_t *write_concern) { switch (rpc->header.opcode) { case MONGOC_OPCODE_REPLY: case MONGOC_OPCODE_QUERY: case MONGOC_OPCODE_MSG: case MONGOC_OPCODE_GET_MORE: case MONGOC_OPCODE_KILL_CURSORS: return false; case MONGOC_OPCODE_INSERT: case MONGOC_OPCODE_UPDATE: case MONGOC_OPCODE_DELETE: default: break; } if (!write_concern || !mongoc_write_concern_get_w(write_concern)) { return false; } return true; }
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 bool hippo_mongo_driver_manager_apply_wc(mongoc_uri_t *uri, const Array options) { int32_t wtimeoutms; mongoc_write_concern_t *new_wc; const mongoc_write_concern_t *old_wc; if (!(old_wc = mongoc_uri_get_write_concern(uri))) { throw MongoDriver::Utils::throwRunTimeException("mongoc_uri_t does not have a write concern"); return false; } if (options.size() == 0) { return true; } if ( !options.exists(s_MongoDBDriverManager_journal) && !options.exists(s_MongoDBDriverManager_safe) && !options.exists(s_MongoDBDriverManager_w) && !options.exists(s_MongoDBDriverManager_wtimeoutms) ) { return true; } wtimeoutms = mongoc_write_concern_get_wtimeout(old_wc); new_wc = mongoc_write_concern_copy(old_wc); if (options.exists(s_MongoDBDriverManager_safe) && options[s_MongoDBDriverManager_safe].isBoolean()) { mongoc_write_concern_set_w(new_wc, options[s_MongoDBDriverManager_safe].toBoolean() ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); } if (options.exists(s_MongoDBDriverManager_wtimeoutms) && options[s_MongoDBDriverManager_wtimeoutms].isInteger()) { wtimeoutms = (int32_t) options[s_MongoDBDriverManager_wtimeoutms].toInt64(); } if (options.exists(s_MongoDBDriverManager_journal) && options[s_MongoDBDriverManager_journal].isBoolean()) { mongoc_write_concern_set_journal(new_wc, !!options[s_MongoDBDriverManager_journal].toBoolean()); } if (options.exists(s_MongoDBDriverManager_w)) { if (options[s_MongoDBDriverManager_w].isInteger()) { int32_t value = (int32_t) options[s_MongoDBDriverManager_w].toInt64(); switch (value) { case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED: case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED: mongoc_write_concern_set_w(new_wc, value); break; default: if (value > 0) { mongoc_write_concern_set_w(new_wc, value); break; } throw MongoDriver::Utils::throwInvalidArgumentException("Unsupported w value: " + Variant(value).toString()); mongoc_write_concern_destroy(new_wc); return false; } } else if (options[s_MongoDBDriverManager_w].isString()) { const char *str = options[s_MongoDBDriverManager_w].toString().c_str(); if (0 == strcasecmp("majority", str)) { mongoc_write_concern_set_wmajority(new_wc, wtimeoutms); } else { mongoc_write_concern_set_wtag(new_wc, str); } } } /* Only set wtimeout if it's still applicable; otherwise, clear it. */ if (mongoc_write_concern_get_w(new_wc) > 1 || mongoc_write_concern_get_wmajority(new_wc) || mongoc_write_concern_get_wtag(new_wc)) { mongoc_write_concern_set_wtimeout(new_wc, wtimeoutms); } else { mongoc_write_concern_set_wtimeout(new_wc, 0); } if (mongoc_write_concern_get_journal(new_wc)) { int32_t w = mongoc_write_concern_get_w(new_wc); if (w == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || w == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED) { throw MongoDriver::Utils::throwInvalidArgumentException("Journal conflicts with w value: " + Variant(w).toString()); mongoc_write_concern_destroy(new_wc); return false; } } /* This may be redundant in light of the last check (unacknowledged w with * journal), but we'll check anyway in case additional validation is * implemented. */ if (!mongoc_write_concern_is_valid(new_wc)) { throw MongoDriver::Utils::throwInvalidArgumentException("Write concern is not valid"); mongoc_write_concern_destroy(new_wc); return false; } mongoc_uri_set_write_concern(uri, new_wc); mongoc_write_concern_destroy(new_wc); return true; }