22
33namespace Amp \Postgres \Test ;
44
5+ use Amp \Future ;
6+ use Amp \Postgres \PostgresListener ;
7+ use Amp \Postgres \PostgresNotification ;
8+ use Amp \Postgres \QueryExecutionError ;
59use Amp \Sql \ConnectionException ;
10+ use Amp \Sql \QueryError ;
11+ use Amp \Sql \SqlException ;
12+ use Revolt \EventLoop ;
613use function Amp \async ;
714
815abstract class AbstractConnectionTest extends AbstractLinkTest
@@ -24,10 +31,83 @@ public function testConnectionCloseDuringQuery(): void
2431 try {
2532 $ query ->await ();
2633 self ::fail (\sprintf ('Expected %s to be thrown ' , ConnectionException::class));
27- } catch (ConnectionException ) {
34+ } catch (SqlException ) {
2835 // Expected
2936 }
3037
3138 $ this ->assertLessThan (0.1 , \microtime (true ) - $ start );
3239 }
40+
41+ public function testListen ()
42+ {
43+ $ channel = "test " ;
44+ $ listener = $ this ->link ->listen ($ channel );
45+
46+ $ this ->assertInstanceOf (PostgresListener::class, $ listener );
47+ $ this ->assertSame ($ channel , $ listener ->getChannel ());
48+
49+ EventLoop::delay (0.1 , function () use ($ channel ): void {
50+ $ this ->link ->query (\sprintf ("NOTIFY %s, '%s' " , $ channel , '0 ' ));
51+ $ this ->link ->query (\sprintf ("NOTIFY %s, '%s' " , $ channel , '1 ' ));
52+ });
53+
54+ $ count = 0 ;
55+ EventLoop::delay (0.2 , fn () => $ listener ->unlisten ());
56+
57+ /** @var PostgresNotification $notification */
58+ foreach ($ listener as $ notification ) {
59+ $ this ->assertSame ($ notification ->getPayload (), (string ) $ count ++);
60+ }
61+
62+ $ this ->assertSame (2 , $ count );
63+ }
64+
65+ /**
66+ * @depends testListen
67+ */
68+ public function testNotify ()
69+ {
70+ $ channel = "test " ;
71+ $ listener = $ this ->link ->listen ($ channel );
72+
73+ EventLoop::delay (0.1 , function () use ($ channel ) {
74+ $ this ->link ->notify ($ channel , '0 ' );
75+ $ this ->link ->notify ($ channel , '1 ' );
76+ });
77+
78+ $ count = 0 ;
79+ EventLoop::delay (0.2 , fn () => $ listener ->unlisten ());
80+
81+ /** @var PostgresNotification $notification */
82+ foreach ($ listener as $ notification ) {
83+ $ this ->assertSame ($ notification ->getPayload (), (string ) $ count ++);
84+ }
85+
86+ $ this ->assertSame (2 , $ count );
87+ }
88+
89+ /**
90+ * @depends testListen
91+ */
92+ public function testListenOnSameChannel ()
93+ {
94+ $ this ->expectException (QueryError::class);
95+ $ this ->expectExceptionMessage ('Already listening on channel ' );
96+
97+ $ channel = "test " ;
98+ Future \await ([$ this ->link ->listen ($ channel ), $ this ->link ->listen ($ channel )]);
99+ }
100+
101+ public function testQueryAfterErroredQuery ()
102+ {
103+ try {
104+ $ result = $ this ->link ->query ("INSERT INTO test VALUES ('github', 'com', '{1, 2, 3}', true, 4.2) " );
105+ } catch (QueryExecutionError $ exception ) {
106+ // Expected exception due to duplicate key.
107+ }
108+
109+ $ result = $ this ->link ->query ("INSERT INTO test VALUES ('gitlab', 'com', '{1, 2, 3}', true, 4.2) " );
110+
111+ $ this ->assertSame (1 , $ result ->getRowCount ());
112+ }
33113}
0 commit comments