Completed
Push — master ( 4ebe21...b06780 )
by Daniel
05:47
created

MySQLiByDanielGP::getMySQLgenericInformations()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
/**
4
 *
5
 * The MIT License (MIT)
6
 *
7
 * Copyright (c) 2015 Daniel Popiniuc
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
29
namespace danielgp\common_lib;
30
31
/**
32
 * Usefull functions to get quick MySQL content
33
 *
34
 * @author Daniel Popiniuc
35
 */
36
trait MySQLiByDanielGP
37
{
38
39
    use DomComponentsByDanielGP,
40
        MySQLiMultipleExecution,
41
        MySQLiByDanielGPqueries,
42
        MySQLiByDanielGPtypes;
43
44
    /**
45
     * Intiates connection to MySQL
46
     *
47
     * @param array $mySQLconfig
48
     *
49
     * $mySQLconfig           = [
50
     * 'host'     => MYSQL_HOST,
51
     * 'port'     => MYSQL_PORT,
52
     * 'username' => MYSQL_USERNAME,
53
     * 'password' => MYSQL_PASSWORD,
54
     * 'database' => MYSQL_DATABASE,
55
     * ];
56
     */
57
    protected function connectToMySql($mySQLconfig)
58
    {
59
        if (is_null($this->mySQLconnection)) {
60
            extract($mySQLconfig);
61
            $this->mySQLconnection = new \mysqli($host, $username, $password, $database, $port);
62
            if (is_null($this->mySQLconnection->connect_error)) {
63
                return '';
64
            }
65
            $this->mySQLconnection = null;
66
            $erNo                  = $this->mySQLconnection->connect_errno;
67
            $erMsg                 = $this->mySQLconnection->connect_error;
68
            $msg                   = $this->lclMsgCmn('i18n_Feedback_ConnectionError');
69
            return sprintf($msg, $erNo, $erMsg, $host, $port, $username, $database);
70
        }
71
    }
72
73
    /**
74
     * Ensures table has special quoes and DOT as final char
75
     * (if not empty, of course)
76
     *
77
     * @param string $referenceTable
78
     * @return string
79
     */
80
    private function correctTableWithQuotesAsFieldPrefix($referenceTable)
81
    {
82
        if ($referenceTable != '') {
83
            return '`' . str_replace('`', '', $referenceTable) . '`.';
84
        }
85
        return '';
86
    }
87
88
    /**
89
     * Return various informations (from predefined list) from the MySQL server
90
     *
91
     * @return int|array
92
     */
93
    protected function getMySQLlistMultiple($returnChoice, $returnType, $additionalFeatures = null)
94
    {
95
        if (is_null($this->mySQLconnection)) {
96
            if ($returnType == 'value') {
97
                return null;
98
            }
99
            return [];
100
        }
101
        return $this->getMySQLlistMultipleFinal($returnChoice, $returnType, $additionalFeatures);
102
    }
103
104
    /**
105
     * Return various informations (from predefined list) from the MySQL server
106
     *
107
     * @return array
108
     */
109
    private function getMySQLlistMultipleFinal($returnChoice, $returnType, $additionalFeatures = null)
110
    {
111
        $queryByChoice = [
112
            'Columns'         => $this->sQueryMySqlColumns($additionalFeatures),
113
            'Databases'       => $this->sQueryMySqlActiveDatabases($additionalFeatures),
114
            'Engines'         => $this->sQueryMySqlActiveEngines($additionalFeatures),
115
            'Indexes'         => $this->sQueryMySqlIndexes($additionalFeatures),
116
            'ServerTime'      => $this->sQueryMySqlServerTime(),
117
            'Statistics'      => $this->sQueryMySqlStatistics($additionalFeatures),
118
            'Tables'          => $this->sQueryMySqlTables($additionalFeatures),
119
            'VariablesGlobal' => $this->sQueryMySqlGlobalVariables(),
120
        ];
121
        if (array_key_exists($returnChoice, $queryByChoice)) {
122
            return $this->setMySQLquery2Server($queryByChoice[$returnChoice], $returnType)['result'];
123
        }
124
        return [];
125
    }
126
127
    /**
128
     * Provides a detection if given Query does contain a Parameter
129
     * that may require statement processing later on
130
     *
131
     * @param string $sQuery
132
     * @param string $paramIdentifier
133
     * @return boolean
134
     */
135
    protected function getMySQLqueryWithParameterIdentifier($sQuery, $paramIdentifier)
136
    {
137
        $sReturn = true;
138
        if (strpos($sQuery, $paramIdentifier) === false) {
139
            $sReturn = false;
140
        }
141
        return $sReturn;
142
    }
143
144
    /**
145
     * Return the time from the MySQL server
146
     *
147
     * @return string
148
     */
149
    protected function getMySQLserverTime()
150
    {
151
        return $this->getMySQLlistMultiple('ServerTime', 'value');
152
    }
153
154
    /**
155
     * Reads data from table into REQUEST super global
156
     *
157
     * @param string $tableName
158
     * @param array $filtersArray
159
     */
160
    protected function getRowDataFromTable($tableName, $filtersArray)
161
    {
162
        $query   = $this->sQueryRowsFromTable([$tableName, $this->setArrayToFilterValues($filtersArray)]);
163
        $rawData = $this->setMySQLquery2Server($query, 'array_pairs_key_value')['result'];
164
        if (!is_null($rawData)) {
165
            $this->initializeSprGlbAndSession();
166
            foreach ($rawData as $key => $value) {
167
                $vToSet = str_replace(['\\\\"', '\\"', "\\\\'", "\\'"], ['"', '"', "'", "'"], $value);
168
                $this->tCmnRequest->request->set($key, $vToSet);
169
            }
170
        }
171
    }
172
173
    /**
174
     * Builds an filter string from pair of key and value, where value is array
175
     *
176
     * @param string $key
177
     * @param array $value
178
     * @param string $referenceTable
179
     * @return string
180
     */
181
    private function setArrayLineArrayToFilter($key, $value, $referenceTable)
182
    {
183
        $filters2 = implode(', ', array_diff($value, ['']));
184
        if ($filters2 != '') {
185
            return '(' . $referenceTable . '`' . $key . '` IN ("'
186
                    . str_replace(',', '","', str_replace(["'", '"'], '', $filters2)) . '"))';
187
        }
188
        return '';
189
    }
190
191
    /**
192
     * Builds an filter string from pair of key and value, none array
193
     *
194
     * @param string $key
195
     * @param int|float|string $value
196
     * @return string
197
     */
198
    private function setArrayLineToFilter($key, $value)
199
    {
200
        $fTemp = '=';
201
        if ((substr($value, 0, 1) == '%') && (substr($value, -1) == '%')) {
202
            $fTemp = 'LIKE';
203
        }
204
        return '(`' . $key . '` ' . $fTemp . '"' . $value . '")';
205
    }
206
207
    /**
208
     * Transforms an array into usable filters
209
     *
210
     * @param array $entryArray
211
     * @param string $referenceTable
212
     * @return array
213
     */
214
    private function setArrayToFilterValues($entryArray, $referenceTable = '')
215
    {
216
        $filters  = [];
217
        $refTable = $this->correctTableWithQuotesAsFieldPrefix($referenceTable);
218
        foreach ($entryArray as $key => $value) {
219
            if (is_array($value)) {
220
                $filters[] = $this->setArrayLineArrayToFilter($key, $value, $refTable);
221
            } elseif (!in_array($value, ['', '%%'])) {
222
                $filters[] = $this->setArrayLineToFilter($key, $value);
223
            }
224
        }
225
        return implode(' AND ', array_diff($filters, ['']));
226
    }
227
228
    /**
229
     * Transmit Query to MySQL server and get results back
230
     *
231
     * @param string $sQuery
232
     * @param string $sReturnType
233
     * @param array $ftrs
234
     * @return boolean|array|string
235
     */
236
    protected function setMySQLquery2Server($sQuery, $sReturnType = null, $ftrs = null)
237
    {
238
        if (is_null($sReturnType)) {
239
            $this->mySQLconnection->query(html_entity_decode($sQuery));
240
            return '';
241
        } elseif (is_null($this->mySQLconnection)) {
242
            return ['customError' => $this->lclMsgCmn('i18n_MySQL_ConnectionNotExisting'), 'result' => null];
243
        }
244
        $result = $this->mySQLconnection->query(html_entity_decode($sQuery));
245
        if ($result) {
246
            return $this->setMySQLquery2ServerConnected(['Result' => $result, 'RType' => $sReturnType, 'F' => $ftrs]);
247
        }
248
        $erM  = [$this->mySQLconnection->errno, $this->mySQLconnection->error];
249
        $cErr = sprintf($this->lclMsgCmn('i18n_MySQL_QueryError'), $erM[0], $erM[1]);
250
        return ['customError' => $cErr, 'result' => null];
251
    }
252
253
    /**
254
     * Turns a raw query result into various structures
255
     * based on different predefined $parameters['returnType'] value
256
     *
257
     * @param array $parameters
258
     * @return array as ['customError' => '...', 'result' => '...']
259
     */
260
    private function setMySQLquery2ServerByPattern($parameters)
261
    {
262
        $aReturn = $parameters['return'];
263
        $vld     = $this->setMySQLqueryValidateInputs($parameters);
264
        if ($vld[1] !== '') {
265
            return ['customError' => $vld[1], 'result' => ''];
266
        } elseif ($parameters['returnType'] == 'value') {
267
            return ['customError' => $vld[1], 'result' => $parameters['QueryResult']->fetch_row()[0]];
268
        }
269
        $counter2 = 0;
270
        for ($counter = 0; $counter < $parameters['NoOfRows']; $counter++) {
271
            $line = $parameters['QueryResult']->fetch_row();
272
            if (in_array($parameters['returnType'], ['array_key_value', 'array_key2_value', 'array_numbered'])) {
273
                $rslt                        = $this->setMySQLquery2ServerByPatternKey($parameters, $line, $counter);
274
                $aReturn['result'][$rslt[0]] = $rslt[1];
275
            } elseif ($parameters['returnType'] == 'array_key_value2') {
276
                $aReturn['result'][$line[0]][] = $line[1];
277
            } else {
278
                $finfo = $parameters['QueryResult']->fetch_fields();
279
                foreach ($finfo as $columnCounter => $value) {
280
                    switch ($parameters['returnType']) {
281
                        case 'array_first_key_rest_values':
282
                            if ($columnCounter !== 0) {
283
                                $aReturn['result'][$line[0]][$value->name] = $line[$columnCounter];
284
                            }
285
                            break;
286
                        case 'array_pairs_key_value':
287
                            $aReturn['result'][$value->name]                                   = $line[$columnCounter];
288
                            break;
289
                        case 'full_array_key_numbered':
290
                            $aReturn['result'][$counter2][$value->name]                        = $line[$columnCounter];
291
                            break;
292
                        case 'full_array_key_numbered_with_record_number_prefix':
293
                            $parameters['prefix']                                              = 'RecordNo';
294
                        // intentionally left open
295
                        case 'full_array_key_numbered_with_prefix':
296
                            $aReturn['result'][$parameters['prefix']][$counter2][$value->name] = $line[$columnCounter];
297
                            break;
298
                    }
299
                }
300
                $counter2++;
301
            }
302
        }
303
        return ['customError' => '', 'result' => $aReturn['result']];
304
    }
305
306
    private function setMySQLquery2ServerByPatternKey($parameters, $line, $counter)
307
    {
308
        switch ($parameters['returnType']) {
309
            case 'array_key_value':
310
                return [$line[0], $line[1]];
311
            // intentionally left open
312
            case 'array_key2_value':
313
                return [$line[0] . '@' . $line[1], $line[1]];
314
            // intentionally left open
315
            case 'array_numbered':
316
                return [$counter, $line[0]];
317
            // intentionally left open
318
        }
319
    }
320
321
    private function setMySQLquery2ServerConnected($inArray)
322
    {
323
        if ($inArray['RType'] == 'id') {
324
            return ['customError' => '', 'result' => $this->mySQLconnection->insert_id];
325
        } elseif ($inArray['RType'] == 'lines') {
326
            return ['result' => $inArray['Result']->num_rows, 'customError' => ''];
327
        }
328
        $parameters = [
329
            'NoOfColumns' => $inArray['Result']->field_count,
330
            'NoOfRows'    => $inArray['Result']->num_rows,
331
            'QueryResult' => $inArray['Result'],
332
            'returnType'  => $inArray['RType'],
333
            'return'      => ['customError' => '', 'result' => null]
334
        ];
335
        if (substr($inArray['RType'], -6) == 'prefix') {
336
            $parameters['prefix'] = $inArray['F']['prefix'];
337
        }
338
        return $this->setMySQLquery2ServerByPattern($parameters);
339
    }
340
341
    private function setMySQLqueryValidateInputs($prm)
342
    {
343
        $rMap = $this->setMySQLqueryValidationMap();
344
        if (array_key_exists($prm['returnType'], $rMap)) {
345
            $elC = [$prm['NoOfRows'], $rMap[$prm['returnType']]['r'][0], $rMap[$prm['returnType']]['r'][1]];
346
            if (filter_var($elC[0], FILTER_VALIDATE_INT, ['min_range' => $elC[1], 'max_range' => $elC[2]]) === false) {
347
                $msg = $this->lclMsgCmn('i18n_MySQL_QueryResultExpected' . $rMap[$prm['returnType']][2]);
348
                return [false, sprintf($msg, $prm['NoOfColumns'])];
349
            }
350
            $elR = [$prm['NoOfColumns'], $rMap[$prm['returnType']]['c'][0], $rMap[$prm['returnType']]['c'][1]];
351
            if (filter_var($elR[0], FILTER_VALIDATE_INT, ['min_range' => $elR[1], 'max_range' => $elR[2]])) {
352
                return [true, ''];
353
            }
354
            $msg = $this->lclMsgCmn('i18n_MySQL_QueryResultExpected' . $rMap[$prm['returnType']][1]);
355
            return [false, sprintf($msg, $prm['NoOfColumns'])];
356
        }
357
        return [false, $prm['returnType'] . ' is not defined!'];
358
    }
359
360
    private function setMySQLqueryValidationMap()
361
    {
362
        $lngKey = 'full_array_key_numbered_with_record_number_prefix';
363
        return [
364
            'array_first_key_rest_values'         => ['r' => [1, 999999], 'c' => [2, 99], 'AtLeast2ColsResultedOther'],
365
            'array_key_value'                     => ['r' => [1, 999999], 'c' => [2, 2], '2ColumnsResultedOther'],
366
            'array_key_value2'                    => ['r' => [1, 999999], 'c' => [2, 2], '2ColumnsResultedOther'],
367
            'array_key2_value'                    => ['r' => [1, 999999], 'c' => [2, 2], '2ColumnsResultedOther'],
368
            'array_numbered'                      => ['r' => [1, 999999], 'c' => [1, 1], '1ColumnResultedOther'],
369
            'array_pairs_key_value'               => ['r' => [1, 1], 'c' => [1, 99], '1RowManyColumnsResultedOther'],
370
            'full_array_key_numbered'             => ['r' => [1, 999999], 'c' => [1, 99], '1OrMoreRows0Resulted'],
371
            'full_array_key_numbered_with_prefix' => ['r' => [1, 999999], 'c' => [1, 99], '1OrMoreRows0Resulted'],
372
            $lngKey                               => ['r' => [1, 999999], 'c' => [1, 99], '1OrMoreRows0Resulted'],
373
            'value'                               => ['r' => [1, 1], 'c' => [1, 1], '1ResultedOther'],
374
        ];
375
    }
376
}
377