Completed
Push — master ( d8f60e...a72876 )
by Changwan
03:40
created

MysqlConnection::execute()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 8
nop 2
dl 0
loc 17
ccs 12
cts 12
cp 1
crap 4
rs 9.2
c 0
b 0
f 0
1
<?php
2
namespace Wandu\Database\Connection;
3
4
use Exception;
5
use PDO;
6
use PDOStatement;
7
use Throwable;
8
use Wandu\Collection\ArrayList;
9
use Wandu\Database\Configuration;
10
use Wandu\Database\Contracts\ConnectionInterface;
11
use Wandu\Database\Contracts\QueryInterface;
12
use Wandu\Database\Events\Connect;
13
use Wandu\Database\Events\ExecuteQuery;
14
use Wandu\Event\DispatcherInterface;
15
16
class MysqlConnection implements ConnectionInterface
17
{
18
    /** @var \PDO */
19
    protected $pdo;
20
21
    /** @var \Wandu\Database\Configuration */
22
    protected $config;
23
24
    /** @var \Wandu\Event\DispatcherInterface */
25
    protected $dispatcher;
26
    
27 19
    public function __construct(
28
        Configuration $config,
29
        DispatcherInterface $dispatcher = null
30
    ) {
31 19
        $this->config = $config;
32 19
        $this->dispatcher = $dispatcher;
33 19
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38 19
    public function connect()
39
    {
40 19
        if (!$this->pdo) {
41 19
            $this->pdo = $this->config->createPdo();
42 19
            if ($this->dispatcher) {
43 18
                $this->dispatcher->trigger(new Connect());
44
            }
45
        }
46 19
        return $this;
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52 8
    public function fetch($query, array $bindings = [])
53
    {
54 8
        $statement = $this->execute($query, $bindings);
55 8
        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
56 8
            yield $row;
57
        }
58 8
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function all($query, array $bindings = [])
64
    {
65
        return new ArrayList($this->fetch($query, $bindings));
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71 12
    public function first($query, array $bindings = [])
72
    {
73 12
        $attributes = $this->execute($query, $bindings)->fetch(PDO::FETCH_ASSOC);
74 12
        return $attributes ?: null;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80 2
    public function query($query, array $bindings = [])
81
    {
82 2
        return $this->execute($query, $bindings)->rowCount();
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 1
    public function getLastInsertId()
89
    {
90 1
        return $this->pdo->lastInsertId();
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function transaction(callable $handler)
97
    {
98
        $this->pdo->beginTransaction();
99
        try {
100
            call_user_func($handler, $this);
101
        } catch (Exception $e) {
102
            $this->pdo->rollBack();
103
            throw $e;
104
        } catch (Throwable $e) {
105
            $this->pdo->rollBack();
106
            throw $e;
107
        }
108
        $this->pdo->commit();
109
    }
110
111
    /**
112
     * @param string|callable|\Wandu\Database\Contracts\QueryInterface $query
113
     * @param array $bindings
114
     * @return \PDOStatement
115
     */
116 18
    protected function execute($query, array $bindings = [])
117
    {
118 18
        while (is_callable($query)) {
119 2
            $query = call_user_func($query);
120
        }
121 18
        if ($query instanceof QueryInterface) {
122 12
            $bindings = $query->getBindings();
123 12
            $query = $query->toSql();
124
        }
125 18
        $statement = $this->pdo->prepare($query);
126 18
        $this->bindValues($statement, $bindings);
127 18
        $statement->execute();
128 18
        if ($this->dispatcher) {
129 18
            $this->dispatcher->trigger(new ExecuteQuery($statement->queryString, $bindings));
130
        }
131 18
        return $statement;
132
    }
133
    
134
    /**
135
     * @param \PDOStatement $statement
136
     * @param array $bindings
137
     */
138 18
    protected function bindValues(PDOStatement $statement, array $bindings = [])
139
    {
140 18
        foreach ($bindings as $key => $value) {
141 18
            if (is_int($value)) {
142 11
                $dataType = PDO::PARAM_INT;
143 12
            } elseif (is_bool($value)) {
144
                $dataType = PDO::PARAM_BOOL;
145 12
            } elseif (is_null($value)) {
146
                $dataType = PDO::PARAM_NULL;
147
            } else {
148 12
                $dataType = PDO::PARAM_STR;
149
            }
150 18
            $statement->bindValue(
151 18
                is_int($key) ? $key + 1 : $key,
152
                $value,
153
                $dataType
154
            );
155
        }
156 18
    }
157
}
158