· 6 years ago · Jul 12, 2019, 09:26 AM
1<?php
2#
3#
4# tinyMy http://spicausis.lv/tinymy/
5# small mysql management console
6# (c) 2005-2008, Einar Lielmanis <einar@spicausis.lv>
7#
8#
9
10error_reporting(E_ALL);
11ini_set('display_errors', 'on');
12
13# which host to connect to?
14$db_host = 'localhost';
15
16
17# if you don't have SHOW DATABASES privilege and are unable to
18# see accessible databases, set this to your default db
19$default_database = 'chineser_cyadmin';
20
21# how many characters to display for blob/text fields?
22define('BLOB_MAX_SIZE', 128);
23
24# should non-ASCII characters be skipped?
25# you can probably try to use this with non-utf-8 databases
26define('BLOB_SKIP_NON_ASCII', false);
27
28
29# text to display for blob and null fields (boring)
30$null_text = '<em>NULL</em>';
31
32
33
34// tinymy starts here, you don't want to read further
35
36ob_start();
37process_tinyadm();
38$content = ob_get_contents();
39ob_end_clean();
40
41?>
42<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
43 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
44<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
45<head>
46<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
47<style type="text/css" media="all"><?php echo css_compact(css_default()) ?></style>
48<title><?php
49if ($db->is_connected()) {
50 // you may want to change these lines to display something more meaningful, if
51 // you have multiple sites to manage and the default title is not meaningful enough
52 $host_to_show = $db_host;
53 if (strtolower($host_to_show) == 'localhost' || $host_to_show == '127.0.0.1') {
54 $host_to_show = $_SERVER['SERVER_ADDR'];
55 }
56 h("%s@%s - tinyMy", $_SESSION['user'], $host_to_show);
57} else {
58 echo 'tinyMy';
59}
60?></title><script type="text/javascript">
61function ctrl_enter(evt) {
62 if (!evt || !document.getElementById('sqlarea')) return;
63 if (evt.keyCode==13 && evt.ctrlKey) {
64 document.getElementById('sqlarea').submit();
65 evt.preventDefault();
66 }
67}
68</script></head>
69 <body onkeydown="ctrl_enter(event)"><?php echo $content?></body></html><?php
70
71function css_default() {
72 return <<<CSS
73* {
74 margin:0;
75 padding:0;
76}
77pre {
78 font-family: courier, monospace;
79}
80textarea {
81 font-family: andale mono, courier, monospace;
82}
83body {
84 font-family: verdana, arial, sans-serif;
85 font-size: 14px;
86 padding-bottom: 30px;
87}
88a {
89 color: #33c;
90}
91textarea {
92 height: 200px;
93 width: 530px;
94 font-size: 12px;
95 padding: 4px;
96}
97input {
98 padding: 2px 0 2px 3px;
99}
100input, textarea {
101 border: 1px solid #666;
102 border-bottom: 1px solid #ccc;
103 border-right: 1px solid #ccc;
104 margin-bottom: 2px;
105}
106button {
107 width: 538px;
108 border: 1px solid #ccc;
109 border-bottom: 1px solid #666;
110 border-right: 1px solid #666;
111 padding: 3px 20px 3px 20px;
112}
113pre {
114 margin-left: 20px;
115}
116form#sqlarea {
117 width: 545px;
118 margin-bottom: 10px;
119}
120p#historyurl {
121 text-align:right;
122 padding: 0 10px 3px 0;
123 font-size: 80%;
124}
125
126#login h2 {
127 background-color: #999;
128 padding: 2px;
129 font-size: 12px;
130 margin-bottom: 4px;
131}
132form#login {
133 margin: 20px auto 0 auto;
134 border: 1px solid #999;
135 width: 174px;
136 padding-bottom: 6px;
137 text-align: center;
138}
139form#login input {
140 width: 150px;
141}
142form#login button {
143 width: 155px;
144 padding: 3px 0 3px 0;
145}
146
147div.history {
148 font-size: 80%;
149 padding: 3px 0 3px 0;
150 margin: 3px 0 3px 0;
151 font-family: andale mono, courier new, courier;
152}
153div.history h2 {
154 font-size: 12px;
155}
156
157form#export {
158 padding: 20px;
159 border:1px solid #666;
160 margin-top: 0;
161}
162form#export h2 {
163 font-size: 12px;
164 margin: 0;
165 padding: 5px 35px 5px 5px;
166 background-color: #666;
167 color: #fff;
168}
169form#export button {
170 width: 200px;
171}
172form#export input {
173 border:auto;
174 padding: 0;
175}
176
177ul#dbmenu {
178 list-style: none;
179 border-right: 1px solid #666;
180 border-bottom: 1px solid #666;
181 position: absolute;
182 left: 0;
183 top: 0;
184 width: 200px;
185 overflow: hidden;
186}
187li {
188 margin-left: 3px;
189}
190li.title {
191 background-color: #669;
192 font-weight: bold;
193 color: #fff;
194 margin-left: 0;
195 padding: 3px;
196}
197.selected {
198 font-weight: bold;
199}
200.pad {
201 margin-left: 10px;
202}
203li.actions {
204 border-top: 1px solid #999;
205 margin-top: 2px;
206 margin-right: 5px;
207}
208li.footer {
209 font-size: 70%;
210 font-style: italic;
211 text-align: right;
212 color: #666;
213}
214li.footer a {
215 color: #666;
216}
217div#content {
218 margin-left: 220px;
219 margin-right: 20px;
220 padding-top: 10px;
221}
222
223table {
224 border: 1px solid #ccc;
225 border-collapse: collapse;
226 font-size: 90%;
227 margin-bottom: 10px;
228}
229th {
230 border: 1px solid #ccc;
231 background-color: #666;
232 color: #fff;
233 text-align: left;
234 padding: 0 3px 0 3px;
235}
236tr.odd {
237 background-color: #eee;
238}
239td {
240 border: 1px solid #ccc;
241 padding: 0 3px 0 3px;
242 vertical-align: top;
243}
244td em {
245 color: #aaa;
246}
247th.primary {
248 color: #fef;
249}
250
251div.sql {
252 font-family: courier, monospace;
253 background-color: #eee;
254 padding: 5px;
255 border: 1px solid #999;
256 width: 528px;
257 margin-bottom: 2px;
258 margin-top: 6px;
259}
260div.sql em {
261 font-family: verdana, arial, sans-serif;
262 font-size: 70%;
263 font-style: normal;
264 color: #777;
265}
266
267div.error {
268 color: #933;
269 font-weight: bold;
270 padding: 0;
271 border:0;
272 background-color: transparent;
273 margin-top: 5px;
274 font-size: 80%;
275}
276div.startup_error {
277 font-family: verdana, arial, sans-serif;
278 width: 548px;
279 margin: 10px 0 0 220px;
280 background-color: #fee;
281 border: 1px solid #933;
282 padding: 5px;
283}
284
285ul.pager {
286 height: 16px;
287 list-style: none;
288}
289ul.pager li {
290 float: left;
291 padding-right: 4px;
292 font-size: 11px;
293}
294ul.pager li {
295 padding: 0 3px 3px 3px;
296}
297ul.pager li.selected {
298 font-weight: bold;
299 background-color: #ccc;
300}
301div.afterpgr {
302 clear: both;
303 height: 1px;
304 overflow: hidden;
305}
306CSS;
307}
308
309
310
311function css_compact($css)
312{
313 $css = preg_replace('/ +/', ' ', $css);
314 $css = preg_replace('/(\s*\r?\n)+\s*/m', ' ', $css);
315 $css = preg_replace('/([{:;]) /', '\1', $css);
316 $css = str_replace(';} ', "}", $css);
317 return $css;
318}
319
320function process_tinyadm() {
321 global $db;
322 @session_start();
323 remove_magic_quotes();
324 if (!isset($_SESSION['user'])) $_SESSION['user'] = '';
325 if (!isset($_SESSION['password'])) $_SESSION['password'] = '';
326 if (!isset($_SESSION['database'])) $_SESSION['database'] = '';
327 if (!isset($_SESSION['table'])) $_SESSION['table'] = '';
328 if (!isset($_SESSION['last_sql'])) $_SESSION['last_sql'] = '';
329 if (!isset($_SESSION['sql_history'])) $_SESSION['sql_history'] = array();
330
331 $act = get_var('act');
332
333 if ($act == 'login') {
334 setcookie('tinymy_user', get_var('user'), time() + 5184000); // 2 months
335 $_SESSION['user'] = addslashes(get_var('user'));
336 $_SESSION['password'] = addslashes(get_var('password'));
337 }
338
339 $db = new sqldb($_SESSION['user'], $_SESSION['password'], $_SESSION['database']);
340
341 if (!$db->is_connected()) {
342 return draw_login_form();
343 }
344
345 if ($act == 'login') {// switch to default databas
346 if (get_cookie('tinymy_database')) {
347 $_SESSION['database'] = get_cookie('tinymy_database');
348 }
349 }
350
351 switch($act) {
352 case 'sel_db':
353 $_SESSION['database'] = get_var('d');
354 $_SESSION['table'] = '';
355 setcookie('tinymy_database', get_var('d'), time() + 5184000); // 2 months
356 redirect_self();
357 exit();
358 case 'use_history':
359 $idx = (int)get_var('idx');
360 if (isset($_SESSION['sql_history'][$idx])) {
361 $_SESSION['database'] = $_SESSION['sql_history'][$idx]['db'];
362 $_SESSION['last_sql'] = $_SESSION['sql_history'][$idx]['sql'];
363 }
364 redirect_self();
365 exit();
366 case 'sel_table':
367 $_SESSION['table'] = get_var('table');
368 break;
369 case 'do_export':
370 ob_end_clean(); // we need to pass through the following output from export immediately, without caching
371 do_export();
372 break;
373 case 'logout':
374 session_unset();
375 session_destroy();
376 redirect_self();
377 exit();
378 case 'exec_sql':
379 history_add(get_var('sql'));
380 }
381
382 ob_start();// menu needs to be created after the possible sql has executed
383 echo '<div id="content">';
384
385 if ($act != 'export' && $act != 'do_export') {
386 draw_sqlarea();
387 }
388
389 switch($act) {
390 case 'history':
391 draw_history();
392 break;
393 case 'export':
394 draw_export();
395 break;
396 case 'sel_db':
397 break;
398 case 'sel_table':
399 case 'show_structure':
400 h('<p style="margin-bottom: 8px;"><a href="?act=show_contents">Show contents of %s</a></p>', $_SESSION['table']);
401 exec_sql_internal(sprintf('desc `%s`', mysqli_escape_string($db->conn_id, $_SESSION['table'])));
402 exec_sql_singlerow(sprintf('show create table `%s`', mysqli_escape_string($db->conn_id, $_SESSION['table'])));
403
404 break;
405 case 'show_contents':
406 h('<p style="margin-bottom: 8px;"><a href="?act=show_structure">Show structure of %s</a></p>', $_SESSION['table']);
407 $res = mysqli_query($db->conn_id, sprintf("select count(*) from `%s`", mysqli_escape_string($db->conn_id, $_SESSION['table']) ));
408 if ( ! $res) {
409 $db->error();
410 //
411 } else {
412 list($reccount) = mysqli_fetch_row($res);
413 pager($reccount);
414 exec_sql_internal(sprintf('select * from `%s` %s', mysqli_escape_string($db->conn_id, $_SESSION['table']), pager_limits()));
415 }
416 case 'exec_sql':
417 exec_sql();
418 // in case the query changed the database, switch to it
419 $cur_database = $db->get_current_database();
420 if ($cur_database != $_SESSION['database']) {
421 $_SESSION['database'] = $cur_database;
422 setcookie('tinymy_database', $cur_database, time() + 5184000); // 2 months
423 }
424 break;
425 }
426 echo '</div>'; // content
427 $content = ob_get_contents();
428 ob_end_clean();
429
430 // menu needs to be created after all the sql has executed
431 draw_db_menu();
432 echo $content;
433}
434
435
436function remove_magic_quotes()
437{
438 if( get_magic_quotes_gpc() ) {
439 if (is_array($_GET)) {
440 foreach($_GET as $k=>$v) {
441 $_GET[$k] = stripslashes($v);
442 }
443 }
444 if (is_array($_POST)) {
445 foreach($_POST as $k=>$v) {
446 $_POST[$k] = stripslashes($v);
447 }
448 }
449 }
450}
451
452
453
454class sqldb {
455 var $conn_id = 0;
456 var $serverinfo = '';
457
458
459 function is_connected()
460 {
461 return !! $this->conn_id;
462 }
463
464
465
466 function error($error_text = '')
467 {
468 if ($error_text == '') {
469 h('<div class="error">%d: %s</div>', @mysqli_errno($this->conn_id), @mysqli_error($this->conn_id));
470 } else {
471 h('<div class="startup_error"><strong>%d: %s</strong><br>%s</div>', @mysqli_errno($this->conn_id), $error_text, @mysqli_error($this->conn_id));
472 }
473 }
474
475
476
477 function sqldb($user, $password, $dbase)
478 {
479 global $db_host;
480 if ($user != '') {
481 $this->conn_id = @mysqli_connect($db_host, $user, $password);
482 mysqli_set_charset($this->conn_id, 'utf-8');
483 if ($this->conn_id) {
484 $this->serverinfo = mysqli_get_server_info($this->conn_id);
485 if ($dbase != '') {
486 if (!@mysqli_select_db($this->conn_id, $dbase)) {
487 $this->error(hs("Cannot select database %s", $dbase));
488 $_SESSION['database'] = '';
489 }
490 } else {
491 $dbs = $this->get_databases();
492 if (sizeof($dbs)==1) {
493 if (@mysqli_select_db($this->conn_id, $dbs[0])) {
494 $_SESSION['database'] = $dbs[0];
495 } else {
496 $_SESSION['database'] = '';
497 }
498 }
499 }
500 }
501 }
502 }
503
504
505
506 function exp_get_row($sql)
507 {
508 $res = @mysqli_query($this->conn_id, $sql);
509 if (!$res) {
510 $this->error();
511 } else {
512 $row = @mysqli_fetch_array($res, MYSQLI_ASSOC);
513 @mysqli_free_result($res);
514 return $row;
515 }
516 }
517
518
519 function get_array($query)
520 {
521 $output = array();
522 if ($this->is_connected()) {
523 $list = mysqli_query($this->conn_id, $query);
524 while ($row = mysqli_fetch_row($list)) {
525 $output[] = $row[0];
526 }
527 }
528 return $output;
529 }
530
531 function get_databases()
532 {
533 $output = $this->get_array('show databases');
534 if (!$output) {
535 global $default_database;
536 if (isset($default_database) and $default_database) {
537 $output[] = $default_database;
538 }
539 }
540 return $output;
541 }
542
543
544
545 function get_tables($database)
546 {
547 return $this->get_array("show tables from $database");
548 }
549
550
551
552 function get_current_database()
553 {
554 $row = $this->get_array('select database()');
555 return $row[0];
556 }
557
558
559 function print_blob(&$contents)
560 {
561 $blob_length = strlen($contents);
562 if ($blob_length == 0) {
563 return NULL;
564 }
565
566 if (BLOB_SKIP_NON_ASCII) {
567 $contents = preg_replace('/[^ -~]/', '?', $contents);
568 }
569 if ($blob_length > BLOB_MAX_SIZE) {
570
571 // we may want to try to find a space to break on it
572 $space_found = false;
573 for ($i = BLOB_MAX_SIZE - 10; $i < BLOB_MAX_SIZE + 10; $i++) {
574 if ($contents[$i] == ' ') {
575 $contents = substr($contents, 0, $i);
576 $space_found = true;
577 break;
578 }
579 }
580 if (!$space_found) {
581 $contents = substr($contents, 0, BLOB_MAX_SIZE);
582 }
583 return hs('%s... (%.2fk)', $contents, $blob_length / 1024);
584 } else {
585 return $contents;
586 }
587
588 }
589
590
591 function query($sql, $process_blob = true) {
592 # sure enough, this sucks heavily when blobs are used in resultset, as they are retrieved anyway,
593 # but usually I know what I'm doing, and I don't want to do any query preprocessing anyway
594
595 $result = array('failed'=>false, 'rows'=>0, 'rows_affected'=>0, 'result'=>array(), 'field_types'=>array(), 'field_names'=>array(), 'time'=>0);
596 if ($this->is_connected()) {
597
598 $start_time = microtime_float();
599 $res = @mysqli_query($this->conn_id, $sql);
600 $result['time'] = max(microtime_float() - $start_time, 0);
601
602 if (!$res) {
603 $this->error();
604 $result['failed'] = true;
605 return $result;
606 }
607 $nr = @mysqli_num_rows($res);
608 $result['rows'] = $nr ? $nr : 0;
609 $result['rows_affected'] = mysqli_affected_rows($this->conn_id);
610 for ($i = 0 ; $i < $result['rows']; $i++) {
611 $row = mysqli_fetch_row($res);
612 if($i == 0) { // populate field_flags
613 $fields = mysqli_fetch_fields($res);
614 for ($j = 0; $j < sizeof($fields); $j++) {
615 $f = $fields[$j];
616 $field_name = $f->name;
617 $field_type = $f->type;
618 $result['field_types'][$field_name] = $field_type;
619 $result['field_types'][$j] = $field_type;
620 $result['field_names'][$j] = $field_name;
621 }
622 }
623 for($j = 0 ; $j < sizeof($row); $j++) {
624 if ($process_blob) {
625 if ($result['field_types'][$j] == 'blob') {
626 $row[$j] = $this->print_blob($row[$j]);
627 }
628 }
629 if ($result['field_types'][$j] == 'datetime') {
630 if (substr($row[$j], -8) == '00:00:00') {
631 $row[$j] = substr($row[$j], 0, -8);
632 }
633 }
634 }
635 $result['result'][] = $row;
636 }
637
638 }
639 return $result;
640 }
641}
642
643
644function get_var($name)
645{
646 return trim(!empty($_GET[$name]) ? $_GET[$name] : ( !empty($_POST[$name]) ? $_POST[$name] : '' ));
647}
648
649
650function get_cookie($name)
651{
652 return isset($_COOKIE[$name]) ? $_COOKIE[$name] : '';
653}
654
655
656function draw_login_form()
657{
658 h('<form id="login" method="post" action="?"><h2><a style="color:#fff;text-decoration:none;" href="http://elfz.laacz.lv/tinymy/">tinyMy</a></h2><p style="margin:0"><input type="hidden" name="act" value="login">
659 <input id="u" name="user" value="%s"><input id="p" type="password" name="password"><button type="submit">Login</button>
660 </p></form>
661 <script type="text/javascript">
662var u = document.getElementById(\'u\');
663if (u.value == \'\') u.focus(); else document.getElementById(\'p\').focus();</script>', get_var('user') ? get_var('user') : get_cookie('tinymy_user'));
664}
665
666
667function draw_db_menu()
668{
669 global $db;
670 echo '<ul id="dbmenu"><li class="title">' . $db->serverinfo . '</li>';
671 $databases = $db->get_databases();
672 foreach ($databases as $d) {
673 h('<li class="%s"><a href="?act=sel_db&d=%s">%s</a></li>'
674 , ($d == $_SESSION['database'] ? 'selected' : '')
675 , rawurlencode($d)
676 , $d
677 );
678 if ($d == $_SESSION['database']) {
679 $tables = $db->get_tables($d);
680 foreach ($tables as $t) {
681 h('<li class="%s"><a title="%s" href="?act=sel_table&table=%s">%s</a></li>'
682 , ($t == $_SESSION['table'] ? 'selected pad':'pad')
683 , $t
684 , rawurlencode($t)
685 , $t
686 );
687 }
688 }
689 }
690 if ($_SESSION['database'] != '') {
691 h('<li class="actions"><a href="?act=export">Export %s</a></li>', $_SESSION['database']);
692 }
693 h('<li class="actions"><a href="?act=logout">Logout %s</a></li>', $_SESSION['user']);
694 echo '<li class="footer">Powered by <a href="http://github.com/einars/tinymy/">tinyMy</a></li>';
695 echo '</ul>';
696}
697
698
699function draw_export()
700{
701 global $db;
702 $tables = $db->get_tables($_SESSION['database']);
703 h('<h2>Exporting tables from %s</h2>', $_SESSION['database']);
704 echo '<form id="export" method="post" action="?"><p><input type="hidden" name="act" value="do_export">';
705
706 $checked_tables = $tables;
707 if (get_cookie('tinymy_tables_' . $_SESSION['database'])) {
708 $checked_tables = explode(',',get_cookie('tinymy_tables_' . $_SESSION['database']));
709 }
710
711 foreach($tables as $table) {
712 $checked = (false!==array_search($table, $checked_tables) ? 'checked="checked" ':'');
713 h('<label><input ' . $checked . ' type="checkbox" name="e_%s"> %s</label><br>'
714 , $table
715 , $table
716 );
717 }
718 echo '<br><label><input type="checkbox" checked="checked" name="drop"> add <em>drop</em> statements</label><br><br><button type="submit">Export</button></p></form>';
719}
720
721
722function do_export()
723{
724 global $db;
725 $file_name = $_SESSION['database'] . '_' . date('Ymd') . '.sql';
726 header('Content-Type: text/sql');
727 $attachment = strstr($_SERVER['HTTP_USER_AGENT'],'MSIE')?'':' attachment;';
728 header("Content-Disposition:$attachment filename=$file_name");
729 header('Content-Transfer-Encoding: binary');
730 $drops = isset($_POST['drop']) && $_POST['drop'] == 'on';
731
732 $tables = array();
733 foreach($_POST as $post=>$var) {
734 if (substr($post, 0, 2) == 'e_' && $var == 'on') {
735 $tables[] = substr($post, 2);
736 }
737 }
738
739 setcookie('tinymy_tables_' . $_SESSION['database'], implode(',', $tables), time() + 5184000); // 2 months
740
741 echo "-- generated by tinyMy\n\nset names utf8;\n";
742
743
744 foreach($tables as $table) {
745 $table_ue = mysqli_escape_string($db->conn_id, $table);
746 echo "\n--\n-- $table\n--\n";
747
748 $test = mysqli_query($db->conn_id, "select 1 from `$table_ue` where 1=0");
749 if ($test === FALSE) {
750 echo "\n-- unable to access the table $table\n-- ";
751 echo str_replace("\n", "\n -- ", mysqli_error());
752 echo "\n\n";
753 } else {
754
755
756 if ($drops) {
757 echo "\ndrop table if exists $table;";
758 }
759 $row = $db->exp_get_row("show create table `$table_ue`");
760 echo "\n\n{$row['Create Table']};\n\n";
761
762 $res = mysqli_query($db->conn_id, "select * from `$table_ue`");
763 while ($row = mysqli_fetch_array($res, MYSQLI_NUM)) {
764 $values = array();
765 foreach($row as $value) {
766 if ($value === NULL) {
767 $values[] = 'null';
768 } elseif (preg_match('/^\d+(\.\d+)?$/', $value)) {
769 $values[] = $value;
770 } else {
771 $values[] = "'" . mysqli_escape_string($db->conn_id, $value) . "'";
772 }
773 }
774 printf("insert into %s values (%s);\n", $table, implode(',', $values));
775 }
776 }
777 }
778 die();
779}
780
781
782function draw_sqlarea()
783{
784 $sqltext = get_var('sql');
785 if('' == $sqltext) {
786 $sqltext = $_SESSION['last_sql'];
787 }
788 echo '<form id="sqlarea" method="post" action="?">';
789 if (sizeof($_SESSION['sql_history'])) {
790 echo '<p id="historyurl"><a href="?act=history">History</a></p>';
791 }
792 h('<p><input type="hidden" name="act" value="exec_sql"><textarea id="sql" rows="0" cols="0" name="sql">%s</textarea><br><button type="submit">Execute SQL%s</button></p></form><script type="text/javascript">document.getElementById(\'sql\').focus();</script>'
793 , $sqltext
794 , $_SESSION['database'] ? " [$_SESSION[database]]" : ''
795 );
796}
797
798
799function html_format_val($value)
800{
801 global $null_text;
802 if ($value === NULL) return $null_text;
803 $value = str_replace(' ', ' ', r_htmlspecialchars($value));
804 if ($value == '') $value = ' ';
805 return $value;
806}
807
808
809function exec_sql()
810{
811 $sql = get_var('sql');
812 if ('' == $sql) return;
813
814 $_SESSION['last_sql'] = $sql;
815
816 // check if the sql is multipart
817 // correct the probable formatting errors induced by explode as well i.e. ... where a= ";";
818 $now_running = '';
819 foreach(explode(';', $sql) as $single_sql) {
820 $now_running .= ($now_running == '' ? '' : ';') . $single_sql;
821 preg_match_all('/[^\\\\]\'/', $now_running, $matches_sq);
822 preg_match_all('/[^\\\\]\"/', $now_running, $matches_dq);
823 if ((!isset($matches_sq[0]) || sizeof($matches_sq[0]) % 2 == 0) && (!isset($matches_dq[0]) || sizeof($matches_dq[0]) % 2 == 0)) {
824 exec_sql_internal($now_running, true, true);
825 $now_running = '';
826 }
827 }
828 if ($now_running != '') {
829 exec_sql_internal($now_running, true, true);
830 }
831}
832
833
834function exec_sql_singlerow($sql_text = '', $show_stats = false)
835{
836 global $db;
837 $res = $db->query($sql_text);
838 if ($res['rows'] > 0) {
839 printf('<pre>%s</pre>', str_replace("\n", "", r_htmlspecialchars($res['result'][0][1])));
840 }
841}
842
843
844function exec_sql_internal($sql_text = '', $show_stats = false, $show_query = false)
845{
846 global $db;
847
848 $sql_text = trim($sql_text);
849
850 if (!$sql_text || ';' == $sql_text || substr($sql_text, 0, 2) == '--') return;
851
852 if ($show_query || $show_stats) {
853 echo '<div class="sql">';
854 }
855
856 if ($show_query) {
857 h('%s<br>', $sql_text);
858 }
859
860 $res = $db->query($sql_text);
861
862 if ($show_stats && !$res['failed']) {
863 echo '<em>Ok';
864 if ($res['rows']) {
865 if ($res['rows'] != $res['rows_affected']) {
866 h(', rows: %d', $res['rows']);
867 }
868 }
869 if ($res['rows_affected']) {
870 h(', rows affected: %d', $res['rows_affected']);
871 }
872 if ($res['time']) {
873 h(', time: %.3f s', $res['time']);
874 }
875 echo '</em>';
876 }
877
878
879 if ($show_query || $show_stats) {
880
881 echo '</div>';
882 }
883
884 if (!$res['failed']) {
885
886 if ($res['rows'] != 0) {
887 echo '<table class="result"><tr>';
888 foreach($res['field_names'] as $title) {
889 h('<th>%s</th>', $title);
890 }
891 echo '</tr>';
892
893 $odd = true;
894 for ($i = 0 ; $i < $res['rows']; $i++) {
895 h('<tr class="%s">', $odd ? 'odd' : 'even');
896 $odd = !$odd;
897 foreach($res['result'][$i] as $title=>$value) {
898 printf('<td>%s</td>', html_format_val($value)); // sic printf
899 }
900 echo '</tr>';
901 }
902 echo '</table>';
903 } else {
904 echo '<p style="font-size: 70%;padding-left: 5px; margin-bottom: 10px;">Query executed, but returned no result.</p>';
905 }
906 }
907}
908
909
910function pager($records, $records_pp = 50, $break_on_page = 15)
911{
912 if ($records == 0) return;
913
914 $cur = (int)get_var('p');
915
916 $uri = '?';
917 foreach($_GET as $var=>$val) {
918 if ($var != 'p') {
919 $uri .= $var . '=' . rawurlencode($val) . '&';
920 }
921 }
922
923 if ($records < $records_pp) return;
924 echo '<ul class="pager">';
925
926 // adjust start page, if neccessary
927 $total_pages = (int)($records / $records_pp + 0.5);
928 $start_page = 0;
929 if ($total_pages > $break_on_page) {
930 if ($total_pages - $cur < $break_on_page / 2) {
931 $start_page = $total_pages - $break_on_page;
932 } else {
933 $start_page = $cur - (int)($break_on_page / 2);
934 if ($start_page < 0) {
935 $start_page = 0;
936 }
937 }
938 }
939
940 $page = $start_page;
941 $start_rec = $page * $records_pp + 1;
942
943 $broken = false;
944 while ($start_rec < $records + 1) {
945 h('<li class="%s"><a href="%sp=%d">%d</a></li>'
946 , ($page == $cur ? 'selected':'')
947 , $uri
948 , $page
949 , $page + 1
950 );
951 $start_rec += $records_pp;
952 $page++;
953 if ($page == $break_on_page + $start_page + 1) {
954 $broken = true;
955 break;
956 }
957
958 }
959 h('<li class="recordcount">%d %s</li>', $broken ?
960 format_numeric(1 + $total_pages, '%d page', '%d pages') :
961 format_numeric(1 + $total_pages, '%d record', '%d records')
962 );
963
964 echo '</ul>';
965 echo '<div class="afterpgr"> </div>';
966
967}
968
969
970function pager_limits($records_pp = 50)
971{
972 $cur = (int)get_var('p');
973 if ($cur == 0) return " limit $records_pp ";
974 return ' limit ' . $records_pp . ' offset ' . $records_pp * $cur . ' ';
975}
976
977
978function format_numeric($num, $single, $multiple)
979{
980 return sprintf(($num % 10 == 1 && $num % 100 != 11) ? $single : $multiple, $num);
981}
982
983
984function history_add($sql)
985{
986 if ($sql) {
987 $item = array('sql'=>$sql, 'db'=>$_SESSION['database']);
988 $idx = array_search($item, $_SESSION['sql_history']);
989 if ($idx !== FALSE) {
990 unset($_SESSION['sql_history'][$idx]);
991 }
992 $_SESSION['sql_history'][] = $item;
993 }
994}
995
996
997function draw_history()
998{
999 $n = sizeof($_SESSION['sql_history']) - 1;
1000 $lastdb = NULL;
1001 foreach(array_reverse($_SESSION['sql_history']) as $sql) {
1002 echo '<div class="history">';
1003 $db = $sql['db'] ? $sql['db'] : 'no database';
1004 if ($db == $lastdb) {
1005 h('<a href="?act=use_history&idx=%d">%s</a>', $n, $sql['sql']);
1006 } else {
1007 h('<h2>%s</h2>', $db);
1008 h('<a href="?act=use_history&idx=%d">%s</a>', $n, $sql['sql']);
1009 }
1010 $lastdb = $db;
1011 --$n;
1012 echo '</div>';
1013 }
1014}
1015function redirect_self()
1016{
1017 header("Location: " . $_SERVER['PHP_SELF']);
1018 exit;
1019}
1020function microtime_float()
1021{
1022 list($usec, $sec) = explode(" ", microtime());
1023 return ((float)$usec + (float)$sec);
1024}
1025
1026
1027
1028// html-safe printf
1029// hprintf('%s = %s', $a, "<foo>'</foo>")
1030function h($fmt /*, ... */)
1031{
1032 $args = func_get_args();
1033 vprintf(array_shift($args), array_map('r_htmlspecialchars', $args));
1034}
1035// html-safe sprintf
1036// $_ = hsprintf('%s', "<foo>'</foo>")
1037function hs($fmt /*, ... */)
1038{
1039 $args = func_get_args();
1040 return vsprintf(array_shift($args), array_map('r_htmlspecialchars', $args));
1041}
1042function r_htmlspecialchars($s)
1043{
1044 return nl2br(htmlspecialchars($s, ENT_QUOTES, 'UTF-8'));
1045}
1046
1047?>