Passed
Push — master ( 8fe57b...ddc32f )
by Ron
10:31
created

QueryStatement::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Kir\MySQL\Builder;
4
5
use Kir\MySQL\Database\DatabaseStatement;
6
use Kir\MySQL\Databases\MySQL\MySQLExceptionInterpreter;
7
use Kir\MySQL\Exceptions\SqlException;
8
use Kir\MySQL\QueryLogger\QueryLoggers;
9
use PDO;
10
use PDOException;
11
use PDOStatement;
12
use Stringable;
13
14
class QueryStatement implements DatabaseStatement, Stringable {
15
	/**
16
	 * @param PDOStatement<mixed> $stmt
17
	 * @param string $query
18
	 * @param MySQLExceptionInterpreter $exceptionInterpreter
19
	 * @param QueryLoggers $queryLoggers
20
	 */
21
	public function __construct(
22
		private PDOStatement $stmt,
23
		private string $query,
24
		private MySQLExceptionInterpreter $exceptionInterpreter,
25
		private QueryLoggers $queryLoggers,
26
	) {}
27
28
	/**
29
	 * @return PDOStatement<mixed>
30
	 */
31
	public function getStatement(): PDOStatement {
32
		return $this->stmt;
33
	}
34
35
	/**
36
	 * @param int $mode
37
	 * @param mixed $arg0
38
	 * @param array<mixed, mixed>|null $arg1
39
	 * @return $this
40
	 */
41
	public function setFetchMode(int $mode = PDO::FETCH_ASSOC, $arg0 = null, ?array $arg1 = null) {
42
		$args = [$mode];
43
		if($arg0 !== null) {
44
			$args[] = $arg0;
45
		}
46
		if($arg1 !== null) {
47
			$args[] = $arg1;
48
		}
49
		$this->stmt->setFetchMode(...$args);
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $mode of PDOStatement::setFetchMode() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

49
		$this->stmt->setFetchMode(/** @scrutinizer ignore-type */ ...$args);
Loading history...
50
51
		return $this;
52
	}
53
54
	/**
55
	 * @param array<string, mixed> $params
56
	 * @return $this
57
	 * @throws SqlException
58
	 */
59
	public function execute(array $params = []) {
60
		$this->exceptionHandler(function() use ($params) {
61
			$this->queryLoggers->logRegion($this->query, function() use ($params) {
62
				$response = $this->stmt->execute($params);
63
				if(!$response) {
64
					throw new SqlException('Execution returned with "false".');
65
				}
66
			});
67
		});
68
69
		return $this;
70
	}
71
72
	/**
73
	 * @param int $fetchStyle
74
	 * @param mixed|null $fetchArgument
75
	 * @param mixed[] $ctorArgs
76
	 * @return array<mixed, mixed>
77
	 */
78
	public function fetchAll($fetchStyle = PDO::FETCH_ASSOC, $fetchArgument = null, array $ctorArgs = []): array {
79
		$result = $x = $this->exceptionHandler(function() use ($fetchStyle, $fetchArgument, $ctorArgs) {
80
			if($fetchArgument !== null) {
81
				return $this->stmt->fetchAll($fetchStyle, $fetchArgument, ...$ctorArgs);
82
			}
83
84
			return $this->stmt->fetchAll($fetchStyle);
85
		});
86
		/** @var array<mixed, mixed>|false $x */
87
		if($x === false) {
88
			return [];
89
		}
90
91
		return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type Kir\MySQL\Builder\T which is incompatible with the type-hinted return array.
Loading history...
92
	}
93
94
	/**
95
	 * @param int $fetchStyle
96
	 * @param int $cursorOrientation
97
	 * @param int $cursorOffset
98
	 * @return mixed
99
	 */
100
	public function fetch($fetchStyle = PDO::FETCH_ASSOC, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) {
101
		return $this->exceptionHandler(fn() => $this->stmt->fetch($fetchStyle, $cursorOrientation, $cursorOffset));
102
	}
103
104
	/**
105
	 * @param int $columnNo
106
	 * @return mixed
107
	 */
108
	public function fetchColumn($columnNo = 0) {
109
		return $this->exceptionHandler(fn() => $this->stmt->fetchColumn($columnNo));
110
	}
111
112
	/**
113
	 * @return bool
114
	 */
115
	public function closeCursor(): bool {
116
		return $this->exceptionHandler(fn() => $this->stmt->closeCursor());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->exceptionH...ion(...) { /* ... */ }) returns the type Kir\MySQL\Builder\T which is incompatible with the type-hinted return boolean.
Loading history...
117
	}
118
119
	/**
120
	 * @return int
121
	 */
122
	public function columnCount(): int {
123
		return $this->exceptionHandler(fn() => $this->stmt->columnCount());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->exceptionH...ion(...) { /* ... */ }) returns the type Kir\MySQL\Builder\T which is incompatible with the type-hinted return integer.
Loading history...
124
	}
125
126
	/**
127
	 * @param int $columnNo
128
	 * @return null|array<string, mixed>
129
	 */
130
	public function getColumnMeta(int $columnNo): ?array {
131
		return $this->exceptionHandler(function() use ($columnNo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->exceptionH...ion(...) { /* ... */ }) returns the type Kir\MySQL\Builder\T which is incompatible with the type-hinted return array|null.
Loading history...
132
			$columnMeta = $this->stmt->getColumnMeta($columnNo);
133
			if($columnMeta === false) {
134
				return null;
135
			}
136
137
			return $columnMeta;
138
		});
139
	}
140
141
	/**
142
	 * @template T
143
	 * @param callable(): T $fn
144
	 * @return T
145
	 */
146
	private function exceptionHandler(callable $fn) {
147
		try {
148
			return $fn();
149
		} catch(PDOException $exception) {
150
			throw $this->exceptionInterpreter->getMoreConcreteException($exception);
151
		}
152
	}
153
154
	public function __toString(): string {
155
		return $this->query;
156
	}
157
}
158