Skip to content

Commit 61912ed

Browse files
committed
Consistent WriteError and WriteConcernError parsing for bulk write results
1 parent 3c7a65a commit 61912ed

File tree

6 files changed

+89
-65
lines changed

6 files changed

+89
-65
lines changed

Diff for: src/MongoDB/BulkWriteCommandResult.c

+51-48
Original file line numberDiff line numberDiff line change
@@ -40,78 +40,81 @@
4040

4141
zend_class_entry* php_phongo_bulkwritecommandresult_ce;
4242

43-
static bool php_phongo_bulkwritecommandresult_get_writeconcernerrors(php_phongo_bulkwritecommandresult_t* intern, zval* return_value)
43+
/* Populates return_value with a list of WriteConcernError objects. Returns true
44+
* on success; otherwise, false is returned and an exception is thrown. */
45+
static bool phongo_bulkwritecommandresult_get_writeconcernerrors(php_phongo_bulkwritecommandresult_t* intern, zval* return_value)
4446
{
4547
bson_iter_t iter;
4648

4749
array_init(return_value);
4850

49-
if (!intern->write_concern_errors) {
50-
return true;
51-
}
51+
if (intern->write_concern_errors && bson_iter_init(&iter, intern->write_concern_errors)) {
52+
while (bson_iter_next(&iter)) {
53+
bson_t bson;
54+
uint32_t len;
55+
const uint8_t* data;
56+
zval write_concern_error;
5257

53-
for (bson_iter_init(&iter, intern->write_concern_errors); bson_iter_next(&iter);) {
54-
bson_t bson;
55-
uint32_t len;
56-
const uint8_t* data;
57-
zval write_concern_error;
58+
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
59+
continue;
60+
}
5861

59-
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
60-
continue;
61-
}
62+
bson_iter_document(&iter, &len, &data);
6263

63-
bson_iter_document(&iter, &len, &data);
64+
if (!bson_init_static(&bson, data, len)) {
65+
continue;
66+
}
6467

65-
if (!bson_init_static(&bson, data, len)) {
66-
continue;
67-
}
68+
if (!phongo_writeconcernerror_init(&write_concern_error, &bson)) {
69+
/* Exception already thrown */
70+
zval_ptr_dtor(&write_concern_error);
71+
return false;
72+
}
6873

69-
if (!phongo_writeconcernerror_init(&write_concern_error, &bson)) {
70-
zval_ptr_dtor(&write_concern_error);
71-
continue;
74+
add_next_index_zval(return_value, &write_concern_error);
7275
}
73-
74-
add_next_index_zval(return_value, &write_concern_error);
7576
}
7677

7778
return true;
7879
}
7980

