-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Statement.php
124 lines (106 loc) · 3.31 KB
/
Statement.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\OCI8\Exception\Error;
use Doctrine\DBAL\Driver\OCI8\Exception\UnknownParameterIndex;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
use function is_int;
use function oci_bind_by_name;
use function oci_execute;
use function oci_new_descriptor;
use const OCI_B_BIN;
use const OCI_B_BLOB;
use const OCI_COMMIT_ON_SUCCESS;
use const OCI_D_LOB;
use const OCI_NO_AUTO_COMMIT;
use const OCI_TEMP_BLOB;
use const SQLT_CHR;
final class Statement implements StatementInterface
{
/**
* @internal The statement can be only instantiated by its driver connection.
*
* @param resource $connection
* @param resource $statement
* @param array<int,string> $parameterMap
*/
public function __construct(
private readonly mixed $connection,
private readonly mixed $statement,
private readonly array $parameterMap,
private readonly ExecutionMode $executionMode
) {
}
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$this->bindParam($param, $value, $type);
}
public function bindParam(
int|string $param,
mixed &$variable,
ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
if (is_int($param)) {
if (! isset($this->parameterMap[$param])) {
throw UnknownParameterIndex::new($param);
}
$param = $this->parameterMap[$param];
}
if ($type === ParameterType::LARGE_OBJECT) {
if ($variable !== null) {
$lob = oci_new_descriptor($this->connection, OCI_D_LOB);
$lob->writeTemporary($variable, OCI_TEMP_BLOB);
$variable =& $lob;
} else {
$type = ParameterType::STRING;
}
}
if (
! @oci_bind_by_name(
$this->statement,
$param,
$variable,
$length ?? -1,
$this->convertParameterType($type)
)
) {
throw Error::new($this->statement);
}
}
/**
* Converts DBAL parameter type to oci8 parameter type
*/
private function convertParameterType(ParameterType $type): int
{
return match ($type) {
ParameterType::BINARY => OCI_B_BIN,
ParameterType::LARGE_OBJECT => OCI_B_BLOB,
default => SQLT_CHR,
};
}
public function execute(?array $params = null): Result
{
if ($params !== null) {
foreach ($params as $key => $val) {
if (is_int($key)) {
$param = $key + 1;
} else {
$param = $key;
}
$this->bindValue($param, $val);
}
}
if ($this->executionMode->isAutoCommitEnabled()) {
$mode = OCI_COMMIT_ON_SUCCESS;
} else {
$mode = OCI_NO_AUTO_COMMIT;
}
$ret = @oci_execute($this->statement, $mode);
if (! $ret) {
throw Error::new($this->statement);
}
return new Result($this->statement);
}
}