• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

prooph / event-store-client / 9555551525

17 Jun 2024 10:16PM UTC coverage: 70.262% (-1.1%) from 71.395%
9555551525

push

github

prolic
update coveralls repo token

3466 of 4933 relevant lines covered (70.26%)

67.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.13
/src/ClientOperations/ConditionalAppendToStreamOperation.php
1
<?php
2

3
/**
4
 * This file is part of `prooph/event-store-client`.
5
 * (c) 2018-2024 Alexander Miertsch <kontakt@codeliner.ws>
6
 * (c) 2018-2024 Sascha-Oliver Prolic <saschaprolic@googlemail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace Prooph\EventStoreClient\ClientOperations;
15

16
use Amp\DeferredFuture;
17
use Google\Protobuf\Internal\Message;
18
use Prooph\EventStore\ConditionalWriteResult;
19
use Prooph\EventStore\ConditionalWriteStatus;
20
use Prooph\EventStore\EventData;
21
use Prooph\EventStore\Exception\AccessDenied;
22
use Prooph\EventStore\Exception\InvalidTransaction;
23
use Prooph\EventStore\Exception\UnexpectedOperationResult;
24
use Prooph\EventStore\Position;
25
use Prooph\EventStore\UserCredentials;
26
use Prooph\EventStoreClient\Internal\NewEventConverter;
27
use Prooph\EventStoreClient\Messages\ClientMessages\NewEvent;
28
use Prooph\EventStoreClient\Messages\ClientMessages\OperationResult;
29
use Prooph\EventStoreClient\Messages\ClientMessages\WriteEvents;
30
use Prooph\EventStoreClient\Messages\ClientMessages\WriteEventsCompleted;
31
use Prooph\EventStoreClient\SystemData\InspectionDecision;
32
use Prooph\EventStoreClient\SystemData\InspectionResult;
33
use Prooph\EventStoreClient\SystemData\TcpCommand;
34
use Psr\Log\LoggerInterface as Logger;
35

36
/**
37
 * @internal
38
 * @extends AbstractOperation<WriteEventsCompleted, ConditionalWriteResult>
39
 */
40
class ConditionalAppendToStreamOperation extends AbstractOperation
41
{
42
    /**
43
     * @param Logger $logger
44
     * @param DeferredFuture $deferred
45
     * @param bool $requireMaster
46
     * @param string $stream
47
     * @param int $expectedVersion
48
     * @param list<EventData> $events
49
     * @param UserCredentials|null $userCredentials
50
     */
51
    public function __construct(
52
        Logger $logger,
53
        DeferredFuture $deferred,
54
        private readonly bool $requireMaster,
55
        private readonly string $stream,
56
        private readonly int $expectedVersion,
57
        private readonly array $events,
58
        ?UserCredentials $userCredentials
59
    ) {
60
        parent::__construct(
3✔
61
            $logger,
3✔
62
            $deferred,
3✔
63
            $userCredentials,
3✔
64
            TcpCommand::WriteEvents,
3✔
65
            TcpCommand::WriteEventsCompleted,
3✔
66
            WriteEventsCompleted::class
3✔
67
        );
3✔
68
    }
69

70
    protected function createRequestDto(): Message
71
    {
72
        $events = \array_map(
3✔
73
            fn (EventData $event): NewEvent => NewEventConverter::convert($event),
3✔
74
            $this->events
3✔
75
        );
3✔
76

77
        $message = new WriteEvents();
3✔
78
        $message->setEventStreamId($this->stream);
3✔
79
        $message->setExpectedVersion($this->expectedVersion);
3✔
80
        $message->setRequireMaster($this->requireMaster);
3✔
81
        $message->setEvents($events);
3✔
82

83
        return $message;
3✔
84
    }
85

86
    /**
87
     * @param WriteEventsCompleted $response
88
     * @return InspectionResult
89
     */
90
    protected function inspectResponse(Message $response): InspectionResult
91
    {
92
        switch ($response->getResult()) {
3✔
93
            case OperationResult::Success:
94
                $this->succeed($response);
1✔
95

96
                return new InspectionResult(InspectionDecision::EndOperation, 'Success');
1✔
97
            case OperationResult::PrepareTimeout:
98
                return new InspectionResult(InspectionDecision::Retry, 'PrepareTimeout');
×
99
            case OperationResult::ForwardTimeout:
100
                return new InspectionResult(InspectionDecision::Retry, 'ForwardTimeout');
×
101
            case OperationResult::CommitTimeout:
102
                return new InspectionResult(InspectionDecision::Retry, 'CommitTimeout');
×
103
            case OperationResult::WrongExpectedVersion:
104
                $this->succeed($response);
1✔
105

106
                return new InspectionResult(InspectionDecision::EndOperation, 'ExpectedVersionMismatch');
1✔
107
            case OperationResult::StreamDeleted:
108
                $this->succeed($response);
1✔
109

110
                return new InspectionResult(InspectionDecision::EndOperation, 'StreamDeleted');
1✔
111
            case OperationResult::InvalidTransaction:
112
                $exception = new InvalidTransaction();
×
113
                $this->fail($exception);
×
114

115
                return new InspectionResult(InspectionDecision::EndOperation, 'InvalidTransaction');
×
116
            case OperationResult::AccessDenied:
117
                $exception = AccessDenied::toStream($this->stream);
×
118
                $this->fail($exception);
×
119

120
                return new InspectionResult(InspectionDecision::EndOperation, 'AccessDenied');
×
121
            default:
122
                throw new UnexpectedOperationResult();
×
123
        }
124
    }
125

126
    protected function transformResponse(Message $response): ConditionalWriteResult
127
    {
128
        if ($response->getResult() === OperationResult::WrongExpectedVersion) {
3✔
129
            return ConditionalWriteResult::fail(ConditionalWriteStatus::VersionMismatch);
1✔
130
        }
131

132
        if ($response->getResult() === OperationResult::StreamDeleted) {
2✔
133
            return ConditionalWriteResult::fail(ConditionalWriteStatus::StreamDeleted);
1✔
134
        }
135

136
        /** @psalm-suppress DocblockTypeContradiction */
137
        return ConditionalWriteResult::success(
1✔
138
            (int) $response->getLastEventNumber(),
1✔
139
            new Position(
1✔
140
                (int) ($response->getCommitPosition() ?? -1),
1✔
141
                (int) ($response->getPreparePosition() ?? -1)
1✔
142
            )
1✔
143
        );
1✔
144
    }
145

146
    public function name(): string
147
    {
148
        return 'ConditionalAppendToStream';
3✔
149
    }
150

151
    public function __toString(): string
152
    {
153
        return \sprintf(
3✔
154
            'Stream: %s, ExpectedVersion: %d, RequireMaster: %s',
3✔
155
            $this->stream,
3✔
156
            $this->expectedVersion,
3✔
157
            $this->requireMaster ? 'yes' : 'no'
3✔
158
        );
3✔
159
    }
160
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc