-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathCommand.php
119 lines (92 loc) · 3.52 KB
/
Command.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
<?php
declare(strict_types=1);
namespace Yiisoft\Db\Oracle;
use PDO;
use Yiisoft\Db\Constant\DataType;
use Yiisoft\Db\Constant\PhpType;
use Yiisoft\Db\Driver\Pdo\AbstractPdoCommand;
use Yiisoft\Db\QueryBuilder\AbstractQueryBuilder;
use function array_keys;
use function count;
use function implode;
use function strlen;
/**
* Implements a database command that can be executed against a PDO (PHP Data Object) database connection for Oracle
* Server.
*/
final class Command extends AbstractPdoCommand
{
public function insertWithReturningPks(string $table, array $columns): array|false
{
$tableSchema = $this->db->getSchema()->getTableSchema($table);
$returnColumns = $tableSchema?->getPrimaryKey() ?? [];
if ($returnColumns === []) {
if ($this->insert($table, $columns)->execute() === 0) {
return false;
}
return [];
}
$params = [];
$sql = $this->getQueryBuilder()->insert($table, $columns, $params);
$tableColumns = $tableSchema?->getColumns() ?? [];
$returnParams = [];
$returning = [];
foreach ($returnColumns as $name) {
$phName = AbstractQueryBuilder::PARAM_PREFIX . (count($params) + count($returnParams));
$returnParams[$phName] = [
'column' => $name,
'value' => '',
];
if (!isset($tableColumns[$name]) || $tableColumns[$name]->getPhpType() !== PhpType::INT) {
$returnParams[$phName]['dataType'] = PDO::PARAM_STR;
} else {
$returnParams[$phName]['dataType'] = PDO::PARAM_INT;
}
$returnParams[$phName]['size'] = ($tableColumns[$name]?->getSize() ?? 3998) + 2;
$returning[] = $this->db->getQuoter()->quoteColumnName($name);
}
$sql .= ' RETURNING ' . implode(', ', $returning) . ' INTO ' . implode(', ', array_keys($returnParams));
$this->setSql($sql)->bindValues($params);
$this->prepare(false);
/** @psalm-var array<string, array{column: string, value: mixed, dataType: DataType::*, size: int}> $returnParams */
foreach ($returnParams as $name => &$value) {
$this->bindParam($name, $value['value'], $value['dataType'], $value['size']);
}
unset($value);
if (!$this->execute()) {
return false;
}
$result = [];
foreach ($returnParams as $value) {
/** @psalm-var mixed */
$result[$value['column']] = $value['value'];
}
return $result;
}
public function showDatabases(): array
{
$sql = <<<SQL
SELECT PDB_NAME FROM DBA_PDBS WHERE PDB_NAME NOT IN ('PDB\$SEED', 'PDB\$ROOT', 'ORCLPDB1', 'XEPDB1')
SQL;
return $this->setSql($sql)->queryColumn();
}
protected function bindPendingParams(): void
{
$paramsPassedByReference = [];
$params = $this->params;
foreach ($params as $name => $value) {
if (PDO::PARAM_STR === $value->getType()) {
/** @var mixed */
$paramsPassedByReference[$name] = $value->getValue();
$this->pdoStatement?->bindParam(
$name,
$paramsPassedByReference[$name],
$value->getType(),
strlen((string) $value->getValue())
);
} else {
$this->pdoStatement?->bindValue($name, $value->getValue(), $value->getType());
}
}
}
}