mirror of
https://github.com/danog/postgres.git
synced 2024-12-02 09:27:54 +01:00
Reuse connection statement with dissimilar parameters
This commit is contained in:
parent
93f5a9cf1f
commit
a60569ad76
@ -364,20 +364,22 @@ final class PgSqlHandle implements Handle
|
||||
throw new \Error("The connection to the database has been closed");
|
||||
}
|
||||
|
||||
return call(function () use ($sql) {
|
||||
$modifiedSql = Internal\parseNamedParams($sql, $names);
|
||||
|
||||
$name = Handle::STATEMENT_NAME_PREFIX . \sha1($sql);
|
||||
$name = Handle::STATEMENT_NAME_PREFIX . \sha1($modifiedSql);
|
||||
|
||||
if (isset($this->statements[$name])) {
|
||||
$storage = $this->statements[$name];
|
||||
|
||||
if ($storage->promise instanceof Promise) {
|
||||
return $storage->promise;
|
||||
// Do not return promised prepared statement object, as the $names array may differ.
|
||||
yield $storage->promise;
|
||||
}
|
||||
|
||||
++$storage->refCount; // Only increase refCount when returning a new object.
|
||||
++$storage->refCount;
|
||||
|
||||
return new Success(new PgSqlStatement($this, $name, $sql, $names));
|
||||
return new PgSqlStatement($this, $name, $sql, $names);
|
||||
}
|
||||
|
||||
$storage = new class {
|
||||
@ -388,20 +390,13 @@ final class PgSqlHandle implements Handle
|
||||
|
||||
$this->statements[$name] = $storage;
|
||||
|
||||
return $storage->promise = call(function () use ($storage, $name, $names, $sql, $modifiedSql) {
|
||||
try {
|
||||
/** @var resource $result PostgreSQL result resource. */
|
||||
yield ($storage->promise = call(function () use ($name, $modifiedSql) {
|
||||
$result = yield from $this->send("pg_send_prepare", $name, $modifiedSql);
|
||||
} catch (\Throwable $exception) {
|
||||
unset($this->statements[$name]);
|
||||
throw $exception;
|
||||
} finally {
|
||||
$storage->promise = null;
|
||||
}
|
||||
|
||||
switch (\pg_result_status($result, \PGSQL_STATUS_LONG)) {
|
||||
case \PGSQL_COMMAND_OK:
|
||||
return new PgSqlStatement($this, $name, $sql, $names);
|
||||
return $name; // Statement created successfully.
|
||||
|
||||
case \PGSQL_NONFATAL_ERROR:
|
||||
case \PGSQL_FATAL_ERROR:
|
||||
@ -419,6 +414,15 @@ final class PgSqlHandle implements Handle
|
||||
throw new FailureException("Unknown result status");
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}));
|
||||
} catch (\Throwable $exception) {
|
||||
unset($this->statements[$name]);
|
||||
throw $exception;
|
||||
} finally {
|
||||
$storage->promise = null;
|
||||
}
|
||||
|
||||
return new PgSqlStatement($this, $name, $sql, $names);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -385,20 +385,22 @@ final class PqHandle implements Handle
|
||||
throw new \Error("The connection to the database has been closed");
|
||||
}
|
||||
|
||||
return call(function () use ($sql) {
|
||||
$modifiedSql = Internal\parseNamedParams($sql, $names);
|
||||
|
||||
$name = Handle::STATEMENT_NAME_PREFIX . \sha1($sql);
|
||||
$name = Handle::STATEMENT_NAME_PREFIX . \sha1($modifiedSql);
|
||||
|
||||
if (isset($this->statements[$name])) {
|
||||
$storage = $this->statements[$name];
|
||||
|
||||
if ($storage->promise instanceof Promise) {
|
||||
return $storage->promise;
|
||||
// Do not return promised prepared statement object, as the $names array may differ.
|
||||
yield $storage->promise;
|
||||
}
|
||||
|
||||
++$storage->refCount; // Only increase refCount when returning a new object.
|
||||
++$storage->refCount;
|
||||
|
||||
return new Success(new PqStatement($this, $name, $sql, $names));
|
||||
return new PqStatement($this, $name, $sql, $names);
|
||||
}
|
||||
|
||||
$storage = new class {
|
||||
@ -410,9 +412,10 @@ final class PqHandle implements Handle
|
||||
|
||||
$this->statements[$name] = $storage;
|
||||
|
||||
return $storage->promise = call(function () use ($storage, $names, $name, $sql, $modifiedSql) {
|
||||
try {
|
||||
$storage->statement = yield from $this->send([$this->handle, "prepareAsync"], $name, $modifiedSql);
|
||||
$storage->statement = yield (
|
||||
$storage->promise = new Coroutine($this->send([$this->handle, "prepareAsync"], $name, $modifiedSql))
|
||||
);
|
||||
} catch (\Throwable $exception) {
|
||||
unset($this->statements[$name]);
|
||||
throw $exception;
|
||||
|
@ -361,6 +361,19 @@ abstract class AbstractLinkTest extends TestCase
|
||||
$this->assertInstanceOf(Statement::class, $statement2);
|
||||
|
||||
$this->assertNotSame($statement1, $statement2);
|
||||
|
||||
$data = $this->getData()[0];
|
||||
|
||||
$results = yield [$statement1->execute([$data[0]]), $statement2->execute(['domain' => $data[0]])];
|
||||
|
||||
foreach ($results as $result) {
|
||||
/** @var \Amp\Postgres\ResultSet $result */
|
||||
while (yield $result->advance()) {
|
||||
$row = $result->getCurrent();
|
||||
$this->assertSame($data[0], $row['domain']);
|
||||
$this->assertSame($data[1], $row['tld']);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user