e202f8a926acea3a64840db9be52d24a00c2ff7f
[lhc/web/wiklou.git] / includes / db / DatabaseMysqli.php
1 <?php
2 /**
3 * This is the MySQLi database abstraction layer.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Database
22 */
23
24 /**
25 * Database abstraction object for PHP extension mysqli.
26 *
27 * @ingroup Database
28 * @since 1.22
29 * @see Database
30 */
31 class DatabaseMysqli extends DatabaseMysqlBase {
32 /**
33 * @param string $sql
34 * @return resource
35 */
36 protected function doQuery( $sql ) {
37 if ( $this->bufferResults() ) {
38 $ret = $this->mConn->query( $sql );
39 } else {
40 $ret = $this->mConn->query( $sql, MYSQLI_USE_RESULT );
41 }
42
43 return $ret;
44 }
45
46 /**
47 * @param string $realServer
48 * @return bool|mysqli
49 * @throws DBConnectionError
50 */
51 protected function mysqlConnect( $realServer ) {
52 global $wgDBmysql5;
53 # Fail now
54 # Otherwise we get a suppressed fatal error, which is very hard to track down
55 if ( !function_exists( 'mysqli_init' ) ) {
56 throw new DBConnectionError( $this, "MySQLi functions missing,"
57 . " have you compiled PHP with the --with-mysqli option?\n" );
58 }
59
60 $connFlags = 0;
61 if ( $this->mFlags & DBO_SSL ) {
62 $connFlags |= MYSQLI_CLIENT_SSL;
63 }
64 if ( $this->mFlags & DBO_COMPRESS ) {
65 $connFlags |= MYSQLI_CLIENT_COMPRESS;
66 }
67 if ( $this->mFlags & DBO_PERSISTENT ) {
68 $realServer = 'p:' . $realServer;
69 }
70
71 $mysqli = mysqli_init();
72 if ( $wgDBmysql5 ) {
73 // Tell the server we're communicating with it in UTF-8.
74 // This may engage various charset conversions.
75 $mysqli->options( MYSQLI_SET_CHARSET_NAME, 'utf8' );
76 } else {
77 $mysqli->options( MYSQLI_SET_CHARSET_NAME, 'binary' );
78 }
79
80 $numAttempts = 2;
81 for ( $i = 0; $i < $numAttempts; $i++ ) {
82 if ( $i > 1 ) {
83 usleep( 1000 );
84 }
85 if ( $mysqli->real_connect( $realServer, $this->mUser,
86 $this->mPassword, $this->mDBname, null, null, $connFlags )
87 ) {
88 return $mysqli;
89 }
90 }
91
92 return false;
93 }
94
95 protected function connectInitCharset() {
96 // already done in mysqlConnect()
97 return true;
98 }
99
100 /**
101 * @param string $charset
102 * @return bool
103 */
104 protected function mysqlSetCharset( $charset ) {
105 if ( method_exists( $this->mConn, 'set_charset' ) ) {
106 return $this->mConn->set_charset( $charset );
107 } else {
108 return $this->query( 'SET NAMES ' . $charset, __METHOD__ );
109 }
110 }
111
112 /**
113 * @return bool
114 */
115 protected function closeConnection() {
116 return $this->mConn->close();
117 }
118
119 /**
120 * @return int
121 */
122 function insertId() {
123 return $this->mConn->insert_id;
124 }
125
126 /**
127 * @return int
128 */
129 function lastErrno() {
130 if ( $this->mConn ) {
131 return $this->mConn->errno;
132 } else {
133 return mysqli_connect_errno();
134 }
135 }
136
137 /**
138 * @return int
139 */
140 function affectedRows() {
141 return $this->mConn->affected_rows;
142 }
143
144 /**
145 * @param string $db
146 * @return bool
147 */
148 function selectDB( $db ) {
149 $this->mDBname = $db;
150
151 return $this->mConn->select_db( $db );
152 }
153
154 /**
155 * @return string
156 */
157 function getServerVersion() {
158 return $this->mConn->server_info;
159 }
160
161 /**
162 * @param mysqli $res
163 * @return bool
164 */
165 protected function mysqlFreeResult( $res ) {
166 $res->free_result();
167
168 return true;
169 }
170
171 /**
172 * @param mysqli $res
173 * @return bool
174 */
175 protected function mysqlFetchObject( $res ) {
176 $object = $res->fetch_object();
177 if ( $object === null ) {
178 return false;
179 }
180
181 return $object;
182 }
183
184 /**
185 * @param mysqli $res
186 * @return bool
187 */
188 protected function mysqlFetchArray( $res ) {
189 $array = $res->fetch_array();
190 if ( $array === null ) {
191 return false;
192 }
193
194 return $array;
195 }
196
197 /**
198 * @param mysqli $res
199 * @return mixed
200 */
201 protected function mysqlNumRows( $res ) {
202 return $res->num_rows;
203 }
204
205 /**
206 * @param mysqli $res
207 * @return mixed
208 */
209 protected function mysqlNumFields( $res ) {
210 return $res->field_count;
211 }
212
213 /**
214 * @param mysqli $res
215 * @param int $n
216 * @return mixed
217 */
218 protected function mysqlFetchField( $res, $n ) {
219 $field = $res->fetch_field_direct( $n );
220 $field->not_null = $field->flags & MYSQLI_NOT_NULL_FLAG;
221 $field->primary_key = $field->flags & MYSQLI_PRI_KEY_FLAG;
222 $field->unique_key = $field->flags & MYSQLI_UNIQUE_KEY_FLAG;
223 $field->multiple_key = $field->flags & MYSQLI_MULTIPLE_KEY_FLAG;
224 $field->binary = $field->flags & MYSQLI_BINARY_FLAG;
225
226 return $field;
227 }
228
229 /**
230 * @param resource|ResultWrapper $res
231 * @param int $n
232 * @return mixed
233 */
234 protected function mysqlFieldName( $res, $n ) {
235 $field = $res->fetch_field_direct( $n );
236
237 return $field->name;
238 }
239
240 /**
241 * @param resource|ResultWrapper $res
242 * @param int $n
243 * @return mixed
244 */
245 protected function mysqlFieldType( $res, $n ) {
246 $field = $res->fetch_field_direct( $n );
247
248 return $field->type;
249 }
250
251 /**
252 * @param resource|ResultWrapper $res
253 * @param int $row
254 * @return mixed
255 */
256 protected function mysqlDataSeek( $res, $row ) {
257 return $res->data_seek( $row );
258 }
259
260 /**
261 * @param mysqli $conn Optional connection object
262 * @return string
263 */
264 protected function mysqlError( $conn = null ) {
265 if ( $conn === null ) {
266 return mysqli_connect_error();
267 } else {
268 return $conn->error;
269 }
270 }
271
272 /**
273 * Escapes special characters in a string for use in an SQL statement
274 * @param string $s
275 * @return string
276 */
277 protected function mysqlRealEscapeString( $s ) {
278 return $this->mConn->real_escape_string( $s );
279 }
280
281 protected function mysqlPing() {
282 return $this->mConn->ping();
283 }
284 }