Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7c6d456

Browse files
committed
BulkWriteCommand update methods
1 parent b6fcb3b commit 7c6d456

File tree

1 file changed

+312
-9
lines changed

1 file changed

+312
-9
lines changed

‎src/MongoDB/BulkWriteCommand.c‎

Lines changed: 312 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,35 @@ static void php_phongo_bulkwritecommand_extract_id(bson_t* doc, zval** return_va
6161
zval_ptr_dtor(&state.zchild);
6262
}
6363

64+
// TODO: Make this a common utility function to share with BulkWrite.c
65+
/* Returns whether the BSON array's keys are a sequence of integer strings
66+
* starting with "0". */
67+
static inline bool phongo_bulkwrite_bson_array_has_valid_keys(bson_t* array)
68+
{
69+
bson_iter_t iter;
70+
71+
if (bson_empty(array)) {
72+
return true;
73+
}
74+
75+
if (bson_iter_init(&iter, array)) {
76+
char key[12];
77+
int count = 0;
78+
79+
while (bson_iter_next(&iter)) {
80+
bson_snprintf(key, sizeof(key), "%d", count);
81+
82+
if (0 != strcmp(key, bson_iter_key(&iter))) {
83+
return false;
84+
}
85+
86+
count++;
87+
}
88+
}
89+
90+
return true;
91+
}
92+
6493
/* Constructs a new BulkWrite */
6594
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, __construct)
6695
{
@@ -176,6 +205,28 @@ static bool phongo_bwc_parse_document(zval* zdocument, bson_t* bdocument, const
176205
return true;
177206
}
178207

208+
static bool phongo_bwc_parse_array(zval* zarray, bson_t* barray, const char* key)
209+
{
210+
if (Z_TYPE_P(zarray) != IS_OBJECT && Z_TYPE_P(zarray) != IS_ARRAY) {
211+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" option to be array or object, %s given", key, zend_get_type_by_const(Z_TYPE_P(zarray)));
212+
return false;
213+
}
214+
215+
// Explicitly allow MongoDB\BSON\PackedArray for array values
216+
php_phongo_zval_to_bson(zarray, PHONGO_BSON_ALLOW_ROOT_ARRAY, barray, NULL);
217+
218+
if (EG(exception)) {
219+
return false;
220+
}
221+
222+
if (!phongo_bulkwrite_bson_array_has_valid_keys(barray)) {
223+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" option to yield array but got non-sequential keys", key);
224+
return false;
225+
}
226+
227+
return true;
228+
}
229+
179230
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, deleteMany)
180231
{
181232
php_phongo_bulkwritecommand_t* intern;
@@ -378,32 +429,284 @@ static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, insertOne)
378429

379430
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, replaceOne)
380431
{
381-
php_phongo_bulkwritecommand_t* intern;
432+
php_phongo_bulkwritecommand_t* intern;
433+
char* ns;
434+
size_t ns_len;
435+
zval* zfilter;
436+
zval* zupdate;
437+
zval* zoptions = NULL;
438+
bson_t bfilter = BSON_INITIALIZER;
439+
bson_t bupdate = BSON_INITIALIZER;
440+
mongoc_bulkwrite_replaceoneopts_t* opts = NULL;
441+
bson_error_t error = { 0 };
382442

383443
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
384444

385-
// TODO: implementation
386-
PHONGO_PARSE_PARAMETERS_NONE();
445+
PHONGO_PARSE_PARAMETERS_START(3, 4)
446+
Z_PARAM_STRING(ns, ns_len)
447+
Z_PARAM_ARRAY_OR_OBJECT(zfilter)
448+
Z_PARAM_ARRAY_OR_OBJECT(zupdate)
449+
Z_PARAM_OPTIONAL
450+
Z_PARAM_ARRAY_OR_NULL(zoptions)
451+
PHONGO_PARSE_PARAMETERS_END();
452+
453+
if (strlen(ns) != ns_len) {
454+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Namespace string should not contain null bytes");
455+
return;
456+
}
457+
458+
php_phongo_zval_to_bson(zfilter, PHONGO_BSON_NONE, &bfilter, NULL);
459+
460+
if (EG(exception)) {
461+
goto cleanup;
462+
}
463+
464+
// Explicitly allow MongoDB\BSON\PackedArray for update pipelines
465+
php_phongo_zval_to_bson(zupdate, PHONGO_BSON_ALLOW_ROOT_ARRAY, &bupdate, NULL);
466+
467+
if (EG(exception)) {
468+
goto cleanup;
469+
}
470+
471+
if (zoptions) {
472+
opts = mongoc_bulkwrite_replaceoneopts_new();
473+
474+
if (php_array_existsc(zoptions, "collation")) {
475+
bson_t bcollation = BSON_INITIALIZER;
476+
477+
if (!phongo_bwc_parse_document(php_array_fetchc_deref(zoptions, "collation"), &bcollation, "collation")) {
478+
bson_destroy(&bcollation);
479+
goto cleanup;
480+
}
481+
482+
mongoc_bulkwrite_replaceoneopts_set_collation(opts, &bcollation);
483+
bson_destroy(&bcollation);
484+
}
485+
486+
if (php_array_existsc(zoptions, "hint")) {
487+
bson_value_t bhint = { 0 };
488+
489+
if (!phongo_bwc_parse_hint(php_array_fetchc_deref(zoptions, "hint"), &bhint)) {
490+
bson_value_destroy(&bhint);
491+
goto cleanup;
492+
}
493+
494+
mongoc_bulkwrite_replaceoneopts_set_hint(opts, &bhint);
495+
bson_value_destroy(&bhint);
496+
}
497+
498+
if (php_array_existsc(zoptions, "upsert")) {
499+
mongoc_bulkwrite_replaceoneopts_set_upsert(opts, php_array_fetchc_bool(zoptions, "upsert"));
500+
}
501+
}
502+
503+
if (!mongoc_bulkwrite_append_replaceone(intern->bw, ns, &bfilter, &bupdate, opts, &error)) {
504+
phongo_throw_exception_from_bson_error_t(&error);
505+
goto cleanup;
506+
}
507+
508+
intern->num_ops++;
509+
510+
cleanup:
511+
bson_destroy(&bfilter);
512+
bson_destroy(&bupdate);
513+
mongoc_bulkwrite_replaceoneopts_destroy(opts);
387514
}
388515

