Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | n/a |
0 / 0 |
n/a |
0 / 0 |
CRAP | n/a |
0 / 0 |
|||
Select | n/a |
0 / 0 |
n/a |
0 / 0 |
36 | n/a |
0 / 0 |
|||
createPdoConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
2 | |||||
setReadConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
getReadConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
5 | |||||
hasReadConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
2 | |||||
closeReadConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
setWriteConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
getWriteConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
8 | |||||
hasWriteConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
2 | |||||
closeWriteConnection | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
setQueryCache | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
setProfiling | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
setCriticalReadSession | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
setTransaction | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
writeRollback | n/a |
0 / 0 |
n/a |
0 / 0 |
3 | |||||
writeCommit | n/a |
0 / 0 |
n/a |
0 / 0 |
4 | |||||
writeCommitWithStartLock | n/a |
0 / 0 |
n/a |
0 / 0 |
2 |
1 | <?php |
2 | |
3 | namespace BO\Zmsdb\Connection; |
4 | |
5 | /** |
6 | * |
7 | * @codeCoverageIgnore |
8 | * |
9 | * @SuppressWarnings(TooManyFields) |
10 | * Handle read and write connections |
11 | */ |
12 | class Select |
13 | { |
14 | /** |
15 | * @var Bool $enableProfiling |
16 | */ |
17 | public static $enableProfiling = false; |
18 | |
19 | /** |
20 | * @var String $readSourceName PDO connection string |
21 | */ |
22 | public static $readSourceName = null; |
23 | |
24 | /** |
25 | * @var String $writeSourceName PDO connection string |
26 | */ |
27 | public static $writeSourceName = null; |
28 | |
29 | /** |
30 | * @var String $dbname_zms |
31 | */ |
32 | public static $dbname_zms = 'zmsbo'; |
33 | |
34 | /** |
35 | * @var String $username Login |
36 | */ |
37 | public static $username = null; |
38 | |
39 | /** |
40 | * @var String $password Credential |
41 | */ |
42 | public static $password = null; |
43 | |
44 | /** |
45 | * @var Array $pdoOptions compatible to the 4th PDO::__construct parameter |
46 | */ |
47 | public static $pdoOptions = []; |
48 | |
49 | /** |
50 | * @var String $connectionTimezone |
51 | * |
52 | */ |
53 | public static $connectionTimezone = ' UTC'; |
54 | |
55 | /** |
56 | * @var Bool $enableWsrepSyncWait |
57 | */ |
58 | public static $enableWsrepSyncWait = false; |
59 | |
60 | /** |
61 | * @var Bool $enableWsrepSyncWait |
62 | */ |
63 | public static $galeraConnection = false; |
64 | |
65 | /** |
66 | * @var PdoInterface $readConnection for read only requests |
67 | */ |
68 | protected static $readConnection = null; |
69 | |
70 | /** |
71 | * @var PdoInterface $writeConnection for write only requests |
72 | */ |
73 | protected static $writeConnection = null; |
74 | |
75 | /** |
76 | * @var \Aura\Sql\Profiler $readProfiler for read only requests |
77 | */ |
78 | protected static $readProfiler = null; |
79 | |
80 | /** |
81 | * @var \Aura\Sql\Profiler $writeProfiler for write only requests |
82 | */ |
83 | protected static $writeProfiler = null; |
84 | |
85 | /** |
86 | * @var Bool $useTransaction |
87 | * |
88 | */ |
89 | protected static $useTransaction = false; |
90 | |
91 | /** |
92 | * @var Bool $useProfiling |
93 | * |
94 | */ |
95 | protected static $useProfiling = false; |
96 | |
97 | /** |
98 | * @var Bool $useQueryCache |
99 | * |
100 | */ |
101 | protected static $useQueryCache = true; |
102 | |
103 | /** |
104 | * Create a PDO compatible object |
105 | * |
106 | * @param String $dataSourceName compatible with PDO |
107 | * @return PdoInterface |
108 | */ |
109 | protected static function createPdoConnection($dataSourceName) |
110 | { |
111 | try { |
112 | $pdoOptions = array_merge([ |
113 | ], self::$pdoOptions); |
114 | $pdo = new Pdo($dataSourceName, self::$username, self::$password, $pdoOptions); |
115 | $pdo->exec('SET NAMES "UTF8";'); |
116 | //$timezone = date_default_timezone_get(); |
117 | //$pdo->prepare('SET time_zone = ?;')->execute([$timezone]); |
118 | $pdo->exec('SET SESSION sql_mode = "STRICT_ALL_TABLES";'); |
119 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
120 | } catch (\Exception $exception) { |
121 | // Extend exception message with connection information |
122 | $connectInfo = $dataSourceName; |
123 | throw new \BO\Zmsdb\Exception\Pdo\PDOFailed( |
124 | $connectInfo . $exception->getMessage(), |
125 | (int)$exception->getCode(), |
126 | $exception |
127 | ); |
128 | } |
129 | return $pdo; |
130 | } |
131 | |
132 | /** |
133 | * Set the read connection. |
134 | * Usually this function is only required to set mockups for testing |
135 | * |
136 | * @param PdoInterface $connection |
137 | */ |
138 | public static function setReadConnection(PdoInterface $connection) |
139 | { |
140 | self::$readConnection = $connection; |
141 | } |
142 | |
143 | /** |
144 | * Create or return a connection for reading data |
145 | * |
146 | * @return PdoInterface |
147 | */ |
148 | public static function getReadConnection() |
149 | { |
150 | if (null === self::$readConnection) { |
151 | self::$readConnection = self::createPdoConnection(self::$readSourceName); |
152 | self::$readProfiler = new \Aura\Sql\Profiler\Profiler(); |
153 | self::$readProfiler->setActive(self::$enableProfiling); |
154 | self::$readConnection->setProfiler(self::$readProfiler); |
155 | //self::$readConnection->exec('SET SESSION TRANSACTION READ ONLY'); |
156 | if (!self::$useQueryCache) { |
157 | try { |
158 | self::$readConnection->exec('SET SESSION query_cache_type = 0;'); |
159 | } catch (\Exception $exception) { |
160 | // ignore, query cache might be disabled |
161 | } |
162 | } |
163 | if (self::$useProfiling) { |
164 | self::$readConnection->exec('SET profiling = 1;'); |
165 | } |
166 | } |
167 | return self::$readConnection; |
168 | } |
169 | |
170 | /** |
171 | * Test if a read connection is established |
172 | * |
173 | */ |
174 | public static function hasReadConnection() |
175 | { |
176 | return (null === self::$readConnection) ? false : true; |
177 | } |
178 | |
179 | /** |
180 | * Close a connection for reading data |
181 | * |
182 | */ |
183 | public static function closeReadConnection() |
184 | { |
185 | self::$readConnection = null; |
186 | } |
187 | |
188 | /** |
189 | * Set the write connection. |
190 | * Usually this function is only required to set mockups for testing |
191 | * |
192 | * @param PdoInterface $connection |
193 | * @return self |
194 | */ |
195 | public static function setWriteConnection(PdoInterface $connection) |
196 | { |
197 | self::$writeConnection = $connection; |
198 | } |
199 | |
200 | /** |
201 | * Create or return a connection for writing data |
202 | * |
203 | * @return PdoInterface |
204 | */ |
205 | public static function getWriteConnection() |
206 | { |
207 | if (null === self::$writeConnection) { |
208 | self::$writeConnection = self::createPdoConnection(self::$writeSourceName); |
209 | self::$writeProfiler = new \Aura\Sql\Profiler\Profiler(); |
210 | self::$writeProfiler->setActive(self::$enableProfiling); |
211 | self::$writeConnection->setProfiler(self::$writeProfiler); |
212 | if (self::$useTransaction) { |
213 | self::$writeConnection->exec('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED'); |
214 | self::$writeConnection->exec('SET SESSION innodb_lock_wait_timeout=15'); |
215 | self::$writeConnection->beginTransaction(); |
216 | } |
217 | if (!self::$useQueryCache) { |
218 | try { |
219 | self::$writeConnection->exec('SET SESSION query_cache_type = 0;'); |
220 | } catch (\Exception $exception) { |
221 | // ignore, query cache might be disabled |
222 | } |
223 | } |
224 | if (self::$useProfiling) { |
225 | self::$writeConnection->exec('SET profiling = 1;'); |
226 | } |
227 | if (self::$galeraConnection && self::$enableWsrepSyncWait) { |
228 | self::$writeConnection->exec( |
229 | 'SET SESSION wsrep_sync_wait = ( |
230 | SELECT CAST(value AS INT) FROM config WHERE name = "setting__wsrepsync" |
231 | );' |
232 | ); |
233 | } |
234 | // On writing, use the same host to avoid racing/transaction conditions |
235 | self::$readConnection = self::$writeConnection; |
236 | } |
237 | return self::$writeConnection; |
238 | } |
239 | |
240 | /** |
241 | * Test if a write connection is established |
242 | * |
243 | */ |
244 | public static function hasWriteConnection() |
245 | { |
246 | return (null === self::$writeConnection) ? false : true; |
247 | } |
248 | |
249 | /** |
250 | * Close a connection for writing data |
251 | * |
252 | */ |
253 | public static function closeWriteConnection() |
254 | { |
255 | self::$writeConnection = null; |
256 | } |
257 | |
258 | /** |
259 | * Set query cache |
260 | * |
261 | * @param Bool $useQueryCache |
262 | * |
263 | */ |
264 | public static function setQueryCache($useQueryCache = true) |
265 | { |
266 | static::$useQueryCache = $useQueryCache; |
267 | } |
268 | |
269 | /** |
270 | * Set profiling |
271 | * |
272 | * @param Bool $useProfiling |
273 | * |
274 | */ |
275 | public static function setProfiling($useProfiling = true) |
276 | { |
277 | static::$useProfiling = $useProfiling; |
278 | } |
279 | |
280 | /** |
281 | * Set cluster wide causality checks, needed for critical reads across different nodes |
282 | * @param Bool $wsrepStatus Set to true for critical reads |
283 | */ |
284 | public static function setCriticalReadSession($wsrepStatus = true) |
285 | { |
286 | static::$enableWsrepSyncWait = $wsrepStatus; |
287 | static::getWriteConnection(); |
288 | } |
289 | |
290 | /** |
291 | * Set transaction |
292 | * |
293 | * @param Bool $useTransaction |
294 | * |
295 | */ |
296 | public static function setTransaction($useTransaction = true) |
297 | { |
298 | static::$useTransaction = $useTransaction; |
299 | } |
300 | |
301 | /** |
302 | * Rollback transaction if started |
303 | * |
304 | */ |
305 | public static function writeRollback() |
306 | { |
307 | if (self::$useTransaction && self::getWriteConnection()->inTransaction()) { |
308 | return self::getWriteConnection()->rollBack(); |
309 | } |
310 | return null; |
311 | } |
312 | |
313 | /** |
314 | * Commit transaction if started |
315 | * |
316 | */ |
317 | public static function writeCommit() |
318 | { |
319 | if (self::$useTransaction && null !== self::$writeConnection && self::getWriteConnection()->inTransaction()) { |
320 | $status = self::getWriteConnection()->commit(); |
321 | self::$writeConnection->beginTransaction(); |
322 | return $status; |
323 | } |
324 | return null; |
325 | } |
326 | |
327 | public static function writeCommitWithStartLock() |
328 | { |
329 | return self::writeCommit() && (new \BO\Zmsdb\Config())->readProperty('status__calculateSlotsLastRun', true); |
330 | } |
331 | } |