Server.c 20.4 KB
Newer Older
1
/*
Ondrej Sury's avatar
Ondrej Sury committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15
 * Copyright 2014-2017 MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

#ifdef HAVE_CONFIG_H
#	include "config.h"
#endif

/* External libs */
#include <bson.h>
#include <mongoc.h>

/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/standard/info.h>
#include <ext/standard/file.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
/* Our Compatability header */
#include "phongo_compat.h"

/* Our stuffz */
#include "php_phongo.h"
#include "php_bson.h"


PHONGO_API zend_class_entry *php_phongo_server_ce;

zend_object_handlers php_phongo_handler_server;


45 46
/* {{{ proto void Server::__construct()
   Throws MongoDB\Driver\RuntimeException (can only be created internally) */
47 48
PHP_METHOD(Server, __construct)
{
49
	SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) SUPPRESS_UNUSED_WARNING(return_value_ptr) (void)ZEND_NUM_ARGS(); (void)getThis();
50 51 52 53

	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Accessing private constructor");
}
/* }}} */
54

55
/* {{{ proto MongoDB\Driver\Cursor Server::executeCommand(string $db, MongoDB\Driver\Command $command[, MongoDB\Driver\ReadPreference $readPreference = null]))
56
   Executes a Command on this Server */
57 58 59 60
PHP_METHOD(Server, executeCommand)
{
	php_phongo_server_t      *intern;
	char                     *db;
61
	phongo_zpp_char_len       db_len;
62 63
	zval                     *command;
	zval                     *readPreference = NULL;
64 65
	DECLARE_RETURN_VALUE_USED
	SUPPRESS_UNUSED_WARNING(return_value_ptr)
66 67


68
	intern = Z_SERVER_OBJ_P(getThis());
69 70 71 72 73

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &db, &db_len, &command, php_phongo_command_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) {
		return;
	}

74
#if PHP_VERSION_ID >= 70000
75
	phongo_execute_command(&intern->manager, db, command, readPreference, intern->server_id, return_value, return_value_used TSRMLS_CC);
76
#else
77
	phongo_execute_command(intern->manager, db, command, readPreference, intern->server_id, return_value, return_value_used TSRMLS_CC);
78
#endif
79 80
}
/* }}} */
81 82 83

/* {{{ proto MongoDB\Driver\Cursor Server::executeQuery(string $namespace, MongoDB\Driver\Query $query[, MongoDB\Driver\ReadPreference $readPreference = null]))
   Executes a Query on this Server */
84 85 86 87
PHP_METHOD(Server, executeQuery)
{
	php_phongo_server_t      *intern;
	char                     *namespace;
88
	phongo_zpp_char_len       namespace_len;
89
	zval                     *query;
90
	zval                     *readPreference = NULL;
91 92
	DECLARE_RETURN_VALUE_USED
	SUPPRESS_UNUSED_WARNING(return_value_ptr)
93 94


95
	intern = Z_SERVER_OBJ_P(getThis());
96

97
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &query, php_phongo_query_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) {
98 99 100
		return;
	}

101
#if PHP_VERSION_ID >= 70000
102
	phongo_execute_query(&intern->manager, namespace, query, readPreference, intern->server_id, return_value, return_value_used TSRMLS_CC);
103
#else
104
	phongo_execute_query(intern->manager, namespace, query, readPreference, intern->server_id, return_value, return_value_used TSRMLS_CC);
105
#endif
106 107
}
/* }}} */
108

109
/* {{{ proto MongoDB\Driver\WriteResult Server::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, MongoDB\Driver\WriteConcern $writeConcern = null])
110 111
   Executes a BulkWrite (i.e. any number of insert, update, and delete ops) on
   this Server */
