Skip to content
Merged
2 changes: 2 additions & 0 deletions php_phongo_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ typedef struct {
} php_phongo_cursor_t;

typedef struct {
bool initialized;
int64_t id;
HashTable* properties;
zend_object std;
} php_phongo_cursorid_t;

Expand Down
5 changes: 3 additions & 2 deletions src/MongoDB/Cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,9 @@ static void php_phongo_cursor_id_new_from_id(zval* object, int64_t cursorid) /*

object_init_ex(object, php_phongo_cursorid_ce);

intern = Z_CURSORID_OBJ_P(object);
intern->id = cursorid;
intern = Z_CURSORID_OBJ_P(object);
intern->id = cursorid;
intern->initialized = true;
} /* }}} */

/* {{{ proto array MongoDB\Driver\Cursor::toArray()
Expand Down
89 changes: 74 additions & 15 deletions src/MongoDB/CursorId.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ static bool php_phongo_cursorid_init_from_string(php_phongo_cursorid_t* intern,
return false;
}

intern->id = id;
intern->id = id;
intern->initialized = true;
return true;
} /* }}} */

Expand All @@ -57,6 +58,61 @@ static bool php_phongo_cursorid_init_from_hash(php_phongo_cursorid_t* intern, Ha
return false;
} /* }}} */

static HashTable* php_phongo_cursorid_get_properties_hash(phongo_compat_object_handler_type* object, bool is_debug) /* {{{ */
{
php_phongo_cursorid_t* intern;
HashTable* props;

intern = Z_OBJ_CURSORID(PHONGO_COMPAT_GET_OBJ(object));

PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2);

if (!intern->initialized) {
return props;
}

{
zval value;

if (is_debug) {
#if SIZEOF_ZEND_LONG == 4
ZVAL_INT64_STRING(&value, intern->id);
#else
ZVAL_LONG(&value, intern->id);
#endif
} else {
ZVAL_INT64_STRING(&value, intern->id);
}
zend_hash_str_update(props, "id", sizeof("id") - 1, &value);
}

return props;
} /* }}} */

/* {{{ proto MongoDB\Driver\CursorId MongoDB\Driver\CursorId::__set_state(array $properties)
*/
static PHP_METHOD(CursorId, __set_state)
{
zend_error_handling error_handling;
php_phongo_cursorid_t* intern;
HashTable* props;
zval* array;

zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);

object_init_ex(return_value, php_phongo_cursorid_ce);

intern = Z_CURSORID_OBJ_P(return_value);
props = Z_ARRVAL_P(array);

php_phongo_cursorid_init_from_hash(intern, props);
} /* }}} */

/* {{{ proto string MongoDB\Driver\CursorId::__toString()
Returns the string representation of the CursorId */
static PHP_METHOD(CursorId, __toString)
Expand Down Expand Up @@ -148,6 +204,10 @@ static PHP_METHOD(CursorId, unserialize)
} /* }}} */

/* {{{ MongoDB\Driver\CursorId function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CursorId___set_state, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, properties, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(ai_CursorId_unserialize, 0, 0, 1)
ZEND_ARG_INFO(0, serialized)
ZEND_END_ARG_INFO()
Expand All @@ -157,6 +217,7 @@ ZEND_END_ARG_INFO()

static zend_function_entry php_phongo_cursorid_me[] = {
/* clang-format off */
PHP_ME(CursorId, __set_state, ai_CursorId___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(CursorId, __toString, ai_CursorId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CursorId, serialize, ai_CursorId_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CursorId, unserialize, ai_CursorId_unserialize, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
Expand All @@ -175,6 +236,11 @@ static void php_phongo_cursorid_free_object(zend_object* object) /* {{{ */
php_phongo_cursorid_t* intern = Z_OBJ_CURSORID(object);

zend_object_std_dtor(&intern->std);

if (intern->properties) {
zend_hash_destroy(intern->properties);
FREE_HASHTABLE(intern->properties);
}
} /* }}} */

static zend_object* php_phongo_cursorid_create_object(zend_class_entry* class_type) /* {{{ */
Expand All @@ -193,24 +259,16 @@ static zend_object* php_phongo_cursorid_create_object(zend_class_entry* class_ty

static HashTable* php_phongo_cursorid_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
php_phongo_cursorid_t* intern;
zval retval = ZVAL_STATIC_INIT;

*is_temp = 1;
intern = Z_OBJ_CURSORID(PHONGO_COMPAT_GET_OBJ(object));

array_init(&retval);

#if SIZEOF_ZEND_LONG == 4
ADD_ASSOC_INT64_AS_STRING(&retval, "id", intern->id);
#else
ADD_ASSOC_LONG_EX(&retval, "id", intern->id);
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep this around so var_dump() behavior isn't changed by this PR. That should entail copying this to php_phongo_cursorid_get_properties_hash and placing it within a conditional dependent on is_debug.


return Z_ARRVAL(retval);
return php_phongo_cursorid_get_properties_hash(object, true);
} /* }}} */
/* }}} */

static HashTable* php_phongo_cursorid_get_properties(phongo_compat_object_handler_type* object) /* {{{ */
{
return php_phongo_cursorid_get_properties_hash(object, false);
} /* }}} */

void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
Expand All @@ -224,6 +282,7 @@ void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS) /* {{{ */