80-
static bool php_phongo_bulkwritecommandresult_get_writeerrors(php_phongo_bulkwritecommandresult_t* intern, zval* return_value)
81+
/* Populates return_value with a map of WriteError objects indexed by the offset
82+
* of the corresponding operation. Returns true on success; otherwise, false is
83+
* returned and an exception is thrown. */
84+
static bool phongo_bulkwritecommandresult_get_writeerrors(php_phongo_bulkwritecommandresult_t* intern, zval* return_value)
8185
{
8286
bson_iter_t iter;
8387

8488
array_init(return_value);
8589

86-
if (!intern->write_errors) {
87-
return true;
88-
}
90+
if (intern->write_errors && bson_iter_init(&iter, intern->write_errors)) {
91+
while (bson_iter_next(&iter)) {
92+
bson_t bson;
93+
uint32_t len;
94+
const uint8_t* data;
95+
zval write_error;
96+
zend_ulong index;
8997

90-
for (bson_iter_init(&iter, intern->write_errors); bson_iter_next(&iter);) {
91-
bson_t bson;
92-
uint32_t len;
93-
const uint8_t* data;
94-
zval write_error;
95-
zend_ulong index;
98+
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
99+
continue;
100+
}
96101

97-
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
98-
continue;
99-
}
102+
bson_iter_document(&iter, &len, &data);
100103

101-
bson_iter_document(&iter, &len, &data);
104+
if (!bson_init_static(&bson, data, len)) {
105+
continue;
106+
}
102107

103-
if (!bson_init_static(&bson, data, len)) {
104-
continue;
105-
}
108+
index = (zend_ulong) ZEND_STRTOUL(bson_iter_key(&iter), NULL, 10);
106109

107-
index = (zend_ulong) ZEND_STRTOUL(bson_iter_key(&iter), NULL, 10);
110+
if (!phongo_writeerror_init_ex(&write_error, &bson, (int32_t) index)) {
111+
/* Exception already thrown */
112+
zval_ptr_dtor(&write_error);
113+
return false;
114+
}
108115

109-
if (!phongo_writeerror_init_ex(&write_error, &bson, (int32_t) index)) {
110-
zval_ptr_dtor(&write_error);
111-
continue;
116+
add_index_zval(return_value, index, &write_error);
112117
}
113-
114-
add_index_zval(return_value, index, &write_error);
115118
}
116119

117120
return true;
@@ -258,7 +261,7 @@ static PHP_METHOD(MongoDB_Driver_BulkWriteCommandResult, getWriteConcernErrors)
258261

259262
PHONGO_PARSE_PARAMETERS_NONE();
260263

261-
php_phongo_bulkwritecommandresult_get_writeconcernerrors(intern, return_value);
264+
phongo_bulkwritecommandresult_get_writeconcernerrors(intern, return_value);
262265
}
263266

264267
/* Returns any write errors that occurred */
@@ -270,7 +273,7 @@ static PHP_METHOD(MongoDB_Driver_BulkWriteCommandResult, getWriteErrors)
270273

271274
PHONGO_PARSE_PARAMETERS_NONE();
272275

273-
php_phongo_bulkwritecommandresult_get_writeerrors(intern, return_value);
276+
phongo_bulkwritecommandresult_get_writeerrors(intern, return_value);
274277
}
275278

276279
static PHP_METHOD(MongoDB_Driver_BulkWriteCommandResult, getErrorReply)
@@ -378,14 +381,14 @@ static HashTable* php_phongo_bulkwritecommandresult_get_debug_info(zend_object*
378381
{
379382
zval writeerrors;
380383

381-
php_phongo_bulkwritecommandresult_get_writeerrors(intern, &writeerrors);
384+
phongo_bulkwritecommandresult_get_writeerrors(intern, &writeerrors);
382385
ADD_ASSOC_ZVAL_EX(&retval, "writeErrors", &writeerrors);
383386
}
384387

385388
{
386389
zval writeconcernerrors;
387390

388-
php_phongo_bulkwritecommandresult_get_writeconcernerrors(intern, &writeconcernerrors);
391+
phongo_bulkwritecommandresult_get_writeconcernerrors(intern, &writeconcernerrors);
389392
ADD_ASSOC_ZVAL_EX(&retval, "writeConcernErrors", &writeconcernerrors);
390393
}
391394

Diff for: src/MongoDB/WriteConcernError.c

+10-4
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,13 @@ void php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS)
133133
php_phongo_handler_writeconcernerror.offset = XtOffsetOf(php_phongo_writeconcernerror_t, std);
134134
}
135135