112 113 114 115
PHP_METHOD(Server, executeBulkWrite)
{
	php_phongo_server_t      *intern;
	char                     *namespace;
116
	phongo_zpp_char_len       namespace_len;
117 118
	zval                     *zbulk;
	zval                     *zwrite_concern = NULL;
119 120 121
	php_phongo_bulkwrite_t   *bulk;
	DECLARE_RETURN_VALUE_USED
	SUPPRESS_UNUSED_WARNING(return_value_ptr)
122 123


124
	intern = Z_SERVER_OBJ_P(getThis());
125 126 127 128 129 130

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &zwrite_concern, php_phongo_writeconcern_ce) == FAILURE) {
		return;
	}


131
	bulk = Z_BULKWRITE_OBJ_P(zbulk);
132
#if PHP_VERSION_ID >= 70000
133
	phongo_execute_write(&intern->manager, namespace, bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
134
#else
135
	phongo_execute_write(intern->manager, namespace, bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
136
#endif
137 138
}
/* }}} */
139

140
/* {{{ proto string Server::getHost()
141
   Returns the hostname for this Server */
142 143
PHP_METHOD(Server, getHost)
{
144
	php_phongo_server_t         *intern;
145
	mongoc_server_description_t *sd;
146
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
147

148
	intern = Z_SERVER_OBJ_P(getThis());
149 150 151 152 153

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

154 155 156 157
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		PHONGO_RETVAL_STRING(mongoc_server_description_host(sd)->host);
		mongoc_server_description_destroy(sd);
		return;
158 159
	}

160
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
161 162
}
/* }}} */
163

164
/* {{{ proto array Server::getTags()
165
   Returns the currently configured tags for this Server */
166 167
PHP_METHOD(Server, getTags)
{
168
	php_phongo_server_t         *intern;
169
	mongoc_server_description_t *sd;
170
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
171 172


173
	intern = Z_SERVER_OBJ_P(getThis());
174 175 176 177 178 179

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}


180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		const bson_t *is_master = mongoc_server_description_ismaster(sd);
		bson_iter_t   iter;

		if (bson_iter_init_find(&iter, is_master, "tags") && BSON_ITER_HOLDS_DOCUMENT(&iter)) {
			const uint8_t         *bytes;
			uint32_t               len;
			php_phongo_bson_state  state = PHONGO_BSON_STATE_INITIALIZER;

			state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
			state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY;

			bson_iter_document(&iter, &len, &bytes);
			phongo_bson_to_zval_ex(bytes, len, &state);
			mongoc_server_description_destroy(sd);
195

196
#if PHP_VERSION_ID >= 70000
197
			RETURN_ZVAL(&state.zchild, 0, 1);
198
#else
199
			RETURN_ZVAL(state.zchild, 0, 1);
200
#endif
201 202 203 204 205
		}

		array_init(return_value);
		mongoc_server_description_destroy(sd);
		return;
206 207
	}

208
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
209 210
}
/* }}} */
211

212
/* {{{ proto array Server::getInfo()
213
   Returns the last isMaster result document for this Server */
214 215
PHP_METHOD(Server, getInfo)
{
216
	php_phongo_server_t         *intern;
217
	mongoc_server_description_t *sd;
218
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
219 220


221
	intern = Z_SERVER_OBJ_P(getThis());
222 223 224 225 226 227

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}


228 229
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		const bson_t          *is_master = mongoc_server_description_ismaster(sd);
230
		php_phongo_bson_state  state = PHONGO_BSON_STATE_INITIALIZER;
231

232 233 234
		state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
		state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY;

235 236
		phongo_bson_to_zval_ex(bson_get_data(is_master), is_master->len, &state);
		mongoc_server_description_destroy(sd);
237 238 239 240

#if PHP_VERSION_ID >= 70000
		RETURN_ZVAL(&state.zchild, 0, 1);
#else
241
		RETURN_ZVAL(state.zchild, 0, 1);
242
#endif
243 244
	}

245
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
246 247
}
/* }}} */
248

249
/* {{{ proto integer Server::getLatency()
250
   Returns the last messured latency for this Server */
