Merge "Declare visibility for class properties in MySQLMasterPos"
[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 $sql string
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 protected function mysqlConnect( $realServer ) {
47 global $wgDBmysql5;
48 # Fail now
49 # Otherwise we get a suppressed fatal error, which is very hard to track down
50 if ( !function_exists( 'mysqli_init' ) ) {
51 throw new DBConnectionError( $this, "MySQLi functions missing,"
52 . " have you compiled PHP with the --with-mysqli option?\n" );
53 }
54
55 $connFlags = 0;
56 if ( $this->mFlags & DBO_SSL ) {
57 $connFlags |= MYSQLI_CLIENT_SSL;
58 }
59 if ( $this->mFlags & DBO_COMPRESS ) {
60 $connFlags |= MYSQLI_CLIENT_COMPRESS;
61 }
62 if ( $this->mFlags & DBO_PERSISTENT ) {
63 $realServer = 'p:' . $realServer;
64 }
65
66 $mysqli = mysqli_init();
67 if ( $wgDBmysql5 ) {
68 // Tell the server we're communicating with it in UTF-8.
69 // This may engage various charset conversions.
70 $mysqli->options( MYSQLI_SET_CHARSET_NAME, 'utf8' );
71 } else {
72 $mysqli->options( MYSQLI_SET_CHARSET_NAME, 'binary' );
73 }
74
75 $numAttempts = 2;
76 for ( $i = 0; $i < $numAttempts; $i++ ) {
77 if ( $i > 1 ) {
78 usleep( 1000 );
79 }
80 if ( $mysqli->real_connect( $realServer, $this->mUser,
81 $this->mPassword, $this->mDBname, null, null, $connFlags )
82 ) {
83 return $mysqli;
84 }
85 }
86
87 return false;
88 }
89
90 protected function connectInitCharset() {
91 // already done in mysqlConnect()
92 return true;
93 }
94
95 /**
96 * @return bool
97 */
98 protected function mysqlSetCharset( $charset ) {
99 if ( method_exists( $this->mConn, 'set_charset' ) ) {
100 return $this->mConn->set_charset( $charset );
101 } else {
102 return $this->query( 'SET NAMES ' . $charset, __METHOD__ );
103 }
104 }
105
106 /**
107 * @return bool
108 */
109 protected function closeConnection() {
110 return $this->mConn->close();
111 }
112
113 /**
114 * @return int
115 */
116 function insertId() {
117 return $this->mConn->insert_id;
118 }
119
120 /**
121 * @return int
122 */
123 function lastErrno() {
124 if ( $this->mConn ) {
125 return $this->mConn->errno;
126 } else {
127 return mysqli_connect_errno();
128 }
129 }
130
131 /**
132 * @return int
133 */
134 function affectedRows() {
135 return $this->mConn->affected_rows;
136 }
137
138 /**
139 * @param $db
140 * @return bool
141 */
142 function selectDB( $db ) {
143 $this->mDBname = $db;
144
145 return $this->mConn->select_db( $db );
146 }
147
148 /**
149 * @return string
150 */
151 function getServerVersion() {
152 return $this->mConn->server_info;
153 }
154
155 protected function mysqlFreeResult( $res ) {
156 $res->free_result();
157
158 return true;
159 }
160
161 protected function mysqlFetchObject( $res ) {
162 $object = $res->fetch_object();
163 if ( $object === null ) {
164 return false;
165 }
166
167 return $object;
168 }
169
170 protected function mysqlFetchArray( $res ) {
171 $array = $res->fetch_array();
172 if ( $array === null ) {
173 return false;
174 }
175
176 return $array;
177 }
178
179 protected function mysqlNumRows( $res ) {
180 return $res->num_rows;
181 }
182
183 protected function mysqlNumFields( $res ) {
184 return $res->field_count;
185 }
186
187 protected function mysqlFetchField( $res, $n ) {
188 $field = $res->fetch_field_direct( $n );
189 $field->not_null = $field->flags & MYSQLI_NOT_NULL_FLAG;
190 $field->primary_key = $field->flags & MYSQLI_PRI_KEY_FLAG;
191 $field->unique_key = $field->flags & MYSQLI_UNIQUE_KEY_FLAG;
192 $field->multiple_key = $field->flags & MYSQLI_MULTIPLE_KEY_FLAG;
193 $field->binary = $field->flags & MYSQLI_BINARY_FLAG;
194
195 return $field;
196 }
197
198 protected function mysqlFieldName( $res, $n ) {
199 $field = $res->fetch_field_direct( $n );
200
201 return $field->name;
202 }
203
204 protected function mysqlFieldType( $res, $n ) {
205 $field = $res->fetch_field_direct( $n );
206 return $field->type;
207 }
208
209 protected function mysqlDataSeek( $res, $row ) {
210 return $res->data_seek( $row );
211 }
212
213 protected function mysqlError( $conn = null ) {
214 if ( $conn === null ) {
215 return mysqli_connect_error();
216 } else {
217 return $conn->error;
218 }
219 }
220
221 protected function mysqlRealEscapeString( $s ) {
222 return $this->mConn->real_escape_string( $s );
223 }
224
225 protected function mysqlPing() {
226 return $this->mConn->ping();
227 }
228 }