Completed
Push — master ( c45ea4...665550 )
by Daniel
02:25
created

setMySQLquery2ServerByPatternKey()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 14
rs 9.2
cc 4
eloc 8
nc 4
nop 3
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
     * Return various informations (from predefined list) from the MySQL server
75
     *
76
     * @return int|array
77
     */
78
    protected function getMySQLlistMultiple($returnChoice, $returnType, $additionalFeatures = null)
79
    {
80
        if (is_null($this->mySQLconnection)) {
81
            if ($returnType == 'value') {
82
                return null;
83
            }
84
            return [];
85
        }
86
        return $this->getMySQLlistMultipleFinal($returnChoice, $returnType, $additionalFeatures);
87
    }
88
89
    /**
90
     * Return various informations (from predefined list) from the MySQL server
91
     *
92
     * @return array
93
     */
94
    private function getMySQLlistMultipleFinal($returnChoice, $returnType, $additionalFeatures = null)
95
    {
96
        $queryByChoice = [
97
            'Columns'         => $this->sQueryMySqlColumns($additionalFeatures),
98
            'Databases'       => $this->sQueryMySqlActiveDatabases($additionalFeatures),
99
            'Engines'         => $this->sQueryMySqlActiveEngines($additionalFeatures),
100
            'Indexes'         => $this->sQueryMySqlIndexes($additionalFeatures),
101
            'ServerTime'      => $this->sQueryMySqlServerTime(),
102
            'Statistics'      => $this->sQueryMySqlStatistics($additionalFeatures),
103
            'Tables'          => $this->sQueryMySqlTables($additionalFeatures),
104
            'VariablesGlobal' => $this->sQueryMySqlGlobalVariables(),
105
        ];
106
        if (array_key_exists($returnChoice, $queryByChoice)) {
107
            return $this->setMySQLquery2Server($queryByChoice[$returnChoice], $returnType)['result'];
108
        }
109
        return [];
110
    }
111
112
    /**
113
     * Provides a detection if given Query does contain a Parameter
114
     * that may require statement processing later on
115
     *
116
     * @param string $sQuery
117
     * @param string $paramIdentifier
118
     * @return boolean
119
     */
120
    protected function getMySQLqueryWithParameterIdentifier($sQuery, $paramIdentifier)
121
    {
122
        $sReturn = true;
123
        if (strpos($sQuery, $paramIdentifier) === false) {
124
            $sReturn = false;
125
        }
126
        return $sReturn;
127
    }
128
129
    /**
130
     * Transmit Query to MySQL server and get results back
131
     *
132
     * @param string $sQuery
133
     * @param string $sReturnType
134
     * @param array $ftrs
135
     * @return boolean|array|string
136
     */
137
    protected function setMySQLquery2Server($sQuery, $sReturnType = null, $ftrs = null)
138
    {
139
        if (is_null($sReturnType)) {
140
            $this->mySQLconnection->query(html_entity_decode($sQuery));
141
            return '';
142
        } elseif (is_null($this->mySQLconnection)) {
143
            return ['customError' => $this->lclMsgCmn('i18n_MySQL_ConnectionNotExisting'), 'result' => null];
144
        }
145
        $result = $this->mySQLconnection->query(html_entity_decode($sQuery));
146
        if ($result) {
147
            return $this->setMySQLquery2ServerConnected(['Result' => $result, 'RType' => $sReturnType, 'F' => $ftrs]);
148
        }
149
        $erM  = [$this->mySQLconnection->errno, $this->mySQLconnection->error];
150
        $cErr = sprintf($this->lclMsgCmn('i18n_MySQL_QueryError'), $erM[0], $erM[1]);
151
        return ['customError' => $cErr, 'result' => null];
152
    }
153
154
    /**
155
     * Turns a raw query result into various structures
156
     * based on different predefined $parameters['returnType'] value
157
     *
158
     * @param array $parameters
159
     * @return array as ['customError' => '...', 'result' => '...']
160
     */
161
    private function setMySQLquery2ServerByPattern($parameters)
162
    {
163
        $aReturn = $parameters['return'];
164
        $vld     = $this->setMySQLqueryValidateInputs($parameters);
165
        if ($vld[1] !== '') {
166
            return ['customError' => $vld[1], 'result' => ''];
167
        } elseif ($parameters['returnType'] == 'value') {
168
            return ['customError' => $vld[1], 'result' => $parameters['QueryResult']->fetch_row()[0]];
169
        }
170
        $counter2 = 0;
171
        for ($counter = 0; $counter < $parameters['NoOfRows']; $counter++) {
172
            $line = $parameters['QueryResult']->fetch_row();
173
            if (in_array($parameters['returnType'], ['array_key_value', 'array_key2_value', 'array_numbered'])) {
174
                $rslt                        = $this->setMySQLquery2ServerByPatternKey($parameters, $line, $counter);
175
                $aReturn['result'][$rslt[0]] = $rslt[1];
176
            } elseif ($parameters['returnType'] == 'array_key_value2') {
177
                $aReturn['result'][$line[0]][] = $line[1];
178
            } else {
179
                $finfo = $parameters['QueryResult']->fetch_fields();
180
                foreach ($finfo as $columnCounter => $value) {
181
                    switch ($parameters['returnType']) {
182
                        case 'array_first_key_rest_values':
183
                            if ($columnCounter !== 0) {
184
                                $aReturn['result'][$line[0]][$value->name] = $line[$columnCounter];
185
                            }
186
                            break;
187
                        case 'array_pairs_key_value':
188
                            $aReturn['result'][$value->name]                                   = $line[$columnCounter];
189
                            break;
190
                        case 'full_array_key_numbered':
191
                            $aReturn['result'][$counter2][$value->name]                        = $line[$columnCounter];
192
                            break;
193
                        case 'full_array_key_numbered_with_record_number_prefix':
194
                            $parameters['prefix']                                              = 'RecordNo';
195
                        // intentionally left open
196
                        case 'full_array_key_numbered_with_prefix':
197
                            $aReturn['result'][$parameters['prefix']][$counter2][$value->name] = $line[$columnCounter];
198
                            break;
199
                    }
200
                }
201
                $counter2++;
202
            }
203
        }
204
        return ['customError' => '', 'result' => $aReturn['result']];
205
    }
