2007-07-16 22:40:55 +00:00
< ? php
2009-09-13 22:22:37 +00:00
/** Print select result
* @ param Min_Result
* @ param Min_DB connection to examine indexes
* @ return null
*/
2009-09-22 10:51:40 +00:00
function select ( $result , $connection2 = null ) {
2009-09-13 22:22:37 +00:00
if ( ! $result -> num_rows ) {
echo " <p class='message'> " . lang ( 'No rows.' ) . " \n " ;
} else {
echo " <table cellspacing='0' class='nowrap'> \n " ;
$links = array (); // colno => orgtable - create links from these columns
$indexes = array (); // orgtable => array(column => colno) - primary keys
$columns = array (); // orgtable => array(column => ) - not selected columns in primary key
$blobs = array (); // colno => bool - display bytes for blobs
$types = array (); // colno => type - display char in <code>
odd ( '' ); // reset odd for each result
for ( $i = 0 ; $row = $result -> fetch_row (); $i ++ ) {
if ( ! $i ) {
echo " <thead><tr> " ;
for ( $j = 0 ; $j < count ( $row ); $j ++ ) {
$field = $result -> fetch_field ();
2010-03-11 20:07:14 +00:00
$orgtable = $field -> orgtable ;
$orgname = $field -> orgname ;
if ( $orgtable != " " ) {
if ( ! isset ( $indexes [ $orgtable ])) {
2009-09-13 22:22:37 +00:00
// find primary key in each table
2010-03-11 20:07:14 +00:00
$indexes [ $orgtable ] = array ();
foreach ( indexes ( $orgtable , $connection2 ) as $index ) {
2009-09-13 22:22:37 +00:00
if ( $index [ " type " ] == " PRIMARY " ) {
2010-03-11 20:07:14 +00:00
$indexes [ $orgtable ] = array_flip ( $index [ " columns " ]);
2009-09-13 22:22:37 +00:00
break ;
}
}
2010-03-11 20:07:14 +00:00
$columns [ $orgtable ] = $indexes [ $orgtable ];
2009-09-13 22:22:37 +00:00
}
2010-03-11 20:07:14 +00:00
if ( isset ( $columns [ $orgtable ][ $orgname ])) {
unset ( $columns [ $orgtable ][ $orgname ]);
$indexes [ $orgtable ][ $orgname ] = $j ;
$links [ $j ] = $orgtable ;
2009-09-13 22:22:37 +00:00
}
}
if ( $field -> charsetnr == 63 ) {
$blobs [ $j ] = true ;
}
$types [ $j ] = $field -> type ;
2010-03-11 20:07:14 +00:00
echo " <th " . ( $orgtable != " " || $field -> name != $orgname ? " title=' " . h (( $orgtable != " " ? " $orgtable . " : " " ) . $orgname ) . " ' " : " " ) . " > " . h ( $field -> name );
2009-09-13 22:22:37 +00:00
}
echo " </thead> \n " ;
}
echo " <tr " . odd () . " > " ;
foreach ( $row as $key => $val ) {
if ( ! isset ( $val )) {
$val = " <i>NULL</i> " ;
} else {
if ( $blobs [ $key ] && ! is_utf8 ( $val )) {
$val = " <i> " . lang ( '%d byte(s)' , strlen ( $val )) . " </i> " ; //! link to download
2010-01-09 23:33:41 +00:00
} elseif ( $val == " " ) {
2009-09-13 22:22:37 +00:00
$val = " " ; // some content to print a border
} else {
2009-10-13 19:43:33 +00:00
$val = h ( $val );
2009-09-13 22:22:37 +00:00
if ( $types [ $key ] == 254 ) {
$val = " <code> $val </code> " ;
}
}
if ( isset ( $links [ $key ]) && ! $columns [ $links [ $key ]]) {
$link = " edit= " . urlencode ( $links [ $key ]);
foreach ( $indexes [ $links [ $key ]] as $col => $j ) {
$link .= " &where " . urlencode ( " [ " . bracket_escape ( $col ) . " ] " ) . " = " . urlencode ( $row [ $j ]);
}
$val = " <a href=' " . h ( ME . $link ) . " '> $val </a> " ;
}
}
echo " <td> $val " ;
}
}
echo " </table> \n " ;
}
}
2009-10-23 15:43:51 +00:00
/** Get referencable tables with single column primary key except self
* @ param string
* @ return array ( $table_name => $field )
*/
2009-07-02 22:37:10 +00:00
function referencable_primary ( $self ) {
$return = array (); // table_name => field
foreach ( table_status_referencable () as $table_name => $table ) {
if ( $table_name != $self ) {
foreach ( fields ( $table_name ) as $field ) {
if ( $field [ " primary " ]) {
if ( $return [ $table_name ]) { // multi column primary key
unset ( $return [ $table_name ]);
break ;
}
$return [ $table_name ] = $field ;
}
}
}
}
return $return ;
}
2009-10-23 15:43:51 +00:00
/** Print table columns for type edit
* @ param string
* @ param array
* @ param array
* @ param array returned by referencable_primary ()
* @ return null
*/
2009-07-02 22:37:10 +00:00
function edit_type ( $key , $field , $collations , $foreign_keys = array ()) {
2009-07-14 16:16:12 +00:00
global $structured_types , $unsigned , $inout ;
2008-03-20 16:17:37 +00:00
?>
2009-12-17 13:22:28 +00:00
< td >< select name = " <?php echo $key ; ?>[type] " class = " type " onfocus = " lastType = selectValue(this); " onchange = " editingTypeChange(this); " >< ? php echo optionlist ( $structured_types + ( $foreign_keys ? array ( lang ( 'Foreign keys' ) => $foreign_keys ) : array ()), $field [ " type " ]); ?> </select>
2010-02-19 14:13:07 +00:00
< td >< input name = " <?php echo $key ; ?>[length] " value = " <?php echo h( $field["length"] ); ?> " size = " 3 " onfocus = " editingLengthFocus(this); " >< td >< ? php
2009-10-06 10:40:52 +00:00
echo " <select name=' $key " . " [collation]' " . ( ereg ( '(char|text|enum|set)$' , $field [ " type " ]) ? " " : " class='hidden' " ) . '><option value="">(' . lang ( 'collation' ) . ')' . optionlist ( $collations , $field [ " collation " ]) . '</select>' ;
2010-03-02 16:33:28 +00:00
echo ( $unsigned ? " <select name=' $key " . " [unsigned]' " . ( ! $field [ " type " ] || ereg ( '(int|float|double|decimal)$' , $field [ " type " ]) ? " " : " class='hidden' " ) . '><option>' . optionlist ( $unsigned , $field [ " unsigned " ]) . '</select> ' : ' ' ); // space for IE
2007-07-16 22:40:55 +00:00
}
2009-10-23 15:43:51 +00:00
/** Filter length value including enums
* @ param string
* @ return string
*/
2009-07-27 15:31:11 +00:00
function process_length ( $length ) {
global $enum_length ;
return ( preg_match ( " ~^ \\ s*(?: $enum_length )(?: \\ s*, \\ s*(?: $enum_length ))* \\ s* \$ ~ " , $length ) && preg_match_all ( " ~ $enum_length ~ " , $length , $matches ) ? implode ( " , " , $matches [ 0 ]) : preg_replace ( '~[^0-9,+-]~' , '' , $length ));
}
2009-10-23 15:43:51 +00:00
/** Create SQL string from field type
* @ param array
* @ param string
* @ return string
*/
2007-07-17 05:51:09 +00:00
function process_type ( $field , $collate = " COLLATE " ) {
2009-10-06 10:40:52 +00:00
global $connection , $unsigned ;
2007-07-16 22:40:55 +00:00
return " $field[type] "
2010-01-09 23:33:41 +00:00
. ( $field [ " length " ] != " " && ! ereg ( '^date|time$' , $field [ " type " ]) ? " ( " . process_length ( $field [ " length " ]) . " ) " : " " )
2009-07-13 16:03:51 +00:00
. ( ereg ( 'int|float|double|decimal' , $field [ " type " ]) && in_array ( $field [ " unsigned " ], $unsigned ) ? " $field[unsigned] " : " " )
2009-09-22 10:51:40 +00:00
. ( ereg ( 'char|text|enum|set' , $field [ " type " ]) && $field [ " collation " ] ? " $collate " . $connection -> quote ( $field [ " collation " ]) : " " )
2007-07-16 22:40:55 +00:00
;
}
2009-10-23 15:43:51 +00:00
/** Create SQL string from field
* @ param array basic field information
* @ param array information about field type
* @ return string
*/
2009-09-09 19:47:15 +00:00
function process_field ( $field , $type_field ) {
2009-09-22 10:51:40 +00:00
global $connection ;
2009-09-09 19:47:15 +00:00
return idf_escape ( $field [ " field " ]) . process_type ( $type_field )
. ( $field [ " null " ] ? " NULL " : " NOT NULL " ) // NULL for timestamp
2009-10-06 10:40:52 +00:00
. ( ! isset ( $field [ " default " ]) ? " " : " DEFAULT " . ( $field [ " type " ] == " timestamp " && eregi ( " ^CURRENT_TIMESTAMP $ " , $field [ " default " ]) ? $field [ " default " ] : $connection -> quote ( $field [ " default " ])))
. ( $field [ " on_update " ] ? " ON UPDATE $field[on_update] " : " " )
2009-09-22 10:51:40 +00:00
. " COMMENT " . $connection -> quote ( $field [ " comment " ])
2009-09-09 19:47:15 +00:00
;
}
2009-10-23 15:43:51 +00:00
/** Get type class to use in CSS
* @ param string
* @ return string class = ''
*/
2009-07-14 08:45:24 +00:00
function type_class ( $type ) {
2009-09-19 19:31:16 +00:00
foreach ( array (
'char' => 'text' ,
'date' => 'time|year' ,
'binary' => 'blob' ,
'enum' => 'set' ,
) as $key => $val ) {
2009-09-19 19:37:39 +00:00
if ( ereg ( " $key | $val " , $type )) {
2009-09-19 19:31:16 +00:00
return " class=' $key ' " ;
}
2009-07-14 08:45:24 +00:00
}
}
2009-10-23 15:43:51 +00:00
/** Print table interior for fields editing
* @ param array
* @ param array
* @ param string TABLE or PROCEDURE
* @ param int number of fields allowed by Suhosin
* @ param array returned by referencable_primary ()
* @ return bool column comments used
*/
2009-07-02 22:37:10 +00:00
function edit_fields ( $fields , $collations , $type = " TABLE " , $allowed = 0 , $foreign_keys = array ()) {
2009-07-28 15:39:41 +00:00
global $inout ;
2009-05-29 16:14:54 +00:00
$column_comments = false ;
foreach ( $fields as $field ) {
2010-01-09 23:33:41 +00:00
if ( $field [ " comment " ] != " " ) {
2009-05-29 16:14:54 +00:00
$column_comments = true ;
2009-10-23 15:43:51 +00:00
break ;
2009-05-29 16:14:54 +00:00
}
}
2008-03-20 16:17:37 +00:00
?>
2010-01-28 15:17:20 +00:00
< thead >< tr class = " wrap " >
2009-08-25 15:42:43 +00:00
< ? php if ( $type == " PROCEDURE " ) { ?> <td> <?php } ?>
2009-07-11 20:30:40 +00:00
< th >< ? php echo ( $type == " TABLE " ? lang ( 'Column name' ) : lang ( 'Parameter name' )); ?>
2010-02-19 14:13:07 +00:00
< td >< ? php echo lang ( 'Type' ); ?> <textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;" onblur="editingLengthBlur(this);"></textarea>
2009-07-11 20:30:40 +00:00
< td >< ? php echo lang ( 'Length' ); ?>
< td >< ? php echo lang ( 'Options' ); ?>
2007-07-16 22:40:55 +00:00
< ? php if ( $type == " TABLE " ) { ?>
2009-08-25 15:42:43 +00:00
< td > NULL
2009-10-19 04:46:33 +00:00
< td >< input type = " radio " name = " auto_increment_col " value = " " >< acronym title = " <?php echo lang('Auto Increment'); ?> " > A_I </ acronym >
2009-08-21 16:54:10 +00:00
< td class = " hidden " >< ? php echo lang ( 'Default values' ); ?>
2009-07-11 20:30:40 +00:00
< td < ? php echo ( $column_comments ? " " : " class='hidden' " ); ?> ><?php echo lang('Comment'); ?>
2007-07-16 22:40:55 +00:00
< ? php } ?>
2009-09-23 09:56:07 +00:00
< td >< ? php echo " <input type='image' name='add[0]' src='../adminer/static/plus.gif' alt='+' title=' " . lang ( 'Add next' ) . " '> " ; ?> <script type="text/javascript">row_count = <?php echo count($fields); ?>;</script>
2009-07-11 20:30:40 +00:00
</ thead >
2007-07-16 22:40:55 +00:00
< ? php
2007-07-16 23:08:55 +00:00
foreach ( $fields as $i => $field ) {
$i ++ ;
2008-10-03 16:05:03 +00:00
$display = ( isset ( $_POST [ " add " ][ $i - 1 ]) || ( isset ( $field [ " field " ]) && ! $_POST [ " drop_col " ][ $i ]));
2007-07-16 23:08:55 +00:00
?>
2009-06-11 04:50:35 +00:00
< tr < ? php echo ( $display ? " " : " style='display: none;' " ); ?> >
2009-10-02 13:21:34 +00:00
< ? php
if ( $type == " PROCEDURE " ) {
echo " <td> " . html_select ( " fields[ $i ][inout] " , $inout , $field [ " inout " ]);
}
?>
2010-01-09 23:33:41 +00:00
< th >< ? php if ( $display ) { ?> <input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" onchange="<?php echo ($field["field"] != "" || count($fields) > 1 ? "" : "editingAddRow(this, $allowed); "); ?>editingNameChange(this);" maxlength="64"><?php } ?><input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo h($field[($_POST ? "orig" : "field")]); ?>">
2009-07-02 22:37:10 +00:00
< ? php edit_type ( " fields[ $i ] " , $field , $collations , $foreign_keys ); ?>
2007-07-16 22:40:55 +00:00
< ? php if ( $type == " TABLE " ) { ?>
2009-09-25 12:03:30 +00:00
< td >< ? php echo checkbox ( " fields[ $i ][null] " , 1 , $field [ " null " ]); ?>
2009-07-28 16:28:47 +00:00
< td >< input type = " radio " name = " auto_increment_col " value = " <?php echo $i ; ?> " < ? php if ( $field [ " auto_increment " ]) { ?> checked<?php } ?>>
2010-01-28 15:17:20 +00:00
< td class = " hidden " >< ? php echo checkbox ( " fields[ $i ][has_default] " , 1 , $field [ " has_default " ]); ?> <input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" onchange="this.previousSibling.checked = true;">
2009-07-28 16:20:50 +00:00
< td < ? php echo ( $column_comments ? " " : " class='hidden' " ); ?> ><input name="fields[<?php echo $i; ?>][comment]" value="<?php echo h($field["comment"]); ?>" maxlength="255">
2007-07-16 22:40:55 +00:00
< ? php } ?>
< ? php
2010-01-28 15:17:20 +00:00
echo " <td><input type='image' name='add[ $i ]' src='../adminer/static/plus.gif' alt='+' title=' " . lang ( 'Add next' ) . " ' onclick='return !editingAddRow(this, $allowed , 1);'> " ;
2009-12-17 13:22:28 +00:00
echo " <input type='image' name='drop_col[ $i ]' src='../adminer/static/cross.gif' alt='x' title=' " . lang ( 'Remove' ) . " ' onclick='return !editingRemoveRow(this);'> " ;
2009-09-23 09:56:07 +00:00
echo " <input type='image' name='up[ $i ]' src='../adminer/static/up.gif' alt='^' title=' " . lang ( 'Move up' ) . " '> " ;
echo " <input type='image' name='down[ $i ]' src='../adminer/static/down.gif' alt='v' title=' " . lang ( 'Move down' ) . " '> " ;
2009-10-13 19:43:33 +00:00
echo " \n " ;
2007-07-16 22:40:55 +00:00
}
2007-07-16 23:08:55 +00:00
return $column_comments ;
2007-07-16 22:40:55 +00:00
}
2007-07-16 23:08:55 +00:00
2009-10-23 15:43:51 +00:00
/** Move fields up and down or add field
* @ param array
* @ return null
*/
2008-05-07 11:22:08 +00:00
function process_fields ( & $fields ) {
ksort ( $fields );
$offset = 0 ;
if ( $_POST [ " up " ]) {
$last = 0 ;
foreach ( $fields as $key => $field ) {
if ( key ( $_POST [ " up " ]) == $key ) {
unset ( $fields [ $key ]);
array_splice ( $fields , $last , 0 , array ( $field ));
break ;
}
if ( isset ( $field [ " field " ])) {
$last = $offset ;
}
$offset ++ ;
}
}
if ( $_POST [ " down " ]) {
$found = false ;
foreach ( $fields as $key => $field ) {
if ( isset ( $field [ " field " ]) && $found ) {
unset ( $fields [ key ( $_POST [ " down " ])]);
array_splice ( $fields , $offset , 0 , array ( $found ));
break ;
}
if ( key ( $_POST [ " down " ]) == $key ) {
$found = $field ;
}
$offset ++ ;
}
}
$fields = array_values ( $fields );
if ( $_POST [ " add " ]) {
array_splice ( $fields , key ( $_POST [ " add " ]), 0 , array ( array ()));
}
}
2009-10-23 15:43:51 +00:00
/** Callback used in routine ()
* @ param array
* @ return string
*/
2007-07-17 09:12:15 +00:00
function normalize_enum ( $match ) {
return " ' " . str_replace ( " ' " , " '' " , addcslashes ( stripcslashes ( str_replace ( $match [ 0 ]{ 0 } . $match [ 0 ]{ 0 }, $match [ 0 ]{ 0 }, substr ( $match [ 0 ], 1 , - 1 ))), '\\' )) . " ' " ;
}
2009-10-23 15:43:51 +00:00
/** Get information about stored routine
* @ param string
* @ param string FUNCTION or PROCEDURE
* @ return array ( " fields " => array ( " field " => , " type " => , " length " => , " unsigned " => , " inout " => , " collation " => ), " returns " => , " definition " => )
*/
2007-07-16 22:40:55 +00:00
function routine ( $name , $type ) {
2009-09-22 10:51:40 +00:00
global $connection , $enum_length , $inout , $types ;
2007-08-16 08:32:11 +00:00
$aliases = array ( " bit " => " tinyint " , " bool " => " tinyint " , " boolean " => " tinyint " , " integer " => " int " , " double precision " => " float " , " real " => " float " , " dec " => " decimal " , " numeric " => " decimal " , " fixed " => " decimal " , " national char " => " char " , " national varchar " => " varchar " );
2009-09-16 21:47:23 +00:00
$type_pattern = " ( " . implode ( " | " , array_keys ( $types + $aliases )) . " )(?: \\ s* \\ (((?:[^' \" )]*| $enum_length )+) \\ ))? \\ s*(zerofill \\ s*)?(unsigned(?: \\ s+zerofill)?)?(?: \\ s*(?:CHARSET|CHARACTER \\ s+SET) \\ s*[' \" ]?([^' \" \\ s]+)[' \" ]?)? " ;
2009-08-19 17:10:06 +00:00
$pattern = " \\ s*( " . ( $type == " FUNCTION " ? " " : implode ( " | " , $inout )) . " )? \\ s*(?:`((?:[^`]|``)*)` \\ s*| \\ b( \\ S+) \\ s+) $type_pattern " ;
2009-09-22 10:51:40 +00:00
$create = $connection -> result ( $connection -> query ( " SHOW CREATE $type " . idf_escape ( $name )), 2 );
2007-07-17 09:12:15 +00:00
preg_match ( " ~ \\ (((?: $pattern\\s *,?)*) \\ ) " . ( $type == " FUNCTION " ? " \\ s*RETURNS \\ s+ $type_pattern " : " " ) . " \\ s*(.*)~is " , $create , $match );
2007-07-16 22:40:55 +00:00
$fields = array ();
2007-07-17 09:12:15 +00:00
preg_match_all ( " ~ $pattern\\s *,?~is " , $match [ 1 ], $matches , PREG_SET_ORDER );
2009-07-24 16:16:50 +00:00
foreach ( $matches as $param ) {
$name = str_replace ( " `` " , " ` " , $param [ 2 ]) . $param [ 3 ];
2007-08-16 08:32:11 +00:00
$data_type = strtolower ( $param [ 4 ]);
2009-12-17 15:42:25 +00:00
$fields [] = array (
2009-07-24 16:16:50 +00:00
" field " => $name ,
2007-08-16 08:32:11 +00:00
" type " => ( isset ( $aliases [ $data_type ]) ? $aliases [ $data_type ] : $data_type ),
2007-07-16 22:40:55 +00:00
" length " => preg_replace_callback ( " ~ $enum_length ~s " , 'normalize_enum' , $param [ 5 ]),
" unsigned " => strtolower ( preg_replace ( '~\\s+~' , ' ' , trim ( " $param[7] $param[6] " ))),
" inout " => strtoupper ( $param [ 1 ]),
2007-07-17 09:12:15 +00:00
" collation " => strtolower ( $param [ 8 ]),
2007-07-16 22:40:55 +00:00
);
}
if ( $type != " FUNCTION " ) {
2007-07-17 09:12:15 +00:00
return array ( " fields " => $fields , " definition " => $match [ 10 ]);
2007-07-16 22:40:55 +00:00
}
2007-07-17 09:12:15 +00:00
$returns = array ( " type " => $match [ 10 ], " length " => $match [ 11 ], " unsigned " => $match [ 13 ], " collation " => $match [ 14 ]);
return array ( " fields " => $fields , " returns " => $returns , " definition " => $match [ 15 ]);
2007-07-16 22:40:55 +00:00
}
2009-09-09 11:03:03 +00:00
2009-10-23 15:43:51 +00:00
/** Issue grant or revoke commands
* @ param string GRANT or REVOKE
* @ param array
* @ param string
* @ param string
* @ return
*/
2009-09-09 11:03:03 +00:00
function grant ( $grant , $privileges , $columns , $on ) {
if ( ! $privileges ) {
return true ;
}
if ( $privileges == array ( " ALL PRIVILEGES " , " GRANT OPTION " )) {
// can't be granted or revoked together
return ( $grant == " GRANT "
? queries ( " $grant ALL PRIVILEGES $on WITH GRANT OPTION " )
: queries ( " $grant ALL PRIVILEGES $on " ) && queries ( " $grant GRANT OPTION $on " )
);
}
return queries ( " $grant " . preg_replace ( '~(GRANT OPTION)\\([^)]*\\)~' , '\\1' , implode ( " $columns , " , $privileges ) . $columns ) . $on );
}
2009-10-13 19:33:50 +00:00
2009-10-23 15:43:51 +00:00
/** Drop old object and create a new one
* @ param string drop query
* @ param string create query
* @ param string
* @ param string
* @ param string
* @ param string
* @ param string
* @ return bool dropped
*/
2009-10-13 19:33:50 +00:00
function drop_create ( $drop , $create , $location , $message_drop , $message_alter , $message_create , $name ) {
if ( $_POST [ " drop " ]) {
return query_redirect ( $drop , $location , $message_drop , true , ! $_POST [ " dropped " ]);
}
2010-01-09 23:33:41 +00:00
$dropped = $name != " " && ( $_POST [ " dropped " ] || queries ( $drop ));
2009-10-13 19:33:50 +00:00
$created = queries ( $create );
2010-01-09 23:33:41 +00:00
if ( ! queries_redirect ( $location , ( $name != " " ? $message_alter : $message_create ), $created ) && $dropped ) {
2009-11-03 10:55:57 +00:00
restart_session ();
2009-10-13 19:33:50 +00:00
$_SESSION [ " messages " ][] = $message_drop ;
}
return $dropped ;
}