Skip to content

Commit 2c9ecf7

Browse files
author
Christian Hergert
committed
uri: parse w=tagname and ensure its set in write concern.
also adds mongoc_uri_get_write_concern() to build write concern from uri settings.
1 parent 2da6c03 commit 2c9ecf7

File tree

6 files changed

+179
-34
lines changed

6 files changed

+179
-34
lines changed

build/cmake/libmongoc-ssl.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ mongoc_uri_get_read_prefs
155155
mongoc_uri_get_replica_set
156156
mongoc_uri_get_string
157157
mongoc_uri_get_username
158+
mongoc_uri_get_write_concern
158159
mongoc_uri_new
159160
mongoc_uri_new_for_host_port
160161
mongoc_uri_unescape

build/cmake/libmongoc.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ mongoc_uri_get_read_prefs
152152
mongoc_uri_get_replica_set
153153
mongoc_uri_get_string
154154
mongoc_uri_get_username
155+
mongoc_uri_get_write_concern
155156
mongoc_uri_new
156157
mongoc_uri_new_for_host_port
157158
mongoc_uri_unescape

src/libmongoc.symbols

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ mongoc_uri_get_read_prefs
160160
mongoc_uri_get_replica_set
161161
mongoc_uri_get_string
162162
mongoc_uri_get_username
163+
mongoc_uri_get_write_concern
163164
mongoc_uri_new
164165
mongoc_uri_new_for_host_port
165166
mongoc_uri_unescape

src/mongoc/mongoc-uri.c

Lines changed: 100 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@
3737

3838
struct _mongoc_uri_t
3939
{
40-
char *str;
41-
mongoc_host_list_t *hosts;
42-
char *username;
43-
char *password;
44-
char *database;
45-
bson_t options;
46-
bson_t read_prefs;
40+
char *str;
41+
mongoc_host_list_t *hosts;
42+
char *username;
43+
char *password;
44+
char *database;
45+
bson_t options;
46+
bson_t read_prefs;
47+
mongoc_write_concern_t *write_concern;
4748
};
4849

4950

@@ -359,8 +360,9 @@ mongoc_uri_parse_database (mongoc_uri_t *uri,
359360

360361

361362
static void
362-
mongoc_uri_parse_read_prefs (mongoc_uri_t *uri,
363-
const char *str)
363+
mongoc_uri_parse_tags (mongoc_uri_t *uri, /* IN */
364+
const char *str, /* IN */
365+
bson_t *doc) /* IN */
364366
{
365367
const char *end_keyval;
366368
const char *end_key;
@@ -388,9 +390,9 @@ mongoc_uri_parse_read_prefs (mongoc_uri_t *uri,
388390
}
389391
}
390392

391-
i = bson_count_keys(&uri->read_prefs);
393+
i = bson_count_keys(doc);
392394
bson_snprintf(keystr, sizeof keystr, "%u", i);
393-
bson_append_document(&uri->read_prefs, keystr, -1, &b);
395+
bson_append_document(doc, keystr, -1, &b);
394396
bson_destroy(&b);
395397
}
396398

@@ -423,18 +425,20 @@ mongoc_uri_parse_option (mongoc_uri_t *uri,
423425
bson_append_int32(&uri->options, key, -1, v_int);
424426
} else if (!strcasecmp(key, "w")) {
425427
if (*value == '-' || isdigit(*value)) {
426-
v_int = strtol(value, NULL, 10);
427-
bson_append_int32(&uri->options, key, -1, v_int);
428-
} else {
429-
bson_append_utf8(&uri->options, key, -1, value, -1);
428+
v_int = strtol (value, NULL, 10);
429+
BSON_APPEND_INT32 (&uri->options, "w", v_int);
430+
} else if (0 == strcasecmp (value, "majority")) {
431+
BSON_APPEND_UTF8 (&uri->options, "w", "majority");
432+
} else if (*value) {
433+
BSON_APPEND_UTF8 (&uri->options, "W", value);
430434
}
431435
} else if (!strcasecmp(key, "journal") ||
432436
!strcasecmp(key, "safe") ||
433437
!strcasecmp(key, "slaveok") ||
434438
!strcasecmp(key, "ssl")) {
435439
bson_append_bool(&uri->options, key, -1, !strcasecmp(value, "true"));
436440
} else if (!strcasecmp(key, "readpreferencetags")) {
437-
mongoc_uri_parse_read_prefs(uri, value);
441+
mongoc_uri_parse_tags(uri, value, &uri->read_prefs);
438442
} else {
439443
bson_append_utf8(&uri->options, key, -1, value, -1);
440444
}
@@ -552,6 +556,73 @@ mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri)
552556
}
553557

554558

