assertSame( [ 'mysqli', 'curl', 'mbstring', 'sodium', ], Util::listPHPExtensions() ); } public function testGetUniqueCondition(): void { $GLOBALS['db'] = 'db'; $GLOBALS['cfg']['Server']['DisableIS'] = false; $actual = Util::getUniqueCondition(0, [], []); $this->assertEquals(['', false, []], $actual); $actual = Util::getUniqueCondition(0, [], [], true); $this->assertEquals(['', true, []], $actual); } public function testGetUniqueConditionWithMultipleFields(): void { $meta = [ new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field1', 'table' => 'table', 'orgtable' => 'table', ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field2', 'table' => 'table', 'orgtable' => 'table', ]), new FieldMetadata(MYSQLI_TYPE_SHORT, MYSQLI_NUM_FLAG, (object) [ 'name' => 'field3', 'table' => 'table', 'orgtable' => 'table', ]), new FieldMetadata(MYSQLI_TYPE_LONG, MYSQLI_NUM_FLAG, (object) [ 'name' => 'field4', 'table' => 'table', 'orgtable' => 'table', ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field5', 'table' => 'table', 'orgtable' => 'table', 'charsetnr' => 63, // binary ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field6', 'table' => 'table', 'orgtable' => 'table', 'charsetnr' => 63, // binary ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field7', 'table' => 'table', 'orgtable' => 'table', 'numeric' => false, 'type' => 'blob', 'charsetnr' => 32, // armscii8_general_ci ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field8', 'table' => 'table', 'orgtable' => 'table', 'numeric' => false, 'type' => 'blob', 'charsetnr' => 48, // latin1_general_ci ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field9', 'table' => 'table', 'orgtable' => 'table', 'numeric' => false, 'type' => 'blob', 'charsetnr' => 63, // binary ]), new FieldMetadata(MYSQLI_TYPE_GEOMETRY, 0, (object) [ 'name' => 'field10', 'table' => 'table', 'orgtable' => 'table', ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field11', 'table' => 'table2', 'orgtable' => 'table2', ]), new FieldMetadata(MYSQLI_TYPE_BIT, 0, (object) [ 'name' => 'field12', 'table' => 'table', 'orgtable' => 'table', 'length' => 4, ]), ]; $actual = Util::getUniqueCondition(count($meta), $meta, [ null, 'value\'s', 123456, 123.456, 'value', str_repeat('*', 1001), 'value', 'value', 'value', 'value', 'value', 0x1, ], false, 'table'); $this->assertEquals( [ '`table`.`field1` IS NULL AND `table`.`field2` = \'value\\\'s\' AND `table`.`field3` = 123456' . ' AND `table`.`field4` = 123.456 AND `table`.`field5` = CAST(0x76616c7565 AS BINARY)' . ' AND `table`.`field7` = \'value\' AND `table`.`field8` = \'value\'' . ' AND `table`.`field9` = CAST(0x76616c7565 AS BINARY)' . ' AND `table`.`field10` = CAST(0x76616c7565 AS BINARY)' . ' AND `table`.`field12` = b\'0001\'', false, [ '`table`.`field1`' => 'IS NULL', '`table`.`field2`' => '= \'value\\\'s\'', '`table`.`field3`' => '= 123456', '`table`.`field4`' => '= 123.456', '`table`.`field5`' => '= CAST(0x76616c7565 AS BINARY)', '`table`.`field7`' => '= \'value\'', '`table`.`field8`' => '= \'value\'', '`table`.`field9`' => '= CAST(0x76616c7565 AS BINARY)', '`table`.`field10`' => '', '`table`.`field12`' => '= b\'0001\'', ], ], $actual ); } public function testGetUniqueConditionWithSingleBigBinaryField(): void { $meta = [ new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field', 'table' => 'table', 'orgtable' => 'table', 'charsetnr' => 63, // binary ]), ]; $actual = Util::getUniqueCondition(1, $meta, [str_repeat('*', 1001)]); $this->assertEquals( ['CHAR_LENGTH(`table`.`field`) = 1001', false, ['`table`.`field`' => ' = 1001']], $actual ); } public function testGetUniqueConditionWithPrimaryKey(): void { $meta = [ new FieldMetadata(MYSQLI_TYPE_LONG, MYSQLI_PRI_KEY_FLAG | MYSQLI_NUM_FLAG, (object) [ 'name' => 'id', 'table' => 'table', 'orgtable' => 'table', ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field', 'table' => 'table', 'orgtable' => 'table', ]), ]; $actual = Util::getUniqueCondition(count($meta), $meta, [1, 'value']); $this->assertEquals(['`table`.`id` = 1', true, ['`table`.`id`' => '= 1']], $actual); } public function testGetUniqueConditionWithUniqueKey(): void { $meta = [ new FieldMetadata(MYSQLI_TYPE_STRING, MYSQLI_UNIQUE_KEY_FLAG, (object) [ 'name' => 'id', 'table' => 'table', 'orgtable' => 'table', ]), new FieldMetadata(MYSQLI_TYPE_STRING, 0, (object) [ 'name' => 'field', 'table' => 'table', 'orgtable' => 'table', ]), ]; $actual = Util::getUniqueCondition(count($meta), $meta, ['unique', 'value']); $this->assertEquals(['`table`.`id` = \'unique\'', true, ['`table`.`id`' => '= \'unique\'']], $actual); } /** * Test for Util::getUniqueCondition * note: GROUP_FLAG = MYSQLI_NUM_FLAG = 32769 * * @param FieldMetadata[] $meta Meta Information for Field * @param array $row Current Ddata Row * @param array $expected Expected Result * @psalm-param array $row * @psalm-param array{string, bool, array} $expected * * @dataProvider providerGetUniqueConditionForGroupFlag */ public function testGetUniqueConditionForGroupFlag(array $meta, array $row, array $expected): void { $fieldsCount = count($meta); $actual = Util::getUniqueCondition($fieldsCount, $meta, $row); $this->assertEquals($expected, $actual); } /** * Provider for testGetUniqueConditionForGroupFlag * * @return array, array{string, bool, array}}> */ public function providerGetUniqueConditionForGroupFlag(): array { return [ 'field type is integer, value is number - not escape string' => [ [ new FieldMetadata(FIELD_TYPE_INTEGER, MYSQLI_NUM_FLAG, (object) [ 'name' => 'col', 'table' => 'table', 'orgtable' => 'table', ]), ], [123], [ '`table`.`col` = 123', false, ['`table`.`col`' => '= 123'], ], ], 'field type is unknown, value is string - escape string' => [ [ new FieldMetadata(FIELD_TYPE_UNKNOWN, MYSQLI_NUM_FLAG, (object) [ 'name' => 'col', 'table' => 'table', 'orgtable' => 'table', ]), ], ['test'], [ "`table`.`col` = 'test'", false, ['`table`.`col`' => "= 'test'"], ], ], 'field type is varchar, value is string - escape string' => [ [ new FieldMetadata(FIELD_TYPE_VARCHAR, MYSQLI_NUM_FLAG, (object) [ 'name' => 'col', 'table' => 'table', 'orgtable' => 'table', ]), ], ['test'], [ "`table`.`col` = 'test'", false, ['`table`.`col`' => "= 'test'"], ], ], 'field type is varchar, value is string with double quote - escape string' => [ [ new FieldMetadata(FIELD_TYPE_VARCHAR, MYSQLI_NUM_FLAG, (object) [ 'name' => 'col', 'table' => 'table', 'orgtable' => 'table', ]), ], ['"test"'], [ "`table`.`col` = '\\\"test\\\"'", false, ['`table`.`col`' => "= '\\\"test\\\"'"], ], ], 'field type is varchar, value is string with single quote - escape string' => [ [ new FieldMetadata(FIELD_TYPE_VARCHAR, MYSQLI_NUM_FLAG, (object) [ 'name' => 'col', 'table' => 'table', 'orgtable' => 'table', ]), ], ["'test'"], [ "`table`.`col` = '\'test\''", false, ['`table`.`col`' => "= '\'test\''"], ], ], 'group by multiple columns and field type is mixed' => [ [ new FieldMetadata(FIELD_TYPE_VARCHAR, MYSQLI_NUM_FLAG, (object) [ 'name' => 'col', 'table' => 'table', 'orgtable' => 'table', ]), new FieldMetadata(FIELD_TYPE_INTEGER, MYSQLI_NUM_FLAG, (object) [ 'name' => 'status_id', 'table' => 'table', 'orgtable' => 'table', ]), ], ['test', 2], [ "`table`.`col` = 'test' AND `table`.`status_id` = 2", false, [ '`table`.`col`' => "= 'test'", '`table`.`status_id`' => '= 2', ], ], ], ]; } /** * Test for Page Selector */ public function testPageSelector(): void { $this->assertStringContainsString( '