136-
zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson)
136+
/* Initializes a new WriteConcernError in return_value using the BSON document.
137+
* Returns true on success; otherwise, false is returned and an exception is
138+
* thrown.
139+
*
140+
* This function supports documents from both mongoc_bulk_operation_execute and
141+
* mongoc_bulkwriteexception_t (returned by mongoc_bulkwrite_execute). */
142+
bool phongo_writeconcernerror_init(zval* return_value, const bson_t* bson)
137143
{
138144
bson_iter_t iter;
139145
php_phongo_writeconcernerror_t* intern;
@@ -150,10 +156,10 @@ zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson)
150156
// Additionally check for field name used by mongoc_bulkwriteexception_t
151157
if ((bson_iter_init_find(&iter, bson, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) ||
152158
(bson_iter_init_find(&iter, bson, "message") && BSON_ITER_HOLDS_UTF8(&iter))) {
153-
uint32_t errmsg_len;
154-
const char* err_msg = bson_iter_utf8(&iter, &errmsg_len);
159+
uint32_t len;
160+
const char* message = bson_iter_utf8(&iter, &len);
155161

156-
intern->message = estrndup(err_msg, errmsg_len);
162+
intern->message = estrndup(message, len);
157163
}
158164

159165
// Additionally check for field name used by mongoc_bulkwriteexception_t

Diff for: src/MongoDB/WriteConcernError.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121

2222
#include <php.h>
2323

24-
zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson);
24+
bool phongo_writeconcernerror_init(zval* return_value, const bson_t* bson);
2525

2626
#endif /* PHONGO_WRITECONCERNERROR_H */

Diff for: src/MongoDB/WriteError.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,19 @@ void php_phongo_writeerror_init_ce(INIT_FUNC_ARGS)
143143
php_phongo_handler_writeerror.offset = XtOffsetOf(php_phongo_writeerror_t, std);
144144
}
145145

146-
zend_bool phongo_writeerror_init(zval* return_value, bson_t* bson)
146+
bool phongo_writeerror_init(zval* return_value, const bson_t* bson)
147147
{
148148
return phongo_writeerror_init_ex(return_value, bson, 0);
149149
}
150150