389516
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, updateMany)
390517
{
391-
php_phongo_bulkwritecommand_t* intern;
518+
php_phongo_bulkwritecommand_t* intern;
519+
char* ns;
520+
size_t ns_len;
521+
zval* zfilter;
522+
zval* zupdate;
523+
zval* zoptions = NULL;
524+
bson_t bfilter = BSON_INITIALIZER;
525+
bson_t bupdate = BSON_INITIALIZER;
526+
mongoc_bulkwrite_updatemanyopts_t* opts = NULL;
527+
bson_error_t error = { 0 };
392528

393529
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
394530

395-
// TODO: implementation
396-
PHONGO_PARSE_PARAMETERS_NONE();
531+
PHONGO_PARSE_PARAMETERS_START(3, 4)
532+
Z_PARAM_STRING(ns, ns_len)
533+
Z_PARAM_ARRAY_OR_OBJECT(zfilter)
534+
Z_PARAM_ARRAY_OR_OBJECT(zupdate)
535+
Z_PARAM_OPTIONAL
536+
Z_PARAM_ARRAY_OR_NULL(zoptions)
537+
PHONGO_PARSE_PARAMETERS_END();
538+
539+
if (strlen(ns) != ns_len) {
540+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Namespace string should not contain null bytes");
541+
return;
542+
}
543+
544+
php_phongo_zval_to_bson(zfilter, PHONGO_BSON_NONE, &bfilter, NULL);
545+
546+
if (EG(exception)) {
547+
goto cleanup;
548+
}
549+
550+
// Explicitly allow MongoDB\BSON\PackedArray for update pipelines
551+
php_phongo_zval_to_bson(zupdate, PHONGO_BSON_ALLOW_ROOT_ARRAY, &bupdate, NULL);
552+
553+
if (EG(exception)) {
554+
goto cleanup;
555+
}
556+
557+
if (zoptions) {
558+
opts = mongoc_bulkwrite_updatemanyopts_new();
559+
560+
if (php_array_existsc(zoptions, "arrayFilters")) {
561+
bson_t barrayfilters = BSON_INITIALIZER;
562+
563+
if (!phongo_bwc_parse_array(php_array_fetchc_deref(zoptions, "arrayFilters"), &barrayfilters, "arrayFilters")) {
564+
bson_destroy(&barrayfilters);
565+
goto cleanup;
566+
}
567+
568+
mongoc_bulkwrite_updatemanyopts_set_arrayfilters(opts, &barrayfilters);
569+
bson_destroy(&barrayfilters);
570+
}
571+
572+
if (php_array_existsc(zoptions, "collation")) {
573+
bson_t bcollation = BSON_INITIALIZER;
574+
575+
if (!phongo_bwc_parse_document(php_array_fetchc_deref(zoptions, "collation"), &bcollation, "collation")) {
576+
bson_destroy(&bcollation);
577+
goto cleanup;
578+
}
579+
580+
mongoc_bulkwrite_updatemanyopts_set_collation(opts, &bcollation);
581+
bson_destroy(&bcollation);
582+
}
583+
584+
if (php_array_existsc(zoptions, "hint")) {
585+
bson_value_t bhint = { 0 };
586+
587+
if (!phongo_bwc_parse_hint(php_array_fetchc_deref(zoptions, "hint"), &bhint)) {
588+
bson_value_destroy(&bhint);
589+
goto cleanup;
590+
}
591+
592+
mongoc_bulkwrite_updatemanyopts_set_hint(opts, &bhint);
593+
bson_value_destroy(&bhint);
594+
}
595+
596+
if (php_array_existsc(zoptions, "upsert")) {
597+
mongoc_bulkwrite_updatemanyopts_set_upsert(opts, php_array_fetchc_bool(zoptions, "upsert"));
598+
}
599+
}
600+
601+
if (!mongoc_bulkwrite_append_updatemany(intern->bw, ns, &bfilter, &bupdate, opts, &error)) {
602+
phongo_throw_exception_from_bson_error_t(&error);
603+
goto cleanup;
604+
}
605+
606+
intern->num_ops++;
607+
608+
cleanup:
609+
bson_destroy(&bfilter);
610+
bson_destroy(&bupdate);
611+
mongoc_bulkwrite_updatemanyopts_destroy(opts);
397612
}
398613

399614
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, updateOne)
400615
{
401-
php_phongo_bulkwritecommand_t* intern;
616+
php_phongo_bulkwritecommand_t* intern;
617+
char* ns;
618+
size_t ns_len;
619+
zval* zfilter;
620+
zval* zupdate;
621+
zval* zoptions = NULL;
622+
bson_t bfilter = BSON_INITIALIZER;
623+
bson_t bupdate = BSON_INITIALIZER;
624+
mongoc_bulkwrite_updateoneopts_t* opts = NULL;
625+
bson_error_t error = { 0 };
402626

403627
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
404628

405-
// TODO: implementation
406-
PHONGO_PARSE_PARAMETERS_NONE();
629+
PHONGO_PARSE_PARAMETERS_START(3, 4)
630+
Z_PARAM_STRING(ns, ns_len)
631+
Z_PARAM_ARRAY_OR_OBJECT(zfilter)
632+
Z_PARAM_ARRAY_OR_OBJECT(zupdate)
633+
Z_PARAM_OPTIONAL
634+
Z_PARAM_ARRAY_OR_NULL(zoptions)
635+
PHONGO_PARSE_PARAMETERS_END();
636+
637+
if (strlen(ns) != ns_len) {
638+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Namespace string should not contain null bytes");
639+
return;
640+
}
641+
642+
php_phongo_zval_to_bson(zfilter, PHONGO_BSON_NONE, &bfilter, NULL);
643+
644+
if (EG(exception)) {
645+
goto cleanup;
646+
}
647+
648+
// Explicitly allow MongoDB\BSON\PackedArray for update pipelines
649+
php_phongo_zval_to_bson(zupdate, PHONGO_BSON_ALLOW_ROOT_ARRAY, &bupdate, NULL);
650+
651+
if (EG(exception)) {
652+
goto cleanup;
653+
}
654+
655+
if (zoptions) {
656+
opts = mongoc_bulkwrite_updateoneopts_new();
657+
658+
if (php_array_existsc(zoptions, "arrayFilters")) {
659+
bson_t barrayfilters = BSON_INITIALIZER;
660+
661+
if (!phongo_bwc_parse_array(php_array_fetchc_deref(zoptions, "arrayFilters"), &barrayfilters, "arrayFilters")) {
662+
bson_destroy(&barrayfilters);
663+
goto cleanup;
664+
}
665+
666+
mongoc_bulkwrite_updateoneopts_set_arrayfilters(opts, &barrayfilters);
667+
bson_destroy(&barrayfilters);
668+
}
669+
670+
if (php_array_existsc(zoptions, "collation")) {
671+
bson_t bcollation = BSON_INITIALIZER;
672+
673+
if (!phongo_bwc_parse_document(php_array_fetchc_deref(zoptions, "collation"), &bcollation, "collation")) {
674+
bson_destroy(&bcollation);
675+
goto cleanup;
676+
}
677+
678+
mongoc_bulkwrite_updateoneopts_set_collation(opts, &bcollation);
679+
bson_destroy(&bcollation);
680+
}
681+
682+
if (php_array_existsc(zoptions, "hint")) {
683+
bson_value_t bhint = { 0 };
684+
685+
if (!phongo_bwc_parse_hint(php_array_fetchc_deref(zoptions, "hint"), &bhint)) {
686+
bson_value_destroy(&bhint);
687+
goto cleanup;
688+
}
689+
690+
mongoc_bulkwrite_updateoneopts_set_hint(opts, &bhint);
691+
bson_value_destroy(&bhint);
692+
}
693+
694+
if (php_array_existsc(zoptions, "upsert")) {
695+
mongoc_bulkwrite_updateoneopts_set_upsert(opts, php_array_fetchc_bool(zoptions, "upsert"));
696+
}
697+
}
698+
699+
if (!mongoc_bulkwrite_append_updateone(intern->bw, ns, &bfilter, &bupdate, opts, &error)) {
700+
phongo_throw_exception_from_bson_error_t(&error);
701+
goto cleanup;
702+
}
703+
704+
intern->num_ops++;
705+
706+
cleanup:
707+
bson_destroy(&bfilter);
708+
bson_destroy(&bupdate);
709+
mongoc_bulkwrite_updateoneopts_destroy(opts);
407710
}
408711

409712
/* MongoDB\Driver\BulkWriteCommand object handlers */

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /