Skip to content

Commit 3044366

Browse files
authored
Merge pull request #65 from clue-labs/quit
Rename close() to quit() and use promises for quit() method
2 parents 12b344f + 8f8a6db commit 3044366

File tree

10 files changed

+118
-79
lines changed

10 files changed

+118
-79
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ $factory->createConnection($uri)->then(function (ConnectionInterface $connection
4444
}
4545
);
4646

47-
$connection->close();
47+
$connection->quit();
4848
});
4949

5050
$loop->run();
@@ -259,6 +259,22 @@ $connection->ping()->then(function () {
259259
});
260260
```
261261

262+
#### quit()
263+
264+
The `quit(): PromiseInterface<void, Exception>` method can be used to
265+
quit (soft-close) the connection.
266+
267+
This method returns a promise that will resolve (with a void value) on
268+
success or will reject with an `Exception` on error. The MySQL protocol
269+
is inherently sequential, so that all commands will be performed in order
270+
and outstanding commands will be put into a queue to be executed once the
271+
previous commands are completed.
272+
273+
```php
274+
$connection->query('CREATE TABLE test ...');
275+
$connection->quit();
276+
```
277+
262278
## Install
263279

264280
The recommended way to install this library is [through Composer](https://getcomposer.org).

examples/01-query.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
echo 'Error: ' . $error->getMessage() . PHP_EOL;
3333
});
3434

35-
$connection->close();
35+
$connection->quit();
3636
}, 'printf');
3737

3838
$loop->run();

examples/02-query-stream.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
echo 'CLOSED' . PHP_EOL;
2727
});
2828

29-
$connection->close();
29+
$connection->quit();
3030
}, 'printf');
3131

3232
$loop->run();

examples/11-interactive.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
if ($query === 'exit') {
3232
// exit command should close the connection
3333
echo 'bye.' . PHP_EOL;
34-
$connection->close();
34+
$connection->quit();
3535
return;
3636
}
3737

@@ -74,9 +74,7 @@
7474

7575
// close connection when STDIN closes (EOF or CTRL+D)
7676
$stdin->on('close', function () use ($connection) {
77-
if ($connection->getState() === ConnectionInterface::STATE_AUTHENTICATED) {
78-
$connection->close();
79-
}
77+
$connection->quit();
8078
});
8179

8280
// close STDIN (stop reading) when connection closes

src/ConnectionInterface.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,20 @@ public function getServerOptions();
208208
public function getState();
209209

210210
/**
211-
* Close the connection.
211+
* Quits (soft-close) the connection.
212212
*
213-
* @param callable|null $callback A callback which should be run after
214-
* connection successfully closed.
215-
*
216-
* $callback signature:
213+
* This method returns a promise that will resolve (with a void value) on
214+
* success or will reject with an `Exception` on error. The MySQL protocol
215+
* is inherently sequential, so that all commands will be performed in order
216+
* and outstanding commands will be put into a queue to be executed once the
217+
* previous commands are completed.
217218
*
218-
* function (ConnectionInterface $conn): void
219+
* ```php
220+
* $connection->query('CREATE TABLE test ...');
221+
* $connection->quit();
222+
* ```
219223
*
220-
* @return void
221-
* @throws Exception if the connection is not initialized or already closed/closing
224+
* @return PromiseInterface Returns a Promise<void,Exception>
222225
*/
223-
public function close($callback = null);
226+
public function quit();
224227
}

src/Io/Connection.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -215,21 +215,21 @@ public function getState()
215215
return $this->state;
216216
}
217217

218-
/**
219-
* {@inheritdoc}
220-
*/
221-
public function close($callback = null)
218+
public function quit()
222219
{
223-
$this->_doCommand(new QuitCommand($this))
224-
->on('success', function () use ($callback) {
225-
$this->state = self::STATE_CLOSED;
226-
$this->emit('end', [$this]);
227-
$this->emit('close', [$this]);
228-
if (is_callable($callback)) {
229-
$callback($this);
230-
}
231-
});
232-
$this->state = self::STATE_CLOSEING;
220+
return new Promise(function ($resolve, $reject) {
221+
$this->_doCommand(new QuitCommand($this))
222+
->on('error', function ($reason) use ($reject) {
223+
$reject($reason);
224+
})
225+
->on('success', function () use ($resolve) {
226+
$this->state = self::STATE_CLOSED;
227+
$this->emit('end', [$this]);
228+
$this->emit('close', [$this]);
229+
$resolve();
230+
});
231+
$this->state = self::STATE_CLOSEING;
232+
});
233233
}
234234

235235
/**

tests/FactoryTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public function testConnectWithValidAuthWillRunUtilClose()
106106
$uri = $this->getConnectionString();
107107
$factory->createConnection($uri)->then(function (ConnectionInterface $connection) {
108108
echo 'connected.';
109-
$connection->close(function ($e) {
109+
$connection->quit()->then(function () {
110110
echo 'closed.';
111111
});
112112
}, 'printf')->then(null, 'printf');
@@ -127,7 +127,7 @@ public function testConnectWithValidAuthCanPingAndClose()
127127
$connection->ping()->then(function () {
128128
echo 'ping.';
129129
});
130-
$connection->close(function ($e) {
130+
$connection->quit()->then(function () {
131131
echo 'closed.';
132132
});
133133
}, 'printf')->then(null, 'printf');

tests/Io/ConnectionTest.php

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,19 @@ public function testConnectTwiceThrowsExceptionForSecondCall()
5656
$conn->doConnect(function () { });
5757
}
5858

59-
/**
60-
* @expectedException React\MySQL\Exception
61-
* @expectedExceptionMessage Can't send command
62-
*/
63-
public function testCloseWithoutConnectThrows()
59+
public function testQuitWithoutConnectRejects()
6460
{
6561
$options = $this->getConnectionOptions();
6662
$loop = \React\EventLoop\Factory::create();
6763
$conn = new Connection($loop, $options);
6864

69-
$conn->close(function () { });
65+
$conn->quit()->done(
66+
$this->expectCallableNever(),
67+
function (\Exception $error) {
68+
$this->assertInstanceOf('React\MySQL\Exception', $error);
69+
$this->assertSame('Can\'t send command', $error->getMessage());
70+
}
71+
);
7072
}
7173

7274
public function testQueryWithoutConnectRejects()
@@ -99,7 +101,7 @@ function (\Exception $error) {
99101
);
100102
}
101103

102-
public function testCloseWhileConnectingWillBeQueuedAfterConnection()
104+
public function testQuitWhileConnectingWillBeQueuedAfterConnection()
103105
{
104106
$this->expectOutputString('connectedclosed');
105107
$options = $this->getConnectionOptions();
@@ -109,14 +111,34 @@ public function testCloseWhileConnectingWillBeQueuedAfterConnection()
109111
$conn->doConnect(function ($err) {
110112
echo $err ? $err : 'connected';
111113
});
112-
$conn->close(function () {
114+
$conn->quit()->then(function () {
113115
echo 'closed';
114116
});
115117

116118
$loop->run();
117119
}
118120

119-
public function testPingAfterConnectWillEmitErrorWhenServerClosesConnection()
121+
public function testQuitAfterQuitWhileConnectingWillBeRejected()
122+
{
123+
$options = $this->getConnectionOptions();
124+
$loop = \React\EventLoop\Factory::create();
125+
$conn = new Connection($loop, $options);
126+
127+
$conn->doConnect(function ($err) { });
128+
$conn->quit();
129+
130+
$conn->quit()->done(
131+
$this->expectCallableNever(),
132+
function (\Exception $error) {
133+
$this->assertInstanceOf('React\MySQL\Exception', $error);
134+
$this->assertSame('Can\'t send command', $error->getMessage());
135+
}
136+
);
137+
138+
$loop->run();
139+
}
140+
141+
public function testConnectWillEmitErrorWhenServerClosesConnection()
120142
{
121143
$this->expectOutputString('Connection lost');
122144

@@ -142,7 +164,7 @@ public function testPingAfterConnectWillEmitErrorWhenServerClosesConnection()
142164
$loop->run();
143165
}
144166

145-
public function testConnectWillEmitErrorWhenServerClosesConnection()
167+
public function testPingAfterConnectWillEmitErrorWhenServerClosesConnection()
146168
{
147169
$this->expectOutputString('Connection lost');
148170

@@ -172,7 +194,7 @@ function ($err) {
172194
$loop->run();
173195
}
174196

175-
public function testPingAndCloseWhileConnectingWillBeQueuedAfterConnection()
197+
public function testPingAndQuitWhileConnectingWillBeQueuedAfterConnection()
176198
{
177199
$this->expectOutputString('connectedpingclosed');
178200
$options = $this->getConnectionOptions();
@@ -187,14 +209,14 @@ public function testPingAndCloseWhileConnectingWillBeQueuedAfterConnection()
187209
}, function () {
188210
echo $err;
189211
});
190-
$conn->close(function () {
212+
$conn->quit()->then(function () {
191213
echo 'closed';
192214
});
193215

194216
$loop->run();
195217
}
196218

197-
public function testPingAfterCloseWhileConnectingRejectsImmediately()
219+
public function testPingAfterQuitWhileConnectingRejectsImmediately()
198220
{
199221
$this->expectOutputString('connectedclosed');
200222
$options = $this->getConnectionOptions();
@@ -204,7 +226,7 @@ public function testPingAfterCloseWhileConnectingRejectsImmediately()
204226
$conn->doConnect(function ($err) {
205227
echo $err ? $err : 'connected';
206228
});
207-
$conn->close(function () {
229+
$conn->quit()->then(function () {
208230
echo 'closed';
209231
});
210232

@@ -217,7 +239,7 @@ public function testPingAfterCloseWhileConnectingRejectsImmediately()
217239
$loop->run();
218240
}
219241

220-
public function testCloseWhileConnectingWithInvalidPassWillNeverFire()
242+
public function testQuitWhileConnectingWithInvalidPassWillNeverFire()
221243
{
222244
$this->expectOutputString('error');
223245
$options = $this->getConnectionOptions();
@@ -227,7 +249,7 @@ public function testCloseWhileConnectingWithInvalidPassWillNeverFire()
227249
$conn->doConnect(function ($err) {
228250
echo $err ? 'error' : 'connected';
229251
});
230-
$conn->close(function () {
252+
$conn->quit()->then(function () {
231253
echo 'never';
232254
});
233255

@@ -260,7 +282,7 @@ public function testConnectWithValidPass()
260282
});
261283

262284
$conn->ping()->then(function () use ($loop, $conn) {
263-
$conn->close(function ($conn) {
285+
$conn->quit()->done(function () use ($conn) {
264286
$this->assertEquals($conn::STATE_CLOSED, $conn->getState());
265287
});
266288
});

tests/NoResultQueryTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public function setUp()
1515
$connection->query('DROP TABLE IF EXISTS book');
1616
$connection->query($this->getDataTable());
1717

18-
$connection->close();
18+
$connection->quit();
1919
$loop->run();
2020
}
2121

@@ -28,7 +28,7 @@ public function testUpdateSimpleNonExistentReportsNoAffectedRows()
2828
$this->assertEquals(0, $command->affectedRows);
2929
});
3030

31-
$connection->close();
31+
$connection->quit();
3232
$loop->run();
3333
}
3434

@@ -42,7 +42,7 @@ public function testInsertSimpleReportsFirstInsertId()
4242
$this->assertEquals(1, $command->insertId);
4343
});
4444

45-
$connection->close();
45+
$connection->quit();
4646
$loop->run();
4747
}
4848

@@ -56,7 +56,7 @@ public function testUpdateSimpleReportsAffectedRow()
5656
$this->assertEquals(1, $command->affectedRows);
5757
});
5858

59-
$connection->close();
59+
$connection->quit();
6060
$loop->run();
6161
}
6262
}

0 commit comments

Comments
 (0)