151-
zend_bool phongo_writeerror_init_ex(zval* return_value, bson_t* bson, int32_t index)
151+
/* Initializes a new WriteError in return_value using the BSON document. Returns
152+
* true on success; otherwise, false is returned and an exception is thrown.
153+
*
154+
* This function supports documents from both mongoc_bulk_operation_execute and
155+
* mongoc_bulkwriteexception_t (returned by mongoc_bulkwrite_execute). When
156+
* initializing from mongoc_bulkwriteexception_t, an index should be explicitly
157+
* provided since the BSON document will not have an "index" field. */
158+
bool phongo_writeerror_init_ex(zval* return_value, const bson_t* bson, int32_t index)
152159
{
153160
bson_iter_t iter;
154161
php_phongo_writeerror_t* intern;
@@ -181,6 +188,7 @@ zend_bool phongo_writeerror_init_ex(zval* return_value, bson_t* bson, int32_t in
181188
bson_iter_document(&iter, &len, &data);
182189

183190
if (!php_phongo_bson_data_to_zval(data, len, &intern->info)) {
191+
/* Exception already thrown */
184192
zval_ptr_dtor(&intern->info);
185193
ZVAL_UNDEF(&intern->info);
186194

@@ -189,7 +197,7 @@ zend_bool phongo_writeerror_init_ex(zval* return_value, bson_t* bson, int32_t in
189197
}
190198

191199
/* If the WriteError is initialized from mongoc_bulkwriteexception_t, an
192-
* index will already have been specified. */
200+
* index should already have been specified. */
193201
if (!intern->index && bson_iter_init_find(&iter, bson, "index") && BSON_ITER_HOLDS_INT32(&iter)) {
194202
intern->index = bson_iter_int32(&iter);
195203
}

Diff for: src/MongoDB/WriteError.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
#include <php.h>
2323

24-
zend_bool phongo_writeerror_init(zval* return_value, bson_t* bson);
25-
zend_bool phongo_writeerror_init_ex(zval* return_value, bson_t* bson, int32_t index);
24+
bool phongo_writeerror_init(zval* return_value, const bson_t* bson);
25+
bool phongo_writeerror_init_ex(zval* return_value, const bson_t* bson, int32_t index);
2626

2727
#endif /* PHONGO_WRITEERROR_H */

Diff for: src/MongoDB/WriteResult.c

+14-7
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545

4646
zend_class_entry* php_phongo_writeresult_ce;
4747

48-
static bool php_phongo_writeresult_get_writeconcernerror(php_phongo_writeresult_t* intern, zval* return_value)
48+
/* Populates return_value with a WriteConcernError object (if available).
49+
* Returns true on success; otherwise, false is returned and an exception is
50+
* thrown. */
51+
static bool phongo_writeresult_get_writeconcernerror(php_phongo_writeresult_t* intern, zval* return_value)
4952
{
5053
bson_iter_t iter, child;
5154
zval writeconcernerror;
@@ -69,6 +72,7 @@ static bool php_phongo_writeresult_get_writeconcernerror(php_phongo_writeresult_
6972
}
7073

7174
if (!phongo_writeconcernerror_init(&writeconcernerror, &cbson)) {
75+
/* Exception already thrown */
7276
zval_ptr_dtor(&writeconcernerror);
7377
return false;
7478
}
@@ -82,7 +86,9 @@ static bool php_phongo_writeresult_get_writeconcernerror(php_phongo_writeresult_
8286
return true;
8387
}
8488

85-
static bool php_phongo_writeresult_get_writeerrors(php_phongo_writeresult_t* intern, zval* return_value)
89+
/* Populates return_value with a list of WriteError objects. Returns true on
90+
* success; otherwise, false is returned and an exception is thrown. */
91+
static bool phongo_writeresult_get_writeerrors(php_phongo_writeresult_t* intern, zval* return_value)
8692
{
8793
bson_iter_t iter, child;
8894

@@ -106,8 +112,9 @@ static bool php_phongo_writeresult_get_writeerrors(php_phongo_writeresult_t* int
106112
}
107113

108114
if (!phongo_writeerror_init(&writeerror, &cbson)) {
115+
/* Exception already thrown */
109116
zval_ptr_dtor(&writeerror);
110-
continue;
117+
return false;
111118
}
112119

113120
add_next_index_zval(return_value, &writeerror);
@@ -283,7 +290,7 @@ static PHP_METHOD(MongoDB_Driver_WriteResult, getWriteConcernError)
283290

284291
PHONGO_PARSE_PARAMETERS_NONE();
285292

286-
php_phongo_writeresult_get_writeconcernerror(intern, return_value);
293+
phongo_writeresult_get_writeconcernerror(intern, return_value);
287294
}
288295

289296
/* Returns any write errors that occurred */
@@ -295,7 +302,7 @@ static PHP_METHOD(MongoDB_Driver_WriteResult, getWriteErrors)
295302

296303
PHONGO_PARSE_PARAMETERS_NONE();
297304

298-
php_phongo_writeresult_get_writeerrors(intern, return_value);
305+
phongo_writeresult_get_writeerrors(intern, return_value);
299306
}
300307

301308
static PHP_METHOD(MongoDB_Driver_WriteResult, getErrorReplies)
@@ -402,14 +409,14 @@ static HashTable* php_phongo_writeresult_get_debug_info(zend_object* object, int
402409
{
403410
zval writeerrors;
404411

405-
php_phongo_writeresult_get_writeerrors(intern, &writeerrors);
412+
phongo_writeresult_get_writeerrors(intern, &writeerrors);
406413
ADD_ASSOC_ZVAL_EX(&retval, "writeErrors", &writeerrors);
407414
}
408415

409416
{
410417
zval writeconcernerror;
411418

412-
php_phongo_writeresult_get_writeconcernerror(intern, &writeconcernerror);
419+
phongo_writeresult_get_writeconcernerror(intern, &writeconcernerror);
413420
ADD_ASSOC_ZVAL_EX(&retval, "writeConcernError", &writeconcernerror);
414421
}
415422

0 commit comments

Comments
 (0)