Skip to content

Commit 4fff6cb

Browse files
committed
BulkWriteCommand ctor and insertOne
1 parent 880c6f2 commit 4fff6cb

File tree

9 files changed

+530
-1
lines changed

9 files changed

+530
-1
lines changed

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ if test "$PHP_MONGODB" != "no"; then
168168
src/BSON/UTCDateTimeInterface.c \
169169
src/BSON/functions.c \
170170
src/MongoDB/BulkWrite.c \
171+
src/MongoDB/BulkWriteCommand.c \
171172
src/MongoDB/ClientEncryption.c \
172173
src/MongoDB/Command.c \
173174
src/MongoDB/Cursor.c \

config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ if (PHP_MONGODB != "no") {
116116
EXTENSION("mongodb", "php_phongo.c", null, PHP_MONGODB_CFLAGS);
117117
MONGODB_ADD_SOURCES("/src", "phongo_apm.c phongo_atomic.c phongo_bson.c phongo_bson_encode.c phongo_client.c phongo_compat.c phongo_error.c phongo_execute.c phongo_ini.c phongo_log.c phongo_util.c");
118118
MONGODB_ADD_SOURCES("/src/BSON", "Binary.c BinaryInterface.c Document.c Iterator.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c PackedArray.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c");
119-
MONGODB_ADD_SOURCES("/src/MongoDB", "BulkWrite.c ClientEncryption.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c ServerApi.c ServerDescription.c Session.c TopologyDescription.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c");
119+
MONGODB_ADD_SOURCES("/src/MongoDB", "BulkWrite.c BulkWriteCommand.c ClientEncryption.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c ServerApi.c ServerDescription.c Session.c TopologyDescription.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c");
120120
MONGODB_ADD_SOURCES("/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c CommandException.c ConnectionException.c ConnectionTimeoutException.c EncryptionException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c ServerException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c");
121121
MONGODB_ADD_SOURCES("/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c LogSubscriber.c SDAMSubscriber.c Subscriber.c ServerChangedEvent.c ServerClosedEvent.c ServerHeartbeatFailedEvent.c ServerHeartbeatStartedEvent.c ServerHeartbeatSucceededEvent.c ServerOpeningEvent.c TopologyChangedEvent.c TopologyClosedEvent.c TopologyOpeningEvent.c functions.c");
122122
MONGODB_ADD_SOURCES("/src/libmongoc/src/common/src", PHP_MONGODB_COMMON_SOURCES);

php_phongo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ PHP_MINIT_FUNCTION(mongodb) /* {{{ */
252252
php_phongo_cursor_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU);
253253

254254
php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS_PASSTHRU);
255+
php_phongo_bulkwritecommand_init_ce(INIT_FUNC_ARGS_PASSTHRU);
255256
php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS_PASSTHRU);
256257
php_phongo_command_init_ce(INIT_FUNC_ARGS_PASSTHRU);
257258
php_phongo_cursor_init_ce(INIT_FUNC_ARGS_PASSTHRU);