memcpy(&php_phongo_handler_cursorid, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_cursorid.get_debug_info = php_phongo_cursorid_get_debug_info;
php_phongo_handler_cursorid.get_properties = php_phongo_cursorid_get_properties;
php_phongo_handler_cursorid.free_obj = php_phongo_cursorid_free_object;
php_phongo_handler_cursorid.offset = XtOffsetOf(php_phongo_cursorid_t, std);
} /* }}} */
Expand Down
2 changes: 1 addition & 1 deletion tests/cursorid/cursorid-001.phpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--TEST--
MongoDB\Driver\CursorID BSON serialization
MongoDB\Driver\CursorId BSON serialization
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
Expand Down
2 changes: 1 addition & 1 deletion tests/cursorid/cursorid-002.phpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--TEST--
MongoDB\Driver\CursorID BSON serialization for killCursors command
MongoDB\Driver\CursorId BSON serialization for killCursors command
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
Expand Down
20 changes: 20 additions & 0 deletions tests/cursorid/cursorid-debug-001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
MongoDB\Driver\CursorId debug output
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

$cursorId = unserialize('C:23:"MongoDB\Driver\CursorId":42:{a:1:{s:2:"id";s:19:"7250031947823432848";}}');

var_dump($cursorId);

?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\CursorId)#%d (%d) {
["id"]=>
%rint\(|string\(19\) "|%r7250031947823432848%r"|\)%r
}
===DONE===
22 changes: 22 additions & 0 deletions tests/cursorid/cursorid-debug-002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
MongoDB\Driver\CursorId debug output on 32-bit platform
--SKIPIF--
<?php if (4 !== PHP_INT_SIZE) { die('skip Only for 32-bit platform'); } ?>
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

$cursorId = unserialize('C:23:"MongoDB\Driver\CursorId":42:{a:1:{s:2:"id";s:19:"7250031947823432848";}}');

var_dump($cursorId);

?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\CursorId)#%d (%d) {
["id"]=>
string(19) "7250031947823432848"
}
===DONE===
22 changes: 22 additions & 0 deletions tests/cursorid/cursorid-debug-003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
MongoDB\Driver\CursorId debug output on 64-bit platform
--SKIPIF--
<?php if (8 !== PHP_INT_SIZE) { die('skip Only for 64-bit platform'); } ?>
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

$cursorId = unserialize('C:23:"MongoDB\Driver\CursorId":42:{a:1:{s:2:"id";s:19:"7250031947823432848";}}');

var_dump($cursorId);

?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\CursorId)#%d (%d) {
["id"]=>
int(7250031947823432848)
}
===DONE===
2 changes: 1 addition & 1 deletion tests/cursorid/cursorid-serialization-001.phpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--TEST--
MongoDB\Driver\CursorID serialization
MongoDB\Driver\CursorId serialization
--FILE--
<?php

Expand Down
18 changes: 18 additions & 0 deletions tests/cursorid/cursorid-set_state-001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
MongoDB\Driver\CursorId::__set_state()
--FILE--
<?php

var_export(MongoDB\Driver\CursorId::__set_state([
'id' => '7250031947823432848',
]));
echo "\n";

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
MongoDB\Driver\CursorId::__set_state(array(
'id' => '7250031947823432848',
))
===DONE===
18 changes: 18 additions & 0 deletions tests/cursorid/cursorid-set_state_error-001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
MongoDB\Driver\CursorId::__set_state() requires "id" string field
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

echo throws(function() {
MongoDB\Driver\CursorId::__set_state(['id' => 0]);
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
MongoDB\Driver\CursorId initialization requires "id" string field
===DONE===
15 changes: 15 additions & 0 deletions tests/cursorid/cursorid-tostring-001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
MongoDB\Driver\CursorId::__toString()
--FILE--
<?php

$cursorId = unserialize('C:23:"MongoDB\Driver\CursorId":42:{a:1:{s:2:"id";s:19:"7250031947823432848";}}');

var_dump((string) $cursorId);

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
string(19) "7250031947823432848"
===DONE===
19 changes: 19 additions & 0 deletions tests/cursorid/cursorid-var_export-001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
MongoDB\Driver\CursorId: var_export()
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

$cursorId = unserialize('C:23:"MongoDB\Driver\CursorId":42:{a:1:{s:2:"id";s:19:"7250031947823432848";}}');

echo var_export($cursorId, true), "\n";

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
MongoDB\Driver\CursorId::__set_state(array(
'id' => '7250031947823432848',
))
===DONE===