You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2018/10/09 14:47:30 UTC
[15/21] ignite git commit: IGNITE-7783: PHP thin client
http://git-wip-us.apache.org/repos/asf/ignite/blob/f28e4f3f/modules/platforms/php/src/Apache/Ignite/Type/CollectionObjectType.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Type/CollectionObjectType.php b/modules/platforms/php/src/Apache/Ignite/Type/CollectionObjectType.php
new file mode 100644
index 0000000..b9591cb
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Type/CollectionObjectType.php
@@ -0,0 +1,142 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache\Ignite\Type;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Utils\ArgumentChecker;
+use Apache\Ignite\Internal\Binary\BinaryUtils;
+
+/**
+ * Class representing a collection type of Ignite object.
+ *
+ * It is described by ObjectType::COLLECTION and one of @ref CollectionSubType.
+ */
+class CollectionObjectType extends ObjectType
+{
+ /** @name CollectionSubType
+ * @anchor CollectionSubType
+ * @{
+ */
+
+ /**
+ * General set type, which can not be mapped to more specific set type.
+ */
+ const USER_SET = -1;
+
+ /**
+ * General collection type, which can not be mapped to any specific collection type.
+ */
+ const USER_COL = 0;
+
+ /**
+ * Resizeable array type.
+ */
+ const ARRAY_LIST = 1;
+
+ /**
+ * Linked list type.
+ */
+ const LINKED_LIST = 2;
+
+ /**
+ * Basic hash set type.
+ */
+ const HASH_SET = 3;
+
+ /**
+ * Hash set type, which maintains element order.
+ */
+ const LINKED_HASH_SET = 4;
+
+ /**
+ * This is a collection that only contains a single element, but behaves as a collection.
+ */
+ const SINGLETON_LIST = 5;
+
+ /** @} */ // end of CollectionSubType
+
+ private $subType;
+ private $elementType;
+
+ /**
+ * Public constructor.
+ *
+ * Specifies the collection subtype and optionally specifies Ignite type of elements in the collection.
+ *
+ * If Ignite type of elements is not specified then during operations the Ignite client
+ * tries to make automatic mapping between PHP types and Ignite object types -
+ * according to the mapping table defined in the description of the ObjectType class.
+ *
+ * @param int $subType collection subtype, one of @ref CollectionSubType constants.
+ * @param int|ObjectType|null $elementType Ignite type of elements in the collection:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null (or not specified) that means the type is not specified
+ *
+ * @throws ClientException if error.
+ */
+ public function __construct(int $subType, $elementType = null)
+ {
+ parent::__construct(ObjectType::COLLECTION);
+ ArgumentChecker::hasValueFrom(
+ $subType, 'subType', false,
+ [
+ CollectionObjectType::USER_SET,
+ CollectionObjectType::USER_COL,
+ CollectionObjectType::ARRAY_LIST,
+ CollectionObjectType::LINKED_LIST,
+ CollectionObjectType::HASH_SET,
+ CollectionObjectType::LINKED_HASH_SET,
+ CollectionObjectType::SINGLETON_LIST
+ ]);
+ BinaryUtils::checkObjectType($elementType, 'elementType');
+ $this->subType = $subType;
+ $this->elementType = $elementType;
+ }
+
+ /**
+ * Returns collection subtype, one of @ref CollectionSubType constants.
+ *
+ * @return int collection subtype, one of @ref CollectionSubType constants.
+ */
+ public function getSubType(): int
+ {
+ return $this->subType;
+ }
+
+ /**
+ * Returns Ignite type of elements in the collection.
+ *
+ * @return int|ObjectType|null type of elements in the collection:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null that means the type is not specified
+ */
+ public function getElementType()
+ {
+ return $this->elementType;
+ }
+
+ public static function isSet($subType): bool
+ {
+ return $subType === CollectionObjectType::USER_SET ||
+ $subType === CollectionObjectType::HASH_SET ||
+ $subType === CollectionObjectType::LINKED_HASH_SET;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f28e4f3f/modules/platforms/php/src/Apache/Ignite/Type/ComplexObjectType.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Type/ComplexObjectType.php b/modules/platforms/php/src/Apache/Ignite/Type/ComplexObjectType.php
new file mode 100644
index 0000000..b62272e
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Type/ComplexObjectType.php
@@ -0,0 +1,165 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache\Ignite\Type;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Binary\BinaryUtils;
+
+/**
+ * Class representing a complex type of Ignite object.
+ *
+ * It corresponds to the ObjectType::COMPLEX_OBJECT Ignite type code.
+ *
+ * This class may be needed to help Ignite client to:
+ * - deserialize an Ignite complex object to a PHP object when reading data,
+ * - serialize a PHP object to an Ignite complex object when writing data.
+ *
+ * Note: only public properties of PHP objects can be serialized/deserialized.
+ */
+class ComplexObjectType extends ObjectType
+{
+ private $phpClassName;
+ private $typeName;
+ private $fieldTypes;
+
+ /**
+ * Public constructor.
+ *
+ * Creates a default representation of Ignite complex object type.
+ * setPhpClassName(), setIgniteTypeName(), setFieldType() methods may be used
+ * to change the default representation.
+ */
+ public function __construct()
+ {
+ parent::__construct(ObjectType::COMPLEX_OBJECT);
+ $this->phpClassName = null;
+ $this->typeName = null;
+ $this->fieldTypes = [];
+ }
+
+ /**
+ * Sets the name of the PHP class.
+ *
+ * Affects data reading operations only.
+ *
+ * The specified name will be used as PHP class name to instantiate a PHP object
+ * the received Ignite complex object is deserialized to.
+ *
+ * By default (if the name is not specified), the Ignite complex type name of the received complex object
+ * is used as PHP class name to instantiate a PHP object during deserialization.
+ *
+ * The PHP Class must have a constructor without parameters or with optional parameters only.
+ *
+ * @param string|null $phpClassName name of the PHP class or null (the name is not specified).
+ *
+ * @return ComplexObjectType the same instance of the ComplexObjectType.
+ */
+ public function setPhpClassName(?string $phpClassName): ComplexObjectType
+ {
+ $this->phpClassName = $phpClassName;
+ return $this;
+ }
+
+ /**
+ * Gets the name of the PHP class.
+ *
+ * @return string|null name of the PHP class or null (the name is not specified).
+ */
+ public function getPhpClassName(): ?string
+ {
+ return $this->phpClassName;
+ }
+
+ /**
+ * Sets the name of the Ignite complex type.
+ *
+ * Affects data writing operations only.
+ *
+ * The specified name will be used as the Ignite complex type name during the complex object's writing operations.
+ *
+ * By default (if the name is not specified), the Ignite complex type name of the serialized complex object
+ * is taken from the name of the PHP class which instance is provided in a data writing operation.
+ *
+ * @param string|null $typeName name of the Ignite complex type or null (the name is not specified).
+ *
+ * @return ComplexObjectType the same instance of the ComplexObjectType.
+ */
+ public function setIgniteTypeName(?string $typeName): ComplexObjectType
+ {
+ $this->typeName = $typeName;
+ return $this;
+ }
+
+ /**
+ * Gets the name of the Ignite complex type.
+ *
+ * @return string|null name of the Ignite complex type or null (the name is not specified).
+ */
+ public function getIgniteTypeName(): ?string
+ {
+ return $this->typeName;
+ }
+
+ /**
+ * Specifies Ignite type of the indicated field in the complex type.
+ *
+ * Affects data writing operations only.
+ *
+ * During data serialization Ignite client will assume that the indicated field
+ * has the Ignite type specified by this method.
+ *
+ * By default (if the type of the field is not specified),
+ * Ignite client tries to make automatic mapping between PHP types and Ignite object types -
+ * according to the mapping table defined in the description of the ObjectType class.
+ *
+ * @param string $fieldName name of the field.
+ * @param int|ObjectType|null $fieldType Ignite type of the field:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null (or not specified) that means the type is not specified
+ *
+ * @return ComplexObjectType the same instance of the ComplexObjectType.
+ *
+ * @throws ClientException if error.
+ */
+ public function setFieldType(string $fieldName, $fieldType): ComplexObjectType
+ {
+ BinaryUtils::checkObjectType($fieldType, 'fieldType');
+ $this->fieldTypes[$fieldName] = $fieldType;
+ return $this;
+ }
+
+ /**
+ * Gets Ignite type of the indicated field in the complex type.
+ *
+ * @param string $fieldName name of the field.
+ *
+ * @return int|ObjectType|null Ignite type of the field:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null that means the type is not specified
+ */
+ public function getFieldType(string $fieldName)
+ {
+ if (array_key_exists($fieldName, $this->fieldTypes)) {
+ return $this->fieldTypes[$fieldName];
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f28e4f3f/modules/platforms/php/src/Apache/Ignite/Type/MapObjectType.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Type/MapObjectType.php b/modules/platforms/php/src/Apache/Ignite/Type/MapObjectType.php
new file mode 100644
index 0000000..043ae6a
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Type/MapObjectType.php
@@ -0,0 +1,123 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache\Ignite\Type;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Utils\ArgumentChecker;
+use Apache\Ignite\Internal\Binary\BinaryUtils;
+
+/**
+ * Class representing a map type of Ignite object.
+ *
+ * It is described by ObjectType::MAP and one of @ref MapSubType.
+ */
+class MapObjectType extends ObjectType
+{
+ /** @name MapSubType
+ * @anchor MapSubType
+ * @{
+ */
+
+ /**
+ * Basic hash map.
+ */
+ const HASH_MAP = 1;
+
+ /**
+ * Hash map, which maintains element order.
+ */
+ const LINKED_HASH_MAP = 2;
+
+ /** @} */ // end of MapSubType
+
+ private $subType;
+ private $keyType;
+ private $valueType;
+
+ /**
+ * Public constructor.
+ *
+ * Optionally specifies the map subtype and Ignite types of keys and values in the map.
+ *
+ * If the map subtype is not specified, MapObjectType::HASH_MAP is assumed.
+ *
+ * If Ignite type is not specified for the key and/or value then during operations the Ignite client
+ * tries to make automatic mapping between PHP types and Ignite object types -
+ * according to the mapping table defined in the description of the ObjectType class.
+ *
+ * @param int $subType map subtype, one of @ref MapSubType constants.
+ * @param int|ObjectType|null $keyType Ignite type of the keys in the map:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null (or not specified) that means the type is not specified
+ * @param int|ObjectType|null $valueType Ignite type of the values in the map:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null (or not specified) that means the type is not specified
+ *
+ * @throws ClientException if error.
+ */
+ public function __construct(int $subType = MapObjectType::HASH_MAP, $keyType = null, $valueType = null)
+ {
+ parent::__construct(ObjectType::MAP);
+ ArgumentChecker::hasValueFrom(
+ $subType, 'subType', false, [MapObjectType::HASH_MAP, MapObjectType::LINKED_HASH_MAP]);
+ BinaryUtils::checkObjectType($keyType, 'keyType');
+ BinaryUtils::checkObjectType($valueType, 'valueType');
+ $this->subType = $subType;
+ $this->keyType = $keyType;
+ $this->valueType = $valueType;
+ }
+
+ /**
+ * Returns the map subtype, one of @ref MapSubType constants.
+ *
+ * @return int map subtype, one of @ref MapSubType constants.
+ */
+ public function getSubType(): int
+ {
+ return $this->subType;
+ }
+
+ /**
+ * Returns Ignite type of the keys in the map.
+ *
+ * @return int|ObjectType|null type of the keys in the map:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null that means the type is not specified
+ */
+ public function getKeyType()
+ {
+ return $this->keyType;
+ }
+
+ /**
+ * Returns Ignite type of the values in the map.
+ *
+ * @return int|ObjectType|null type of the values in the map:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null that means the type is not specified
+ */
+ public function getValueType()
+ {
+ return $this->valueType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f28e4f3f/modules/platforms/php/src/Apache/Ignite/Type/ObjectArrayType.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Type/ObjectArrayType.php b/modules/platforms/php/src/Apache/Ignite/Type/ObjectArrayType.php
new file mode 100644
index 0000000..89c8eca
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Type/ObjectArrayType.php
@@ -0,0 +1,68 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache\Ignite\Type;
+
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Internal\Binary\BinaryUtils;
+
+/**
+ * Class representing an array type of Ignite objects.
+ *
+ * It is described by ObjectType::OBJECT_ARRAY.
+ */
+class ObjectArrayType extends ObjectType
+{
+ private $elementType;
+
+ /**
+ * Public constructor.
+ *
+ * Optionally specifies Ignite type of elements in the array.
+ *
+ * If Ignite type of elements is not specified then during operations the Ignite client
+ * tries to make automatic mapping between PHP types and Ignite object types -
+ * according to the mapping table defined in the description of the ObjectType class.
+ *
+ * @param int|ObjectType|null $elementType Ignite type of the array element:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null (or not specified) that means the type is not specified
+ *
+ * @throws ClientException if error.
+ */
+ public function __construct($elementType = null)
+ {
+ parent::__construct(ObjectType::OBJECT_ARRAY);
+ BinaryUtils::checkObjectType($elementType, 'elementType');
+ $this->elementType = $elementType;
+ }
+
+ /**
+ * Returns Ignite type of the array element.
+ *
+ * @return int|ObjectType|null Ignite type of the array element:
+ * - either a type code of primitive (simple) type (@ref PrimitiveTypeCodes)
+ * - or an instance of class representing non-primitive (composite) type
+ * - or null that means the type is not specified
+ */
+ public function getElementType()
+ {
+ return $this->elementType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f28e4f3f/modules/platforms/php/src/Apache/Ignite/Type/ObjectType.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/src/Apache/Ignite/Type/ObjectType.php b/modules/platforms/php/src/Apache/Ignite/Type/ObjectType.php
new file mode 100644
index 0000000..c91d120
--- /dev/null
+++ b/modules/platforms/php/src/Apache/Ignite/Type/ObjectType.php
@@ -0,0 +1,442 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache\Ignite\Type;
+
+/**
+ * Base class representing a type of Ignite object.
+ *
+ * The class is abstract and has no public constructor. Only subclasses may be instantiated.
+ *
+ * There are two groups of Ignite object types:
+ *
+ * - Primitive (simple) types. To fully describe such a type:
+ * it is enough to specify Ignite type code @ref PrimitiveTypeCodes only.
+ *
+ * - Non-primitive (composite) types. To fully describe such a type:
+ * Ignite type code @ref CompositeTypeCodes with additional information
+ * (eg. a kind of map or a kind of collection) should be specified.
+ *
+ * This class helps the Ignite client to make a mapping between PHP types
+ * and types used by Ignite according to the following mapping tables:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * COMMENTS TO ALL TABLES
+ * ----------------
+ *
+ * PHP type
+ * ----------------
+ * It is a PHP primitive or a PHP object: http://php.net/manual/en/language.types.intro.php
+ *
+ * Associative and indexed PHP arrays: http://php.net/manual/en/language.types.array.php
+ *
+ * Additional types:
+ * - Ds\\Set, Ds\\Map - PHP Data Structures extension classes: http://php.net/manual/en/book.ds.php
+ * - Brick\\Math\\BigDecimal - PHP class from the extension library
+ * to work with arbitrary precision numbers: https://github.com/brick/math
+ * - Date, Time, Timestamp, EnumItem, BinaryObject - PHP classes introduced by the Ignite client.
+ *
+ * Ignite type code
+ * ----------------
+ * It is a type code of Ignite primitive type (@ref PrimitiveTypeCodes)
+ * or Ignite composite type (@ref CompositeTypeCodes).
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * MAPPING FROM IGNITE TYPE CODE TO PHP TYPE WHEN READING DATA
+ * ----------------
+ *
+ * | Ignite type code | PHP type |
+ * | ---------------------------- | ----------------------------------------------|
+ * | BYTE | integer |
+ * | SHORT | integer |
+ * | INTEGER | integer |
+ * | LONG | float |
+ * | FLOAT | float |
+ * | DOUBLE | float |
+ * | DECIMAL | Brick\\Math\\BigDecimal |
+ * | BOOLEAN | boolean |
+ * | STRING | string |
+ * | CHAR | string (one character) |
+ * | UUID | indexed array of integers (16 items) |
+ * | DATE | Date |
+ * | TIME | Time |
+ * | TIMESTAMP | Timestamp |
+ * | ENUM | EnumItem |
+ * | COMPLEX_OBJECT | BinaryObject or PHP object* |
+ * | BYTE_ARRAY | indexed array of integer |
+ * | SHORT_ARRAY | indexed array of integer |
+ * | INTEGER_ARRAY | indexed array of integer |
+ * | LONG_ARRAY | indexed array of float |
+ * | FLOAT_ARRAY | indexed array of float |
+ * | DOUBLE_ARRAY | indexed array of float |
+ * | DECIMAL_ARRAY | indexed array of Brick\\Math\\BigDecimal |
+ * | BOOLEAN_ARRAY | indexed array of boolean |
+ * | STRING_ARRAY | indexed array of string |
+ * | CHAR_ARRAY | indexed array of string (one character) |
+ * | UUID_ARRAY | indexed array of array of integers (16 items) |
+ * | DATE_ARRAY | indexed array of Date |
+ * | TIME_ARRAY | indexed array of Time |
+ * | TIMESTAMP_ARRAY | indexed array of Timestamp |
+ * | ENUM_ARRAY | indexed array of EnumItem |
+ * | OBJECT_ARRAY | indexed array |
+ * | COLLECTION (USER_COL) | indexed array |
+ * | COLLECTION (ARR_LIST) | indexed array |
+ * | COLLECTION (LINKED_LIST) | indexed array |
+ * | COLLECTION (SINGLETON_LIST) | indexed array |
+ * | COLLECTION (HASH_SET) | Ds\\Set |
+ * | COLLECTION (LINKED_HASH_SET) | Ds\\Set |
+ * | COLLECTION (USER_SET) | Ds\\Set |
+ * | MAP (HASH_MAP) | Ds\\Map |
+ * | MAP (LINKED_HASH_MAP) | Ds\\Map |
+ * | NULL | null** |
+ *
+ * (*) If an application does not explicitly specify an Ignite type for a field and
+ * COMPLEX_OBJECT is received, the Ignite client returns BinaryObject to the application.
+ * If an application explicitly specifies ComplexObjectType for a field,
+ * the Ignite client deserializes the received COMPLEX_OBJECT into PHP object
+ * specified by the ComplexObjectType.
+ *
+ * (**) NULL cannot be specified as an Ignite type of a field but PHP null may be returned
+ * as a value of a field.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * DEFAULT MAPPING FROM PHP TYPE TO IGNITE TYPE CODE WHEN WRITING DATA
+ * ----------------
+ *
+ * This mapping is used when an application does not explicitly specify an Ignite type
+ * for a field and it is writing data to that field.
+ *
+ * | PHP type | Ignite type code |
+ * | ------------------------------------------- | ----------------------|
+ * | boolean | BOOLEAN |
+ * | integer | INTEGER |
+ * | float | DOUBLE |
+ * | string | STRING |
+ * | Date | DATE |
+ * | Time | TIME |
+ * | Timestamp | TIMESTAMP |
+ * | EnumItem | ENUM |
+ * | Brick\\Math\\BigDecimal | DECIMAL |
+ * | BinaryObject | COMPLEX_OBJECT |
+ * | any other PHP Object* | COMPLEX_OBJECT |
+ * | associative array of PHP supported type** | MAP (HASH_MAP) |
+ * | indexed array of boolean*** | BOOLEAN_ARRAY |
+ * | indexed array of integer | INTEGER_ARRAY |
+ * | indexed array of float | DOUBLE_ARRAY |
+ * | indexed array of string | STRING_ARRAY |
+ * | indexed array of Date | DATE_ARRAY |
+ * | indexed array of Time | TIME_ARRAY |
+ * | indexed array of Timestamp | TIMESTAMP_ARRAY |
+ * | indexed array of EnumItem | ENUM_ARRAY |
+ * | indexed array of Brick\\Math\\BigDecimal | DECIMAL_ARRAY |
+ * | indexed array of BinaryObject | OBJECT_ARRAY |
+ * | indexed array of any other PHP Object* | OBJECT_ARRAY |
+ * | Ds\\Set | COLLECTION (HASH_SET) |
+ * | Ds\\Map | MAP (HASH_MAP) |
+ *
+ * All other PHP types have no default mapping to Ignite type codes.
+ *
+ * (*) Any other PHP Object - is any PHP class, not explicitly mentioned in the table.
+ *
+ * (**) PHP supported type - is any PHP type mentioned in the table.
+ *
+ * (***) Type of an indexed array's value is determined by the value's type in the first element of the array.
+ * Empty array has no default mapping.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * ALLOWED PHP TYPES WHEN WRITING DATA OF THE SPECIFIED IGNITE TYPE CODE
+ * ----------------
+ *
+ * When an application explicitly specifies an Ignite type for a field
+ * and it is writing data to that field, the following PHP types
+ * are allowed for every concrete Ignite type code.
+ *
+ * | Specified Ignite type code | Allowed PHP types |
+ * | ---------------------------- | ----------------------------------------------|
+ * | BYTE | integer |
+ * | SHORT | integer |
+ * | INTEGER | integer |
+ * | LONG | float, integer |
+ * | FLOAT | float, integer |
+ * | DOUBLE | float, integer |
+ * | DECIMAL | Brick\\Math\\BigDecimal |
+ * | BOOLEAN | boolean |
+ * | STRING | string |
+ * | CHAR | string (one character) |
+ * | UUID | indexed array of integers (16 items) |
+ * | DATE | Date |
+ * | TIME | Time |
+ * | TIMESTAMP | Timestamp |
+ * | ENUM | EnumItem |
+ * | COMPLEX_OBJECT | BinaryObject, any PHP object |
+ * | BYTE_ARRAY* | indexed array of integer |
+ * | SHORT_ARRAY | indexed array of integer |
+ * | INTEGER_ARRAY | indexed array of integer |
+ * | LONG_ARRAY | indexed array of float/integer |
+ * | FLOAT_ARRAY | indexed array of float/integer |
+ * | DOUBLE_ARRAY | indexed array of float/integer |
+ * | DECIMAL_ARRAY | indexed array of Brick\\Math\\BigDecimal |
+ * | BOOLEAN_ARRAY | indexed array of boolean |
+ * | STRING_ARRAY | indexed array of string |
+ * | CHAR_ARRAY | indexed array of string (one character) |
+ * | UUID_ARRAY | indexed array of array of integers (16 items) |
+ * | DATE_ARRAY | indexed array of Date |
+ * | TIME_ARRAY | indexed array of Time |
+ * | TIMESTAMP_ARRAY | indexed array of Timestamp |
+ * | ENUM_ARRAY | indexed array of EnumItem |
+ * | OBJECT_ARRAY | indexed array |
+ * | COLLECTION (USER_COL) | indexed array |
+ * | COLLECTION (ARR_LIST) | indexed array |
+ * | COLLECTION (LINKED_LIST) | indexed array |
+ * | COLLECTION (SINGLETON_LIST) | indexed array |
+ * | COLLECTION (HASH_SET) | Ds\\Set |
+ * | COLLECTION (LINKED_HASH_SET) | Ds\\Set |
+ * | COLLECTION (USER_SET) | Ds\\Set |
+ * | MAP (HASH_MAP) | Ds\\Map, associative array |
+ * | MAP (LINKED_HASH_MAP) | Ds\\Map, associative array |
+ *
+ * (*) For all *_ARRAY Ignite types an empty PHP indexed array is allowed.
+ *
+ * PHP null is allowed as value of a field (but not as a key/value in a cache)
+ * or as a value of Array/Set/Map element for all Ignite types,
+ * except BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, CHAR, BOOLEAN.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ */
+abstract class ObjectType
+{
+ /** @name PrimitiveTypeCodes
+ * @anchor PrimitiveTypeCodes
+ * @{
+ */
+
+ /**
+ * Single byte value. Can also represent small signed integer value.
+ */
+ const BYTE = 1;
+
+ /**
+ * 2-bytes long signed integer number.
+ */
+ const SHORT = 2;
+
+ /**
+ * 4-bytes long signed integer number.
+ */
+ const INTEGER = 3;
+
+ /**
+ * 8-bytes long signed integer number.
+ */
+ const LONG = 4;
+
+ /**
+ * 4-byte long floating-point number.
+ */
+ const FLOAT = 5;
+
+ /**
+ * 8-byte long floating-point number.
+ */
+ const DOUBLE = 6;
+
+ /**
+ * Single UTF-16 code unit.
+ */
+ const CHAR = 7;
+
+ /**
+ * Boolean value.
+ */
+ const BOOLEAN = 8;
+
+ /**
+ * String in UTF-8 encoding.
+ */
+ const STRING = 9;
+
+ /**
+ * A universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems.
+ */
+ const UUID = 10;
+
+ /**
+ * Date, represented as a number of milliseconds elapsed since 00:00:00 1 Jan 1970 UTC.
+ */
+ const DATE = 11;
+
+ /**
+ * Array of bytes.
+ */
+ const BYTE_ARRAY = 12;
+
+ /**
+ * Array of short signed integer numbers.
+ */
+ const SHORT_ARRAY = 13;
+
+ /**
+ * Array of signed integer numbers.
+ */
+ const INTEGER_ARRAY = 14;
+
+ /**
+ * Array of long signed integer numbers.
+ */
+ const LONG_ARRAY = 15;
+
+ /**
+ * Array of floating point numbers.
+ */
+ const FLOAT_ARRAY = 16;
+
+ /**
+ * Array of floating point numbers with double precision.
+ */
+ const DOUBLE_ARRAY = 17;
+
+ /**
+ * Array of UTF-16 code units.
+ */
+ const CHAR_ARRAY = 18;
+
+ /**
+ * Array of boolean values.
+ */
+ const BOOLEAN_ARRAY = 19;
+
+ /**
+ * Array of UTF-8 string values.
+ */
+ const STRING_ARRAY = 20;
+
+ /**
+ * Array of UUIDs.
+ */
+ const UUID_ARRAY = 21;
+
+ /**
+ * Array of dates.
+ */
+ const DATE_ARRAY = 22;
+
+ /**
+ * Value of an enumerable type. For such types defined only a finite number of named values.
+ */
+ const ENUM = 28;
+
+ /**
+ * Array of enumerable type value.
+ */
+ const ENUM_ARRAY = 29;
+
+ /**
+ * Numeric value of any desired precision and scale.
+ */
+ const DECIMAL = 30;
+
+ /**
+ * Array of decimal values.
+ */
+ const DECIMAL_ARRAY = 31;
+
+ /**
+ * More precise than a Date data type. Except for a milliseconds since epoch, contains a nanoseconds
+ * fraction of a last millisecond, which value could be in a range from 0 to 999999.
+ */
+ const TIMESTAMP = 33;
+
+ /**
+ * Array of timestamp values.
+ */
+ const TIMESTAMP_ARRAY = 34;
+
+ /**
+ * Time, represented as a number of milliseconds elapsed since midnight, i.e. 00:00:00 UTC.
+ */
+ const TIME = 36;
+
+ /**
+ * Array of time values.
+ */
+ const TIME_ARRAY = 37;
+ /** @} */ // end of PrimitiveTypeCodes
+
+ /** @name CompositeTypeCodes
+ * @anchor CompositeTypeCodes
+ * @{
+ */
+ /**
+ * Array of objects of any type.
+ */
+ const OBJECT_ARRAY = 23;
+
+ /**
+ * General collection type.
+ */
+ const COLLECTION = 24;
+
+ /**
+ * Map-like collection type. Contains pairs of key and value objects.
+ */
+ const MAP = 25;
+
+ /**
+ * Wrapped binary object type.
+ */
+ const BINARY_OBJECT = 27;
+
+ /**
+ * Wrapped enumerable type.
+ */
+ const BINARY_ENUM = 38;
+
+ /**
+ * null value.
+ */
+ const NULL = 101;
+
+ /**
+ * Complex object.
+ */
+ const COMPLEX_OBJECT = 103;
+ /** @} */ // end of CompositeTypeCodes
+
+ private $typeCode;
+
+ /**
+ * Gets Ignite type code of this Ignite object type.
+ *
+ * @return int Ignite type code
+ */
+ public function getTypeCode(): int
+ {
+ return $this->typeCode;
+ }
+
+ //The class is abstract and has no public constructor. Only subclasses may be instantiated.
+ protected function __construct(int $typeCode)
+ {
+ $this->typeCode = $typeCode;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f28e4f3f/modules/platforms/php/tests/BinaryObjectTest.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/tests/BinaryObjectTest.php b/modules/platforms/php/tests/BinaryObjectTest.php
new file mode 100644
index 0000000..c5ca517
--- /dev/null
+++ b/modules/platforms/php/tests/BinaryObjectTest.php
@@ -0,0 +1,196 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache\Ignite\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Data\BinaryObject;
+use Apache\Ignite\Data\Date;
+
+final class BinaryObjectTestCase extends TestCase
+{
+ const CACHE_NAME = '__php_test_cache';
+
+ const TYPE_NAME = 'TestClass';
+ const INNER_TYPE_NAME = 'InnerTestClass';
+ const STRING_VALUE = 'abc';
+ const DOUBLE_VALUE = 123.45;
+ const BOOL_VALUE = false;
+ const INT_VALUE = 456;
+
+ private static $cache;
+
+ public static function setUpBeforeClass(): void
+ {
+ TestingHelper::init();
+ self::cleanUp();
+ self::$cache = TestingHelper::$client->getOrCreateCache(self::CACHE_NAME);
+ }
+
+ public static function tearDownAfterClass(): void
+ {
+ self::cleanUp();
+ TestingHelper::cleanUp();
+ }
+
+ public function testBinaryObjectSetGetFields(): void
+ {
+ $cache = self::$cache;
+ try {
+ $obj1 = new BinaryObject(self::TYPE_NAME);
+ $obj1->setField('field_double', self::DOUBLE_VALUE);
+ $obj1->setField('field_string', self::STRING_VALUE);
+
+ $cache->put(2, $obj1);
+ $cache->put(3, $obj1);
+ $obj2 = $cache->get(2);
+ $this->assertTrue(TestingHelper::compare($obj1, $obj2));
+
+ $obj2->setField('field_double', $obj1->getField('field_double'));
+ $obj2->setField('field_string', $obj1->getField('field_string'));
+ $this->assertTrue(TestingHelper::compare($obj1, $obj2));
+
+ $obj3 = $cache->get(3);
+ $obj1->setField('field_double', $obj3->getField('field_double'));
+ $obj1->setField('field_string', $obj3->getField('field_string'));
+ $this->assertTrue(TestingHelper::compare($obj1, $obj3));
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testBinaryObjectGetNonexistentField(): void
+ {
+ $cache = self::$cache;
+ try {
+ $obj1 = new BinaryObject(self::TYPE_NAME);
+ $obj1->setField('field_double', self::DOUBLE_VALUE);
+ $obj1->setField('field_string', self::STRING_VALUE);
+
+ $this->expectException(ClientException::class);
+ $obj1->getField('field_bool');
+
+ $cache->put(2, $obj1);
+ $obj2 = $cache->get(2);
+ $obj2->getField('field_bool');
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testBinaryObjectRemoveField(): void
+ {
+ $cache = self::$cache;
+ try {
+ $obj1 = new BinaryObject(self::TYPE_NAME);
+ $obj1->setField('field_double', self::DOUBLE_VALUE);
+ $obj1->setField('field_string', self::STRING_VALUE);
+ $obj1->setField('field_bool', self::BOOL_VALUE);
+ $this->assertTrue($obj1->hasField('field_bool'));
+ $this->assertEquals($obj1->getField('field_bool'), self::BOOL_VALUE);
+
+ $obj1->removeField('field_bool');
+ $this->assertFalse($obj1->hasField('field_bool'));
+
+ $cache->put(3, $obj1);
+ $obj2 = $cache->get(3);
+ $this->assertTrue(TestingHelper::compare($obj1, $obj2));
+
+ $obj2->setField('field_bool', self::BOOL_VALUE);
+ $this->assertTrue($obj2->hasField('field_bool'));
+ $this->assertEquals($obj2->getField('field_bool'), self::BOOL_VALUE);
+
+ $obj2->removeField('field_bool');
+ $this->assertFalse($obj2->hasField('field_bool'));
+
+ $obj2->setField('field_bool', self::BOOL_VALUE);
+ $cache->put(4, $obj2);
+
+ $obj1->setField('field_bool', self::BOOL_VALUE);
+ $cache->put(5, $obj1);
+
+ $this->assertTrue(TestingHelper::compare($cache->get(4), $cache->get(5)));
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testBinaryObjectOfDifferentSchemas(): void
+ {
+ $cache = self::$cache;
+ try {
+ $obj1 = new BinaryObject(self::TYPE_NAME);
+ $obj1->setField('field_int', self::INT_VALUE);
+ $obj1->setField('field_string', self::STRING_VALUE);
+ $obj1->setField('field_bool', self::BOOL_VALUE);
+ $cache->put(1, $obj1);
+
+ $obj2 = new BinaryObject(self::TYPE_NAME);
+ $obj2->setField('field_int', self::INT_VALUE);
+ $obj2->setField('field_bool', self::BOOL_VALUE);
+ $obj2->setField('field_date', new Date(12345));
+ $cache->put(2, $obj2);
+
+ $obj3 = $cache->get(1);
+ $obj3->removeField('field_string');
+ $obj4 = $cache->get(2);
+ $obj4->removeField('field_date');
+ $this->assertTrue(TestingHelper::compare($obj3, $obj4));
+
+ $cache->put(3, $obj3);
+ $cache->put(4, $obj4);
+ $this->assertTrue(TestingHelper::compare($cache->get(3), $cache->get(4)));
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testNestedBinaryObjects(): void
+ {
+ $cache = self::$cache;
+ try {
+ $obj2 = new BinaryObject(self::INNER_TYPE_NAME);
+ $obj2->setField('field_int', self::INT_VALUE);
+ $obj2->setField('field_date', new Date(1234567));
+
+ $obj1 = new BinaryObject(self::TYPE_NAME);
+ $obj1->setField('field_double', self::DOUBLE_VALUE);
+ $obj1->setField('field_string', self::STRING_VALUE);
+ $obj1->setField('field_object', $obj2);
+
+ $cache->put(1, $obj1);
+ $obj3 = $cache->get(1);
+ $obj4 = $obj3->getField('field_object');
+ $obj4->setField('field_int', $obj4->getField('field_int') + 1);
+ $obj3->setField('field_object', $obj4);
+ $cache->put(3, $obj3);
+
+ $obj2->setField('field_int', self::INT_VALUE + 1);
+ $obj1->setField('field_object', $obj2);
+ $this->assertTrue(TestingHelper::compare($cache->get(3), $obj1));
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ private static function cleanUp(): void
+ {
+ TestingHelper::destroyCache(self::CACHE_NAME);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f28e4f3f/modules/platforms/php/tests/CacheKeyValueOpsTest.php
----------------------------------------------------------------------
diff --git a/modules/platforms/php/tests/CacheKeyValueOpsTest.php b/modules/platforms/php/tests/CacheKeyValueOpsTest.php
new file mode 100644
index 0000000..b7e1dea
--- /dev/null
+++ b/modules/platforms/php/tests/CacheKeyValueOpsTest.php
@@ -0,0 +1,763 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache\Ignite\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Apache\Ignite\Exception\ClientException;
+use Apache\Ignite\Cache\CacheEntry;
+use Apache\Ignite\Cache\CacheConfiguration;
+use Apache\Ignite\Cache\CacheInterface;
+
+final class CacheKeyValueOpsTestCase extends TestCase
+{
+ const CACHE_NAME = '__php_test_cache';
+
+ public static function setUpBeforeClass(): void
+ {
+ TestingHelper::init();
+ self::cleanUp();
+ TestingHelper::$client->getOrCreateCache(self::CACHE_NAME);
+ }
+
+ public static function tearDownAfterClass(): void
+ {
+ self::cleanUp();
+ TestingHelper::cleanUp();
+ }
+
+ public function testCacheGet(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $value = $cache->get(1);
+ $this->assertEquals($value, null);
+ $cache->put(1, 2);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 2);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function cacheWrongKeys(): array
+ {
+ return array(
+ array(null)
+ );
+ }
+
+ /**
+ * @dataProvider cacheWrongKeys
+ */
+ public function testCacheGetWrongArgs($cacheKey): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->get($cacheKey);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheGetAll(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ for ($i = 0; $i < 5; $i++) {
+ $cache->put($i, $i * 2);
+ }
+ $entries = $cache->getAll([3, 4, 5, 6, 7]);
+ $this->assertCount(2, $entries);
+ foreach ($entries as $entry) {
+ $this->assertTrue($entry->getKey() === 3 || $entry->getKey() === 4);
+ $this->assertEquals($entry->getValue(), $entry->getKey() * 2);
+ }
+ $entries = $cache->getAll([6, 7, 8]);
+ $this->assertCount(0, $entries);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function cacheGetAllWrongKeys(): array
+ {
+ return array(
+ array([])
+ );
+ }
+
+ /**
+ * @dataProvider cacheGetAllWrongKeys
+ */
+ public function testCacheGetAllWrongArgs($keys): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->getAll($keys);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCachePut(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $value = $cache->get(1);
+ $this->assertEquals($value, null);
+ $cache->put(1, 2);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 2);
+ $cache->put(1, 4);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 4);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function cacheWrongKeyValues(): array
+ {
+ return array(
+ array(null, 1),
+ array(1, null),
+ array(null, null)
+ );
+ }
+
+ /**
+ * @dataProvider cacheWrongKeyValues
+ */
+ public function testCachePutWrongArgs($key, $value): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->put($key, $value);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCachePutAll(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $cacheEntries = array();
+ for ($i = 0; $i < 5; $i++) {
+ array_push($cacheEntries, new CacheEntry($i, $i * 2));
+ }
+ $cache->putAll($cacheEntries);
+ $entries = $cache->getAll([3, 4, 5, 6, 7]);
+ $this->assertCount(2, $entries);
+ foreach ($entries as $entry) {
+ $this->assertTrue($entry->getKey() === 3 || $entry->getKey() === 4);
+ $this->assertEquals($entry->getValue(), $entry->getKey() * 2);
+ }
+ $entries = $cache->getAll([-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]);
+ $this->assertCount(5, $entries);
+ foreach ($entries as $entry) {
+ $this->assertTrue($entry->getKey() >= 0 && $entry->getKey() <= 4);
+ $this->assertEquals($entry->getValue(), $entry->getKey() * 2);
+ }
+ $entries = $cache->getAll([6, 7, 8]);
+ $this->assertCount(0, $entries);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function cachePutAllWrongArgs(): array
+ {
+ return array(
+ array([]),
+ array([new CacheConfiguration])
+ );
+ }
+
+ /**
+ * @dataProvider cachePutAllWrongArgs
+ */
+ public function testCachePutAllWrongArgs($entries): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->putAll($entries);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testContainsKey(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $result = $cache->containsKey(1);
+ $this->assertFalse($result);
+ $cache->put(1, 2);
+ $result = $cache->containsKey(1);
+ $this->assertTrue($result);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeys
+ */
+ public function testContainsKeyWrongArgs($cacheKey): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->containsKey($cacheKey);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheContainsKeys(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $result = $cache->containsKeys([1, 2, 3]);
+ $this->assertFalse($result);
+ $cache->putAll([new CacheEntry(1, 2), new CacheEntry(2, 4)]);
+ $result = $cache->containsKeys([1, 2, 3]);
+ $this->assertFalse($result);
+ $cache->put(3, 6);
+ $result = $cache->containsKeys([1, 2, 3]);
+ $this->assertTrue($result);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheGetAllWrongKeys
+ */
+ public function testCacheContainsKeysWrongArgs($keys): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->containsKeys($keys);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheGetAndPut(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $value = $cache->getAndPut(1, 2);
+ $this->assertEquals($value, null);
+ $value = $cache->getAndPut(1, 4);
+ $this->assertEquals($value, 2);
+ $cache->put(1, 6);
+ $value = $cache->getAndPut(1, 8);
+ $this->assertEquals($value, 6);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 8);
+
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeyValues
+ */
+ public function testCacheGetAndPutWrongArgs($key, $value): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->getAndPut($key, $value);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheGetAndReplace(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $value = $cache->getAndReplace(1, 2);
+ $this->assertEquals($value, null);
+ $cache->put(1, 4);
+ $value = $cache->getAndReplace(1, 6);
+ $this->assertEquals($value, 4);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 6);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeyValues
+ */
+ public function testCacheGetAndReplaceWrongArgs($key, $value): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->getAndReplace($key, $value);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheGetAndRemove(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $value = $cache->getAndRemove(1);
+ $this->assertEquals($value, null);
+ $cache->put(1, 2);
+ $value = $cache->getAndRemove(1);
+ $this->assertEquals($value, 2);
+ $value = $cache->get(1);
+ $this->assertEquals($value, null);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeys
+ */
+ public function testCacheGetAndRemoveWrongArgs($cacheKey): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->getAndRemove($cacheKey);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCachePutIfAbsent(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $result = $cache->putIfAbsent(1, 2);
+ $this->assertTrue($result);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 2);
+ $result = $cache->putIfAbsent(1, 4);
+ $this->assertFalse($result);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 2);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeyValues
+ */
+ public function testCachePutIfAbsentWrongArgs($key, $value): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->putIfAbsent($key, $value);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheGetAndPutIfAbsent(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $value = $cache->getAndPutIfAbsent(1, 2);
+ $this->assertEquals($value, null);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 2);
+ $value = $cache->getAndPutIfAbsent(1, 4);
+ $this->assertEquals($value, 2);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 2);
+
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeyValues
+ */
+ public function testCacheGetAndPutIfAbsentWrongArgs($key, $value): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->getAndPutIfAbsent($key, $value);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheReplace(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $result = $cache->replace(1, 2);
+ $this->assertFalse($result);
+ $value = $cache->get(1);
+ $this->assertEquals($value, null);
+ $cache->put(1, 1);
+ $result = $cache->replace(1, 4);
+ $this->assertTrue($result);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 4);
+
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeyValues
+ */
+ public function testCacheReplaceWrongArgs($key, $value): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->replace($key, $value);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheReplaceIfEquals(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $result = $cache->replaceIfEquals(1, 2, 3);
+ $this->assertFalse($result);
+ $cache->put(1, 4);
+ $result = $cache->replaceIfEquals(1, 2, 3);
+ $this->assertFalse($result);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 4);
+ $result = $cache->replaceIfEquals(1, 4, 3);
+ $this->assertTrue($result);
+ $value = $cache->get(1);
+ $this->assertEquals($value, 3);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function cacheWrongReplaceIfEqualsArgs(): array
+ {
+ return array(
+ array(null, 1, 1),
+ array(null, 1, null),
+ array(1, null, 1),
+ array(1, null, null),
+ array(null, null, null)
+ );
+ }
+
+ /**
+ * @dataProvider cacheWrongReplaceIfEqualsArgs
+ */
+ public function testCacheReplaceIfEqualsWrongArgs($key, $value, $newValue): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->replaceIfEquals($key, $value, $newValue);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheClear(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $cache->clear();
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $cache->putAll([new CacheEntry(1, 2), new CacheEntry(2, 4), new CacheEntry(3, 6)]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 3);
+ $cache->clear();
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $entries = $cache->getAll([1, 2, 3]);
+ $this->assertCount(0, $entries);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheClearKeys(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $cache->clearKeys([1, 2, 3]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $cache->putAll([new CacheEntry(1, 2), new CacheEntry(2, 4), new CacheEntry(3, 6)]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 3);
+ $cache->clearKeys([1, 2, 7, 8]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 1);
+ $value = $cache->get(3);
+ $this->assertEquals($value, 6);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheGetAllWrongKeys
+ */
+ public function testCacheClearKeysWrongArgs($keys): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->clearKeys($keys);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheClearKey(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $cache->clearKey(1);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $cache->putAll([new CacheEntry(1, 2), new CacheEntry(2, 4), new CacheEntry(3, 6)]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 3);
+ $cache->clearKey(1);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 2);
+ $value = $cache->get(2);
+ $this->assertEquals($value, 4);
+ $value = $cache->get(3);
+ $this->assertEquals($value, 6);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeys
+ */
+ public function testCacheClearKeyWrongArgs($cacheKey): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->clearKey($cacheKey);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheRemoveKey(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $result = $cache->removeKey(1);
+ $this->assertFalse($result);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $cache->putAll([new CacheEntry(1, 2), new CacheEntry(2, 4), new CacheEntry(3, 6)]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 3);
+ $result = $cache->removeKey(1);
+ $this->assertTrue($result);
+ $result = $cache->removeKey(1);
+ $this->assertFalse($result);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 2);
+ $value = $cache->get(2);
+ $this->assertEquals($value, 4);
+ $value = $cache->get(3);
+ $this->assertEquals($value, 6);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeys
+ */
+ public function testCacheRemoveKeyWrongArgs($cacheKey): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->removeKey($cacheKey);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testRemoveIfEquals(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $result = $cache->removeIfEquals(1, 2);
+ $this->assertFalse($result);
+ $cache->put(1, 4);
+ $result = $cache->removeIfEquals(1, 2);
+ $this->assertFalse($result);
+ $result = $cache->removeIfEquals(1, 4);
+ $this->assertTrue($result);
+ $value = $cache->get(1);
+ $this->assertEquals($value, null);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheWrongKeyValues
+ */
+ public function testRemoveIfEqualsWrongArgs($key, $value): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->removeIfEquals($key, $value);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheRemoveKeys(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $cache->removeKeys([1, 2, 3]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $cache->putAll([new CacheEntry(1, 2), new CacheEntry(2, 4), new CacheEntry(3, 6)]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 3);
+ $cache->removeKeys([1, 2, 7, 8]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 1);
+ $value = $cache->get(3);
+ $this->assertEquals($value, 6);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ /**
+ * @dataProvider cacheGetAllWrongKeys
+ */
+ public function testCacheRemoveKeysWrongArgs($keys): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->removeKeys($keys);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheRemoveAll(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $cache->removeAll();
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $cache->putAll([new CacheEntry(1, 2), new CacheEntry(2, 4), new CacheEntry(3, 6)]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 3);
+ $cache->removeAll();
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $entries = $cache->getAll([1, 2, 3]);
+ $this->assertCount(0, $entries);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function testCacheGetSize(): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $result = $cache->getSize();
+ $this->assertEquals($result, 0);
+ $cache->putAll([new CacheEntry(1, 2), new CacheEntry(2, 4), new CacheEntry(3, 6)]);
+ $result = $cache->getSize();
+ $this->assertEquals($result, 3);
+ $result = $cache->getSize(CacheInterface::PEEK_MODE_ALL);
+ $this->assertEquals($result, 3);
+ $result = $cache->getSize(CacheInterface::PEEK_MODE_ALL, CacheInterface::PEEK_MODE_ALL);
+ $this->assertEquals($result, 3);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ public function getSizeWrongArgs(): array
+ {
+ return array(
+ array(-1, -2),
+ array(4, 5, 6, 0)
+ );
+ }
+
+ /**
+ * @dataProvider getSizeWrongArgs
+ */
+ public function testCacheGetSizeWrongArgs($modes): void
+ {
+ $cache = TestingHelper::$client->getCache(self::CACHE_NAME);
+ try {
+ $this->expectException(ClientException::class);
+ $cache->getSize($modes);
+ } finally {
+ $cache->removeAll();
+ }
+ }
+
+ private static function cleanUp(): void
+ {
+ TestingHelper::destroyCache(self::CACHE_NAME);
+ }
+}