559+
static void
560+
_mongoc_uri_build_write_concern (mongoc_uri_t *uri) /* IN */
561+
{
562+
mongoc_write_concern_t *write_concern;
563+
const char *str;
564+
bson_iter_t iter;
565+
int32_t wtimeoutms = 0;
566+
int value;
567+
568+
BSON_ASSERT (uri);
569+
570+
write_concern = mongoc_write_concern_new ();
571+
572+
if (bson_iter_init_find_case (&iter, &uri->options, "safe") &&
573+
BSON_ITER_HOLDS_BOOL (&iter) &&
574+
!bson_iter_bool (&iter)) {
575+
mongoc_write_concern_set_w (write_concern,
576+
MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
577+
}
578+
579+
if (bson_iter_init_find_case (&iter, &uri->options, "wtimeoutms") &&
580+
BSON_ITER_HOLDS_INT32 (&iter)) {
581+
wtimeoutms = bson_iter_int32 (&iter);
582+
}
583+
584+
if (bson_iter_init_find_case (&iter, &uri->options, "w")) {
585+
if (BSON_ITER_HOLDS_INT32 (&iter)) {
586+
value = bson_iter_int32 (&iter);
587+
588+
switch (value) {
589+
case -1:
590+
mongoc_write_concern_set_w (write_concern,
591+
MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED);
592+
break;
593+
case 0:
594+
mongoc_write_concern_set_w (write_concern,
595+
MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
596+
break;
597+
case 1:
598+
mongoc_write_concern_set_w (write_concern,
599+
MONGOC_WRITE_CONCERN_W_DEFAULT);
600+
break;
601+
default:
602+
if (value > 1) {
603+
mongoc_write_concern_set_w (write_concern, value);
604+
break;
605+
}
606+
MONGOC_WARNING ("Unsupported w value [w=%d].", value);
607+
break;
608+
}
609+
} else if (BSON_ITER_HOLDS_UTF8 (&iter)) {
610+
str = bson_iter_utf8 (&iter, NULL);
611+
612+
if (0 == strcasecmp ("majority", str)) {
613+
mongoc_write_concern_set_wmajority (write_concern, wtimeoutms);
614+
} else {
615+
mongoc_write_concern_set_wtag (write_concern, str);
616+
}
617+
} else {
618+
BSON_ASSERT (false);
619+
}
620+
}
621+
622+
uri->write_concern = write_concern;
623+
}
624+
625+
555626
mongoc_uri_t *
556627
mongoc_uri_new (const char *uri_string)
557628
{
@@ -572,13 +643,15 @@ mongoc_uri_new (const char *uri_string)
572643

573644
uri->str = bson_strdup(uri_string);
574645

646+
_mongoc_uri_build_write_concern (uri);
647+
575648
return uri;
576649
}
577650

578651

579652
mongoc_uri_t *
580-
mongoc_uri_new_for_host_port (const char *hostname,
581-
uint16_t port)
653+
mongoc_uri_new_for_host_port (const char *hostname,
654+
uint16_t port)
582655
{
583656
mongoc_uri_t *uri;
584657
char *str;
@@ -765,3 +838,12 @@ mongoc_uri_unescape (const char *escaped_string)
765838

766839
return bson_string_free(str, false);
767840
}
841+
842+
843+
const mongoc_write_concern_t *
844+
mongoc_uri_get_write_concern (const mongoc_uri_t *uri) /* IN */
845+
{
846+
bson_return_val_if_fail (uri, NULL);
847+
848+
return uri->write_concern;
849+
}

src/mongoc/mongoc-uri.h

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <bson.h>
2828

2929
#include "mongoc-host-list.h"
30+
#include "mongoc-write-concern.h"
3031

3132

3233
BSON_BEGIN_DECLS
@@ -35,22 +36,23 @@ BSON_BEGIN_DECLS
3536
typedef struct _mongoc_uri_t mongoc_uri_t;
3637

3738

38-
mongoc_uri_t *mongoc_uri_copy (const mongoc_uri_t *uri);
39-
void mongoc_uri_destroy (mongoc_uri_t *uri);
40-
mongoc_uri_t *mongoc_uri_new (const char *uri_string);
41-
mongoc_uri_t *mongoc_uri_new_for_host_port (const char *hostname,
42-
uint16_t port);
43-
const mongoc_host_list_t *mongoc_uri_get_hosts (const mongoc_uri_t *uri);
44-
const char *mongoc_uri_get_database (const mongoc_uri_t *uri);
45-
const bson_t *mongoc_uri_get_options (const mongoc_uri_t *uri);
46-
const char *mongoc_uri_get_password (const mongoc_uri_t *uri);
47-
const bson_t *mongoc_uri_get_read_prefs (const mongoc_uri_t *uri);
48-
const char *mongoc_uri_get_replica_set (const mongoc_uri_t *uri);
49-
const char *mongoc_uri_get_string (const mongoc_uri_t *uri);
50-
const char *mongoc_uri_get_username (const mongoc_uri_t *uri);
51-
const char *mongoc_uri_get_auth_source (const mongoc_uri_t *uri);
52-
const char *mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri);
53-
char *mongoc_uri_unescape (const char *escaped_string);
39+
mongoc_uri_t *mongoc_uri_copy (const mongoc_uri_t *uri);
40+
void mongoc_uri_destroy (mongoc_uri_t *uri);
41+
mongoc_uri_t *mongoc_uri_new (const char *uri_string);
42+
mongoc_uri_t *mongoc_uri_new_for_host_port (const char *hostname,
43+
uint16_t port);
44+
const mongoc_host_list_t *mongoc_uri_get_hosts (const mongoc_uri_t *uri);
45+
const char *mongoc_uri_get_database (const mongoc_uri_t *uri);
46+
const bson_t *mongoc_uri_get_options (const mongoc_uri_t *uri);
47+
const char *mongoc_uri_get_password (const mongoc_uri_t *uri);
48+
const bson_t *mongoc_uri_get_read_prefs (const mongoc_uri_t *uri);
49+
const char *mongoc_uri_get_replica_set (const mongoc_uri_t *uri);
50+
const char *mongoc_uri_get_string (const mongoc_uri_t *uri);
51+
const char *mongoc_uri_get_username (const mongoc_uri_t *uri);
52+
const char *mongoc_uri_get_auth_source (const mongoc_uri_t *uri);
53+
const char *mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri);
54+
char *mongoc_uri_unescape (const char *escaped_string);
55+
const mongoc_write_concern_t *mongoc_uri_get_write_concern (const mongoc_uri_t *uri);
5456

