|
5 | 5 | namespace staabm\PHPStanDba\PdoReflection; |
6 | 6 |
|
7 | 7 | use PDOStatement; |
| 8 | +use PHPStan\ShouldNotHappenException; |
8 | 9 | use PHPStan\Type\ArrayType; |
9 | 10 | use PHPStan\Type\BenevolentUnionType; |
10 | 11 | use PHPStan\Type\Constant\ConstantArrayTypeBuilder; |
|
21 | 22 | use PHPStan\Type\UnionType; |
22 | 23 | use staabm\PHPStanDba\QueryReflection\QueryReflector; |
23 | 24 |
|
24 | | -class PdoStatementObjectType extends GenericObjectType |
| 25 | +class PdoStatementObjectType extends ObjectType |
25 | 26 | { |
26 | | - /** |
27 | | - * @var Type |
28 | | - */ |
29 | | - private $bothType; |
| 27 | + private ?Type $bothType; |
30 | 28 |
|
31 | 29 | /** |
32 | | - * @param QueryReflector::FETCH_TYPE* $fetchType |
| 30 | + * @var null|QueryReflector::FETCH_TYPE* |
33 | 31 | */ |
34 | | - public function __construct(Type $bothType, int $fetchType) |
35 | | - { |
36 | | - $this->bothType = $bothType; |
37 | | - |
38 | | - $rowTypeInFetchMode = $this->reduceBothType($bothType, $fetchType); |
39 | | - |
40 | | - parent::__construct(PDOStatement::class, [$rowTypeInFetchMode]); |
41 | | - } |
| 32 | + private ?int $fetchType; |
42 | 33 |
|
43 | 34 | public function getRowType(): Type |
44 | 35 | { |
45 | | - $genericTypes = $this->getTypes(); |
46 | | - |
47 | | - return $genericTypes[0]; |
| 36 | + if ($this->bothType === null || $this->fetchType === null) { |
| 37 | + throw new ShouldNotHappenException(); |
| 38 | + } |
| 39 | + return $this->reduceBothType($this->bothType, $this->fetchType); |
48 | 40 | } |
49 | 41 |
|
50 | 42 | public function getIterableValueType(): Type |
51 | 43 | { |
52 | 44 | return $this->getRowType(); |
53 | 45 | } |
54 | 46 |
|
| 47 | + /** |
| 48 | + * @param QueryReflector::FETCH_TYPE* $fetchType |
| 49 | + */ |
| 50 | + static public function newWithBothAndFetchType(Type $bothType, int $fetchType): self |
| 51 | + { |
| 52 | + $new = new self(PDOStatement::class); |
| 53 | + $new->bothType = $bothType; |
| 54 | + $new->fetchType = $fetchType; |
| 55 | + return $new; |
| 56 | + } |
| 57 | + |
55 | 58 | /** |
56 | 59 | * @param QueryReflector::FETCH_TYPE* $fetchType |
57 | 60 | */ |
58 | 61 | public function newWithFetchType(int $fetchType): self |
59 | 62 | { |
60 | | - return new self($this->bothType, $fetchType); |
| 63 | + $new = new self($this->getClassName(), $this->getSubtractedType()); |
| 64 | + $new->bothType = $this->bothType; |
| 65 | + $new->fetchType = $fetchType; |
| 66 | + return $new; |
61 | 67 | } |
62 | 68 |
|
63 | 69 | /** |
@@ -121,23 +127,23 @@ public static function createDefaultType(int $fetchType): Type |
121 | 127 |
|
122 | 128 | switch ($fetchType) { |
123 | 129 | case QueryReflector::FETCH_TYPE_CLASS: |
124 | | - return new GenericObjectType(PDOStatement::class, [new ObjectType('stdClass')]); |
| 130 | + return self::newWithBothAndFetchType(new ObjectType('stdClass'), $fetchType); |
125 | 131 | case QueryReflector::FETCH_TYPE_KEY_VALUE: |
126 | 132 | $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); |
127 | 133 | $arrayBuilder->setOffsetValueType(new ConstantIntegerType(0), new MixedType()); |
128 | 134 | $arrayBuilder->setOffsetValueType(new ConstantIntegerType(1), new MixedType()); |
129 | 135 |
|
130 | | - return new GenericObjectType(PDOStatement::class, [$arrayBuilder->getArray()]); |
| 136 | + return self::newWithBothAndFetchType($arrayBuilder->getArray(), $fetchType); |
131 | 137 | case QueryReflector::FETCH_TYPE_NUMERIC: |
132 | | - return new GenericObjectType(PDOStatement::class, [new ArrayType(IntegerRangeType::fromInterval(0, null), $pdoScalar)]); |
| 138 | + return self::newWithBothAndFetchType(new ArrayType(IntegerRangeType::fromInterval(0, null), $pdoScalar), $fetchType); |
133 | 139 | case QueryReflector::FETCH_TYPE_ASSOC: |
134 | | - return new GenericObjectType(PDOStatement::class, [new ArrayType(new StringType(), $pdoScalar)]); |
| 140 | + return self::newWithBothAndFetchType(new ArrayType(new StringType(), $pdoScalar), $fetchType); |
135 | 141 | case QueryReflector::FETCH_TYPE_BOTH: |
136 | | - return new GenericObjectType(PDOStatement::class, [new ArrayType($arrayKey, $pdoScalar)]); |
| 142 | + return self::newWithBothAndFetchType(new ArrayType($arrayKey, $pdoScalar), $fetchType); |
137 | 143 | case QueryReflector::FETCH_TYPE_COLUMN: |
138 | | - return new GenericObjectType(PDOStatement::class, [$pdoScalar]); |
| 144 | + return self::newWithBothAndFetchType($pdoScalar, $fetchType); |
139 | 145 | } |
140 | 146 |
|
141 | | - return new GenericObjectType(PDOStatement::class, [new MixedType()]); |
| 147 | + return self::newWithBothAndFetchType(new MixedType(), $fetchType); |
142 | 148 | } |
143 | 149 | } |
0 commit comments