Skip to content

Commit 85e22da

Browse files
committed
Merge branch '3.8.x' into 4.0.x
* 3.8.x: Generalize CustomIntrospectionTest (doctrine#6210) Run tests on MySQL 8.2 (doctrine#6207) MySQLSchemaManager. Check expected database type for json columns only. (doctrine#6189) Make the type annotation for CompositeExpression::count more specific (doctrine#6188)
2 parents fa47aee + a47f99c commit 85e22da

File tree

5 files changed

+145
-1
lines changed

5 files changed

+145
-1
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ jobs:
349349
mysql-version:
350350
- "5.7"
351351
- "8.0"
352-
- "8.1"
352+
- "8.2"
353353
extension:
354354
- "mysqli"
355355
- "pdo_mysql"

src/Query/Expression/CompositeExpression.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public function with(self|string $part, self|string ...$parts): self
6868

6969
/**
7070
* Retrieves the amount of expressions on composite expression.
71+
*
72+
* @psalm-return int<0, max>
7173
*/
7274
public function count(): int
7375
{
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Tests\Functional\Schema;
6+
7+
use Doctrine\DBAL\Schema\ColumnDiff;
8+
use Doctrine\DBAL\Schema\Schema;
9+
use Doctrine\DBAL\Tests\Functional\Schema\Types\MoneyType;
10+
use Doctrine\DBAL\Tests\FunctionalTestCase;
11+
use Doctrine\DBAL\Tests\TestUtil;
12+
use Doctrine\DBAL\Types\Type;
13+
14+
use function array_map;
15+
use function implode;
16+
use function sprintf;
17+
18+
/**
19+
* Tests introspection of a custom column type with an underlying decimal column
20+
* on MySQL and MariaDb platforms.
21+
*
22+
* See bug #6185
23+
*/
24+
class CustomIntrospectionTest extends FunctionalTestCase
25+
{
26+
public static function setUpBeforeClass(): void
27+
{
28+
if (TestUtil::isDriverOneOf('oci8', 'pdo_oci')) {
29+
self::markTestSkipped('Skip on Oracle');
30+
}
31+
32+
Type::addType(MoneyType::NAME, MoneyType::class);
33+
}
34+
35+
public function testCustomColumnIntrospection(): void
36+
{
37+
$tableName = 'test_custom_column_introspection';
38+
$schemaManager = $this->connection->createSchemaManager();
39+
$schema = new Schema([], [], $schemaManager->createSchemaConfig());
40+
$table = $schema->createTable($tableName);
41+
42+
$table->addColumn('id', 'integer');
43+
$table->addColumn('quantity', 'decimal', [
44+
'notnull' => false,
45+
'scale' => 2,
46+
'precision' => 10,
47+
]);
48+
$table->addColumn('amount', 'money', [
49+
'notnull' => false,
50+
'scale' => 2,
51+
'precision' => 10,
52+
]);
53+
54+
$this->dropAndCreateTable($table);
55+
56+
$onlineTable = $schemaManager->introspectTable($tableName);
57+
$diff = $schemaManager->createComparator()->compareTables($onlineTable, $table);
58+
$changedCols = array_map(
59+
static fn (ColumnDiff $columnDiff): string => $columnDiff->getOldColumn()->getName(),
60+
$diff->getModifiedColumns(),
61+
);
62+
63+
self::assertTrue($diff->isEmpty(), sprintf(
64+
'Tables should be identical. Differences detected in %s.',
65+
implode(', ', $changedCols),
66+
));
67+
}
68+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Tests\Functional\Schema\Types;
6+
7+
final class Money
8+
{
9+
public function __construct(
10+
private readonly string $value,
11+
) {
12+
}
13+
14+
public function __toString(): string
15+
{
16+
return $this->value;
17+
}
18+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Tests\Functional\Schema\Types;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Exception\InvalidFormat;
9+
use Doctrine\DBAL\Types\Exception\InvalidType;
10+
use Doctrine\DBAL\Types\Type;
11+
use InvalidArgumentException;
12+
13+
use function is_string;
14+
15+
class MoneyType extends Type
16+
{
17+
public const NAME = 'money';
18+
19+
/**
20+
* {@inheritDoc}
21+
*/
22+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
23+
{
24+
return $platform->getDecimalTypeDeclarationSQL($column);
25+
}
26+
27+
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
28+
{
29+
if ($value === null) {
30+
return null;
31+
}
32+
33+
if ($value instanceof Money) {
34+
return (string) $value;
35+
}
36+
37+
throw InvalidType::new($value, self::NAME, ['null', Money::class]);
38+
}
39+
40+
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?Money
41+
{
42+
if ($value === null || $value instanceof Money) {
43+
return $value;
44+
}
45+
46+
if (! is_string($value)) {
47+
throw InvalidType::new($value, self::NAME, ['null', 'string']);
48+
}
49+
50+
try {
51+
return new Money($value);
52+
} catch (InvalidArgumentException $e) {
53+
throw InvalidFormat::new($value, self::NAME, Money::class, $e);
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)