5557

5658
BSON_END_DECLS

tests/test-mongoc-uri.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,69 @@ test_mongoc_uri_unescape (void)
258258
}
259259

260260

261+
typedef struct
262+
{
263+
const char *uri;
264+
bool parses;
265+
int32_t w;
266+
const char *wtag;
267+
} write_concern_test;
268+
269+
270+
static void
271+
test_mongoc_uri_write_concern (void)
272+
{
273+
const mongoc_write_concern_t *wr;
274+
mongoc_uri_t *uri;
275+
const write_concern_test *t;
276+
int i;
277+
static const write_concern_test tests [] = {
278+
{ "mongodb://localhost/?safe=false", true, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED },
279+
{ "mongodb://localhost/?safe=true", true, MONGOC_WRITE_CONCERN_W_DEFAULT },
280+
{ "mongodb://localhost/?w=-1", true, MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED },
281+
{ "mongodb://localhost/?w=0", true, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED },
282+
{ "mongodb://localhost/?w=1", true, MONGOC_WRITE_CONCERN_W_DEFAULT },
283+
{ "mongodb://localhost/?w=2", true, 2 },
284+
{ "mongodb://localhost/?w=majority", true, MONGOC_WRITE_CONCERN_W_MAJORITY },
285+
{ "mongodb://localhost/?w=10", true, 10 },
286+
{ "mongodb://localhost/?w=", true, MONGOC_WRITE_CONCERN_W_DEFAULT },
287+
{ "mongodb://localhost/?w=mytag", true, MONGOC_WRITE_CONCERN_W_TAG, "mytag" },
288+
{ "mongodb://localhost/?w=mytag&safe=false", true, MONGOC_WRITE_CONCERN_W_TAG, "mytag" },
289+
{ "mongodb://localhost/?w=1&safe=false", true, MONGOC_WRITE_CONCERN_W_DEFAULT },
290+
{ NULL }
291+
};
292+
293+
for (i = 0; tests [i].uri; i++) {
294+
t = &tests [i];
295+
296+
uri = mongoc_uri_new (t->uri);
297+
if (t->parses) {
298+
assert (uri);
299+
} else {
300+
assert (!uri);
301+
continue;
302+
}
303+
304+
wr = mongoc_uri_get_write_concern (uri);
305+
assert (wr);
306+
307+
assert (t->w == mongoc_write_concern_get_w (wr));
308+
309+
if (t->wtag) {
310+
assert (0 == strcmp (t->wtag, mongoc_write_concern_get_wtag (wr)));
311+
}
312+
313+
mongoc_uri_destroy (uri);
314+
}
315+
}
316+
317+
261318
void
262319
test_uri_install (TestSuite *suite)
263320
{
264321
TestSuite_Add (suite, "/Uri/new", test_mongoc_uri_new);
265322
TestSuite_Add (suite, "/Uri/new_for_host_port", test_mongoc_uri_new_for_host_port);
266323
TestSuite_Add (suite, "/Uri/unescape", test_mongoc_uri_unescape);
324+
TestSuite_Add (suite, "/Uri/write_concern", test_mongoc_uri_write_concern);
267325
TestSuite_Add (suite, "/HostList/from_string", test_mongoc_host_list_from_string);
268326
}

0 commit comments

Comments
 (0)