2007-07-16 22:40:55 +00:00
< ? php
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 ;
}
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-09-09 11:03:03 +00:00
< td >< select name = " <?php echo $key ; ?>[type] " onchange = " editing_type_change(this); " >< ? php echo optionlist ( $structured_types + ( $foreign_keys ? array ( lang ( 'Foreign keys' ) => $foreign_keys ) : array ()), $field [ " type " ]); // foreign keys can be wide but style="width: 15ex;" narrows expanded optionlist in IE too ?></select>
2009-07-28 16:20:50 +00:00
< td >< input name = " <?php echo $key ; ?>[length] " value = " <?php echo h( $field["length"] ); ?> " size = " 3 " >
2009-06-19 18:57:19 +00:00
< td >< ? php
2009-07-30 14:55:09 +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>' ;
echo ( $unsigned ? " <select name=' $key " . " [unsigned]' " . ( ! $field [ " type " ] || ereg ( '(int|float|double|decimal)$' , $field [ " type " ]) ? " " : " class='hidden' " ) . '><option>' . optionlist ( $unsigned , $field [ " unsigned " ]) . '</select>' : '' );
2009-07-11 20:30:40 +00:00
?>
2007-07-16 22:40:55 +00:00
< ? php
}
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 ));
}
2007-07-17 05:51:09 +00:00
function process_type ( $field , $collate = " COLLATE " ) {
2009-05-08 05:23:03 +00:00
global $dbh , $enum_length , $unsigned ;
2007-07-16 22:40:55 +00:00
return " $field[type] "
2009-07-13 16:03:51 +00:00
. ( $field [ " length " ] && ! ereg ( '^date|time$' , $field [ " type " ]) ? " ( " . process_length ( $field [ " length " ]) . " ) " : " " )
. ( ereg ( 'int|float|double|decimal' , $field [ " type " ]) && in_array ( $field [ " unsigned " ], $unsigned ) ? " $field[unsigned] " : " " )
. ( ereg ( 'char|text|enum|set' , $field [ " type " ]) && $field [ " collation " ] ? " $collate " . $dbh -> quote ( $field [ " collation " ]) : " " )
2007-07-16 22:40:55 +00:00
;
}
2009-09-09 19:47:15 +00:00
function process_field ( $field , $type_field ) {
global $dbh ;
return idf_escape ( $field [ " field " ]) . process_type ( $type_field )
. ( $field [ " null " ] ? " NULL " : " NOT NULL " ) // NULL for timestamp
. ( ! $field [ " has_default " ] || $field [ " auto_increment " ] || ereg ( 'text|blob' , $field [ " type " ]) ? " " : " DEFAULT " . ( $field [ " type " ] == " timestamp " && eregi ( " ^CURRENT_TIMESTAMP( on update CURRENT_TIMESTAMP)? $ " , $field [ " default " ]) ? $field [ " default " ] : $dbh -> quote ( $field [ " default " ])))
. " COMMENT " . $dbh -> quote ( $field [ " comment " ])
;
}
2009-07-14 08:45:24 +00:00
function type_class ( $type ) {
if ( ereg ( 'char|text' , $type )) {
return " class='char' " ;
} elseif ( ereg ( 'date|time|year' , $type )) {
return " class='date' " ;
} elseif ( ereg ( 'binary|blob' , $type )) {
return " class='binary' " ;
} elseif ( ereg ( 'enum|set' , $type )) {
return " class='enum' " ;
}
}
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 ) {
if ( strlen ( $field [ " comment " ])) {
$column_comments = true ;
}
}
2008-03-20 16:17:37 +00:00
?>
2009-04-30 15:21:31 +00:00
< thead >< tr >
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' )); ?>
< td >< ? php echo lang ( 'Type' ); ?>
< 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-07-11 20:30:40 +00:00
< td >< input type = " radio " name = " auto_increment_col " value = " " >< ? php echo lang ( 'Auto Increment' ); ?>
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-07-11 20:30:40 +00:00
< td >< ? php echo " <input type='image' name='add[0]' src='../adminer/plus.gif' alt='+' title=' " . lang ( 'Add next' ) . " '> " ; ?> <script type="text/javascript">row_count = <?php echo count($fields); ?>;</script>
</ 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-07-11 20:30:40 +00:00
< ? php if ( $type == " PROCEDURE " ) { ?> <td><select name="fields[<?php echo $i; ?>][inout]"><?php echo optionlist($inout, $field["inout"]); ?></select><?php } ?>
2009-07-28 16:20:50 +00:00
< th >< ? php if ( $display ) { ?> <input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" onchange="<?php echo (strlen($field["field"]) || count($fields) > 1 ? "" : "editing_add_row(this, $allowed); "); ?>editing_name_change(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-07-28 16:28:47 +00:00
< td >< input type = " checkbox " name = " fields[<?php echo $i ; ?>][null] " value = " 1 " < ? php if ( $field [ " null " ]) { ?> checked<?php } ?>>
< td >< input type = " radio " name = " auto_increment_col " value = " <?php echo $i ; ?> " < ? php if ( $field [ " auto_increment " ]) { ?> checked<?php } ?>>
2009-08-21 16:54:10 +00:00
< td class = " nowrap hidden " >< input type = " checkbox " name = " fields[<?php echo $i ; ?>][has_default] " value = " 1 " < ? php echo ( $field [ " has_default " ] ? " checked " : " " ); ?> ><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
2009-07-11 20:30:40 +00:00
echo " <td class='nowrap'><input type='image' name='add[ $i ]' src='../adminer/plus.gif' alt='+' title=' " . lang ( 'Add next' ) . " ' onclick='var x = editing_add_row(this, $allowed ); if (x) { x.focus(); x.onchange = function () { }; } return !x;'> " ;
echo " <input type='image' name='drop_col[ $i ]' src='../adminer/cross.gif' alt='x' title=' " . lang ( 'Remove' ) . " ' onclick='return !editing_remove_row(this);'> " ;
echo " <input type='image' name='up[ $i ]' src='../adminer/up.gif' alt='^' title=' " . lang ( 'Move up' ) . " '> " ;
echo " <input type='image' name='down[ $i ]' src='../adminer/down.gif' alt='v' title=' " . lang ( 'Move down' ) . " '> " ;
echo " \n \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
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 ()));
}
}
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 ))), '\\' )) . " ' " ;
}
2007-07-16 22:40:55 +00:00
function routine ( $name , $type ) {
2009-05-08 05:23:03 +00:00
global $dbh , $enum_length , $inout ;
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 " );
2008-03-20 16:38:21 +00:00
$type_pattern = " ([a-z]+)(?: \\ 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-05-08 05:23:03 +00:00
$create = $dbh -> result ( $dbh -> 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-07-24 16:16:50 +00:00
$fields [ $name ] = array (
" 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
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 );
}