3 * If enabled through $wgAllowSysopQueries = true, this class
4 * let users with sysop right the possibility to make sql queries
5 * against the cur table.
6 * Heavy queries could slow down the database specially for the
10 * @subpackage SpecialPage
16 function wfSpecialAsksql() {
17 global $wgUser, $wgOut, $wgRequest, $wgAllowSysopQueries;
19 if( !$wgAllowSysopQueries ) {
20 $wgOut->errorpage( 'nosuchspecialpage', 'nospecialpagetext' );
23 if( !$wgUser->isAllowed('asksql') ) {
24 $wgOut->sysopRequired();
28 if( $wgRequest->wasPosted() ) {
29 $query = $wgRequest->getVal( 'wpSqlQuery' );
30 $action = $wgRequest->getVal( 'action' );
35 $f = new SqlQueryForm( $query);
37 if ( "submit" == $action ) {
47 * @subpackage SpecialPage
52 function SqlQueryForm( $query ) {
53 $this->query
= $query;
56 function showForm( $err ) {
57 global $wgOut, $wgUser, $wgLang;
60 $wgOut->setPagetitle( wfMsg( 'asksql' ) );
61 $note = wfMsg( 'asksqltext' );
63 $note .= ' ' . wfMsg( 'sqlislogged' );
64 $wgOut->addWikiText( $note );
67 $wgOut->addHTML( '<p><font color="red" size="+1">' . htmlspecialchars($err) . "</font>\n" );
69 if ( ! $this->query
) { $this->query
= 'SELECT ... FROM ... WHERE ...'; }
70 $q = wfMsg( 'sqlquery' );
71 $qb = wfMsg( 'querybtn' );
72 $titleObj = Title
::makeTitle( NS_SPECIAL
, 'Asksql' );
73 $action = $titleObj->escapeLocalURL( 'action=submit' );
76 <form id=\"asksql\" method=\"post\" action=\"{$action}\">
78 <td align=right>{$q}:</td>
80 <textarea name=\"wpSqlQuery\" cols=80 rows=4 wrap=\"virtual\">"
81 . htmlspecialchars($this->query
) ."
85 <td> </td><td align=\"left\">
86 <input type=submit name=\"wpQueryBtn\" value=\"{$qb}\">
93 global $wgOut, $wgUser, $wgServer, $wgScript, $wgArticlePath, $wgLang, $wgContLang;
94 global $wgDBserver, $wgDBsqluser, $wgDBsqlpassword, $wgDBname, $wgSqlTimeout;
97 $this->query
= trim( $this->query
);
98 if( preg_match( '/^SELECT/i', $this->query
)
99 and !preg_match( '/LIMIT/i', $this->query
) ) {
100 $this->query
.= ' LIMIT 100';
102 $conn = Database
::newFromParams( $wgDBserver, $wgDBsqluser, $wgDBsqlpassword, $wgDBname );
104 $this->logQuery( $this->query
);
106 # Start timer, will kill the DB thread in $wgSqlTimeout seconds
107 $conn->startTimer( $wgSqlTimeout );
108 $res = $conn->query( $this->query
, 'SpecialAsksql::doSubmit' );
110 $this->logFinishedQuery();
113 @$n = $conn->numFields( $res );
118 for ( $x = 0; $x < $n; ++
$x ) {
119 array_push( $k, $conn->fieldName( $res, $x ) );
122 if ( $n == 2 && in_array( 'page_title', $k ) && in_array( 'page_namespace', $k ) ) {
127 while ( $s = $conn->fetchObject( $res ) ) {
128 array_push( $a, $s );
130 $conn->freeResult( $res );
134 foreach ( $a as $y ) {
135 $sTitle = htmlspecialchars( $y->page_title
);
136 if ( $y->page_namespace
) {
137 $sNamespace = $wgContLang->getNsText( $y->page_namespace
);
138 $link = "$sNamespace:$sTitle";
142 $skin = $wgUser->getSkin();
143 $link = $skin->makeLink( $link );
144 $r .= "* [[$link]]<br />\n";
148 $r = "<table border=1 bordercolor=black cellspacing=0 " .
149 "cellpadding=2><tr>\n";
150 foreach ( $k as $x ) $r .= "<th>" . htmlspecialchars( $x ) . "</th>";
153 foreach ( $a as $y ) {
155 foreach ( $k as $x ) {
157 if ( $x == 'page_title' or $x == 'rc_title') {
159 if( $x == 'page_title' && isset( $y->page_namespace
) ) $namespace = $y->page_namespace
;
160 if( $x == 'rc_title' && isset( $y->rc_namespace
) ) $namespace = $y->rc_namespace
;
161 $title =& Title
::makeTitle( $namespace, $o );
162 $o = "<a href=\"" . $title->escapeLocalUrl() . "\" class='internal'>" .
163 htmlspecialchars( $y->$x ) . '</a>' ;
165 $o = htmlspecialchars( $o );
167 $r .= '<td>' . $o . "</td>\n";
174 $this->showForm( wfMsg( "querysuccessful" ) );
175 $wgOut->addHTML( "<hr>{$r}\n" );
178 function logQuery( $q ) {
179 global $wgSqlLogFile, $wgLogQueries, $wgUser;
180 if(!$wgLogQueries) return;
182 $f = fopen( $wgSqlLogFile, 'a' );
183 fputs( $f, "\n\n" . wfTimestampNow() .
184 " query by " . $wgUser->getName() .
187 $this->starttime
= wfTime();
190 function logFinishedQuery() {
191 global $wgSqlLogFile, $wgLogQueries;
192 if(!$wgLogQueries) return;
194 $interval = wfTime() - $this->starttime
;
196 $f = fopen( $wgSqlLogFile, 'a' );
197 fputs( $f, 'finished at ' . wfTimestampNow() . "; took $interval secs\n" );