Skip to content

Commit d1079cf

Browse files
committed
PHPC-564, PHPC-626: WriteResult should use libmongoc's public API
This changes WriteResult to encapsulate a bson_t, which is populated by mongoc_bulk_operation_execute(), instead of the private mongoc_write_result_t struct. This entailed significant changes to the WriteResult debug handler, so new tests have been added for it. With phongo_execute_write() modified to populate a bson_t reply, we also changed error handling to pull a BulkWriteException message from bson_error_t (PHPC-626). That change required several error tests to be modified for the new message format.
1 parent 06d1c73 commit d1079cf

13 files changed

+335
-151
lines changed

php_phongo.c

Lines changed: 15 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -467,34 +467,18 @@ zend_bool phongo_writeerror_init(zval *return_value, bson_t *bson TSRMLS_DC) /*
467467
return true;
468468
} /* }}} */
469469

470-
php_phongo_writeresult_t *phongo_writeresult_init(zval *return_value, mongoc_write_result_t *write_result, mongoc_client_t *client, int server_id TSRMLS_DC) /* {{{ */
470+
php_phongo_writeresult_t *phongo_writeresult_init(zval *return_value, bson_t *reply, mongoc_client_t *client, int server_id TSRMLS_DC) /* {{{ */
471471
{
472472
php_phongo_writeresult_t *writeresult;
473473

474474
object_init_ex(return_value, php_phongo_writeresult_ce);
475475

476476
writeresult = Z_WRITERESULT_OBJ_P(return_value);
477+
writeresult->reply = bson_copy(reply);
477478
writeresult->client = client;
478479
writeresult->server_id = server_id;
479480

480-
/* Copy write_results or else it'll get destroyed with the bulk destruction */
481-
#define SCP(field) writeresult->write_result.field = write_result->field
482-
SCP(omit_nModified);
483-
SCP(nInserted);
484-
SCP(nMatched);
485-
SCP(nModified);
486-
SCP(nRemoved);
487-
SCP(nUpserted);
488-
489-
bson_copy_to(&write_result->upserted, &writeresult->write_result.upserted);
490-
SCP(n_writeConcernErrors);
491-
bson_copy_to(&write_result->writeConcernErrors, &writeresult->write_result.writeConcernErrors);
492-
bson_copy_to(&write_result->writeErrors, &writeresult->write_result.writeErrors);
493-
SCP(upsert_append_count);
494-
#undef SCP
495-
496481
return writeresult;
497-
498482
} /* }}} */
499483
/* }}} */
500484

@@ -522,62 +506,13 @@ mongoc_bulk_operation_t *phongo_bulkwrite_init(zend_bool ordered) { /* {{{ */
522506
return mongoc_bulk_operation_new(ordered);
523507
} /* }}} */
524508