251 252
PHP_METHOD(Server, getLatency)
{
253
	php_phongo_server_t         *intern;
254
	mongoc_server_description_t *sd;
255
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
256 257


258
	intern = Z_SERVER_OBJ_P(getThis());
259 260 261 262 263

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

264 265 266 267
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		RETVAL_LONG((phongo_long) mongoc_server_description_round_trip_time(sd));
		mongoc_server_description_destroy(sd);
		return;
268 269
	}

270
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
271 272
}
/* }}} */
273

274
/* {{{ proto integer Server::getPort()
275
   Returns the port for this Server */
276 277 278 279
PHP_METHOD(Server, getPort)
{
	php_phongo_server_t         *intern;
	mongoc_server_description_t *sd;
280
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
281 282


283
	intern = Z_SERVER_OBJ_P(getThis());
284 285 286 287 288

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

289 290 291 292
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		RETVAL_LONG(mongoc_server_description_host(sd)->port);
		mongoc_server_description_destroy(sd);
		return;
293 294
	}

295
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
296 297
}
/* }}} */
298

299 300 301 302
/* {{{ proto integer Server::getType()
   Returns the node type of this Server */
PHP_METHOD(Server, getType)
{
303
	php_phongo_server_t         *intern;
304
	mongoc_server_description_t *sd;
305
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
306 307


308
	intern = Z_SERVER_OBJ_P(getThis());
309 310 311 312 313

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

314 315 316 317
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		RETVAL_LONG(php_phongo_server_description_type(sd));
		mongoc_server_description_destroy(sd);
		return;
318 319
	}

320
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
321 322
}
/* }}} */
323

324
/* {{{ proto bool Server::isPrimary()
325
   Returns whether this Server is a primary member of a replica set */
326 327
PHP_METHOD(Server, isPrimary)
{
328
	php_phongo_server_t         *intern;
329
	mongoc_server_description_t *sd;
330
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
331 332


333
	intern = Z_SERVER_OBJ_P(getThis());
334 335 336 337 338

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

339 340 341 342
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_PRIMARY].name));
		mongoc_server_description_destroy(sd);
		return;
343 344
	}

345
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
346 347
}
/* }}} */
348

349
/* {{{ proto bool Server::isSecondary()
350
   Returns whether this Server is a secondary member of a replica set */
351 352
PHP_METHOD(Server, isSecondary)
{
353
	php_phongo_server_t         *intern;
354
	mongoc_server_description_t *sd;
355
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
356 357


358
	intern = Z_SERVER_OBJ_P(getThis());
359 360 361 362 363

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

364 365 366 367
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_SECONDARY].name));
		mongoc_server_description_destroy(sd);
		return;
368 369
	}

370
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
371 372
}
/* }}} */
373

374
/* {{{ proto bool Server::isArbiter()
375
   Returns whether this Server is an arbiter member of a replica set */
376 377
PHP_METHOD(Server, isArbiter)
{
378
	php_phongo_server_t         *intern;
379
	mongoc_server_description_t *sd;
380
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
381 382


383
	intern = Z_SERVER_OBJ_P(getThis());
384 385 386 387 388

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

389 390 391 392
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_ARBITER].name));
		mongoc_server_description_destroy(sd);
		return;
393 394
	}

395
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
396 397
}
/* }}} */
398

399
/* {{{ proto bool Server::isHidden()
400
   Returns whether this Server is a hidden member of a replica set */
401 402
PHP_METHOD(Server, isHidden)
{
403
	php_phongo_server_t         *intern;
404
	mongoc_server_description_t *sd;
405
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
406 407


408
	intern = Z_SERVER_OBJ_P(getThis());
409 410 411 412 413

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

414
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
415 416
		bson_iter_t iter;

417 418 419
		RETVAL_BOOL(bson_iter_init_find_case(&iter, mongoc_server_description_ismaster(sd), "hidden") && bson_iter_as_bool(&iter));
		mongoc_server_description_destroy(sd);
		return;
420 421
	}

