1 /*
2  * Copyright 2016-2017 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 <php.h>
18 #include <Zend/zend_interfaces.h>
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "phongo_compat.h"
25 #include "php_phongo.h"
26 
27 zend_class_entry* php_phongo_commandfailedevent_ce;
28 
29 /* {{{ proto string CommandFailedEvent::getCommandName()
30    Returns the command name for this event */
PHP_METHOD(CommandFailedEvent,getCommandName)31 PHP_METHOD(CommandFailedEvent, getCommandName)
32 {
33 	zend_error_handling              error_handling;
34 	php_phongo_commandfailedevent_t* intern;
35 
36 	intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
37 
38 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
39 	if (zend_parse_parameters_none() == FAILURE) {
40 		zend_restore_error_handling(&error_handling);
41 		return;
42 	}
43 	zend_restore_error_handling(&error_handling);
44 
45 	RETVAL_STRING(intern->command_name);
46 } /* }}} */
47 
48 /* {{{ proto int CommandFailedEvent::getDurationMicros()
49    Returns the event's duration in microseconds */
PHP_METHOD(CommandFailedEvent,getDurationMicros)50 PHP_METHOD(CommandFailedEvent, getDurationMicros)
51 {
52 	zend_error_handling              error_handling;
53 	php_phongo_commandfailedevent_t* intern;
54 
55 	intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
56 
57 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
58 	if (zend_parse_parameters_none() == FAILURE) {
59 		zend_restore_error_handling(&error_handling);
60 		return;
61 	}
62 	zend_restore_error_handling(&error_handling);
63 
64 	RETURN_LONG(intern->duration_micros);
65 } /* }}} */
66 
67 /* {{{ proto Exception CommandFailedEvent::getError()
68    Returns the error document associated with the event */
PHP_METHOD(CommandFailedEvent,getError)69 PHP_METHOD(CommandFailedEvent, getError)
70 {
71 	zend_error_handling              error_handling;
72 	php_phongo_commandfailedevent_t* intern;
73 
74 	intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
75 
76 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
77 	if (zend_parse_parameters_none() == FAILURE) {
78 		zend_restore_error_handling(&error_handling);
79 		return;
80 	}
81 	zend_restore_error_handling(&error_handling);
82 
83 	RETURN_ZVAL(&intern->z_error, 1, 0);
84 } /* }}} */
85 
86 /* {{{ proto string CommandFailedEvent::getOperationId()
87    Returns the event's operation ID */
PHP_METHOD(CommandFailedEvent,getOperationId)88 PHP_METHOD(CommandFailedEvent, getOperationId)
89 {
90 	zend_error_handling              error_handling;
91 	php_phongo_commandfailedevent_t* intern;
92 	char                             int_as_string[20];
93 
94 	intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
95 
96 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
97 	if (zend_parse_parameters_none() == FAILURE) {
98 		zend_restore_error_handling(&error_handling);
99 		return;
100 	}
101 	zend_restore_error_handling(&error_handling);
102 
103 	sprintf(int_as_string, "%" PRIu64, intern->operation_id);
104 	RETVAL_STRING(int_as_string);
105 } /* }}} */
106 
107 /* {{{ proto stdClass CommandFailedEvent::getReply()
108    Returns the reply document associated with the event */
PHP_METHOD(CommandFailedEvent,getReply)109 PHP_METHOD(CommandFailedEvent, getReply)
110 {
111 	zend_error_handling              error_handling;
112 	php_phongo_commandfailedevent_t* intern;
113 	php_phongo_bson_state            state;
114 
115 	PHONGO_BSON_INIT_STATE(state);
116 
117 	intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
118 
119 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
120 	if (zend_parse_parameters_none() == FAILURE) {
121 		zend_restore_error_handling(&error_handling);
122 		return;
123 	}
124 	zend_restore_error_handling(&error_handling);
125 
126 	if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &state)) {
127 		zval_ptr_dtor(&state.zchild);
128 		return;
129 	}
130 
131 	RETURN_ZVAL(&state.zchild, 0, 1);
132 } /* }}} */
133 
134 /* {{{ proto string CommandFailedEvent::getRequestId()
135    Returns the event's request ID */
PHP_METHOD(CommandFailedEvent,getRequestId)136 PHP_METHOD(CommandFailedEvent, getRequestId)
137 {
138 	zend_error_handling              error_handling;
139 	php_phongo_commandfailedevent_t* intern;
140 	char                             int_as_string[20];
141 
142 	intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
143 
144 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
145 	if (zend_parse_parameters_none() == FAILURE) {
146 		zend_restore_error_handling(&error_handling);
147 		return;
148 	}
149 	zend_restore_error_handling(&error_handling);
150 
151 	sprintf(int_as_string, "%" PRIu64, intern->request_id);
152 	RETVAL_STRING(int_as_string);
153 } /* }}} */
154 
155 /* {{{ proto MongoDB\Driver\Server CommandFailedEvent::getServer()
156    Returns the Server from which the event originated */
PHP_METHOD(CommandFailedEvent,getServer)157 PHP_METHOD(CommandFailedEvent, getServer)
158 {
159 	zend_error_handling              error_handling;
160 	php_phongo_commandfailedevent_t* intern;
161 
162 	intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
163 
164 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
165 	if (zend_parse_parameters_none() == FAILURE) {
166 		zend_restore_error_handling(&error_handling);
167 		return;
168 	}
169 	zend_restore_error_handling(&error_handling);
170 
171 	phongo_server_init(return_value, intern->client, intern->server_id);
172 } /* }}} */
173 
174 /**
175  * Event thrown when a command has failed to execute.
176  *
177  * This class is only constructed internally.
178  */
179 
180 /* {{{ MongoDB\Driver\Monitoring\CommandFailedEvent function entries */
181 ZEND_BEGIN_ARG_INFO_EX(ai_CommandFailedEvent_void, 0, 0, 0)
182 ZEND_END_ARG_INFO()
183 
184 static zend_function_entry php_phongo_commandfailedevent_me[] = {
185 	/* clang-format off */
186 	ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandFailedEvent_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
187 	PHP_ME(CommandFailedEvent, getCommandName, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
188 	PHP_ME(CommandFailedEvent, getError, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
189 	PHP_ME(CommandFailedEvent, getDurationMicros, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
190 	PHP_ME(CommandFailedEvent, getOperationId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
191 	PHP_ME(CommandFailedEvent, getReply, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
192 	PHP_ME(CommandFailedEvent, getRequestId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
193 	PHP_ME(CommandFailedEvent, getServer, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
194 	ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
195 	PHP_FE_END
196 	/* clang-format on */
197 };
198 /* }}} */
199 
200 /* {{{ MongoDB\Driver\Monitoring\CommandFailedEvent object handlers */
201 static zend_object_handlers php_phongo_handler_commandfailedevent;
202 
php_phongo_commandfailedevent_free_object(zend_object * object)203 static void php_phongo_commandfailedevent_free_object(zend_object* object) /* {{{ */
204 {
205 	php_phongo_commandfailedevent_t* intern = Z_OBJ_COMMANDFAILEDEVENT(object);
206 
207 	zend_object_std_dtor(&intern->std);
208 
209 	if (!Z_ISUNDEF(intern->z_error)) {
210 		zval_ptr_dtor(&intern->z_error);
211 	}
212 
213 	if (intern->reply) {
214 		bson_destroy(intern->reply);
215 	}
216 
217 	if (intern->command_name) {
218 		efree(intern->command_name);
219 	}
220 } /* }}} */
221 
php_phongo_commandfailedevent_create_object(zend_class_entry * class_type)222 static zend_object* php_phongo_commandfailedevent_create_object(zend_class_entry* class_type) /* {{{ */
223 {
224 	php_phongo_commandfailedevent_t* intern = NULL;
225 
226 	intern = PHONGO_ALLOC_OBJECT_T(php_phongo_commandfailedevent_t, class_type);
227 
228 	zend_object_std_init(&intern->std, class_type);
229 	object_properties_init(&intern->std, class_type);
230 
231 	intern->std.handlers = &php_phongo_handler_commandfailedevent;
232 
233 	return &intern->std;
234 } /* }}} */
235 
php_phongo_commandfailedevent_get_debug_info(phongo_compat_object_handler_type * object,int * is_temp)236 static HashTable* php_phongo_commandfailedevent_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
237 {
238 	php_phongo_commandfailedevent_t* intern;
239 	zval                             retval = ZVAL_STATIC_INIT;
240 	char                             operation_id[20], request_id[20];
241 	php_phongo_bson_state            reply_state;
242 
243 	PHONGO_BSON_INIT_STATE(reply_state);
244 
245 	intern   = Z_OBJ_COMMANDFAILEDEVENT(PHONGO_COMPAT_GET_OBJ(object));
246 	*is_temp = 1;
247 	array_init_size(&retval, 6);
248 
249 	ADD_ASSOC_STRING(&retval, "commandName", intern->command_name);
250 	ADD_ASSOC_INT64(&retval, "durationMicros", (int64_t) intern->duration_micros);
251 
252 	ADD_ASSOC_ZVAL_EX(&retval, "error", &intern->z_error);
253 	Z_ADDREF(intern->z_error);
254 
255 	sprintf(operation_id, "%" PRIu64, intern->operation_id);
256 	ADD_ASSOC_STRING(&retval, "operationId", operation_id);
257 
258 	if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &reply_state)) {
259 		zval_ptr_dtor(&reply_state.zchild);
260 		goto done;
261 	}
262 
263 	ADD_ASSOC_ZVAL(&retval, "reply", &reply_state.zchild);
264 
265 	sprintf(request_id, "%" PRIu64, intern->request_id);
266 	ADD_ASSOC_STRING(&retval, "requestId", request_id);
267 
268 	{
269 		zval server;
270 
271 		phongo_server_init(&server, intern->client, intern->server_id);
272 		ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
273 	}
274 
275 done:
276 	return Z_ARRVAL(retval);
277 } /* }}} */
278 /* }}} */
279 
php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS)280 void php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS) /* {{{ */
281 {
282 	zend_class_entry ce;
283 	(void) type;
284 	(void) module_number;
285 
286 	INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandFailedEvent", php_phongo_commandfailedevent_me);
287 	php_phongo_commandfailedevent_ce                = zend_register_internal_class(&ce);
288 	php_phongo_commandfailedevent_ce->create_object = php_phongo_commandfailedevent_create_object;
289 	PHONGO_CE_FINAL(php_phongo_commandfailedevent_ce);
290 	PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandfailedevent_ce);
291 
292 	memcpy(&php_phongo_handler_commandfailedevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
293 	php_phongo_handler_commandfailedevent.get_debug_info = php_phongo_commandfailedevent_get_debug_info;
294 	php_phongo_handler_commandfailedevent.free_obj       = php_phongo_commandfailedevent_free_object;
295 	php_phongo_handler_commandfailedevent.offset         = XtOffsetOf(php_phongo_commandfailedevent_t, std);
296 } /* }}} */
297 
298 /*
299  * Local variables:
300  * tab-width: 4
301  * c-basic-offset: 4
302  * End:
303  * vim600: noet sw=4 ts=4 fdm=marker
304  * vim<600: noet sw=4 ts=4
305  */
306