Skip to content

Commit b19b970

Browse files
committed
added state transition repository
1 parent 69610aa commit b19b970

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

src/Bolt/ServerStateRepository.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Laudis Neo4j package.
7+
*
8+
* (c) Laudis technologies <http://laudis.tech>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Laudis\Neo4j\Bolt;
15+
16+
use function in_array;
17+
18+
/**
19+
* @see https://7687.org/bolt/bolt-protocol-server-state-specification-4.html#version-43
20+
*/
21+
final class ServerStateRepository
22+
{
23+
private const KEYS = ['State' => 0, 'Request Message' => 1, 'Triggers Signal' => 2, 'Server Response' => 3, 'New State' => 4];
24+
public function canSendMessage(string $state, string $message): bool
25+
{
26+
return in_array($message, $this->getMessagesForState($state), true);
27+
}
28+
29+
public function isValidState(string $state): bool
30+
{
31+
return in_array($state, $this->getStates(), true);
32+
}
33+
34+
private const TRANSITIONS = [
35+
['CONNECTED', 'HELLO', null, 'SUCCESS', 'READY'],
36+
['CONNECTED', 'HELLO', null, 'FAILURE', 'DEFUNCT'],
37+
38+
['READY', 'RUN', null, 'SUCCESS', 'STREAMING'],
39+
['READY', 'RUN', null, 'FAILURE', 'FAILED'],
40+
['READY', 'BEGIN', null, 'SUCCESS', 'TX_READY'],
41+
['READY', 'BEGIN', null, 'FAILURE', 'FAILED'],
42+
['READY', 'ROUTE', null, 'SUCCESS', 'READY'],
43+
['READY', 'RESET', 'INTERRUPT', null, null],
44+
['READY', 'GOODBYE', 'DISCONNECT', null, 'DEFUNCT'],
45+
46+
['STREAMING', 'PULL', null, 'SUCCESS', 'STREAMING'],
47+
['STREAMING', 'PULL', null, 'SUCCESS', 'READY'],
48+
['STREAMING', 'PULL', null, 'FAILURE', 'FAILED'],
49+
['STREAMING', 'DISCARD', null, 'SUCCESS', 'STREAMING'],
50+
['STREAMING', 'DISCARD', null, 'SUCCESS', 'READY'],
51+
['STREAMING', 'DISCARD', null, 'FAILURE', 'FAILED'],
52+
['STREAMING', 'RESET', 'INTERRUPT', null, null],
53+
['STREAMING', 'GOODBYE', 'DISCONNECT', null, 'DEFUNCT'],
54+
55+
['TX_READY', 'RUN', null, 'SUCCESS', 'TX_STREAMING'],
56+
['TX_READY', 'RUN', null, 'FAILURE', 'FAILED'],
57+
['TX_READY', 'COMMIT', null, 'SUCCESS', 'READY'],
58+
['TX_READY', 'COMMIT', null, 'FAILURE', 'FAILED'],
59+
['TX_READY', 'ROLLBACK', null, 'SUCCESS', 'READY'],
60+
['TX_READY', 'ROLLBACK', null, 'FAILURE', 'FAILED'],
61+
['TX_READY', 'RESET', 'INTERRUPT', null, null],
62+
['TX_READY', 'GOODBYE', 'DISCONNECT', null, 'DEFUNCT'],
63+
64+
['TX_STREAMING', 'RUN', null, 'SUCCESS', 'TX_STREAMING'],
65+
['TX_STREAMING', 'RUN', null, 'FAILURE', 'FAILED'],
66+
['TX_STREAMING', 'PULL', null, 'SUCCESS', 'TX_STREAMING'],
67+
['TX_STREAMING', 'PULL', null, 'SUCCESS', 'TX_READY'],
68+
['TX_STREAMING', 'PULL', null, 'FAILURE', 'FAILED'],
69+
['TX_STREAMING', 'DISCARD', null, 'SUCCESS', 'TX_STREAMING'],
70+
['TX_STREAMING', 'DISCARD', null, 'SUCCESS', 'TX_READY'],
71+
['TX_STREAMING', 'DISCARD', null, 'FAILURE', 'FAILED'],
72+
['TX_STREAMING', 'RESET', 'INTERRUPT', null, null],
73+
['TX_STREAMING', 'GOODBYE', 'DISCONNECT', null, 'DEFUNCT'],
74+
75+
['FAILED', 'RUN', null, 'IGNORED', 'FAILED'],
76+
['FAILED', 'PULL', null, 'IGNORED', 'FAILED'],
77+
['FAILED', 'DISCARD', null, 'IGNORED', 'FAILED'],
78+
['FAILED', 'RESET', 'INTERRUPT', null, null],
79+
['FAILED', 'GOODBYE', 'DISCONNECT', null, 'DEFUNCT'],
80+
81+
['INTERRUPTED', 'RUN', null, 'IGNORED', 'INTERRUPTED'],
82+
['INTERRUPTED', 'PULL', null, 'IGNORED', 'INTERRUPTED'],
83+
['INTERRUPTED', 'DISCARD', null, 'IGNORED', 'INTERRUPTED'],
84+
['INTERRUPTED', 'BEGIN', null, 'IGNORED', 'INTERRUPTED'],
85+
['INTERRUPTED', 'COMMIT', null, 'IGNORED', 'INTERRUPTED'],
86+
['INTERRUPTED', 'ROLLBACK', null, 'IGNORED', 'INTERRUPTED'],
87+
['INTERRUPTED', 'RESET', 'INTERRUPT', 'SUCCESS', 'READY'],
88+
['INTERRUPTED', 'RESET', 'INTERRUPT', 'FAILURE', 'DEFUNCT'],
89+
['INTERRUPTED', 'GOODBYE', 'DISCONNECT', null, 'DEFUNCT'],
90+
];
91+
92+
/**
93+
* @return list<string>
94+
*/
95+
public function getMessagesForState(string $state): array
96+
{
97+
$messages = [];
98+
foreach (self::TRANSITIONS as $transition) {
99+
if ($transition[self::KEYS['State']] === $state) {
100+
$messages[] = $transition[self::KEYS['Request Message']];
101+
}
102+
}
103+
104+
return $messages;
105+
}
106+
107+
/**
108+
* @return list<string>
109+
*/
110+
public function getStates(): array
111+
{
112+
/** @var list<string> */
113+
return array_unique(array_map(static fn (array $x) => $x[self::KEYS['State']], self::TRANSITIONS));
114+
}
115+
}

tests/Integration/TransactionIntegrationTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,4 +410,18 @@ public function testTransactionRunNoConsumeResult(string $alias): void
410410
$tsx->run('MATCH (x) RETURN x');
411411
$tsx->commit();
412412
}
413+
414+
/**
415+
* @dataProvider connectionAliases
416+
*
417+
* @doesNotPerformAssertions
418+
*/
419+
public function testTransactionRunNoConsumeButSaveResult(string $alias): void
420+
{
421+
$tsx = $this->getClient()->beginTransaction([], $alias);
422+
$result = $tsx->run("MATCH (n:Node) SET n.testing = 'world' RETURN n");
423+
$tsx->commit();
424+
425+
unset($result);
426+
}
413427
}

0 commit comments

Comments
 (0)