TransactionGuard::transaction()   A
last analyzed

Complexity

Conditions 5
Paths 9

Size

Total Lines 43
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 18
nc 9
nop 1
dl 0
loc 43
rs 9.3554
c 0
b 0
f 0
1
<?php
2
/**
3
 * Transaction guard
4
 * User: moyo
5
 * Date: 03/11/2017
6
 * Time: 11:35 AM
7
 */
8
9
namespace Carno\Database\Chips;
10
11
use Carno\Database\Contracts\Executable;
12
use Carno\Database\Contracts\Transaction as TransAPI;
13
use Carno\Database\Exception\TransactionException;
14
use Carno\Database\Programs\Transaction as TransEXE;
15
use Carno\Pool\Pool;
16
use Carno\Pool\Poolable;
17
use Carno\Promise\Promise;
18
use Closure;
19
use Throwable;
20
21
trait TransactionGuard
22
{
23
    /**
24
     * @param Closure $program
25
     * @return mixed
26
     * @throws TransactionException
27
     */
28
    public function transaction(Closure $program)
29
    {
30
        /**
31
         * @var Pool $pool
32
         * @var TransAPI|Executable|Poolable $link
33
         */
34
        $pool = $this->assigned();
0 ignored issues
show
Bug introduced by
It seems like assigned() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

34
        /** @scrutinizer ignore-call */ 
35
        $pool = $this->assigned();
Loading history...
35
        $link = yield $pool->select();
36
37
        // assigned waiters
38
        $start = Promise::deferred();
39
        $commit = Promise::deferred();
40
        $rollback = Promise::deferred();
41
42
        // automatic release after commit
43
        $commit->then(static function () use ($link) {
44
            $link->release();
0 ignored issues
show
Bug introduced by
The method release() does not exist on Carno\Database\Contracts\Transaction. It seems like you code against a sub-type of Carno\Database\Contracts\Transaction such as Carno\Database\Connectors\MySQL. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
            $link->/** @scrutinizer ignore-call */ 
45
                   release();
Loading history...
Bug introduced by
The method release() does not exist on Carno\Database\Contracts\Executable. It seems like you code against a sub-type of Carno\Database\Contracts\Executable such as Carno\Database\Connectors\MySQL. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
            $link->/** @scrutinizer ignore-call */ 
45
                   release();
Loading history...
45
        });
46
47
        // automatic release after rollback
48
        $rollback->then(static function () use ($link) {
49
            $link->release();
50
        });
51
52
        // create session for transaction
53
        $session = new TransEXE($link, $start, $commit, $rollback);
0 ignored issues
show
Bug introduced by
It seems like $link can also be of type Carno\Database\Contracts\Executable and Carno\Pool\Poolable; however, parameter $link of Carno\Database\Programs\Transaction::__construct() does only seem to accept Carno\Database\Contracts\Transaction, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

53
        $session = new TransEXE(/** @scrutinizer ignore-type */ $link, $start, $commit, $rollback);
Loading history...
54
55
        // wait for transaction started
56
        yield $session->begin();
57
58
        // flows
59
        try {
60
            // call user program
61
            $finished = yield $program($session);
62
            // automatic commit
63
            $commit->pended() && $rollback->pended() && yield $session->commit();
64
            // finished
65
            return $finished;
66
        } catch (Throwable $e) {
67
            // automatic rollback
68
            $rollback->pended() && yield $session->rollback();
69
            // throw to next
70
            throw $e;
71
        }
72
    }
73
}
74