Skip to content

Commit c2fe18c

Browse files
committedNov 14, 2017
Add execute() method
Prepare and execute in a single method.
1 parent e830e9d commit c2fe18c

File tree

5 files changed

+107
-5
lines changed

5 files changed

+107
-5
lines changed
 

‎lib/AbstractPool.php

+29
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,35 @@ private function doPrepare(string $sql): \Generator {
182182
return $statement;
183183
}
184184

185+
/**
186+
* {@inheritdoc}
187+
*/
188+
public function execute(string $sql, ...$data): Promise {
189+
return new Coroutine($this->doExecute($sql, $data));
190+
}
191+
192+
private function doExecute(string $sql, array $data): \Generator {
193+
/** @var \Amp\Mysql\Connection $connection */
194+
$connection = yield from $this->pop();
195+
196+
try {
197+
$result = yield $connection->execute($sql, ...$data);
198+
} catch (\Throwable $exception) {
199+
$this->push($connection);
200+
throw $exception;
201+
}
202+
203+
if ($result instanceof Operation) {
204+
$result->onComplete(function () use ($connection) {
205+
$this->push($connection);
206+
});
207+
} else {
208+
$this->push($connection);
209+
}
210+
211+
return $result;
212+
}
213+
185214
/**
186215
* {@inheritdoc}
187216
*/

‎lib/Connection.php

+11
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,17 @@ public function prepare(string $query): Promise {
320320
return $promise;
321321
}
322322

323+
/**
324+
* {@inheritdoc}
325+
*/
326+
public function execute(string $sql, ...$data): Promise {
327+
return \Amp\call(function () use ($sql, $data) {
328+
/** @var \Amp\Mysql\Statement $statment */
329+
$statment = yield $this->prepare($sql);
330+
return yield $statment->execute(...$data);
331+
});
332+
}
333+
323334
public function __destruct() {
324335
$this->processor->delRef();
325336
}

‎lib/Executor.php

+16-4
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
interface Executor {
88
/**
9-
* @param string $sql
9+
* @param string $sql SQL query to execute.
1010
*
11-
* @return \Amp\Promise<\Amp\Postgres\CommandResult|\Amp\Postgres\TupleResult>
11+
* @return \Amp\Promise<\Amp\Mysql\CommandResult|\Amp\Mysql\ResultSet>
1212
*
1313
* @throws \Amp\Mysql\FailureException If the operation fails due to unexpected condition.
1414
* @throws \Amp\Mysql\ConnectionException If the connection to the database is lost.
@@ -17,16 +17,28 @@ interface Executor {
1717
public function query(string $sql): Promise;
1818

1919
/**
20-
* @param string $sql
20+
* @param string $sql SQL query to prepare.
2121
*
22-
* @return \Amp\Promise<\Amp\Postgres\Statement>
22+
* @return \Amp\Promise<\Amp\Mysql\Statement>
2323
*
2424
* @throws \Amp\Mysql\FailureException If the operation fails due to unexpected condition.
2525
* @throws \Amp\Mysql\ConnectionException If the connection to the database is lost.
2626
* @throws \Amp\Mysql\QueryError If the operation fails due to an error in the query (such as a syntax error).
2727
*/
2828
public function prepare(string $sql): Promise;
2929

30+
/**
31+
* @param string $sql SQL query to prepare and execute.
32+
* @param mixed ...$data Query parameters.
33+
*
34+
* @return \Amp\Promise<\Amp\Mysql\CommandResult|\Amp\Mysql\ResultSet>
35+
*
36+
* @throws \Amp\Mysql\FailureException If the operation fails due to unexpected condition.
37+
* @throws \Amp\Mysql\ConnectionException If the connection to the database is lost.
38+
* @throws \Amp\Mysql\QueryError If the operation fails due to an error in the query (such as a syntax error).
39+
*/
40+
public function execute(string $sql, ...$data): Promise;
41+
3042
/**
3143
* Closes the executor. No further queries may be performed.
3244
*/

‎lib/Transaction.php

+18
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public function __destruct() {
3333
}
3434
}
3535

36+
/**
37+
* {@inheritdoc}
38+
*
39+
* Closes and commits all changes in the transaction.
40+
*/
3641
public function close() {
3742
if ($this->connection) {
3843
$this->commit(); // Invokes $this->queue->complete().
@@ -86,6 +91,19 @@ public function prepare(string $sql): Promise {
8691
return $this->connection->prepare($sql);
8792
}
8893

94+
/**
95+
* {@inheritdoc}
96+
*
97+
* @throws \Amp\Mysql\TransactionError If the transaction has been committed or rolled back.
98+
*/
99+
public function execute(string $sql, ...$data): Promise {
100+
if ($this->connection === null) {
101+
throw new TransactionError("The transaction has been committed or rolled back");
102+
}
103+
104+
return $this->connection->execute($sql, ...$data);
105+
}
106+
89107
/**
90108
* Commits the transaction and makes it inactive.
91109
*

‎test/Mysql/ConnectionTest.php

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use Amp\Mysql\CommandResult;
34
use Amp\Mysql\DataTypes;
45
use Amp\Mysql\ResultSet;
56
use PHPUnit\Framework\TestCase;
@@ -28,6 +29,7 @@ function testQuery() {
2829

2930
/** @var \Amp\Mysql\ResultSet $resultset */
3031
$resultset = yield $db->query("SELECT 1 AS a");
32+
$this->assertInstanceOf(ResultSet::class, $resultset);
3133

3234
for ($i = 0; yield $resultset->advance(); ++$i) {
3335
$this->assertEquals(["a" => 1], $resultset->getCurrent());
@@ -48,6 +50,7 @@ function testQueryFetchRow() {
4850

4951
/** @var \Amp\Mysql\ResultSet $resultset */
5052
$resultset = yield $db->query('SELECT a FROM tmp');
53+
$this->assertInstanceOf(ResultSet::class, $resultset);
5154

5255
$got = [];
5356
while (yield $resultset->advance(ResultSet::FETCH_ARRAY)) {
@@ -71,7 +74,7 @@ function testMultiStmt() {
7174

7275
/** @var \Amp\Mysql\ResultSet $resultset */
7376
$resultset = yield $db->query("INSERT INTO tmp VALUES (5, 6), (8, 9); SELECT a FROM tmp; SELECT b FROM tmp WHERE a = 5; SELECT b AS d, a + 1 AS c FROM tmp WHERE b < 7");
74-
77+
$this->assertInstanceOf(ResultSet::class, $resultset);
7578

7679
$got = [];
7780
while (yield $resultset->advance(ResultSet::FETCH_ARRAY)) {
@@ -119,6 +122,7 @@ function testPrepared() {
119122
$this->assertEquals(yield $stmt->getFields(), [$base + ["name" => "a", "original_name" => "a"], $base + ["name" => "b", "original_name" => "b"]]);
120123
$stmt->bind("num", 9);
121124
$result = yield $stmt->execute(5);
125+
$this->assertInstanceOf(ResultSet::class, $result);
122126
$got = [];
123127
while (yield $result->advance(ResultSet::FETCH_ARRAY)) {
124128
$got[] = $result->getCurrent();
@@ -128,6 +132,7 @@ function testPrepared() {
128132
/** @var \Amp\Mysql\Statement $stmt */
129133
$stmt = yield $db->prepare("SELECT * FROM tmp WHERE a = ? OR b = ?");
130134
$result = yield $stmt->execute(5, 8);
135+
$this->assertInstanceOf(ResultSet::class, $result);
131136
$got = [];
132137
while (yield $result->advance(ResultSet::FETCH_ARRAY)) {
133138
$got[] = $result->getCurrent();
@@ -138,6 +143,7 @@ function testPrepared() {
138143
$stmt = yield $db->prepare("SELECT * FROM tmp WHERE a = :a OR b = ?");
139144
$stmt->bind("a", 5);
140145
$result = yield $stmt->execute(9);
146+
$this->assertInstanceOf(ResultSet::class, $result);
141147
$got = [];
142148
while (yield $result->advance(ResultSet::FETCH_ARRAY)) {
143149
$got[] = $result->getCurrent();
@@ -149,6 +155,32 @@ function testPrepared() {
149155
$stmt->bind("bar", 9);
150156
/** @var \Amp\Mysql\CommandResult $result */
151157
$result = yield $stmt->execute();
158+
$this->assertInstanceOf(CommandResult::class, $result);
159+
$this->assertSame(1, $result->affectedRows());
160+
});
161+
}
162+
163+
function testExecute() {
164+
\Amp\Loop::run(function () {
165+
/** @var \Amp\Mysql\Connection $db */
166+
$db = yield connect("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=connectiontest");
167+
168+
$db->query("CREATE TEMPORARY TABLE tmp SELECT 1 AS a, 2 AS b");
169+
$db->query("INSERT INTO tmp VALUES (5, 6), (8, 9), (10, 11), (12, 13)");
170+
171+
/** @var \Amp\Mysql\ResultSet $result */
172+
$result = yield $db->execute("SELECT * FROM tmp WHERE a = ? OR b = ?", 5, 9);
173+
$this->assertInstanceOf(ResultSet::class, $result);
174+
$got = [];
175+
while (yield $result->advance(ResultSet::FETCH_ARRAY)) {
176+
$got[] = $result->getCurrent();
177+
}
178+
$this->assertCount(2, $got);
179+
$this->assertSame([[5, 6], [8, 9]], $got);
180+
181+
/** @var \Amp\Mysql\CommandResult $result */
182+
$result = yield $db->execute("INSERT INTO tmp VALUES (?, ?)", 14, 15);
183+
$this->assertInstanceOf(CommandResult::class, $result);
152184
$this->assertSame(1, $result->affectedRows());
153185
});
154186
}

0 commit comments

Comments
 (0)
Please sign in to comment.