blob: 430c068803d46ec166eecb01db45a90a8684021d [file] [log] [blame]
<?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 Ds\Map;
use PHPUnit\Framework\TestCase;
use Apache\Ignite\Type\ObjectType;
use Apache\Ignite\Type\MapObjectType;
use Apache\Ignite\Type\ComplexObjectType;
use Apache\Ignite\Data\BinaryObject;
class Class1
{
public $field_1_1;
public $field_1_2;
public $field_1_3;
public function __construct()
{
$this->field_1_1 = null;
$this->field_1_2 = new Class2();
$this->field_1_3 = null;
}
}
class SubClass1 extends Class1
{
public $field_1_4;
public $field_1_5;
public $field_1_6;
public $field_1_7;
public $field_1_8;
public function __construct()
{
parent::__construct();
$this->field_1_4 = null;
$this->field_1_5 = new Class3();
$this->field_1_6 = null;
$this->field_1_7 = null;
$this->field_1_8 = null;
}
}
class Class2
{
public $field_2_1;
public $field_2_2;
}
class Class3 {
public $field_3_1;
public $field_3_2;
}
final class ComplexObjectTestCase extends TestCase
{
const CACHE_NAME = '__php_test_compl_obj_cache';
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 testPutGetComplexObjects(): void
{
$value1 = new Class1();
$value1->field_1_1 = $this->getPrimitiveValue(ObjectType::BYTE);
$value1->field_1_2->field_2_1 = $this->getPrimitiveValue(ObjectType::SHORT);
$value1->field_1_2->field_2_2 = $this->getPrimitiveValue(ObjectType::INTEGER);
$value1->field_1_3 = $this->getPrimitiveValue(ObjectType::LONG);
$valueType1 = (new ComplexObjectType())->
setFieldType('field_1_1', ObjectType::BYTE)->
setFieldType('field_1_2', (new ComplexObjectType())->
setIgniteTypeName('Class2ShortInteger')->
setPhpClassName(Class2::class)->
setFieldType('field_2_1', ObjectType::SHORT)->
setFieldType('field_2_2', ObjectType::INTEGER))->
setFieldType('field_1_3', ObjectType::LONG);
$value2 = new SubClass1();
$value2->field_1_1 = $this->getPrimitiveValue(ObjectType::FLOAT);
$value2->field_1_2->field_2_1 = $this->getPrimitiveValue(ObjectType::DOUBLE);
$value2->field_1_2->field_2_2 = $this->getPrimitiveValue(ObjectType::CHAR);
$value2->field_1_3 = $this->getPrimitiveValue(ObjectType::BOOLEAN);
$value2->field_1_4 = $this->getPrimitiveValue(ObjectType::STRING);
$value2->field_1_5->field_3_1 = $this->getPrimitiveValue(ObjectType::DATE);
$value2->field_1_5->field_3_2 = $this->getPrimitiveValue(ObjectType::UUID);
$value2->field_1_6 = $this->getPrimitiveValue(ObjectType::DECIMAL);
$value2->field_1_7 = $this->getPrimitiveValue(ObjectType::TIMESTAMP);
$value2->field_1_8 = $this->getPrimitiveValue(ObjectType::TIME);
$valueType2 = (new ComplexObjectType())->
setFieldType('field_1_1', ObjectType::FLOAT)->
setFieldType('field_1_2', (new ComplexObjectType())->
setIgniteTypeName('Class2DoubleChar')->
setPhpClassName(Class2::class)->
setFieldType('field_2_1', ObjectType::DOUBLE)->
setFieldType('field_2_2', ObjectType::CHAR))->
setFieldType('field_1_3', ObjectType::BOOLEAN)->
setFieldType('field_1_4', ObjectType::STRING)->
setFieldType('field_1_5', (new ComplexObjectType())->
setFieldType('field_3_1', ObjectType::DATE)->
setFieldType('field_3_2', ObjectType::UUID))->
setFieldType('field_1_6', ObjectType::DECIMAL)->
setFieldType('field_1_7', ObjectType::TIMESTAMP)->
setFieldType('field_1_8', ObjectType::TIME);
$this->putGetComplexObjectsWithDifferentTypes(
$value1, $value2, $valueType1, $valueType2, Class1::class, SubClass1::class);
}
public function testPutGetComplexObjectsWithArrays(): void
{
$value1 = new Class1();
$value1->field_1_1 = $this->getArrayValues(ObjectType::BYTE_ARRAY);
$value1->field_1_2->field_2_1 = $this->getArrayValues(ObjectType::SHORT_ARRAY);
$value1->field_1_2->field_2_2 = $this->getArrayValues(ObjectType::INTEGER_ARRAY);
$value1->field_1_3 = $this->getArrayValues(ObjectType::LONG_ARRAY);
$valueType1 = (new ComplexObjectType())->
setIgniteTypeName('Class1WithArrays')->
setPhpClassName(Class1::class)->
setFieldType('field_1_1', ObjectType::BYTE_ARRAY)->
setFieldType('field_1_2', (new ComplexObjectType())->
setIgniteTypeName('Class2WithShortIntegerArrays')->
setPhpClassName(Class2::class)->
setFieldType('field_2_1', ObjectType::SHORT_ARRAY)->
setFieldType('field_2_2', ObjectType::INTEGER_ARRAY))->
setFieldType('field_1_3', ObjectType::LONG_ARRAY);
$value2 = new SubClass1();
$value2->field_1_1 = $this->getArrayValues(ObjectType::FLOAT_ARRAY);
$value2->field_1_2->field_2_1 = $this->getArrayValues(ObjectType::DOUBLE_ARRAY);
$value2->field_1_2->field_2_2 = $this->getArrayValues(ObjectType::CHAR_ARRAY);
$value2->field_1_3 = $this->getArrayValues(ObjectType::BOOLEAN_ARRAY);
$value2->field_1_4 = $this->getArrayValues(ObjectType::STRING_ARRAY);
$value2->field_1_5->field_3_1 = $this->getArrayValues(ObjectType::DATE_ARRAY);
$value2->field_1_5->field_3_2 = $this->getArrayValues(ObjectType::UUID_ARRAY);
$value2->field_1_6 = $this->getArrayValues(ObjectType::DECIMAL_ARRAY);
$value2->field_1_7 = $this->getArrayValues(ObjectType::TIMESTAMP_ARRAY);
$value2->field_1_8 = $this->getArrayValues(ObjectType::TIME_ARRAY);
$valueType2 = (new ComplexObjectType())->
setIgniteTypeName('SubClass1WithArrays')->
setPhpClassName(SubClass1::class)->
setFieldType('field_1_1', ObjectType::FLOAT_ARRAY)->
setFieldType('field_1_2', (new ComplexObjectType())->
setIgniteTypeName('Class2WithDoubleCharArrays')->
setPhpClassName(Class2::class)->
setFieldType('field_2_1', ObjectType::DOUBLE_ARRAY)->
setFieldType('field_2_2', ObjectType::CHAR_ARRAY))->
setFieldType('field_1_3', ObjectType::BOOLEAN_ARRAY)->
setFieldType('field_1_4', ObjectType::STRING_ARRAY)->
setFieldType('field_1_5', (new ComplexObjectType())->
setIgniteTypeName('Class3WithArrays')->
setPhpClassName(Class3::class)->
setFieldType('field_3_1', ObjectType::DATE_ARRAY)->
setFieldType('field_3_2', ObjectType::UUID_ARRAY))->
setFieldType('field_1_6', ObjectType::DECIMAL_ARRAY)->
setFieldType('field_1_7', ObjectType::TIMESTAMP_ARRAY)->
setFieldType('field_1_8', ObjectType::TIME_ARRAY);
$this->putGetComplexObjectsWithDifferentTypes(
$value1, $value2, $valueType1, $valueType2, Class1::class, SubClass1::class, true);
}
public function testPutGetComplexObjectsWithMaps(): void
{
$value1 = new Class1();
$value1->field_1_1 = $this->getMapValue(ObjectType::BYTE);
$value1->field_1_2->field_2_1 = $this->getMapValue(ObjectType::SHORT);
$value1->field_1_2->field_2_2 = $this->getMapValue(ObjectType::INTEGER);
$value1->field_1_3 = $this->getMapValue(ObjectType::LONG);
$valueType1 = (new ComplexObjectType())->
setIgniteTypeName('Class1WithMaps')->
setPhpClassName(Class1::class)->
setFieldType('field_1_1', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::BYTE, ObjectType::BYTE))->
setFieldType('field_1_2', (new ComplexObjectType())->
setIgniteTypeName('Class2WithShortIntegerMaps')->
setPhpClassName(Class2::class)->
setFieldType('field_2_1', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::SHORT, ObjectType::SHORT))->
setFieldType('field_2_2', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::INTEGER, ObjectType::INTEGER)))->
setFieldType('field_1_3', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::LONG));
$value2 = new SubClass1();
$value2->field_1_1 = $this->getMapValue(ObjectType::FLOAT);
$value2->field_1_2->field_2_1 = $this->getMapValue(ObjectType::DOUBLE);
$value2->field_1_2->field_2_2 = $this->getMapValue(ObjectType::CHAR);
$value2->field_1_3 = $this->getMapValue(ObjectType::BOOLEAN);
$value2->field_1_4 = $this->getMapValue(ObjectType::STRING);
$value2->field_1_5->field_3_1 = $this->getMapValue(ObjectType::DATE);
$value2->field_1_5->field_3_2 = $this->getMapValue(ObjectType::UUID);
$value2->field_1_6 = $this->getMapValue(ObjectType::DECIMAL);
$value2->field_1_7 = $this->getMapValue(ObjectType::TIMESTAMP);
$value2->field_1_8 = $this->getMapValue(ObjectType::TIME);
$valueType2 = (new ComplexObjectType())->
setIgniteTypeName('SubClass1WithArrays')->
setPhpClassName(SubClass1::class)->
setFieldType('field_1_1', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::FLOAT))->
setFieldType('field_1_2', (new ComplexObjectType())->
setIgniteTypeName('Class2WithDoubleCharArrays')->
setPhpClassName(Class2::class)->
setFieldType('field_2_1', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::DOUBLE))->
setFieldType('field_2_2', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::CHAR, ObjectType::CHAR)))->
setFieldType('field_1_3', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::BOOLEAN, ObjectType::BOOLEAN))->
setFieldType('field_1_4', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::STRING))->
setFieldType('field_1_5', (new ComplexObjectType())->
setIgniteTypeName('Class3WithArrays')->
setPhpClassName(Class3::class)->
setFieldType('field_3_1', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::DATE))->
setFieldType('field_3_2', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::UUID)))->
setFieldType('field_1_6', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::DECIMAL))->
setFieldType('field_1_7', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::TIMESTAMP))->
setFieldType('field_1_8', new MapObjectType(MapObjectType::HASH_MAP, ObjectType::STRING, ObjectType::TIME));
$this->putGetComplexObjectsWithMaps(
$value1, $value2, $valueType1, $valueType2, Class1::class, SubClass1::class);
}
public function testPutGetBinaryObjectsFromObjects(): void
{
$valueType = (new ComplexObjectType())->
setIgniteTypeName('Class1WithStringObjStringArray')->
setPhpClassName(Class1::class)->
setFieldType('field_1_1', ObjectType::STRING)->
setFieldType('field_1_2', (new ComplexObjectType())->
setIgniteTypeName('Class2WithShortBoolean')->
setPhpClassName(Class2::class)->
setFieldType('field_2_1', ObjectType::SHORT)->
setFieldType('field_2_2', ObjectType::BOOLEAN))->
setFieldType('field_1_3', ObjectType::STRING_ARRAY);
$this->putGetBinaryObjects($valueType);
$defaultValueType = (new ComplexObjectType())->
setIgniteTypeName('Class1Default')->
setPhpClassName(Class1::class)->
setFieldType('field_1_2', (new ComplexObjectType())->
setIgniteTypeName('Class2Default')->
setPhpClassName(Class2::class));
$this->putGetBinaryObjects($defaultValueType);
}
private function putGetComplexObjectsWithDifferentTypes(
$key, $value, $keyType, $valueType, $keyClass, $valueClass, $isNullable = false)
{
$this->putGetComplexObjects($key, $value, $keyType, $valueType, $value);
$binaryKey = BinaryObject::fromObject($key, $keyType);
$binaryValue = BinaryObject::fromObject($value, $valueType);
$this->putGetComplexObjects($binaryKey, $binaryValue, null, null, $value);
if ($isNullable) {
$this->putGetComplexObjects(new $keyClass(), new $valueClass(), $keyType, $valueType, new $valueClass());
}
if ($isNullable) {
$binaryKey = BinaryObject::fromObject(new $keyClass(), $keyType);
$binaryValue = BinaryObject::fromObject(new $valueClass(), $valueType);
$this->putGetComplexObjects($binaryKey, $binaryValue, null, null, new $valueClass());
}
}
private function putGetComplexObjectsWithMaps(
$key, $value, $keyType, $valueType, $keyClass, $valueClass)
{
$this->putGetComplexObjects($key, $value, $keyType, $valueType, $value);
$this->putGetComplexObjects(new $keyClass(), new $valueClass(), $keyType, $valueType, new $valueClass());
}
private function putGetComplexObjects($key, $value, $keyType, $valueType, $valuePattern)
{
self::$cache->
setKeyType($keyType)->
setValueType($valueType);
try {
self::$cache->put($key, $value);
$result = self::$cache->get($key);
$strResult = TestingHelper::printValue($result);
$strValue = TestingHelper::printValue($valuePattern);
$this->assertTrue(
TestingHelper::compare($valuePattern, $result),
"values are not equal: put value={$strValue}, get value={$strResult}");
} finally {
self::$cache->removeAll();
}
}
private function putGetBinaryObjects($valueType): void
{
$value1 = new Class1();
$value1->field_1_1 = 'abc';
$value1->field_1_2->field_2_1 = 1234;
$value1->field_1_2->field_2_2 = true;
$value1->field_1_3 = ['a', 'bb', 'ccc'];
$value2 = new Class1();
$value2->field_1_1 = 'def';
$value2->field_1_2->field_2_1 = 5432;
$value2->field_1_2->field_2_2 = false;
$value2->field_1_3 = ['a', 'bb', 'ccc', 'dddd'];
$value3 = new Class1();
$value3->field_1_1 = 'defdef';
$value3->field_1_2->field_2_1 = 543;
$value3->field_1_2->field_2_2 = false;
$value3->field_1_3 = ['a', 'bb', 'ccc', 'dddd', 'eeeee'];
$field_1_2_Type = $valueType ? $valueType->getFieldType('field_1_2') : null;
$binaryValue1 = BinaryObject::fromObject($value1, $valueType);
$binaryValue2 = BinaryObject::fromObject($value2, $valueType);
$binaryValue3 = BinaryObject::fromObject($value3, $valueType);
self::$cache->
setKeyType(null)->
setValueType(null);
$cache = self::$cache;
try {
$cache->put($binaryValue1, $binaryValue2);
$result = $cache->get($binaryValue1);
$this->binaryObjectEquals($result, $value2, $valueType);
$binaryValue1->setField('field_1_1', 'abcde');
$result = $cache->get($binaryValue1);
$this->assertTrue($result === null);
$binaryValue2->setField('field_1_1', $value3->field_1_1);
$binaryValue2->setField('field_1_2', $value3->field_1_2, $field_1_2_Type);
$binaryValue2->setField('field_1_3', $value3->field_1_3);
$cache->put($binaryValue1, $binaryValue2);
$result = $cache->get($binaryValue1);
$this->binaryObjectEquals($result, $value3, $valueType);
$binaryValue1->setField('field_1_1', 'abc');
$binaryValue1->setField('field_1_3', $binaryValue1->getField('field_1_3'));
$result = $cache->get($binaryValue1);
$this->binaryObjectEquals($result, $value2, $valueType);
$result = $cache->get($binaryValue1);
$this->binaryObjectEquals($result, $value2, $valueType);
$binaryValue3->setField('field_1_1', $result->getField('field_1_1'));
$binaryValue3->setField('field_1_2', $result->getField('field_1_2', $field_1_2_Type), $field_1_2_Type);
$binaryValue3->setField('field_1_3', $result->getField('field_1_3'));
$cache->put($binaryValue1, $binaryValue3);
$result = $cache->get($binaryValue1);
$this->binaryObjectEquals($result, $value2, $valueType);
} finally {
self::$cache->removeAll();
}
}
private function binaryObjectEquals(BinaryObject $binaryObj, $valuePattern, $valueType): void
{
$strBinObj = TestingHelper::printValue($binaryObj);
$strValue = TestingHelper::printValue($valuePattern);
$this->assertTrue(
TestingHelper::compare($valuePattern, $binaryObj),
"binary values are not equal: put value={$strValue}, get value={$strBinObj}");
if ($valueType) {
$object = $binaryObj->toObject($valueType);
$strObject = TestingHelper::printValue($object);
$this->assertTrue(
TestingHelper::compare($valuePattern, $object),
"values are not equal: put value={$strValue}, get value={$strObject}");
}
}
private function getPrimitiveValue(int $typeCode)
{
return TestingHelper::$primitiveValues[$typeCode]['values'][0];
}
private function getArrayValues(int $typeCode)
{
return TestingHelper::$primitiveValues[TestingHelper::$arrayValues[$typeCode]['elemType']]['values'];
}
private function getMapValue(int $typeCode)
{
$map = new Map();
$values = TestingHelper::$primitiveValues[$typeCode]['values'];
$length = count($values);
for ($i = 0; $i < $length; $i++) {
$value = $values[$i];
if (!TestingHelper::$primitiveValues[$typeCode]['isMapKey']) {
$value = print_r($value, true);
}
$map->put($value, $values[$length - $i - 1]);
}
return $map;
}
private static function cleanUp(): void
{
TestingHelper::destroyCache(self::CACHE_NAME);
}
}