422
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
423 424
}
/* }}} */
425

426
/* {{{ proto bool Server::isPassive()
427
   Returns whether this Server is a passive member of a replica set */
428 429 430 431
PHP_METHOD(Server, isPassive)
{
	php_phongo_server_t         *intern;
	mongoc_server_description_t *sd;
432
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
433 434


435
	intern = Z_SERVER_OBJ_P(getThis());
436 437 438 439 440

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

441
	if ((sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
442 443
		bson_iter_t iter;

444 445 446
		RETVAL_BOOL(bson_iter_init_find_case(&iter, mongoc_server_description_ismaster(sd), "passive") && bson_iter_as_bool(&iter));
		mongoc_server_description_destroy(sd);
		return;
447 448
	}

449
	phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
450 451 452 453 454 455 456 457 458
}
/* }}} */

/* {{{ MongoDB\Driver\Server */

ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeCommand, 0, 0, 2)
	ZEND_ARG_INFO(0, db)
	ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0)
	ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1)
459
ZEND_END_ARG_INFO()
460 461 462 463 464

ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeQuery, 0, 0, 2)
	ZEND_ARG_INFO(0, namespace)
	ZEND_ARG_OBJ_INFO(0, zquery, MongoDB\\Driver\\Query, 0)
	ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1)
465
ZEND_END_ARG_INFO()
466 467 468 469 470

ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeBulkWrite, 0, 0, 2)
	ZEND_ARG_INFO(0, namespace)
	ZEND_ARG_OBJ_INFO(0, zbulk, MongoDB\\Driver\\BulkWrite, 0)
	ZEND_ARG_OBJ_INFO(0, writeConcern, MongoDB\\Driver\\WriteConcern, 1)
471
ZEND_END_ARG_INFO()
472

473 474
ZEND_BEGIN_ARG_INFO_EX(ai_Server_void, 0, 0, 0)
ZEND_END_ARG_INFO()
475 476

