Connection   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 210
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 210
rs 10
c 0
b 0
f 0
wmc 15
lcom 2
cbo 3

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A query() 0 8 1
A select() 0 13 1
A prepareBindings() 0 14 3
A run() 0 13 1
A runQueryCallback() 0 15 2
A setDefaultProcessor() 0 4 1
A useDefaultProcessor() 0 4 1
A setProcessor() 0 4 1
A getProcessor() 0 4 1
A getClient() 0 4 1
A getElapsedTime() 0 4 1
1
<?php
2
3
namespace Magister\Services\Database;
4
5
use Closure;
6
use Exception;
7
use GuzzleHttp\Client;
8
use Magister\Services\Database\Query\Builder;
9
use Magister\Services\Database\Query\Processors\Processor;
10
11
/**
12
 * Class Connection.
13
 */
14
class Connection implements ConnectionInterface
15
{
16
    /**
17
     * The active connection.
18
     *
19
     * @var \GuzzleHttp\Client
20
     */
21
    protected $client;
22
23
    /**
24
     * The query processor implementation.
25
     *
26
     * @var \Magister\Services\Database\Query\Processors\Processor
27
     */
28
    protected $processor;
29
30
    /**
31
     * The execution time.
32
     *
33
     * @var float
34
     */
35
    protected $time;
36
37
    /**
38
     * Create a new connection instance.
39
     *
40
     * @param \GuzzleHttp\Client $client
41
     */
42
    public function __construct(Client $client)
43
    {
44
        $this->client = $client;
45
46
        $this->useDefaultProcessor();
47
    }
48
49
    /**
50
     * Start a query against the server.
51
     *
52
     * @param string $query
53
     *
54
     * @return \Magister\Services\Database\Query\Builder
55
     */
56
    public function query($query)
57
    {
58
        $processor = $this->getProcessor();
59
60
        $builder = new Builder($this, $processor);
61
62
        return $builder->from($query);
63
    }
64
65
    /**
66
     * Run a select statement against the server.
67
     *
68
     * @param string $query
69
     * @param array  $bindings
70
     *
71
     * @return mixed
72
     */
73
    public function select($query, $bindings = [])
74
    {
75
        return $this->run($query, $bindings, function ($me, $query, $bindings) {
76
            list($query, $bindings) = $me->prepareBindings($query, $bindings);
77
78
            // For select statements, we'll simply execute the query and return an array
79
            // of the result set. Each element in the array will be a single
80
            // row from the response, and will either be an array or objects.
81
            $statement = $me->getClient()->get($query, ['query' => $bindings]);
82
83
            return $statement->json();
84
        });
85
    }
86
87
    /**
88
     * Prepare the query bindings for execution.
89
     *
90
     * @param string $query
91
     * @param array  $bindings
92
     *
93
     * @return array
94
     */
95
    public function prepareBindings($query, array $bindings)
96
    {
97
        foreach ($bindings as $key => $value) {
98
            $search = ':'.lcfirst($key);
99
100
            if (strpos($query, $search) !== false) {
101
                $query = str_replace($search, $value, $query);
102
103
                unset($bindings[$key]);
104
            }
105
        }
106
107
        return [$query, $bindings];
108
    }
109
110
    /**
111
     * Run a statement and log its execution context.
112
     *
113
     * @param string   $query
114
     * @param array    $bindings
115
     * @param \Closure $callback
116
     *
117
     * @return mixed
118
     */
119
    public function run($query, $bindings, Closure $callback)
120
    {
121
        $start = microtime(true);
122
123
        $result = $this->runQueryCallback($query, $bindings, $callback);
124
125
        // Once we have run the query we will calculate the time that it took to run and
126
        // then log the query, bindings, and execution time so we will report them on
127
        // the event that the developer needs them. We'll log time in milliseconds.
128
        $this->time = $this->getElapsedTime($start);
129
130
        return $result;
131
    }
132
133
    /**
134
     * Run a SQL statement.
135
     *
136
     * @param string   $query
137
     * @param array    $bindings
138
     * @param \Closure $callback
139
     *
140
     * @throws \Magister\Services\Database\QueryException
141
     *
142
     * @return mixed
143
     */
144
    protected function runQueryCallback($query, $bindings, Closure $callback)
145
    {
146
        try {
147
            $result = $callback($this, $query, $bindings);
148
        } catch (Exception $e) {
149
            // If an exception occurs when attempting to run a request, we'll format the error
150
            // message to include the bindings, which will make this exception a
151
            // lot more helpful to the developer instead of just the client's errors.
152
            list($query, $bindings) = $this->prepareBindings($query, $bindings);
153
154
            throw new QueryException($query, $bindings, $e);
155
        }
156
157
        return $result;
158
    }
159
160
    /**
161
     * Set the default processor.
162
     *
163
     * @return \Magister\Services\Database\Query\Processors\Processor
164
     */
165
    public function setDefaultProcessor()
166
    {
167
        return new Processor();
168
    }
169
170
    /**
171
     * Use the default processor.
172
     *
173
     * @return void
174
     */
175
    public function useDefaultProcessor()
176
    {
177
        $this->processor = $this->setDefaultProcessor();
178
    }
179
180
    /**
181
     * Set the processor used by the connection.
182
     *
183
     * @param \Magister\Services\Database\Query\Processors\Processor $processor
184
     *
185
     * @return void
186
     */
187
    public function setProcessor(Processor $processor)
188
    {
189
        $this->processor = $processor;
190
    }
191
192
    /**
193
     * Get the processor used by the connection.
194
     *
195
     * @return \Magister\Services\Database\Query\Processors\Processor
196
     */
197
    public function getProcessor()
198
    {
199
        return $this->processor;
200
    }
201
202
    /**
203
     * Get the current client.
204
     *
205
     * @return \GuzzleHttp\Client
206
     */
207
    public function getClient()
208
    {
209
        return $this->client;
210
    }
211
212
    /**
213
     * Get the elapsed time since a given starting point.
214
     *
215
     * @param int $start
216
     *
217
     * @return float
218
     */
219
    protected function getElapsedTime($start)
220
    {
221
        return round((microtime(true) - $start) * 1000, 2);
222
    }
223
}
224