Skip to content

Commit b6fcb3b

Browse files
committed
BulkWriteCommand delete methods
1 parent 4fff6cb commit b6fcb3b

File tree

1 file changed

+167
-6
lines changed

1 file changed

+167
-6
lines changed

src/MongoDB/BulkWriteCommand.c

Lines changed: 167 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "php_phongo.h"
2626
#include "phongo_bson_encode.h"
2727
#include "phongo_error.h"
28+
#include "phongo_util.h"
2829
#include "BulkWriteCommand_arginfo.h"
2930

3031
#include "MongoDB/WriteConcern.h"
@@ -137,24 +138,184 @@ static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, count)
137138
RETURN_LONG(intern->num_ops);
138139
}
139140

141+
static bool phongo_bwc_parse_hint(zval* zhint, bson_value_t* bhint)
142+
{
143+
if (Z_TYPE_P(zhint) != IS_STRING && Z_TYPE_P(zhint) != IS_OBJECT && Z_TYPE_P(zhint) != IS_ARRAY) {
144+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(Z_TYPE_P(zhint)));
145+
return false;
146+
}
147+
148+
phongo_zval_to_bson_value(zhint, bhint);
149+
150+
if (EG(exception)) {
151+
return false;
152+
}
153+
154+
// Catch the edge case where the option yields a BSON array
155+
if (bhint->value_type != BSON_TYPE_UTF8 && bhint->value_type != BSON_TYPE_DOCUMENT) {
156+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"hint\" option to yield string or document but got \"%s\"", php_phongo_bson_type_to_string(bhint->value_type));
157+
return false;
158+
}
159+
160+
return true;
161+
}
162+
163+
static bool phongo_bwc_parse_document(zval* zdocument, bson_t* bdocument, const char* key)
164+
{
165+
if (Z_TYPE_P(zdocument) != IS_OBJECT && Z_TYPE_P(zdocument) != IS_ARRAY) {
166+
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(zdocument)));
167+
return false;
168+
}
169+
170+
php_phongo_zval_to_bson(zdocument, PHONGO_BSON_NONE, bdocument, NULL);
171+
172+
if (EG(exception)) {
173+
return false;
174+
}
175+
176+
return true;
177+
}
178+
140179
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, deleteMany)
141180
{
142-
php_phongo_bulkwritecommand_t* intern;
181+
php_phongo_bulkwritecommand_t* intern;
182+
char* ns;
183+
size_t ns_len;
184+
zval* zfilter;
185+
zval* zoptions = NULL;
186+
bson_t bfilter = BSON_INITIALIZER;
187+
mongoc_bulkwrite_deletemanyopts_t* opts = NULL;
188+
bson_error_t error = { 0 };
143189

144190
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
145191

146-
// TODO: implementation
147-
PHONGO_PARSE_PARAMETERS_NONE();
192+
PHONGO_PARSE_PARAMETERS_START(2, 3)
193+
Z_PARAM_STRING(ns, ns_len)
194+
Z_PARAM_ARRAY_OR_OBJECT(zfilter)
195+
Z_PARAM_OPTIONAL
196+
Z_PARAM_ARRAY_OR_NULL(zoptions)
197+
PHONGO_PARSE_PARAMETERS_END();
198+
199+
if (strlen(ns) != ns_len) {
200+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Namespace string should not contain null bytes");
201+
return;
202+
}
203+
204+
php_phongo_zval_to_bson(zfilter, PHONGO_BSON_NONE, &bfilter, NULL);
205+
206+
if (EG(exception)) {
207+
goto cleanup;
208+
}
209+
210+
if (zoptions) {
211+
opts = mongoc_bulkwrite_deletemanyopts_new();
212+
213+
if (php_array_existsc(zoptions, "hint")) {
214+
bson_value_t bhint = { 0 };
215+
216+
if (!phongo_bwc_parse_hint(php_array_fetchc_deref(zoptions, "hint"), &bhint)) {
217+
bson_value_destroy(&bhint);
218+
goto cleanup;
219+
}
220+
221+
mongoc_bulkwrite_deletemanyopts_set_hint(opts, &bhint);
222+
bson_value_destroy(&bhint);
223+
}
224+
225+
if (php_array_existsc(zoptions, "collation")) {
226+
bson_t bcollation = BSON_INITIALIZER;
227+
228+
if (!phongo_bwc_parse_document(php_array_fetchc_deref(zoptions, "collation"), &bcollation, "collation")) {
229+
bson_destroy(&bcollation);
230+
goto cleanup;
231+
}
232+
233+
mongoc_bulkwrite_deletemanyopts_set_collation(opts, &bcollation);
234+
bson_destroy(&bcollation);
235+
}
236+
}
237+
238+
if (!mongoc_bulkwrite_append_deletemany(intern->bw, ns, &bfilter, opts, &error)) {
239+
phongo_throw_exception_from_bson_error_t(&error);
240+
goto cleanup;
241+
}
242+
243+
intern->num_ops++;
244+
245+
cleanup:
246+
bson_destroy(&bfilter);
247+
mongoc_bulkwrite_deletemanyopts_destroy(opts);
148248
}
149249

150250
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, deleteOne)
151251
{
152-
php_phongo_bulkwritecommand_t* intern;
252+
php_phongo_bulkwritecommand_t* intern;
253+
char* ns;
254+
size_t ns_len;
255+
zval* zfilter;
256+
zval* zoptions = NULL;
257+
bson_t bfilter = BSON_INITIALIZER;
258+
mongoc_bulkwrite_deleteoneopts_t* opts = NULL;
259+
bson_error_t error = { 0 };
153260

154261
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
155262

156-
// TODO: implementation
157-
PHONGO_PARSE_PARAMETERS_NONE();
263+
PHONGO_PARSE_PARAMETERS_START(2, 3)
264+
Z_PARAM_STRING(ns, ns_len)
265+
Z_PARAM_ARRAY_OR_OBJECT(zfilter)
266+
Z_PARAM_OPTIONAL
267+
Z_PARAM_ARRAY_OR_NULL(zoptions)
268+
PHONGO_PARSE_PARAMETERS_END();
269+
270+
if (strlen(ns) != ns_len) {
271+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Namespace string should not contain null bytes");
272+
return;
273+
}
274+
275+
php_phongo_zval_to_bson(zfilter, PHONGO_BSON_NONE, &bfilter, NULL);
276+
277+
if (EG(exception)) {
278+
goto cleanup;
279+
}
280+
281+
if (zoptions) {
282+
opts = mongoc_bulkwrite_deleteoneopts_new();
283+
284+
if (php_array_existsc(zoptions, "hint")) {
285+
bson_value_t bhint = { 0 };
286+
287+
if (!phongo_bwc_parse_hint(php_array_fetchc_deref(zoptions, "hint"), &bhint)) {
288+
bson_value_destroy(&bhint);
289+
goto cleanup;
290+
}
291+
292+
mongoc_bulkwrite_deleteoneopts_set_hint(opts, &bhint);
293+
bson_value_destroy(&bhint);
294+
}
295+
296+
if (php_array_existsc(zoptions, "collation")) {
297+
bson_t bcollation = BSON_INITIALIZER;
298+
299+
if (!phongo_bwc_parse_document(php_array_fetchc_deref(zoptions, "collation"), &bcollation, "collation")) {
300+
bson_destroy(&bcollation);
301+
goto cleanup;
302+
}
303+
304+
mongoc_bulkwrite_deleteoneopts_set_collation(opts, &bcollation);
305+
bson_destroy(&bcollation);
306+
}
307+
}
308+
309+
if (!mongoc_bulkwrite_append_deleteone(intern->bw, ns, &bfilter, opts, &error)) {
310+
phongo_throw_exception_from_bson_error_t(&error);
311+
goto cleanup;
312+
}
313+
314+
intern->num_ops++;
315+
316+
cleanup:
317+
bson_destroy(&bfilter);
318+
mongoc_bulkwrite_deleteoneopts_destroy(opts);
158319
}
159320

160321
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, execute)

0 commit comments

Comments
 (0)