src/MongoDB/BulkWriteCommand.c

Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
/*
2+
* Copyright 2024-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "bson/bson.h"
18+
#include "mongoc/mongoc.h"
19+
20+
#include <php.h>
21+
#include <Zend/zend_interfaces.h>
22+
23+
#include "php_array_api.h"
24+
25+
#include "php_phongo.h"
26+
#include "phongo_bson_encode.h"
27+
#include "phongo_error.h"
28+
#include "BulkWriteCommand_arginfo.h"
29+
30+
#include "MongoDB/WriteConcern.h"
31+
32+
#define PHONGO_BULKWRITECOMMAND_BYPASS_UNSET -1
33+
34+
zend_class_entry* php_phongo_bulkwritecommand_ce;
35+
36+
// TODO: Make this a common utility function to share with BulkWrite.c
37+
/* Extracts the "_id" field of a BSON document into a return value. */
38+
static void php_phongo_bulkwritecommand_extract_id(bson_t* doc, zval** return_value)
39+
{
40+
zval* id = NULL;
41+
php_phongo_bson_state state;
42+
43+
PHONGO_BSON_INIT_STATE(state);
44+
state.map.root.type = PHONGO_TYPEMAP_NATIVE_ARRAY;
45+
46+
/* TODO: Instead of converting the entire document, iterate BSON to obtain
47+
* the bson_value_t of the _id field and then use phongo_bson_value_to_zval
48+
* or phongo_bson_value_to_zval_legacy to populate the return value. */
49+
if (!php_phongo_bson_to_zval_ex(doc, &state)) {
50+
goto cleanup;
51+
}
52+
53+
id = php_array_fetchc(&state.zchild, "_id");
54+
55+
if (id) {
56+
ZVAL_ZVAL(*return_value, id, 1, 0);
57+
}
58+
59+
cleanup:
60+
zval_ptr_dtor(&state.zchild);
61+
}
62+
63+
/* Constructs a new BulkWrite */
64+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, __construct)
65+
{
66+
php_phongo_bulkwritecommand_t* intern;
67+
zval* options = NULL;
68+
69+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
70+
71+
PHONGO_PARSE_PARAMETERS_START(0, 1)
72+
Z_PARAM_OPTIONAL
73+
Z_PARAM_ARRAY_OR_NULL(options)
74+
PHONGO_PARSE_PARAMETERS_END();
75+
76+
// TODO: Consider removing initialization for zero values
77+
intern->bw = mongoc_bulkwrite_new();
78+
intern->bypass = PHONGO_BULKWRITECOMMAND_BYPASS_UNSET;
79+
intern->comment = NULL;
80+
intern->let = NULL;
81+
intern->num_ops = 0;
82+
intern->ordered = true;
83+
intern->verbose = false;
84+
85+
if (!options) {
86+
return;
87+
}
88+
89+
if (php_array_existsc(options, "bypassDocumentValidation")) {
90+
intern->bypass = php_array_fetchc_bool(options, "bypassDocumentValidation") ? 1 : 0;
91+
}
92+
93+
if (php_array_existsc(options, "comment")) {
94+
zval* value = php_array_fetchc_deref(options, "comment");
95+
96+
intern->comment = ecalloc(1, sizeof(bson_value_t));
97+
phongo_zval_to_bson_value(value, intern->comment);
98+
99+
if (EG(exception)) {
100+
return;
101+
}
102+
}
103+
104+
if (php_array_existsc(options, "let")) {
105+
zval* value = php_array_fetchc_deref(options, "let");
106+
107+
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
108+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"let\" option to be array or object, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
109+
return;
110+
}
111+
112+
intern->let = bson_new();
113+
php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, intern->let, NULL);
114+
115+
if (EG(exception)) {
116+
return;
117+
}
118+
}
119+
120+
if (php_array_existsc(options, "ordered")) {
121+
intern->ordered = php_array_fetchc_bool(options, "ordered");
122+
}
123+
124+
if (php_array_existsc(options, "verboseResults")) {
125+
intern->verbose = php_array_fetchc_bool(options, "verboseResults");
126+
}
127+
}
128+
129+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, count)
130+
{
131+
php_phongo_bulkwritecommand_t* intern;
132+
133+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
134+
135+
PHONGO_PARSE_PARAMETERS_NONE();
136+
137+
RETURN_LONG(intern->num_ops);
138+
}
139+
140+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, deleteMany)
141+
{
142+
php_phongo_bulkwritecommand_t* intern;
143+
144+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
145+
146+
// TODO: implementation
147+
PHONGO_PARSE_PARAMETERS_NONE();
148+
}
149+
150+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, deleteOne)
151+
{
152+
php_phongo_bulkwritecommand_t* intern;
153+
154+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
155+
156+
// TODO: implementation
157+
PHONGO_PARSE_PARAMETERS_NONE();
158+
}
159+
160+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, execute)
161+
{
162+
php_phongo_bulkwritecommand_t* intern;
163+
164+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
165+
166+
PHONGO_PARSE_PARAMETERS_NONE();
167+
168+
RETURN_LONG(intern->num_ops);
169+
}
170+
171+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, insertOne)
172+
{
173+
php_phongo_bulkwritecommand_t* intern;
174+
char* ns;
175+
size_t ns_len;
176+
zval* zdocument;
177+
bson_t bdocument = BSON_INITIALIZER;
178+
bson_t* bson_out = NULL;
179+
bson_error_t error = { 0 };
180+
181+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
182+
183+
PHONGO_PARSE_PARAMETERS_START(2, 2)
184+
Z_PARAM_STRING(ns, ns_len)
185+
Z_PARAM_ARRAY_OR_OBJECT(zdocument)
186+
PHONGO_PARSE_PARAMETERS_END();
187+
188+
if (strlen(ns) != ns_len) {
189+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Namespace string should not contain null bytes");
190+
return;
191+
}
192+
193+
php_phongo_zval_to_bson(zdocument, (PHONGO_BSON_ADD_ID | PHONGO_BSON_RETURN_ID), &bdocument, &bson_out);
194+
195+
if (EG(exception)) {
196+
goto cleanup;
197+
}
198+
199+
if (!mongoc_bulkwrite_append_insertone(intern->bw, ns, &bdocument, NULL, &error)) {
200+
phongo_throw_exception_from_bson_error_t(&error);
201+
goto cleanup;
202+
}
203+
204+
intern->num_ops++;
205+
206+
if (!bson_out) {
207+
phongo_throw_exception(PHONGO_ERROR_LOGIC, "php_phongo_zval_to_bson() did not return document identifier. Please file a bug report.");
208+
goto cleanup;
209+
}
210+
211+
php_phongo_bulkwritecommand_extract_id(bson_out, &return_value);
212+
213+
cleanup:
214+
bson_destroy(&bdocument);
215+
bson_clear(&bson_out);
216+
}
217+
218+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, replaceOne)
219+
{
220+
php_phongo_bulkwritecommand_t* intern;
221+
222+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
223+
224+
// TODO: implementation
225+
PHONGO_PARSE_PARAMETERS_NONE();
226+
}
227+
228+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, updateMany)
229+
{
230+
php_phongo_bulkwritecommand_t* intern;
231+
232+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
233+
234+
// TODO: implementation
235+
PHONGO_PARSE_PARAMETERS_NONE();
236+
}
237+
238+
static PHP_METHOD(MongoDB_Driver_BulkWriteCommand, updateOne)
239+
{
240+
php_phongo_bulkwritecommand_t* intern;
241+
242+
intern = Z_BULKWRITECOMMAND_OBJ_P(getThis());
243+
244+
// TODO: implementation
245+
PHONGO_PARSE_PARAMETERS_NONE();
246+
}
247+
248+
/* MongoDB\Driver\BulkWriteCommand object handlers */
249+
static zend_object_handlers php_phongo_handler_bulkwritecommand;
250+
251+
static void php_phongo_bulkwritecommand_free_object(zend_object* object)
252+
{
253+
php_phongo_bulkwritecommand_t* intern = Z_OBJ_BULKWRITECOMMAND(object);
254+
255+
zend_object_std_dtor(&intern->std);
256+
257+
if (intern->bw) {
258+
mongoc_bulkwrite_destroy(intern->bw);
259+
}
260+
261+
if (intern->let) {
262+
bson_clear(&intern->let);
263+
}
264+
265+
if (intern->comment) {
266+
bson_value_destroy(intern->comment);
267+
efree(intern->comment);
268+
}
269+
270+
if (!Z_ISUNDEF(intern->session)) {
271+
zval_ptr_dtor(&intern->session);
272+
}
273+
274+
if (intern->write_concern) {
275+
mongoc_write_concern_destroy(intern->write_concern);
276+
}
277+
}
278+
279+
static zend_object* php_phongo_bulkwritecommand_create_object(zend_class_entry* class_type)
280+
{
281+
php_phongo_bulkwritecommand_t* intern = zend_object_alloc(sizeof(php_phongo_bulkwritecommand_t), class_type);
282+
283+
zend_object_std_init(&intern->std, class_type);
284+
object_properties_init(&intern->std, class_type);
285+
286+
intern->std.handlers = &php_phongo_handler_bulkwritecommand;
287+
288+
return &intern->std;
289+
}
290+
291+
static HashTable* php_phongo_bulkwritecommand_get_debug_info(zend_object* object, int* is_temp)
292+
{
293+
zval retval = ZVAL_STATIC_INIT;
294+
php_phongo_bulkwritecommand_t* intern = NULL;
295+
296+
*is_temp = 1;
297+
intern = Z_OBJ_BULKWRITECOMMAND(object);
298+
array_init(&retval);
299+
300+
if (intern->bypass != PHONGO_BULKWRITECOMMAND_BYPASS_UNSET) {
301+
ADD_ASSOC_BOOL_EX(&retval, "bypassDocumentValidation", intern->bypass);
302+
} else {
303+
ADD_ASSOC_NULL_EX(&retval, "bypassDocumentValidation");
304+
}
305+
306+
if (intern->comment) {
307+
zval zv;
308+
309+
if (!phongo_bson_value_to_zval_legacy(intern->comment, &zv)) {
310+
zval_ptr_dtor(&zv);
311+
goto done;
312+
}
313+
314+
ADD_ASSOC_ZVAL_EX(&retval, "comment", &zv);
315+
}
316+
317+
if (intern->let) {
318+
zval zv;
319+
320+
if (!php_phongo_bson_to_zval(intern->let, &zv)) {
321+
zval_ptr_dtor(&zv);
322+
goto done;
323+
}
324+
325+
ADD_ASSOC_ZVAL_EX(&retval, "let", &zv);
326+
}
327+
328+
ADD_ASSOC_BOOL_EX(&retval, "ordered", intern->ordered);
329+
ADD_ASSOC_BOOL_EX(&retval, "verboseResults", intern->verbose);
330+
331+
if (!Z_ISUNDEF(intern->session)) {
332+
ADD_ASSOC_ZVAL_EX(&retval, "session", &intern->session);
333+
Z_ADDREF(intern->session);
334+
} else {
335+
ADD_ASSOC_NULL_EX(&retval, "session");
336+
}
337+
338+
if (intern->write_concern) {
339+
zval write_concern;
340+
341+
php_phongo_write_concern_to_zval(&write_concern, intern->write_concern);
342+
ADD_ASSOC_ZVAL_EX(&retval, "write_concern", &write_concern);
343+
} else {
344+
ADD_ASSOC_NULL_EX(&retval, "write_concern");
345+
}
346+
347+
done:
348+
return Z_ARRVAL(retval);
349+
}
350+
351+
void php_phongo_bulkwritecommand_init_ce(INIT_FUNC_ARGS)
352+
{
353+
php_phongo_bulkwritecommand_ce = register_class_MongoDB_Driver_BulkWriteCommand(zend_ce_countable);
354+
php_phongo_bulkwritecommand_ce->create_object = php_phongo_bulkwritecommand_create_object;
355+
356+
memcpy(&php_phongo_handler_bulkwritecommand, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
357+
php_phongo_handler_bulkwritecommand.get_debug_info = php_phongo_bulkwritecommand_get_debug_info;
358+
php_phongo_handler_bulkwritecommand.free_obj = php_phongo_bulkwritecommand_free_object;
359+
php_phongo_handler_bulkwritecommand.offset = XtOffsetOf(php_phongo_bulkwritecommand_t, std);
360+
}

0 commit comments

Comments
 (0)