Completed
Push — master ( 490d5a...727909 )
by Derek
02:21
created

MySql::getPrimaryKeys()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 23
ccs 12
cts 12
cp 1
rs 9.0856
cc 2
eloc 13
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Subreality\Dilmun\Enki;
4
5
use Subreality\Dilmun\LoggedClassTrait;
6
7
/**
8
 * Class MySql
9
 * @package Subreality\Dilmun\Enki
10
 */
11
class MySql implements EnkiInterface
12
{
13
    use LoggedClassTrait;
14
15
    /**
16
     * @var \PDO
17
     */
18
    private $pdo;
19
20
    /**
21
     * Provides a MySQL connection interface that catches a PDOException on failure.
22
     *
23
     * @param string $host  The host name for the MySQL connection
24
     * @param string $user  The username for the MySQL connection
25
     * @param string $pass  The password for the MySQL connection
26
     * @param string $name  The database name for the MySQL connection
27
     *
28
     * @return bool         Returns true if the connection was successful; returns false otherwise
29
     */
30 14
    public function connect($host, $user, $pass, $name)
31
    {
32 14
        $dsn = "mysql:host={$host};dbname={$name}";
33
34
        try {
35 14
            $this->pdo = new \PDO($dsn, $user, $pass);
36 13
            $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
37
38 13
            $connected = true;
39 14
        } catch (\PDOException $pdo_e) {
40 1
            $context = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 14 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
41 1
            $context["exception"] = $pdo_e;
42
43 1
            $this->updateLog("error", "MySQL connection failed with the following message: {message}", $context);
44
            
45 1
            $connected = false;
46
        }
47
48 14
        return $connected;
49
    }
50
51
    /**
52
     * Destroys an existing PDO connection
53
     *
54
     * @return bool Returns true if the connection existed and was destroyed; returns false otherwise
55
     */
56 2
    public function disconnect()
57
    {
58 2
        if ($this->pdo instanceof \PDO) {
59 1
            $this->pdo = null;
60
61 1
            $disconnected = true;
62 1
        } else {
63 1
            $disconnected = false;
64
        }
65
66 2
        return $disconnected;
67
    }
68
69
    /**
70
     * Gets the column names for all primary keys for a table or returns false if no keys exist
71
     *
72
     * @param string $table The table from which keys will be retrieved
73
     *
74
     * @return array|false  Returns an array of column names representing primary keys;
75
     *                      returns false if the table has no primary keys
76
     */
77 9
    public function getPrimaryKeys($table)
78
    {
79 9
        $keys_query = "SHOW KEYS FROM {$table} WHERE Key_name='PRIMARY'";
80
81 9
        $statement = $this->pdo->prepare($keys_query);
82
83
        try {
84 9
            $statement->execute();
85 9
        } catch (\PDOException $pdo_e) {
86 1
            $context = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 14 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
87 1
            $context["exception"] = $pdo_e;
88
89 1
            $this->updateLog("error", "Trying to get keys failed with the following message: {message}", $context);
90
91 1
            return false;
92
        }
93
94 8
        $result = $statement->fetchAll();
95
96 8
        $keys = $this->processPrimaryKeyResult($result);
97
98 8
        return $keys;
99
    }
100
101
    /**
102
     * Retrieves a row represented by a single primary key
103
     *
104
     * @param int|string $id    A unique id for a table
105
     * @param string $table     The table from which a row will be retrieved
106
     *
107
     * @return array|false      Returns an associative array representing the row corresponding with the primary key;
108
     *                          returns false if the table does not exist, if the provided id does not correspond with a
109
     *                          record, or if the table has a compound primary key
110
     */
111 5
    public function getRowById($id, $table)
112
    {
113 5
        $key = $this->getPrimaryKeys($table);
114
115 5
        if (is_string($id)) {
116 1
            $query_id = "'{$id}'";
117 1
        } else {
118 4
            $query_id = $id;
119
        }
120
121 5
        if ($key === false) {
122 1
            $row = false;
123 5
        } elseif (count($key) > 1) {
124 1
            $row = false;
125 1
        } else {
126 3
            $query = "SELECT * FROM {$table}
127 3
                        WHERE {$key} = {$query_id}";
128
129 3
            $statement = $this->pdo->prepare($query);
130
131 3
            $statement->execute();
132
133 3
            $result = $statement->fetchAll(\PDO::FETCH_ASSOC);
134
135 3
            if (empty($result)) {
136 1
                $row = false;
137 1
            } else {
138 2
                $row = $result[0];
139
            }
140
        }
141
142 5
        return $row;
143
    }
144
145
    /**
146
     * Determines whether a given table exists
147
     *
148
     * @param string $table The table that will be checked for existence
149
     * @return bool         Returns true if the table exists; returns false otherwise
150
     */
151 2
    public function tableExists($table)
152
    {
153 2
        $table_query = "SHOW TABLES LIKE '{$table}'";
154
155 2
        $statement = $this->pdo->prepare($table_query);
156
157 2
        $statement->execute();
158
159 2
        $row_count = $statement->rowCount();
160
161 2
        if ($row_count == 0) {
0 ignored issues
show
Coding Style introduced by
The if-else statement can be simplified to return !($row_count == 0);.
Loading history...
162 1
            return false;
163
        } else {
164 1
            return true;
165
        }
166
    }
167
168
    /**
169
     * Processes the result set from a primary key query
170
     *
171
     * @see MySql::getPrimaryKeys()
172
     *
173
     * @param array $result An array representing the result of a primary key query
174
     *
175
     * @return mixed        Returns a string column name if the result set contains only one key; returns an array of
176
     *                      string column names if the result set contains a compound key; returns false if the result
177
     *                      set was empty
178
     */
179 8
    private function processPrimaryKeyResult($result)
180
    {
181 8
        $row_count = count($result);
182
183 8
        if ($row_count > 1) {
184 2
            $keys = array();
185
186 2
            foreach ($result as $row) {
187 2
                $keys[] = $row['Column_name'];
188 2
            }
189 8
        } elseif ($row_count == 1) {
190 4
            $keys = $result[0]['Column_name'];
191 4
        } else {
192 2
            $keys = false;
193
        }
194
195 8
        return $keys;
196
    }
197
}
198