1 | <?php |
||
2 | /** |
||
3 | * sysPass |
||
4 | * |
||
5 | * @author nuxsmin |
||
6 | * @link https://syspass.org |
||
7 | * @copyright 2012-2019, Rubén Domínguez nuxsmin@$syspass.org |
||
8 | * |
||
9 | * This file is part of sysPass. |
||
10 | * |
||
11 | * sysPass is free software: you can redistribute it and/or modify |
||
12 | * it under the terms of the GNU General Public License as published by |
||
13 | * the Free Software Foundation, either version 3 of the License, or |
||
14 | * (at your option) any later version. |
||
15 | * |
||
16 | * sysPass is distributed in the hope that it will be useful, |
||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
19 | * GNU General Public License for more details. |
||
20 | * |
||
21 | * You should have received a copy of the GNU General Public License |
||
22 | * along with sysPass. If not, see <http://www.gnu.org/licenses/>. |
||
23 | */ |
||
24 | |||
25 | namespace SP\Storage\Database; |
||
26 | |||
27 | use Exception; |
||
28 | use PDO; |
||
29 | |||
30 | defined('APP_ROOT') || die(); |
||
31 | |||
32 | /** |
||
33 | * Class MySQLHandler |
||
34 | * |
||
35 | * Esta clase se encarga de crear las conexiones a la BD |
||
36 | */ |
||
37 | final class MySQLHandler implements DBStorageInterface |
||
38 | { |
||
39 | const STATUS_OK = 0; |
||
40 | const STATUS_KO = 1; |
||
41 | const PDO_OPTS = [ |
||
42 | PDO::ATTR_EMULATE_PREPARES => false, |
||
43 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, |
||
44 | PDO::MYSQL_ATTR_FOUND_ROWS => true, |
||
45 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ |
||
46 | ]; |
||
47 | /** |
||
48 | * @var PDO |
||
49 | */ |
||
50 | private $db; |
||
51 | /** |
||
52 | * @var int |
||
53 | */ |
||
54 | private $dbStatus = self::STATUS_KO; |
||
55 | /** |
||
56 | * @var DatabaseConnectionData |
||
57 | */ |
||
58 | private $connectionData; |
||
59 | |||
60 | /** |
||
61 | * MySQLHandler constructor. |
||
62 | * |
||
63 | * @param DatabaseConnectionData $connectionData |
||
64 | */ |
||
65 | public function __construct(DatabaseConnectionData $connectionData) |
||
66 | { |
||
67 | $this->connectionData = $connectionData; |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * Devuelve el estado de conexión a la BBDD |
||
72 | * |
||
73 | * OK -> 0 |
||
74 | * KO -> 1 |
||
75 | * |
||
76 | * @return int |
||
77 | */ |
||
78 | public function getDbStatus() |
||
79 | { |
||
80 | return $this->dbStatus; |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Realizar la conexión con la BBDD. |
||
85 | * Esta función utiliza PDO para conectar con la base de datos. |
||
86 | * |
||
87 | * @return PDO |
||
88 | * @throws DatabaseException |
||
89 | */ |
||
90 | public function getConnection() |
||
91 | { |
||
92 | if (!$this->db) { |
||
93 | if (null === $this->connectionData->getDbUser() |
||
94 | || null === $this->connectionData->getDbPass() |
||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
95 | || null === $this->connectionData->getDbName() |
||
0 ignored issues
–
show
|
|||
96 | || (null === $this->connectionData->getDbHost() && null === $this->connectionData->getDbSocket()) |
||
0 ignored issues
–
show
|
|||
97 | ) { |
||
98 | throw new DatabaseException( |
||
99 | __u('Unable to connect to DB'), |
||
100 | DatabaseException::CRITICAL, |
||
101 | __u('Please, check the connection parameters')); |
||
102 | } |
||
103 | |||
104 | try { |
||
105 | $this->db = new PDO( |
||
106 | $this->getConnectionUri(), |
||
107 | $this->connectionData->getDbUser(), |
||
108 | $this->connectionData->getDbPass(), |
||
109 | self::PDO_OPTS |
||
110 | ); |
||
111 | |||
112 | // Set prepared statement emulation depending on server version |
||
113 | $serverVersion = $this->db->getAttribute(PDO::ATTR_SERVER_VERSION); |
||
114 | $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, version_compare($serverVersion, '5.1.17', '<')); |
||
115 | |||
116 | $this->dbStatus = self::STATUS_OK; |
||
117 | } catch (Exception $e) { |
||
118 | throw new DatabaseException( |
||
119 | __u('Unable to connect to DB'), |
||
120 | DatabaseException::CRITICAL, |
||
121 | sprintf('Error %s: %s', $e->getCode(), $e->getMessage()), |
||
122 | $e->getCode(), |
||
123 | $e |
||
124 | ); |
||
125 | } |
||
126 | } |
||
127 | |||
128 | return $this->db; |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * @return string |
||
133 | */ |
||
134 | public function getConnectionUri() |
||
135 | { |
||
136 | $dsn = ['charset=utf8']; |
||
137 | |||
138 | if (empty($this->connectionData->getDbSocket())) { |
||
139 | $dsn[] = 'host=' . $this->connectionData->getDbHost(); |
||
140 | |||
141 | if (null !== $this->connectionData->getDbPort()) { |
||
0 ignored issues
–
show
|
|||
142 | $dsn[] = 'port=' . $this->connectionData->getDbPort(); |
||
143 | } |
||
144 | } else { |
||
145 | $dsn[] = 'unix_socket=' . $this->connectionData->getDbSocket(); |
||
146 | } |
||
147 | |||
148 | if (!empty($this->connectionData->getDbName())) { |
||
149 | $dsn[] = 'dbname=' . $this->connectionData->getDbName(); |
||
150 | } |
||
151 | |||
152 | return 'mysql:' . implode(';', $dsn); |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * Obtener una conexión PDO sin seleccionar la BD |
||
157 | * |
||
158 | * @return PDO |
||
159 | * @throws DatabaseException |
||
160 | */ |
||
161 | public function getConnectionSimple() |
||
162 | { |
||
163 | if (!$this->db) { |
||
164 | if (null === $this->connectionData->getDbHost() && null === $this->connectionData->getDbSocket()) { |
||
0 ignored issues
–
show
|
|||
165 | throw new DatabaseException( |
||
166 | __u('Unable to connect to DB'), |
||
167 | DatabaseException::CRITICAL, |
||
168 | __u('Please, check the connection parameters')); |
||
169 | } |
||
170 | |||
171 | try { |
||
172 | $opts = [PDO::ATTR_EMULATE_PREPARES => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]; |
||
173 | |||
174 | $this->db = new PDO($this->getConnectionUri(), $this->connectionData->getDbUser(), $this->connectionData->getDbPass(), $opts); |
||
175 | $this->dbStatus = self::STATUS_OK; |
||
176 | } catch (Exception $e) { |
||
177 | throw new DatabaseException( |
||
178 | __u('Unable to connect to DB'), |
||
179 | DatabaseException::CRITICAL, |
||
180 | sprintf('Error %s: %s', $e->getCode(), $e->getMessage()), |
||
181 | $e->getCode(), |
||
182 | $e |
||
183 | ); |
||
184 | } |
||
185 | } |
||
186 | |||
187 | return $this->db; |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * @return string |
||
192 | */ |
||
193 | public function getDatabaseName() |
||
194 | { |
||
195 | return $this->connectionData->getDbName(); |
||
196 | } |
||
197 | } |