206
207
    private function setMySQLquery2ServerByPatternKey($parameters, $line, $counter)
208
    {
209
        switch ($parameters['returnType']) {
210
            case 'array_key_value':
211
                return [$line[0], $line[1]];
212
            // intentionally left open
213
            case 'array_key2_value':
214
                return [$line[0] . '@' . $line[1], $line[1]];
215
            // intentionally left open
216
            case 'array_numbered':
217
                return [$counter, $line[0]];
218
            // intentionally left open
219
        }
220
    }
221
222
    private function setMySQLquery2ServerConnected($inArray)
223
    {
224
        if ($inArray['RType'] == 'id') {
225
            return ['customError' => '', 'result' => $this->mySQLconnection->insert_id];
226
        } elseif ($inArray['RType'] == 'lines') {
227
            return ['result' => $inArray['Result']->num_rows, 'customError' => ''];
228
        }
229
        $parameters = [
230
            'NoOfColumns' => $inArray['Result']->field_count,
231
            'NoOfRows'    => $inArray['Result']->num_rows,
232
            'QueryResult' => $inArray['Result'],
233
            'returnType'  => $inArray['RType'],
234
            'return'      => ['customError' => '', 'result' => null]
235
        ];
236
        if (substr($inArray['RType'], -6) == 'prefix') {
237
            $parameters['prefix'] = $inArray['F']['prefix'];
238
        }
239
        return $this->setMySQLquery2ServerByPattern($parameters);
240
    }
241
242
    private function setMySQLqueryValidateInputs($prm)
243
    {
244
        $rMap = $this->setMySQLqueryValidationMap();
245
        if (array_key_exists($prm['returnType'], $rMap)) {
246
            $elC = [$prm['NoOfRows'], $rMap[$prm['returnType']]['r'][0], $rMap[$prm['returnType']]['r'][1]];
247
            if (filter_var($elC[0], FILTER_VALIDATE_INT, ['min_range' => $elC[1], 'max_range' => $elC[2]]) === false) {
248
                $msg = $this->lclMsgCmn('i18n_MySQL_QueryResultExpected' . $rMap[$prm['returnType']][2]);
249
                return [false, sprintf($msg, $prm['NoOfColumns'])];
250
            }
251
            $elR = [$prm['NoOfColumns'], $rMap[$prm['returnType']]['c'][0], $rMap[$prm['returnType']]['c'][1]];
252
            if (filter_var($elR[0], FILTER_VALIDATE_INT, ['min_range' => $elR[1], 'max_range' => $elR[2]])) {
253
                return [true, ''];
254
            }
255
            $msg = $this->lclMsgCmn('i18n_MySQL_QueryResultExpected' . $rMap[$prm['returnType']][1]);
256
            return [false, sprintf($msg, $prm['NoOfColumns'])];
257
        }
258
        return [false, $prm['returnType'] . ' is not defined!'];
259
    }
260
261
    private function setMySQLqueryValidationMap()
262
    {
263
        $lngKey = 'full_array_key_numbered_with_record_number_prefix';
264
        return [
265
            'array_first_key_rest_values'         => ['r' => [1, 999999], 'c' => [2, 99], 'AtLeast2ColsResultedOther'],
266
            'array_key_value'                     => ['r' => [1, 999999], 'c' => [2, 2], '2ColumnsResultedOther'],
267
            'array_key_value2'                    => ['r' => [1, 999999], 'c' => [2, 2], '2ColumnsResultedOther'],
268
            'array_key2_value'                    => ['r' => [1, 999999], 'c' => [2, 2], '2ColumnsResultedOther'],
269
            'array_numbered'                      => ['r' => [1, 999999], 'c' => [1, 1], '1ColumnResultedOther'],
270
            'array_pairs_key_value'               => ['r' => [1, 1], 'c' => [1, 99], '1RowManyColumnsResultedOther'],
271
            'full_array_key_numbered'             => ['r' => [1, 999999], 'c' => [1, 99], '1OrMoreRows0Resulted'],
272
            'full_array_key_numbered_with_prefix' => ['r' => [1, 999999], 'c' => [1, 99], '1OrMoreRows0Resulted'],
273
            $lngKey                               => ['r' => [1, 999999], 'c' => [1, 99], '1OrMoreRows0Resulted'],
274
            'value'                               => ['r' => [1, 1], 'c' => [1, 1], '1ResultedOther'],
275
        ];
276
    }
277
}
278