diff --git a/php_phongo.c b/php_phongo.c index 6c9bd29fc..f4f4c3dc7 100644 --- a/php_phongo.c +++ b/php_phongo.c @@ -235,6 +235,7 @@ PHP_MINIT_FUNCTION(mongodb) /* {{{ */ php_phongo_document_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_binary_init_ce(INIT_FUNC_ARGS_PASSTHRU); + php_phongo_binaryvector_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_dbpointer_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_decimal128_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_int64_init_ce(INIT_FUNC_ARGS_PASSTHRU); diff --git a/src/BSON/Binary.c b/src/BSON/Binary.c index 4583ac8ab..17db1c255 100644 --- a/src/BSON/Binary.c +++ b/src/BSON/Binary.c @@ -19,13 +19,18 @@ #include #include "php_phongo.h" +#include "phongo_bson_encode.h" #include "phongo_error.h" +#include "Binary.h" #include "Binary_arginfo.h" - -#define PHONGO_BINARY_UUID_SIZE 16 +#include "BinaryVector_arginfo.h" zend_class_entry* php_phongo_binary_ce; +static phongo_bson_vector_type_t phongo_binaryvector_get_vector_type_from_data(const uint8_t* data, uint32_t data_len); +static phongo_bson_vector_type_t phongo_binaryvector_get_vector_type(const php_phongo_binary_t* intern); +static void phongo_binaryvector_get_vector_as_array(const php_phongo_binary_t* intern, zval* return_value); + /* Initialize the object and return whether it was successful. An exception will * be thrown on error. */ static bool php_phongo_binary_init(php_phongo_binary_t* intern, const char* data, size_t data_len, zend_long type) @@ -40,6 +45,11 @@ static bool php_phongo_binary_init(php_phongo_binary_t* intern, const char* data return false; } + if ((type == BSON_SUBTYPE_VECTOR) && phongo_binaryvector_get_vector_type_from_data((const uint8_t*) data, data_len) == PHONGO_BSON_VECTOR_TYPE_INVALID) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Binary vector data is invalid"); + return false; + } + intern->data = estrndup(data, data_len); intern->data_len = data_len; intern->type = (uint8_t) type; @@ -272,8 +282,29 @@ static int php_phongo_binary_compare_objects(zval* o1, zval* o2) static HashTable* php_phongo_binary_get_debug_info(zend_object* object, int* is_temp) { - *is_temp = 1; - return php_phongo_binary_get_properties_hash(object, true); + *is_temp = 1; + HashTable* props = php_phongo_binary_get_properties_hash(object, true); + + php_phongo_binary_t* intern = Z_OBJ_BINARY(object); + + if (intern->type == BSON_SUBTYPE_VECTOR) { + zval vector; + + phongo_binaryvector_get_vector_as_array(intern, &vector); + + if (EG(exception)) { + return props; + } + + zend_hash_str_update(props, "vector", sizeof("vector") - 1, &vector); + + zval vector_type; + + ZVAL_LONG(&vector_type, phongo_binaryvector_get_vector_type(intern)); + zend_hash_str_update(props, "vectorType", sizeof("vectorType") - 1, &vector_type); + } + + return props; } static HashTable* php_phongo_binary_get_properties(zend_object* object) @@ -296,15 +327,413 @@ void php_phongo_binary_init_ce(INIT_FUNC_ARGS) } bool phongo_binary_new(zval* object, const char* data, size_t data_len, bson_subtype_t type) +{ + switch (type) { + case BSON_SUBTYPE_VECTOR: + object_init_ex(object, php_phongo_binaryvector_ce); + break; + + default: + object_init_ex(object, php_phongo_binary_ce); + } + + return php_phongo_binary_init(Z_BINARY_OBJ_P(object), data, data_len, type); +} + +/* MongoDB\BSON\BinaryVector implementation */ +zend_class_entry* php_phongo_binaryvector_ce; + +static inline void phongo_binaryvector_init_from_bson_key(php_phongo_binary_t* intern, const bson_t* doc, const char* key) +{ + bson_iter_t iter; + + if (!(bson_iter_init_find(&iter, doc, key) && BSON_ITER_HOLDS_VECTOR(&iter))) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "bson_iter_init_find failed to find binary vector in key \"%s\"", key); + return; + } + + uint32_t data_len; + const uint8_t* data; + + bson_iter_binary(&iter, NULL, &data_len, &data); + php_phongo_binary_init(intern, (const char*) data, data_len, BSON_SUBTYPE_VECTOR); +} + +static void phongo_binaryvector_init_from_float32_array(php_phongo_binary_t* intern, HashTable* vector) +{ + if (!zend_array_is_list(vector)) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector to be a list"); + return; + } + + const size_t vector_len = zend_array_count(vector); + + bson_t doc = BSON_INITIALIZER; + bson_vector_float32_view_t view; + + if (!BSON_APPEND_VECTOR_FLOAT32_UNINIT(&doc, "vector", vector_len, &view)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "BSON_APPEND_VECTOR_FLOAT32_UNINIT failed for vector of size %zu", vector_len); + return; + } + + zval* val; + size_t i = 0; + + ZEND_HASH_FOREACH_VAL_IND(vector, val) + { + if (Z_TYPE_P(val) != IS_DOUBLE) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector[%zu] to be a float, %s given", i, zend_zval_type_name(val)); + return; + } + + float v = (float) Z_DVAL_P(val); + + if (!bson_vector_float32_view_write(view, &v, 1, i)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "bson_vector_float32_view_write failed to write vector[%zu]", i); + return; + } + + i += 1; + } + ZEND_HASH_FOREACH_END(); + + phongo_binaryvector_init_from_bson_key(intern, &doc, "vector"); +} + +static void phongo_binaryvector_init_from_int8_array(php_phongo_binary_t* intern, HashTable* vector) +{ + if (!zend_array_is_list(vector)) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector to be a list"); + return; + } + + const size_t vector_len = zend_array_count(vector); + + bson_t doc = BSON_INITIALIZER; + bson_vector_int8_view_t view; + + if (!BSON_APPEND_VECTOR_INT8_UNINIT(&doc, "vector", vector_len, &view)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "BSON_APPEND_VECTOR_INT8_UNINIT failed for vector of size %zu", vector_len); + return; + } + + zval* val; + size_t i = 0; + + ZEND_HASH_FOREACH_VAL_IND(vector, val) + { + if (Z_TYPE_P(val) != IS_LONG) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector[%zu] to be an integer, %s given", i, zend_zval_type_name(val)); + return; + } + + if (Z_LVAL_P(val) < INT8_MIN || Z_LVAL_P(val) > INT8_MAX) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector[%zu] to be a signed 8-bit integer, %" PHONGO_LONG_FORMAT " given", i, Z_LVAL_P(val)); + return; + } + + int8_t v = (int8_t) Z_LVAL_P(val); + + if (!bson_vector_int8_view_write(view, &v, 1, i)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "bson_vector_int8_view_write failed to write vector[%zu]", i); + return; + } + + i += 1; + } + ZEND_HASH_FOREACH_END(); + + phongo_binaryvector_init_from_bson_key(intern, &doc, "vector"); +} + +static void phongo_binaryvector_init_from_packed_bit_array(php_phongo_binary_t* intern, HashTable* vector) +{ + if (!zend_array_is_list(vector)) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector to be a list"); + return; + } + + const size_t vector_len = zend_array_count(vector); + + bson_t doc = BSON_INITIALIZER; + bson_vector_packed_bit_view_t view; + + if (!BSON_APPEND_VECTOR_PACKED_BIT_UNINIT(&doc, "vector", vector_len, &view)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "BSON_APPEND_VECTOR_PACKED_BIT_UNINIT failed for vector of size %zu", vector_len); + return; + } + + zval* val; + size_t i = 0; + + ZEND_HASH_FOREACH_VAL_IND(vector, val) + { + if (Z_TYPE_P(val) != IS_LONG && Z_TYPE_P(val) != IS_TRUE && Z_TYPE_P(val) != IS_FALSE) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector[%zu] to be an integer or boolean, %s given", i, zend_zval_type_name(val)); + return; + } + + if (Z_TYPE_P(val) == IS_LONG && (Z_LVAL_P(val) < 0 || Z_LVAL_P(val) > 1)) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector[%zu] to be 0 or 1, %" PHONGO_LONG_FORMAT " given", i, Z_LVAL_P(val)); + return; + } + + bool v = zend_is_true(val); + + if (!bson_vector_packed_bit_view_pack_bool(view, &v, 1, i)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "bson_vector_packed_bit_view_pack_bool failed to write vector[%zu]", i); + return; + } + + i += 1; + } + ZEND_HASH_FOREACH_END(); + + phongo_binaryvector_init_from_bson_key(intern, &doc, "vector"); +} + +static PHP_METHOD(MongoDB_BSON_BinaryVector, __construct) { php_phongo_binary_t* intern; + HashTable* vector; + zend_long type = BSON_SUBTYPE_BINARY; - object_init_ex(object, php_phongo_binary_ce); + intern = Z_BINARY_OBJ_P(getThis()); - intern = Z_BINARY_OBJ_P(object); - intern->data = estrndup(data, data_len); - intern->data_len = data_len; - intern->type = (uint8_t) type; + PHONGO_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_ARRAY_HT(vector) + Z_PARAM_LONG(type) + PHONGO_PARSE_PARAMETERS_END(); - return true; + switch (type) { + case PHONGO_BSON_VECTOR_TYPE_FLOAT32: + phongo_binaryvector_init_from_float32_array(intern, vector); + break; + + case PHONGO_BSON_VECTOR_TYPE_INT8: + phongo_binaryvector_init_from_int8_array(intern, vector); + break; + + case PHONGO_BSON_VECTOR_TYPE_PACKED_BIT: + phongo_binaryvector_init_from_packed_bit_array(intern, vector); + break; + + default: + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Unsupported binary vector type: %" PHONGO_LONG_FORMAT, type); + RETURN_THROWS(); + } } + +static PHP_METHOD(MongoDB_BSON_BinaryVector, fromFloat32Array) +{ + HashTable* vector; + + PHONGO_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_HT(vector) + PHONGO_PARSE_PARAMETERS_END(); + + object_init_ex(return_value, php_phongo_binaryvector_ce); + php_phongo_binary_t* intern = Z_BINARY_OBJ_P(return_value); + + phongo_binaryvector_init_from_float32_array(intern, vector); +} + +static PHP_METHOD(MongoDB_BSON_BinaryVector, fromInt8Array) +{ + HashTable* vector; + + PHONGO_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_HT(vector) + PHONGO_PARSE_PARAMETERS_END(); + + object_init_ex(return_value, php_phongo_binaryvector_ce); + php_phongo_binary_t* intern = Z_BINARY_OBJ_P(return_value); + + phongo_binaryvector_init_from_int8_array(intern, vector); +} + +static PHP_METHOD(MongoDB_BSON_BinaryVector, fromPackedBitArray) +{ + HashTable* vector; + + PHONGO_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_HT(vector) + PHONGO_PARSE_PARAMETERS_END(); + + object_init_ex(return_value, php_phongo_binaryvector_ce); + php_phongo_binary_t* intern = Z_BINARY_OBJ_P(return_value); + + phongo_binaryvector_init_from_packed_bit_array(intern, vector); +} + +static phongo_bson_vector_type_t phongo_binaryvector_get_vector_type_from_data(const uint8_t* data, uint32_t data_len) +{ + if (bson_vector_int8_const_view_init(NULL, data, data_len)) { + return PHONGO_BSON_VECTOR_TYPE_INT8; + } + + if (bson_vector_float32_const_view_init(NULL, data, data_len)) { + return PHONGO_BSON_VECTOR_TYPE_FLOAT32; + } + + if (bson_vector_packed_bit_const_view_init(NULL, data, data_len)) { + return PHONGO_BSON_VECTOR_TYPE_PACKED_BIT; + } + + return PHONGO_BSON_VECTOR_TYPE_INVALID; +} + +static phongo_bson_vector_type_t phongo_binaryvector_get_vector_type(const php_phongo_binary_t* intern) +{ + return phongo_binaryvector_get_vector_type_from_data((const uint8_t*) intern->data, intern->data_len); +} + +static PHP_METHOD(MongoDB_BSON_BinaryVector, getVectorType) +{ + PHONGO_PARSE_PARAMETERS_NONE(); + + phongo_bson_vector_type_t type = phongo_binaryvector_get_vector_type(Z_BINARY_OBJ_P(getThis())); + + // The vector should always be valid by this point, but check for an error + if (type == PHONGO_BSON_VECTOR_TYPE_INVALID) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Binary vector data is invalid"); + RETURN_THROWS(); + } + + RETURN_LONG(type); +} + +static void phongo_binaryvector_get_vector_as_array(const php_phongo_binary_t* intern, zval* return_value) +{ + phongo_bson_vector_type_t type = phongo_binaryvector_get_vector_type(intern); + + // The vector should always be valid by this point, but check for an error + if (type == PHONGO_BSON_VECTOR_TYPE_INVALID) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Binary vector data is invalid"); + RETURN_THROWS(); + } + + bson_t tmp_doc = BSON_INITIALIZER; + + if (type == PHONGO_BSON_VECTOR_TYPE_INT8) { + bson_vector_int8_const_view_t view; + + if (!bson_vector_int8_const_view_init(&view, (const uint8_t*) intern->data, intern->data_len) || + !BSON_APPEND_ARRAY_FROM_VECTOR_INT8(&tmp_doc, "vector", view)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to convert binary vector data to an array"); + bson_destroy(&tmp_doc); + RETURN_THROWS(); + } + } else if (type == PHONGO_BSON_VECTOR_TYPE_FLOAT32) { + bson_vector_float32_const_view_t view; + + if (!bson_vector_float32_const_view_init(&view, (const uint8_t*) intern->data, intern->data_len) || + !BSON_APPEND_ARRAY_FROM_VECTOR_FLOAT32(&tmp_doc, "vector", view)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to convert binary vector data to an array"); + bson_destroy(&tmp_doc); + RETURN_THROWS(); + } + } else if (type == PHONGO_BSON_VECTOR_TYPE_PACKED_BIT) { + bson_vector_packed_bit_const_view_t view; + + if (!bson_vector_packed_bit_const_view_init(&view, (const uint8_t*) intern->data, intern->data_len) || + !BSON_APPEND_ARRAY_FROM_VECTOR_PACKED_BIT(&tmp_doc, "vector", view)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to convert binary vector data to an array"); + bson_destroy(&tmp_doc); + RETURN_THROWS(); + } + } + + bson_iter_t iter; + + if (!(bson_iter_init_find(&iter, &tmp_doc, "vector") && BSON_ITER_HOLDS_ARRAY(&iter))) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "bson_iter_init_find failed for appended vector"); + bson_destroy(&tmp_doc); + RETURN_THROWS(); + } + + uint32_t data_len; + const uint8_t* data; + + bson_iter_array(&iter, &data_len, &data); + + bson_t tmp_vector = BSON_INITIALIZER; + + if (!bson_init_static(&tmp_vector, data, data_len)) { + phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "bson_init_static failed for appended vector"); + bson_destroy(&tmp_doc); + RETURN_THROWS(); + } + + php_phongo_bson_state state; + PHONGO_BSON_INIT_STATE(state); + state.is_visiting_array = true; + + if (!php_phongo_bson_to_zval_ex(&tmp_vector, &state)) { + // Exception already thrown + bson_destroy(&tmp_doc); + zval_ptr_dtor(&state.zchild); + php_phongo_bson_typemap_dtor(&state.map); + RETURN_THROWS(); + } + + bson_destroy(&tmp_doc); + php_phongo_bson_typemap_dtor(&state.map); + + RETURN_ZVAL(&state.zchild, 0, 1); +} + +static PHP_METHOD(MongoDB_BSON_BinaryVector, toArray) +{ + PHONGO_PARSE_PARAMETERS_NONE(); + + phongo_binaryvector_get_vector_as_array(Z_BINARY_OBJ_P(getThis()), return_value); +} + +static PHP_METHOD(MongoDB_BSON_BinaryVector, __set_state) +{ + php_phongo_binary_t* intern; + HashTable* props; + zval* array; + + PHONGO_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY(array) + PHONGO_PARSE_PARAMETERS_END(); + + /* This implementation is similar to Binary::__set_state(), except that we + * initialize a BinaryVector object and also validate its data. */ + object_init_ex(return_value, php_phongo_binaryvector_ce); + + intern = Z_BINARY_OBJ_P(return_value); + props = Z_ARRVAL_P(array); + + php_phongo_binary_init_from_hash(intern, props); + + if (intern->type != BSON_SUBTYPE_VECTOR || phongo_binaryvector_get_vector_type(intern) == PHONGO_BSON_VECTOR_TYPE_INVALID) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Binary vector data is invalid"); + RETURN_THROWS(); + } +} + +/* MongoDB\BSON\BinaryVector object handlers */ +static zend_object_handlers php_phongo_handler_binaryvector; + +static zend_object* php_phongo_binaryvector_create_object(zend_class_entry* class_type) +{ + php_phongo_binary_t* intern = zend_object_alloc(sizeof(php_phongo_binary_t), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + + intern->std.handlers = &php_phongo_handler_binaryvector; + + return &intern->std; +} + +void php_phongo_binaryvector_init_ce(INIT_FUNC_ARGS) +{ + php_phongo_binaryvector_ce = register_class_MongoDB_BSON_BinaryVector(php_phongo_binary_ce); + php_phongo_binaryvector_ce->create_object = php_phongo_binaryvector_create_object; + + memcpy(&php_phongo_handler_binaryvector, &php_phongo_handler_binary, sizeof(zend_object_handlers)); +} \ No newline at end of file diff --git a/src/BSON/Binary.h b/src/BSON/Binary.h index cdaa179ae..9b6ab4def 100644 --- a/src/BSON/Binary.h +++ b/src/BSON/Binary.h @@ -19,6 +19,13 @@ #define PHONGO_BINARY_UUID_SIZE 16 +typedef enum { + PHONGO_BSON_VECTOR_TYPE_INVALID = 0, + PHONGO_BSON_VECTOR_TYPE_INT8 = 0x03, + PHONGO_BSON_VECTOR_TYPE_FLOAT32 = 0x27, + PHONGO_BSON_VECTOR_TYPE_PACKED_BIT = 0x10, +} phongo_bson_vector_type_t; + bool phongo_binary_new(zval* object, const char* data, size_t data_len, bson_subtype_t type); #endif /* PHONGO_BSON_BINARY_H */ diff --git a/src/BSON/Binary.stub.php b/src/BSON/Binary.stub.php index 134fac6c7..6cf6dc414 100644 --- a/src/BSON/Binary.stub.php +++ b/src/BSON/Binary.stub.php @@ -7,7 +7,7 @@ namespace MongoDB\BSON; -final class Binary implements BinaryInterface, \JsonSerializable, Type, \Stringable +class Binary implements BinaryInterface, \JsonSerializable, Type, \Stringable { /** * @var int @@ -63,19 +63,25 @@ final class Binary implements BinaryInterface, \JsonSerializable, Type, \Stringa */ public const TYPE_SENSITIVE = UNKNOWN; + /** + * @var int + * @cvalue BSON_SUBTYPE_VECTOR + */ + public const TYPE_VECTOR = UNKNOWN; + /** * @var int * @cvalue BSON_SUBTYPE_USER */ public const TYPE_USER_DEFINED = UNKNOWN; - final public function __construct(string $data, int $type = Binary::TYPE_GENERIC) {} + public function __construct(string $data, int $type = Binary::TYPE_GENERIC) {} final public function getData(): string {} final public function getType(): int {} - final public static function __set_state(array $properties): Binary {} + public static function __set_state(array $properties): Binary {} final public function __toString(): string {} diff --git a/src/BSON/BinaryVector.stub.php b/src/BSON/BinaryVector.stub.php new file mode 100644 index 000000000..f4a1603cc --- /dev/null +++ b/src/BSON/BinaryVector.stub.php @@ -0,0 +1,46 @@ +ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_MongoDB_BSON_BinaryInterface, class_entry_JsonSerializable, class_entry_MongoDB_BSON_Type, class_entry_Stringable); zval const_TYPE_GENERIC_value; @@ -114,6 +111,12 @@ static zend_class_entry *register_class_MongoDB_BSON_Binary(zend_class_entry *cl zend_declare_class_constant_ex(class_entry, const_TYPE_SENSITIVE_name, &const_TYPE_SENSITIVE_value, ZEND_ACC_PUBLIC, NULL); zend_string_release(const_TYPE_SENSITIVE_name); + zval const_TYPE_VECTOR_value; + ZVAL_LONG(&const_TYPE_VECTOR_value, BSON_SUBTYPE_VECTOR); + zend_string *const_TYPE_VECTOR_name = zend_string_init_interned("TYPE_VECTOR", sizeof("TYPE_VECTOR") - 1, 1); + zend_declare_class_constant_ex(class_entry, const_TYPE_VECTOR_name, &const_TYPE_VECTOR_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(const_TYPE_VECTOR_name); + zval const_TYPE_USER_DEFINED_value; ZVAL_LONG(&const_TYPE_USER_DEFINED_value, BSON_SUBTYPE_USER); zend_string *const_TYPE_USER_DEFINED_name = zend_string_init_interned("TYPE_USER_DEFINED", sizeof("TYPE_USER_DEFINED") - 1, 1); diff --git a/src/phongo_bson_encode.c b/src/phongo_bson_encode.c index a1bde6d63..0c151c31b 100644 --- a/src/phongo_bson_encode.c +++ b/src/phongo_bson_encode.c @@ -213,6 +213,7 @@ static void php_phongo_bson_append_object(bson_t* bson, php_phongo_field_path* f bson_append_date_time(bson, key, key_len, intern->milliseconds); return; } + // TODO: confirm that this handles binary vector if (instanceof_function(Z_OBJCE_P(object), php_phongo_binary_ce)) { php_phongo_binary_t* intern = Z_BINARY_OBJ_P(object); diff --git a/src/phongo_classes.h b/src/phongo_classes.h index 1bdb0fafb..cc9d9fcad 100644 --- a/src/phongo_classes.h +++ b/src/phongo_classes.h @@ -349,6 +349,7 @@ extern zend_class_entry* php_phongo_persistable_ce; extern zend_class_entry* php_phongo_unserializable_ce; extern zend_class_entry* php_phongo_serializable_ce; extern zend_class_entry* php_phongo_binary_ce; +extern zend_class_entry* php_phongo_binaryvector_ce; extern zend_class_entry* php_phongo_document_ce; extern zend_class_entry* php_phongo_iterator_ce; extern zend_class_entry* php_phongo_dbpointer_ce; @@ -393,6 +394,7 @@ extern zend_class_entry* php_phongo_topologyclosedevent_ce; extern zend_class_entry* php_phongo_topologyopeningevent_ce; extern void php_phongo_binary_init_ce(INIT_FUNC_ARGS); +extern void php_phongo_binaryvector_init_ce(INIT_FUNC_ARGS); extern void php_phongo_packedarray_init_ce(INIT_FUNC_ARGS); extern void php_phongo_document_init_ce(INIT_FUNC_ARGS); extern void php_phongo_iterator_init_ce(INIT_FUNC_ARGS); diff --git a/tests/bson/bson-binary-constants.phpt b/tests/bson/bson-binary-constants.phpt index 7b224769f..edf8358a2 100644 --- a/tests/bson/bson-binary-constants.phpt +++ b/tests/bson/bson-binary-constants.phpt @@ -14,6 +14,7 @@ var_dump(Binary::TYPE_MD5); var_dump(Binary::TYPE_ENCRYPTED); var_dump(Binary::TYPE_COLUMN); var_dump(Binary::TYPE_SENSITIVE); +var_dump(Binary::TYPE_VECTOR); var_dump(Binary::TYPE_USER_DEFINED); ?> @@ -29,5 +30,6 @@ int(5) int(6) int(7) int(8) +int(9) int(128) ===DONE=== diff --git a/tests/bson/bson-binary-serialization-002.phpt b/tests/bson/bson-binary-serialization-002.phpt index 1fe9be000..61277e476 100644 --- a/tests/bson/bson-binary-serialization-002.phpt +++ b/tests/bson/bson-binary-serialization-002.phpt @@ -9,6 +9,7 @@ $tests = [ ["\0foo", MongoDB\BSON\Binary::TYPE_GENERIC], [hex2bin('123e4567e89b12d3a456426655440000'), MongoDB\BSON\Binary::TYPE_UUID], [md5('foobar', true), MongoDB\BSON\Binary::TYPE_MD5], + [hex2bin('030001020304'), MongoDB\BSON\Binary::TYPE_VECTOR], ]; foreach ($tests as $test) { @@ -94,4 +95,44 @@ object(MongoDB\BSON\Binary)#%d (%d) { int(5) } +object(MongoDB\BSON\Binary)#%d (%d) { + ["data"]=> + string(6) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + ["vectorType"]=> + int(3) +} +string(70) "O:19:"MongoDB\BSON\Binary":2:{s:4:"data";s:6:"%a";s:4:"type";i:9;}" +object(MongoDB\BSON\Binary)#%d (%d) { + ["data"]=> + string(6) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + ["vectorType"]=> + int(3) +} + ===DONE=== diff --git a/tests/bson/bson-binary-set_state-001.phpt b/tests/bson/bson-binary-set_state-001.phpt index 84f2468f2..1564e639b 100644 --- a/tests/bson/bson-binary-set_state-001.phpt +++ b/tests/bson/bson-binary-set_state-001.phpt @@ -9,6 +9,7 @@ $tests = [ ["\0foo", MongoDB\BSON\Binary::TYPE_GENERIC], [hex2bin('123e4567e89b12d3a456426655440000'), MongoDB\BSON\Binary::TYPE_UUID], [md5('foobar', true), MongoDB\BSON\Binary::TYPE_MD5], + [hex2bin('030001020304'), MongoDB\BSON\Binary::TYPE_VECTOR], ]; foreach ($tests as $test) { @@ -41,13 +42,18 @@ foreach ($tests as $test) { )) %r\\?%rMongoDB\BSON\Binary::__set_state(array( - 'data' => '>Egè›Ó¤VBfUD' . "\0" . '' . "\0" . '', + 'data' => '%a', 'type' => 4, )) %r\\?%rMongoDB\BSON\Binary::__set_state(array( - 'data' => '8Xö"0¬<‘_0 fCÆ?', + 'data' => '%a', 'type' => 5, )) +%r\\?%rMongoDB\BSON\Binary::__set_state(array( + 'data' => '%a', + 'type' => 9, +)) + ===DONE=== diff --git a/tests/bson/bson-binary-set_state_error-004.phpt b/tests/bson/bson-binary-set_state_error-004.phpt new file mode 100644 index 000000000..34516707b --- /dev/null +++ b/tests/bson/bson-binary-set_state_error-004.phpt @@ -0,0 +1,18 @@ +--TEST-- +MongoDB\BSON\Binary::__set_state() requires valid vector data +--FILE-- + '', 'type' => MongoDB\BSON\Binary::TYPE_VECTOR]); +}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Binary vector data is invalid +===DONE=== diff --git a/tests/bson/bson-binary_error-002.phpt b/tests/bson/bson-binary_error-002.phpt deleted file mode 100644 index 791252b4f..000000000 --- a/tests/bson/bson-binary_error-002.phpt +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -MongoDB\BSON\Binary cannot be extended ---FILE-- - -===DONE=== - ---EXPECTF-- -Fatal error: Class MyBinary %s final class %SMongoDB\BSON\Binary%S in %s on line %d diff --git a/tests/bson/bson-binaryvector-ctor-001.phpt b/tests/bson/bson-binaryvector-ctor-001.phpt new file mode 100644 index 000000000..fb9c71c10 --- /dev/null +++ b/tests/bson/bson-binaryvector-ctor-001.phpt @@ -0,0 +1,71 @@ +--TEST-- +MongoDB\BSON\BinaryVector construction of various vector types +--FILE-- + +===DONE=== + +--EXPECTF-- +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(18) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + float(1) + [1]=> + float(-1) + [2]=> + float(0.5) + [3]=> + float(-0.5) + } + ["vectorType"]=> + int(39) +} +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(6) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + ["vectorType"]=> + int(3) +} +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(3) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(0) + [2]=> + int(1) + [3]=> + int(0) + } + ["vectorType"]=> + int(16) +} +===DONE=== diff --git a/tests/bson/bson-binaryvector-ctor_error-001.phpt b/tests/bson/bson-binaryvector-ctor_error-001.phpt new file mode 100644 index 000000000..c2675f528 --- /dev/null +++ b/tests/bson/bson-binaryvector-ctor_error-001.phpt @@ -0,0 +1,24 @@ +--TEST-- +MongoDB\BSON\BinaryVector construction errors for VECTOR_TYPE_FLOAT32 +--FILE-- + 1.0], MongoDB\BSON\BinaryVector::VECTOR_TYPE_FLOAT32); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + new MongoDB\BSON\BinaryVector([1.0, 2], MongoDB\BSON\BinaryVector::VECTOR_TYPE_FLOAT32); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector to be a list +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be a float, int given +===DONE=== diff --git a/tests/bson/bson-binaryvector-ctor_error-002.phpt b/tests/bson/bson-binaryvector-ctor_error-002.phpt new file mode 100644 index 000000000..c29b429d4 --- /dev/null +++ b/tests/bson/bson-binaryvector-ctor_error-002.phpt @@ -0,0 +1,30 @@ +--TEST-- +MongoDB\BSON\BinaryVector construction errors for VECTOR_TYPE_INT8 +--FILE-- + 1], MongoDB\BSON\BinaryVector::VECTOR_TYPE_INT8); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + new MongoDB\BSON\BinaryVector([1, 2.0], MongoDB\BSON\BinaryVector::VECTOR_TYPE_INT8); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + new MongoDB\BSON\BinaryVector([1, 256], MongoDB\BSON\BinaryVector::VECTOR_TYPE_INT8); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector to be a list +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be an integer, float given +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be a signed 8-bit integer, 256 given +===DONE=== diff --git a/tests/bson/bson-binaryvector-ctor_error-003.phpt b/tests/bson/bson-binaryvector-ctor_error-003.phpt new file mode 100644 index 000000000..06a0d86ab --- /dev/null +++ b/tests/bson/bson-binaryvector-ctor_error-003.phpt @@ -0,0 +1,30 @@ +--TEST-- +MongoDB\BSON\BinaryVector construction errors for VECTOR_TYPE_PACKED_BIT +--FILE-- + 1], MongoDB\BSON\BinaryVector::VECTOR_TYPE_PACKED_BIT); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + new MongoDB\BSON\BinaryVector([true, 1.0], MongoDB\BSON\BinaryVector::VECTOR_TYPE_PACKED_BIT); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + new MongoDB\BSON\BinaryVector([true, 2], MongoDB\BSON\BinaryVector::VECTOR_TYPE_PACKED_BIT); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector to be a list +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be an integer or boolean, float given +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be 0 or 1, 2 given +===DONE=== diff --git a/tests/bson/bson-binaryvector-fromfloat32array-001.phpt b/tests/bson/bson-binaryvector-fromfloat32array-001.phpt new file mode 100644 index 000000000..785a8d51e --- /dev/null +++ b/tests/bson/bson-binaryvector-fromfloat32array-001.phpt @@ -0,0 +1,31 @@ +--TEST-- +MongoDB\BSON\BinaryVector::fromFloat32Array() +--FILE-- + +===DONE=== + +--EXPECTF-- +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(18) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + float(1) + [1]=> + float(-1) + [2]=> + float(0.5) + [3]=> + float(-0.5) + } + ["vectorType"]=> + int(39) +} +===DONE=== diff --git a/tests/bson/bson-binaryvector-fromfloat32array_error-001.phpt b/tests/bson/bson-binaryvector-fromfloat32array_error-001.phpt new file mode 100644 index 000000000..4cfe59635 --- /dev/null +++ b/tests/bson/bson-binaryvector-fromfloat32array_error-001.phpt @@ -0,0 +1,24 @@ +--TEST-- +MongoDB\BSON\BinaryVector::fromFloat32Array() construction errors +--FILE-- + 1.0]); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + MongoDB\BSON\BinaryVector::fromFloat32Array([1.0, 2]); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector to be a list +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be a float, int given +===DONE=== diff --git a/tests/bson/bson-binaryvector-fromint8array-001.phpt b/tests/bson/bson-binaryvector-fromint8array-001.phpt new file mode 100644 index 000000000..e70051d22 --- /dev/null +++ b/tests/bson/bson-binaryvector-fromint8array-001.phpt @@ -0,0 +1,31 @@ +--TEST-- +MongoDB\BSON\BinaryVector::fromInt8Array() +--FILE-- + +===DONE=== + +--EXPECTF-- +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(6) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + ["vectorType"]=> + int(3) +} +===DONE=== diff --git a/tests/bson/bson-binaryvector-fromint8array_error-001.phpt b/tests/bson/bson-binaryvector-fromint8array_error-001.phpt new file mode 100644 index 000000000..9aef08436 --- /dev/null +++ b/tests/bson/bson-binaryvector-fromint8array_error-001.phpt @@ -0,0 +1,30 @@ +--TEST-- +MongoDB\BSON\BinaryVector::fromInt8Array() construction errors +--FILE-- + 1]); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + MongoDB\BSON\BinaryVector::fromInt8Array([1, 2.0]); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + MongoDB\BSON\BinaryVector::fromInt8Array([1, 256]); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector to be a list +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be an integer, float given +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be a signed 8-bit integer, 256 given +===DONE=== diff --git a/tests/bson/bson-binaryvector-frompackedbitarray-001.phpt b/tests/bson/bson-binaryvector-frompackedbitarray-001.phpt new file mode 100644 index 000000000..297b8acb7 --- /dev/null +++ b/tests/bson/bson-binaryvector-frompackedbitarray-001.phpt @@ -0,0 +1,31 @@ +--TEST-- +MongoDB\BSON\BinaryVector::fromPackedBitArray() +--FILE-- + +===DONE=== + +--EXPECTF-- +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(3) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(0) + [2]=> + int(1) + [3]=> + int(0) + } + ["vectorType"]=> + int(16) +} +===DONE=== diff --git a/tests/bson/bson-binaryvector-frompackedbitarray_error-001.phpt b/tests/bson/bson-binaryvector-frompackedbitarray_error-001.phpt new file mode 100644 index 000000000..37a783f38 --- /dev/null +++ b/tests/bson/bson-binaryvector-frompackedbitarray_error-001.phpt @@ -0,0 +1,30 @@ +--TEST-- +MongoDB\BSON\BinaryVector::fromPackedBitArray() construction errors +--FILE-- + 1]); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + MongoDB\BSON\BinaryVector::fromPackedBitArray([true, 1.0]); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + MongoDB\BSON\BinaryVector::fromPackedBitArray([true, 2]); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector to be a list +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be an integer or boolean, float given +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected vector[1] to be 0 or 1, 2 given +===DONE=== diff --git a/tests/bson/bson-binaryvector-gettype-001.phpt b/tests/bson/bson-binaryvector-gettype-001.phpt new file mode 100644 index 000000000..ad38d50e8 --- /dev/null +++ b/tests/bson/bson-binaryvector-gettype-001.phpt @@ -0,0 +1,13 @@ +--TEST-- +MongoDB\BSON\BinaryVector::getVectorType() +--FILE-- +getType()); + +?> +===DONE=== + +--EXPECT-- +int(9) +===DONE=== diff --git a/tests/bson/bson-binaryvector-getvectortype-001.phpt b/tests/bson/bson-binaryvector-getvectortype-001.phpt new file mode 100644 index 000000000..5203260af --- /dev/null +++ b/tests/bson/bson-binaryvector-getvectortype-001.phpt @@ -0,0 +1,17 @@ +--TEST-- +MongoDB\BSON\BinaryVector::getVectorType() +--FILE-- +getVectorType()); +var_dump((new MongoDB\BSON\BinaryVector([1, 2, 3, 4], MongoDB\BSON\BinaryVector::VECTOR_TYPE_INT8))->getVectorType()); +var_dump((new MongoDB\BSON\BinaryVector([1, 0, true, false], MongoDB\BSON\BinaryVector::VECTOR_TYPE_PACKED_BIT))->getVectorType()); + +?> +===DONE=== + +--EXPECT-- +int(39) +int(3) +int(16) +===DONE=== diff --git a/tests/bson/bson-binaryvector-serialization-001.phpt b/tests/bson/bson-binaryvector-serialization-001.phpt new file mode 100644 index 000000000..ba510b09d --- /dev/null +++ b/tests/bson/bson-binaryvector-serialization-001.phpt @@ -0,0 +1,145 @@ +--TEST-- +MongoDB\BSON\BinaryVector serialization (__serialize and __unserialize) +--FILE-- + +===DONE=== + +--EXPECTF-- +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(18) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + float(1) + [1]=> + float(-1) + [2]=> + float(0.5) + [3]=> + float(-0.5) + } + ["vectorType"]=> + int(39) +} +string(89) "O:25:"MongoDB\BSON\BinaryVector":2:{s:4:"data";s:18:"%a";s:4:"type";i:9;}" +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(18) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + float(1) + [1]=> + float(-1) + [2]=> + float(0.5) + [3]=> + float(-0.5) + } + ["vectorType"]=> + int(39) +} + +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(6) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + ["vectorType"]=> + int(3) +} +string(76) "O:25:"MongoDB\BSON\BinaryVector":2:{s:4:"data";s:6:"%a";s:4:"type";i:9;}" +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(6) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + ["vectorType"]=> + int(3) +} + +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(3) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(0) + [2]=> + int(1) + [3]=> + int(0) + } + ["vectorType"]=> + int(16) +} +string(73) "O:25:"MongoDB\BSON\BinaryVector":2:{s:4:"data";s:3:"%a";s:4:"type";i:9;}" +object(MongoDB\BSON\BinaryVector)#%d (%d) { + ["data"]=> + string(3) "%a" + ["type"]=> + int(9) + ["vector"]=> + array(4) { + [0]=> + int(1) + [1]=> + int(0) + [2]=> + int(1) + [3]=> + int(0) + } + ["vectorType"]=> + int(16) +} + +===DONE=== diff --git a/tests/bson/bson-binaryvector-set_state-001.phpt b/tests/bson/bson-binaryvector-set_state-001.phpt new file mode 100644 index 000000000..c6456d6d7 --- /dev/null +++ b/tests/bson/bson-binaryvector-set_state-001.phpt @@ -0,0 +1,21 @@ +--TEST-- +MongoDB\BSON\BinaryVector::__set_state() +--FILE-- + hex2bin('030001020304'), + 'type' => MongoDB\BSON\Binary::TYPE_VECTOR, +])); + +echo "\n"; + +?> +===DONE=== + +--EXPECTF-- +%r\\?%rMongoDB\BSON\BinaryVector::__set_state(array( + 'data' => '%a', + 'type' => 9, +)) +===DONE=== diff --git a/tests/bson/bson-binaryvector-set_state_error-001.phpt b/tests/bson/bson-binaryvector-set_state_error-001.phpt new file mode 100644 index 000000000..3d7a80e45 --- /dev/null +++ b/tests/bson/bson-binaryvector-set_state_error-001.phpt @@ -0,0 +1,18 @@ +--TEST-- +MongoDB\BSON\BinaryVector::__set_state() requires valid vector data +--FILE-- + '', 'type' => MongoDB\BSON\Binary::TYPE_VECTOR]); +}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Binary vector data is invalid +===DONE=== diff --git a/tests/bson/bson-binaryvector-toarray-001.phpt b/tests/bson/bson-binaryvector-toarray-001.phpt new file mode 100644 index 000000000..6e0dc6df3 --- /dev/null +++ b/tests/bson/bson-binaryvector-toarray-001.phpt @@ -0,0 +1,44 @@ +--TEST-- +MongoDB\BSON\BinaryVector::toArray() +--FILE-- +toArray()); +var_dump((new MongoDB\BSON\BinaryVector([1, 2, 3, 4], MongoDB\BSON\BinaryVector::VECTOR_TYPE_INT8))->toArray()); +var_dump((new MongoDB\BSON\BinaryVector([1, 0, true, false], MongoDB\BSON\BinaryVector::VECTOR_TYPE_PACKED_BIT))->toArray()); + +?> +===DONE=== + +--EXPECT-- +array(4) { + [0]=> + float(1) + [1]=> + float(-1) + [2]=> + float(0.5) + [3]=> + float(-0.5) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) +} +array(4) { + [0]=> + int(1) + [1]=> + int(0) + [2]=> + int(1) + [3]=> + int(0) +} +===DONE=== diff --git a/tests/bson/bson-binaryvector_error-001.phpt b/tests/bson/bson-binaryvector_error-001.phpt new file mode 100644 index 000000000..0475399fb --- /dev/null +++ b/tests/bson/bson-binaryvector_error-001.phpt @@ -0,0 +1,36 @@ +--TEST-- +MongoDB\BSON\BinaryVector argument count errors +--SKIPIF-- + +=', '7.99'); ?> +--FILE-- +toArray(2); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() use ($bv) { + $bv->getVectorType(2); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +echo throws(function() { + new MongoDB\BSON\BinaryVector(); +}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n"; + +?> +===DONE=== + +--EXPECTF-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +MongoDB\BSON\BinaryVector::toArray() expects exactly 0 %r(argument|parameter)%rs, 1 given +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +MongoDB\BSON\BinaryVector::getVectorType() expects exactly 0 %r(argument|parameter)%rs, 1 given +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +MongoDB\BSON\BinaryVector::__construct() expects exactly 2 %r(argument|parameter)%rs, 0 given +===DONE=== + diff --git a/tests/bson/bson-binaryvector_error-002.phpt b/tests/bson/bson-binaryvector_error-002.phpt new file mode 100644 index 000000000..980daea98 --- /dev/null +++ b/tests/bson/bson-binaryvector_error-002.phpt @@ -0,0 +1,12 @@ +--TEST-- +MongoDB\BSON\BinaryVector cannot be extended +--FILE-- + +===DONE=== + +--EXPECTF-- +Fatal error: Class MyBinaryVector %s final class %SMongoDB\BSON\BinaryVector%S in %s on line %d