Removed unused function wfUnbufferedQuery().
[lhc/web/wiklou.git] / includes / DatabaseFunctions.php
1 <?
2 include_once( "FulltextStoplist.php" );
3 include_once( "CacheManager.php" );
4
5 define( "DB_READ", -1 );
6 define( "DB_WRITE", -2 );
7 define( "DB_LAST", -3 );
8
9 $wgLastDatabaseQuery = "";
10
11 /* private */ $wgBufferSQLResults = true;
12 /* private */ $wgIgnoreSQLErrors = false;
13
14 function wfGetDB( $altuser = "", $altpassword = "", $altserver = "", $altdb = "" )
15 {
16 global $wgDBserver, $wgDBuser, $wgDBpassword;
17 global $wgDBname, $wgDBconnection, $wgEmergencyContact;
18
19 $noconn = wfMsgNoDB( "noconnect", $wgDBserver );
20 $nodb = wfMsgNoDB( "nodb", $wgDBname );
21
22 $helpme = "\n<p>If this error persists after reloading and clearing " .
23 "your browser cache, please notify the <a href=\"mailto:" .
24 $wgEmergencyContact . "\">Wikipedia developers</a>.</p>";
25
26 if ( $altuser != "" ) {
27 $serve = ($altserver ? $altserver : $wgDBserver );
28 $db = ($altdb ? $altdb : $wgDBname );
29 $wgDBconnection = mysql_connect( $serve, $altuser, $altpassword )
30 or die( "bad sql user" );
31 mysql_select_db( $db, $wgDBconnection ) or die(
32 htmlspecialchars(mysql_error()) );
33 }
34
35 if ( ! $wgDBconnection ) {
36 @$wgDBconnection = mysql_pconnect( $wgDBserver, $wgDBuser, $wgDBpassword )
37 or wfEmergencyAbort();
38
39 if( !mysql_select_db( $wgDBname, $wgDBconnection ) ) {
40 /* Persistent connections may become stuck in an unusable state */
41 wfDebug( "Persistent connection is broken?\n", true );
42
43 @$wgDBconnection = mysql_connect( $wgDBserver, $wgDBuser, $wgDBpassword )
44 or wfEmergencyAbort();
45
46 @mysql_select_db( $wgDBname, $wgDBconnection )
47 or wfEmergencyAbort();
48 }
49 }
50 # mysql_ping( $wgDBconnection );
51 return $wgDBconnection;
52 }
53
54 /* Call this function if we couldn't contact the database...
55 We'll try to use the cache to display something in the meantime */
56 function wfEmergencyAbort( $msg = "" ) {
57 global $wgTitle, $wgUseFileCache, $title, $wgOutputEncoding;
58
59 header( "Content-type: text/html; charset=$wgOutputEncoding" );
60 if($msg == "") $msg = wfMsgNoDB( "noconnect" );
61 $text = $msg;
62
63 if($wgUseFileCache) {
64 if($wgTitle) {
65 $t =& $wgTitle;
66 } else {
67 if($title) {
68 $t = Title::newFromURL( $title );
69 } else {
70 $t = Title::newFromText( wfMsgNoDB( "mainpage" ) );
71 }
72 }
73
74 $cache = new CacheManager( $t );
75 if( $cache->isFileCached() ) {
76 $msg = "<p style='color: red'><b>$msg<br>\n" .
77 wfMsgNoDB( "cachederror" ) . "</b></p>\n";
78
79 $tag = "<div id='article'>";
80 $text = str_replace(
81 $tag,
82 $tag . $msg,
83 $cache->fetchPageText() );
84 }
85 }
86
87 /* Don't cache error pages! They cause no end of trouble... */
88 header( "Cache-control: none" );
89 header( "Pragma: nocache" );
90 echo $text;
91 wfAbruptExit();
92 }
93
94 # $db: DB_READ = -1 read from slave (or only server)
95 # DB_WRITE = -2 write to master (or only server)
96 # 0,1,2,... query a database with a specific index
97 # Replication is not actually implemented just yet
98 function wfQuery( $sql, $db, $fname = "" )
99 {
100 global $wgLastDatabaseQuery, $wgOut, $wgDebugDumpSql, $wgBufferSQLResults,
101 $wgIgnoreSQLErrors, $wgProfiling;
102
103 if ( $wgProfiling ) {
104 # wfGeneralizeSQL will probably cut down the query to reasonable
105 # logging size most of the time. The substr is really just a sanity check.
106 $profName = "wfQuery: " . substr( wfGeneralizeSQL( $sql ), 0, 255 );
107 wfProfileIn( $profName );
108 }
109
110 if ( !is_numeric( $db ) ) {
111 # Someone has tried to call this the old way
112 $wgOut->fatalError( wfMsgNoDB( "wrong_wfQuery_params", $db, $sql ) );
113 }
114
115 $wgLastDatabaseQuery = $sql;
116
117 if( $wgDebugDumpSql ) {
118 $sqlx = substr( $sql, 0, 500 );
119 $sqlx = wordwrap(strtr($sqlx,"\t\n"," "));
120 wfDebug( "SQL: $sqlx\n" );
121 }
122
123 $conn = wfGetDB();
124 if( $wgBufferSQLResults ) {
125 $ret = mysql_query( $sql, $conn );
126 } else {
127 $ret = mysql_unbuffered_query( $sql, $conn );
128 }
129
130 if ( false === $ret ) {
131 if( $wgIgnoreSQLErrors ) {
132 wfDebug("SQL ERROR (ignored): " . mysql_error( $conn ) . "\n");
133 } else {
134 wfDebug("SQL ERROR: " . mysql_error( $conn ) . "\n");
135 $wgOut->databaseError( $fname ); // calls wfAbruptExit()
136 }
137 }
138
139 if ( $wgProfiling ) {
140 wfProfileOut( $profName );
141 }
142 return $ret;
143 }
144
145 # Turns buffering of SQL result sets on (true) or off (false). Default is
146 # "on" and it should not be changed without good reasons.
147 # Returns the previous state.
148
149 function wfBufferSQLResults( $newstate ){
150 global $wgBufferSQLResults;
151 $oldstate = $wgBufferSQLResults;
152 $wgBufferSQLResults = $newstate;
153 return $oldstate;
154 }
155
156 # Turns on (false) or off (true) the automatic generation and sending
157 # of a "we're sorry, but there has been a database error" page on
158 # database errors. Default is on (false). When turned off, the
159 # code should use wfLastErrno() and wfLastError() to handle the
160 # situation as appropriate.
161 # Returns the previous state.
162
163 function wfIgnoreSQLErrors( $newstate ){
164 global $wgIgnoreSQLErrors;
165 $oldstate = $wgIgnoreSQLErrors;
166 $wgIgnoreSQLErrors = $newstate;
167 return $oldstate;
168 }
169
170 function wfFreeResult( $res ) { mysql_free_result( $res ); }
171 function wfFetchObject( $res ) { return mysql_fetch_object( $res ); }
172 function wfNumRows( $res ) { return mysql_num_rows( $res ); }
173 function wfNumFields( $res ) { return mysql_num_fields( $res ); }
174 function wfFieldName( $res, $n ) { return mysql_field_name( $res, $n ); }
175 function wfInsertId() { return mysql_insert_id( wfGetDB() ); }
176 function wfDataSeek( $res, $row ) { return mysql_data_seek( $res, $row ); }
177 function wfLastErrno() { return mysql_errno(); }
178 function wfLastError() { return mysql_error(); }
179 function wfAffectedRows() { return mysql_affected_rows( wfGetDB() ); }
180
181 function wfLastDBquery()
182 {
183 global $wgLastDatabaseQuery;
184 return $wgLastDatabaseQuery;
185 }
186
187 function wfSetSQL( $table, $var, $value, $cond )
188 {
189 $sql = "UPDATE $table SET $var = '" .
190 wfStrencode( $value ) . "' WHERE ($cond)";
191 wfQuery( $sql, DB_WRITE, "wfSetSQL" );
192 }
193
194 function wfGetSQL( $table, $var, $cond )
195 {
196 $sql = "SELECT $var FROM $table WHERE ($cond)";
197 $result = wfQuery( $sql, DB_READ, "wfGetSQL" );
198
199 $ret = "";
200 if ( mysql_num_rows( $result ) > 0 ) {
201 $s = mysql_fetch_object( $result );
202 $ret = $s->$var;
203 mysql_free_result( $result );
204 }
205 return $ret;
206 }
207
208 function wfStrencode( $s )
209 {
210 return addslashes( $s );
211 }
212
213 # Ideally we'd be using actual time fields in the db
214 function wfTimestamp2Unix( $ts ) {
215 return gmmktime( ( (int)substr( $ts, 8, 2) ),
216 (int)substr( $ts, 10, 2 ), (int)substr( $ts, 12, 2 ),
217 (int)substr( $ts, 4, 2 ), (int)substr( $ts, 6, 2 ),
218 (int)substr( $ts, 0, 4 ) );
219 }
220
221 function wfUnix2Timestamp( $unixtime ) {
222 return gmdate( "YmdHis", $unixtime );
223 }
224
225 function wfTimestampNow() {
226 # return NOW
227 return gmdate( "YmdHis" );
228 }
229
230 # Sorting hack for MySQL 3, which doesn't use index sorts for DESC
231 function wfInvertTimestamp( $ts ) {
232 return strtr(
233 $ts,
234 "0123456789",
235 "9876543210"
236 );
237 }
238
239 # Removes most variables from an SQL query and replaces them with X or N for numbers.
240 # It's only slightly flawed. Don't use for anything important.
241 function wfGeneralizeSQL( $sql )
242 {
243 # This does the same as the regexp below would do, but in such a way
244 # as to avoid crashing php on some large strings.
245 # $sql = preg_replace ( "/'([^\\\\']|\\\\.)*'|\"([^\\\\\"]|\\\\.)*\"/", "'X'", $sql);
246
247 $sql = str_replace ( "\\\\", "", $sql);
248 $sql = str_replace ( "\\'", "", $sql);
249 $sql = str_replace ( "\\\"", "", $sql);
250 $sql = preg_replace ("/'.*'/s", "'X'", $sql);
251 $sql = preg_replace ('/".*"/s', "'X'", $sql);
252
253 # All newlines, tabs, etc replaced by single space
254 $sql = preg_replace ( "/\s+/", " ", $sql);
255
256 # All numbers => N
257 $sql = preg_replace ('/-?[0-9]+/s', "N", $sql);
258
259 return $sql;
260 }
261
262 function wfFieldExists( $table, $field )
263 {
264 $fname = "wfFieldExists";
265 $res = wfQuery( "DESCRIBE $table", DB_READ, $fname );
266 $found = false;
267
268 while ( $row = wfFetchObject( $res ) ) {
269 if ( $row->Field == $field ) {
270 $found = true;
271 break;
272 }
273 }
274 return $found;
275 }
276
277 function wfIndexExists( $table, $index )
278 {
279 global $wgDBname;
280 $fname = "wfIndexExists";
281 $sql = "SHOW INDEXES FROM $table";
282 $res = wfQuery( $sql, DB_READ, $fname );
283 $found = false;
284 while ( $row = wfFetchObject( $res ) ) {
285 if ( $row->Key_name == $index ) {
286 $found = true;
287 break;
288 }
289 }
290 return $found;
291 }
292 ?>