525-
static void phongo_bulk_write_error_add_message(char **tmp_msg, bson_t *errors)
526-
{
527-
bson_iter_t iter;
528-
529-
bson_iter_init(&iter, errors);
530-
531-
while (bson_iter_next(&iter)) {
532-
bson_t cbson;
533-
uint32_t len;
534-
const uint8_t *data;
535-
bson_iter_t inner_iter;
536-
537-
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
538-
continue;
539-
}
540-
541-
bson_iter_document(&iter, &len, &data);
542-
543-
if (!bson_init_static(&cbson, data, len)) {
544-
continue;
545-
}
546-
547-
if (bson_iter_init_find(&inner_iter, &cbson, "errmsg") && BSON_ITER_HOLDS_UTF8(&inner_iter)) {
548-
const char *tmp_errmsg = bson_iter_utf8(&inner_iter, NULL);
549-
size_t tmp_errmsg_len = strlen(tmp_errmsg);
550-
551-
*tmp_msg = erealloc(*tmp_msg, strlen(*tmp_msg) + tmp_errmsg_len + 5);
552-
strncpy(*tmp_msg + strlen(*tmp_msg), " :: ", 5);
553-
strncpy(*tmp_msg + strlen(*tmp_msg), tmp_errmsg, tmp_errmsg_len + 1);
554-
}
555-
}
556-
}
557-
558-
static char* phongo_assemble_bulk_write_error(mongoc_write_result_t *write_result)
559-
{
560-
char *tmp_msg = emalloc(sizeof("BulkWrite error"));
561-
562-
strncpy(tmp_msg, "BulkWrite error", sizeof("BulkWrite error"));
563-
564-
if (!bson_empty0(&write_result->writeErrors)) {
565-
phongo_bulk_write_error_add_message(&tmp_msg, &write_result->writeErrors);
566-
}
567-
568-
if (!bson_empty0(&write_result->writeConcernErrors)) {
569-
phongo_bulk_write_error_add_message(&tmp_msg, &write_result->writeConcernErrors);
570-
}
571-
572-
return tmp_msg;
573-
}
574-
575509
bool phongo_execute_write(mongoc_client_t *client, const char *namespace, mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */
576510
{
577511
bson_error_t error;
578512
char *dbname;
579513
char *collname;
580514
int success;
515+
bson_t reply = BSON_INITIALIZER;
581516
php_phongo_writeresult_t *writeresult;
582517

583518
if (!phongo_split_namespace(namespace, &dbname, &collname)) {
@@ -604,38 +539,36 @@ bool phongo_execute_write(mongoc_client_t *client, const char *namespace, mongoc
604539
mongoc_bulk_operation_set_hint(bulk, server_id);
605540
}
606541

607-
success = mongoc_bulk_operation_execute(bulk, NULL, &error);
542+
success = mongoc_bulk_operation_execute(bulk, &reply, &error);
608543

609544
/* Write succeeded and the user doesn't care for the results */
610545
if (success && !return_value_used) {
546+
bson_destroy(&reply);
611547
return true;
612548
}
613549

614550
/* Check for connection related exceptions */
615551
if (EG(exception)) {
552+
bson_destroy(&reply);
616553
return false;
617554
}
618555

619-
writeresult = phongo_writeresult_init(return_value, &bulk->result, client, bulk->hint TSRMLS_CC);
556+
writeresult = phongo_writeresult_init(return_value, &reply, client, bulk->hint TSRMLS_CC);
620557
writeresult->write_concern = mongoc_write_concern_copy(write_concern);
621558

622559
/* The Write failed */
623560
if (!success) {
624-
/* The Command itself failed */
625-
if (bson_empty0(&writeresult->write_result.writeErrors) && bson_empty0(&writeresult->write_result.writeConcernErrors)) {
626-
/* FIXME: Maybe we can look at write_result.error and not pass error at all? */
627-
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
628-
} else {
629-
char *bulk_error_msg;
630-
631-
bulk_error_msg = phongo_assemble_bulk_write_error(&writeresult->write_result);
632-
phongo_throw_exception(PHONGO_ERROR_WRITE_FAILED TSRMLS_CC, "%s", bulk_error_msg);
633-
efree(bulk_error_msg);
561+
if (error.domain == MONGOC_ERROR_COMMAND || error.domain == MONGOC_ERROR_WRITE_CONCERN) {
562+
phongo_throw_exception(PHONGO_ERROR_WRITE_FAILED TSRMLS_CC, "%s", error.message);
634563
phongo_add_exception_prop(ZEND_STRL("writeResult"), return_value TSRMLS_CC);
564+
} else {
565+
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
635566
}
636-
return false;
637567
}
638-
return true;
568+
569+
bson_destroy(&reply);
570+
571+
return success;
639572
} /* }}} */
640573

641574
int phongo_execute_query(mongoc_client_t *client, const char *namespace, const php_phongo_query_t *query, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */

php_phongo_structs-5.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ typedef struct {
111111
typedef struct {
112112
zend_object std;
113113
mongoc_write_concern_t *write_concern;
114-
mongoc_write_result_t write_result;
114+
bson_t *reply;
115115
mongoc_client_t *client;
116116
int server_id;
117117
} php_phongo_writeresult_t;

php_phongo_structs-7.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ typedef struct {
110110

111111
typedef struct {
112112
mongoc_write_concern_t *write_concern;
113-
mongoc_write_result_t write_result;
113+
bson_t *reply;
114114
mongoc_client_t *client;
115115
int server_id;
116116
zend_object std;

0 commit comments

Comments
 (0)