static zend_function_entry php_phongo_server_me[] = {
477
	PHP_ME(Server, __construct, ai_Server_void, ZEND_ACC_FINAL|ZEND_ACC_PRIVATE)
478 479 480
	PHP_ME(Server, executeCommand, ai_Server_executeCommand, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, executeQuery, ai_Server_executeQuery, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, executeBulkWrite, ai_Server_executeBulkWrite, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
481 482 483 484 485 486 487 488 489 490 491 492
	PHP_ME(Server, getHost, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, getTags, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, getInfo, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, getLatency, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, getPort, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, getType, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, isPrimary, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, isSecondary, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, isArbiter, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, isHidden, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Server, isPassive, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
	PHP_ME(Manager, __wakeup, ai_Server_void, ZEND_ACC_PUBLIC)
493 494 495 496 497 498 499 500 501
	PHP_FE_END
};

/* }}} */


/* {{{ Other functions */
static int php_phongo_server_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
{
502
	php_phongo_server_t         *intern1, *intern2;
503
	mongoc_server_description_t *sd1, *sd2;
504
	int                          retval = 0;
505

506 507
	intern1 = Z_SERVER_OBJ_P(o1);
	intern2 = Z_SERVER_OBJ_P(o2);
508

509 510
	sd1 = mongoc_client_get_server_description(intern1->client, intern1->server_id);
	sd2 = mongoc_client_get_server_description(intern2->client, intern2->server_id);
511

512 513 514 515 516 517 518 519 520 521 522 523
	if (sd1 && sd2) {
		retval = strcasecmp(mongoc_server_description_host(sd1)->host_and_port, mongoc_server_description_host(sd2)->host_and_port);
	} else {
		phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description(s)");
	}

	if (sd1) {
		mongoc_server_description_destroy(sd1);
	}

	if (sd2) {
		mongoc_server_description_destroy(sd2);
524 525
	}

526
	return retval;
527 528 529
} /* }}} */
/* }}} */
/* {{{ php_phongo_server_t object handlers */
530
static void php_phongo_server_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */
531
{
532
	php_phongo_server_t *intern = Z_OBJ_SERVER(object);
533 534 535

	zend_object_std_dtor(&intern->std TSRMLS_CC);

536 537
	zval_ptr_dtor(&intern->manager);

538
#if PHP_VERSION_ID < 70000
539
	efree(intern);
540
#endif
541 542
} /* }}} */

543
phongo_create_object_retval php_phongo_server_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
544 545 546
{
	php_phongo_server_t *intern = NULL;

547
	intern = PHONGO_ALLOC_OBJECT_T(php_phongo_server_t, class_type);
548 549 550 551

	zend_object_std_init(&intern->std, class_type TSRMLS_CC);
	object_properties_init(&intern->std, class_type);

552 553 554 555 556 557 558 559 560
#if PHP_VERSION_ID >= 70000
	intern->std.handlers = &php_phongo_handler_server;

	return &intern->std;
#else
	{
		zend_object_value retval;
		retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_server_free_object, NULL TSRMLS_CC);
		retval.handlers = &php_phongo_handler_server;
561

562 563 564
		return retval;
	}
#endif
565 566 567 568 569
} /* }}} */

HashTable *php_phongo_server_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
{
	php_phongo_server_t         *intern = NULL;
570 571 572
#if PHP_VERSION_ID >= 70000
	zval                         retval;
#else
573
	zval                         retval = zval_used_for_init;
574
#endif
575 576 577
	mongoc_server_description_t *sd;

	*is_temp = 1;
578
	intern = Z_SERVER_OBJ_P(object);
579 580


581 582
	if (!(sd = mongoc_client_get_server_description(intern->client, intern->server_id))) {
		phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description");
583 584 585 586
		return NULL;
	}

	php_phongo_server_to_zval(&retval, sd);
587
	mongoc_server_description_destroy(sd);
588 589 590 591 592 593 594 595 596 597 598 599 600 601

	return Z_ARRVAL(retval);
} /* }}} */
/* }}} */

/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(Server)
{
	zend_class_entry ce;
	(void)type;(void)module_number;

	INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Server", php_phongo_server_me);
	php_phongo_server_ce = zend_register_internal_class(&ce TSRMLS_CC);
	php_phongo_server_ce->create_object = php_phongo_server_create_object;
602 603
	PHONGO_CE_FINAL(php_phongo_server_ce);
	PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_server_ce);
604 605 606 607

	memcpy(&php_phongo_handler_server, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
	php_phongo_handler_server.compare_objects = php_phongo_server_compare_objects;
	php_phongo_handler_server.get_debug_info = php_phongo_server_get_debug_info;
608 609 610 611
#if PHP_VERSION_ID >= 70000
	php_phongo_handler_server.free_obj = php_phongo_server_free_object;
	php_phongo_handler_server.offset = XtOffsetOf(php_phongo_server_t, std);
#endif
612

613 614 615 616 617 618 619 620 621
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_UNKNOWN"), PHONGO_SERVER_UNKNOWN TSRMLS_CC);
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_STANDALONE"), PHONGO_SERVER_STANDALONE TSRMLS_CC);
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_MONGOS"), PHONGO_SERVER_MONGOS TSRMLS_CC);
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_POSSIBLE_PRIMARY"), PHONGO_SERVER_POSSIBLE_PRIMARY TSRMLS_CC);
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_PRIMARY"), PHONGO_SERVER_RS_PRIMARY TSRMLS_CC);
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_SECONDARY"), PHONGO_SERVER_RS_SECONDARY TSRMLS_CC);
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_ARBITER"), PHONGO_SERVER_RS_ARBITER TSRMLS_CC);
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_OTHER"), PHONGO_SERVER_RS_OTHER TSRMLS_CC);
	zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_GHOST"), PHONGO_SERVER_RS_GHOST TSRMLS_CC);
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637


	return SUCCESS;
}
/* }}} */



/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */