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
2013-05-08 18:29:19 +00:00
* @ param array
2014-12-06 19:11:34 +00:00
* @ param int
2013-07-17 01:37:33 +00:00
* @ return array $orgtables
2009-09-13 22:22:37 +00:00
*/
2014-12-06 19:11:34 +00:00
function select ( $result , $connection2 = null , $orgtables = array (), $limit = 0 ) {
2013-07-17 01:37:33 +00:00
global $jush ;
2010-05-27 14:10:17 +00:00
$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>
2012-04-15 17:53:40 +00:00
$return = array (); // table => orgtable - mapping to use in EXPLAIN
2010-05-27 14:10:17 +00:00
odd ( '' ); // reset odd for each result
2014-12-06 19:11:34 +00:00
for ( $i = 0 ; ( ! $limit || $i < $limit ) && ( $row = $result -> fetch_row ()); $i ++ ) {
2010-05-27 14:10:17 +00:00
if ( ! $i ) {
echo " <table cellspacing='0' class='nowrap'> \n " ;
echo " <thead><tr> " ;
for ( $j = 0 ; $j < count ( $row ); $j ++ ) {
$field = $result -> fetch_field ();
2011-07-13 14:31:47 +00:00
$name = $field -> name ;
2010-05-27 14:10:17 +00:00
$orgtable = $field -> orgtable ;
$orgname = $field -> orgname ;
2012-04-15 17:53:40 +00:00
$return [ $field -> table ] = $orgtable ;
2013-07-17 01:37:33 +00:00
if ( $orgtables && $jush == " sql " ) { // MySQL EXPLAIN
2011-07-13 14:31:47 +00:00
$links [ $j ] = ( $name == " table " ? " table= " : ( $name == " possible_keys " ? " indexes= " : null ));
} elseif ( $orgtable != " " ) {
2010-05-27 14:10:17 +00:00
if ( ! isset ( $indexes [ $orgtable ])) {
// find primary key in each table
$indexes [ $orgtable ] = array ();
foreach ( indexes ( $orgtable , $connection2 ) as $index ) {
if ( $index [ " type " ] == " PRIMARY " ) {
$indexes [ $orgtable ] = array_flip ( $index [ " columns " ]);
break ;
2009-09-13 22:22:37 +00:00
}
}
2010-05-27 14:10:17 +00:00
$columns [ $orgtable ] = $indexes [ $orgtable ];
2009-09-13 22:22:37 +00:00
}
2010-05-27 14:10:17 +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
}
}
2010-05-27 14:10:17 +00:00
if ( $field -> charsetnr == 63 ) { // 63 - binary
$blobs [ $j ] = true ;
}
$types [ $j ] = $field -> type ;
2013-07-17 01:37:33 +00:00
echo " <th " . ( $orgtable != " " || $field -> name != $orgname ? " title=' " . h (( $orgtable != " " ? " $orgtable . " : " " ) . $orgname ) . " ' " : " " ) . " > " . h ( $name )
2018-02-08 12:56:22 +00:00
. ( $orgtables ? doc_link ( array (
'sql' => " explain-output.html#explain_ " . strtolower ( $name ),
'mariadb' => " explain/#the-columns-in-explain-select " ,
)) : " " )
2013-04-05 01:45:54 +00:00
;
2009-09-13 22:22:37 +00:00
}
2010-05-27 14:10:17 +00:00
echo " </thead> \n " ;
}
echo " <tr " . odd () . " > " ;
foreach ( $row as $key => $val ) {
2012-05-14 06:54:07 +00:00
if ( $val === null ) {
2010-05-27 14:10:17 +00:00
$val = " <i>NULL</i> " ;
2011-07-13 14:31:47 +00:00
} elseif ( $blobs [ $key ] && ! is_utf8 ( $val )) {
$val = " <i> " . lang ( '%d byte(s)' , strlen ( $val )) . " </i> " ; //! link to download
} elseif ( ! strlen ( $val )) { // strlen - SQLite can return int
$val = " " ; // some content to print a border
2010-05-27 14:10:17 +00:00
} else {
2011-07-13 14:31:47 +00:00
$val = h ( $val );
if ( $types [ $key ] == 254 ) { // 254 - char
$val = " <code> $val </code> " ;
2010-05-27 14:10:17 +00:00
}
2011-07-13 14:31:47 +00:00
}
if ( isset ( $links [ $key ]) && ! $columns [ $links [ $key ]]) {
2013-07-17 01:37:33 +00:00
if ( $orgtables && $jush == " sql " ) { // MySQL EXPLAIN
2012-04-15 17:53:40 +00:00
$table = $row [ array_search ( " table= " , $links )];
$link = $links [ $key ] . urlencode ( $orgtables [ $table ] != " " ? $orgtables [ $table ] : $table );
2011-07-13 14:31:47 +00:00
} else {
2010-05-27 14:10:17 +00:00
$link = " edit= " . urlencode ( $links [ $key ]);
foreach ( $indexes [ $links [ $key ]] as $col => $j ) {
$link .= " &where " . urlencode ( " [ " . bracket_escape ( $col ) . " ] " ) . " = " . urlencode ( $row [ $j ]);
2009-09-13 22:22:37 +00:00
}
}
2011-07-13 14:31:47 +00:00
$val = " <a href=' " . h ( ME . $link ) . " '> $val </a> " ;
2009-09-13 22:22:37 +00:00
}
2010-05-27 14:10:17 +00:00
echo " <td> $val " ;
2009-09-13 22:22:37 +00:00
}
}
2010-05-27 14:10:17 +00:00
echo ( $i ? " </table> " : " <p class='message'> " . lang ( 'No rows.' )) . " \n " ;
2012-04-15 17:53:40 +00:00
return $return ;
2009-09-13 22:22:37 +00:00
}
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
2013-04-27 03:04:57 +00:00
foreach ( table_status ( '' , true ) as $table_name => $table ) {
2010-04-21 12:01:32 +00:00
if ( $table_name != $self && fk_support ( $table )) {
2009-07-02 22:37:10 +00:00
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 ;
}
2010-07-13 16:21:38 +00:00
/** Print SQL < textarea > tag
* @ param string
2014-03-07 17:33:37 +00:00
* @ param string or array in which case [ 0 ] of every element is used
2010-07-13 16:21:38 +00:00
* @ param int
* @ param int
* @ return null
*/
2012-06-30 01:38:24 +00:00
function textarea ( $name , $value , $rows = 10 , $cols = 80 ) {
2013-07-22 18:45:09 +00:00
global $jush ;
2013-07-24 01:41:38 +00:00
echo " <textarea name=' $name ' rows=' $rows ' cols=' $cols ' class='sqlarea jush- $jush ' spellcheck='false' wrap='off'> " ;
2011-01-20 22:12:34 +00:00
if ( is_array ( $value )) {
foreach ( $value as $val ) { // not implode() to save memory
2014-03-07 17:33:37 +00:00
echo h ( $val [ 0 ]) . " \n \n \n " ; // $val == array($query, $time, $elapsed)
2011-01-20 22:12:34 +00:00
}
} else {
echo h ( $value );
}
echo " </textarea> " ;
2010-07-13 16:21:38 +00:00
}
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 ()
2018-01-30 14:55:50 +00:00
* @ param array extra types to prepend
2009-10-23 15:43:51 +00:00
* @ return null
*/
2018-01-30 14:55:50 +00:00
function edit_type ( $key , $field , $collations , $foreign_keys = array (), $extra_types = array ()) {
2010-10-13 15:53:59 +00:00
global $structured_types , $types , $unsigned , $on_actions ;
2013-08-09 02:29:10 +00:00
$type = $field [ " type " ];
2008-03-20 16:17:37 +00:00
?>
2018-01-12 17:34:19 +00:00
< td >< select name = " <?php echo h( $key ); ?>[type] " class = " type " aria - labelledby = " label-type " >< ? php
2018-01-30 15:21:04 +00:00
if ( $type && ! isset ( $types [ $type ]) && ! isset ( $foreign_keys [ $type ]) && ! in_array ( $type , $extra_types )) {
2018-01-30 14:55:50 +00:00
$extra_types [] = $type ;
2013-08-09 02:34:40 +00:00
}
2013-08-09 02:36:15 +00:00
if ( $foreign_keys ) {
$structured_types [ lang ( 'Foreign keys' )] = $foreign_keys ;
}
2018-01-30 14:55:50 +00:00
echo optionlist ( array_merge ( $extra_types , $structured_types ), $type );
2013-08-09 02:28:05 +00:00
?> </select>
2018-01-12 17:11:00 +00:00
< ? php echo on_help ( " getTarget(event).value " , 1 ); ?>
2018-01-13 16:40:21 +00:00
< ? php echo script ( " mixin(qsl('select'), { onfocus: function () { lastType = selectValue(this); }, onchange: editingTypeChange}); " , " " ); ?>
2018-01-12 17:46:44 +00:00
< td >< input name = " <?php echo h( $key ); ?>[length] " value = " <?php echo h( $field["length"] ); ?> " size = " 3 " < ? php echo ( ! $field [ " length " ] && preg_match ( '~var(char|binary)$~' , $type ) ? " class='required' " : " " ); ?> aria-labelledby="label-length"><?php echo script("mixin(qsl('input'), {onfocus: editingLengthFocus, oninput: editingLengthChange});", ""); ?><td class="options"><?php //! type="number" with enabled JavaScript
2015-11-08 20:15:45 +00:00
echo " <select name=' " . h ( $key ) . " [collation]' " . ( preg_match ( '~(char|text|enum|set)$~' , $type ) ? " " : " class='hidden' " ) . '><option value="">(' . lang ( 'collation' ) . ')' . optionlist ( $collations , $field [ " collation " ]) . '</select>' ;
2018-02-06 13:52:12 +00:00
echo ( $unsigned ? " <select name=' " . h ( $key ) . " [unsigned]' " . ( ! $type || preg_match ( number_type (), $type ) ? " " : " class='hidden' " ) . '><option>' . optionlist ( $unsigned , $field [ " unsigned " ]) . '</select>' : '' );
2015-11-08 20:15:45 +00:00
echo ( isset ( $field [ 'on_update' ]) ? " <select name=' " . h ( $key ) . " [on_update]' " . ( preg_match ( '~timestamp|datetime~' , $type ) ? " " : " class='hidden' " ) . '>' . optionlist ( array ( " " => " ( " . lang ( 'ON UPDATE' ) . " ) " , " CURRENT_TIMESTAMP " ), $field [ " on_update " ]) . '</select>' : '' );
echo ( $foreign_keys ? " <select name=' " . h ( $key ) . " [on_delete]' " . ( preg_match ( " ~`~ " , $type ) ? " " : " class='hidden' " ) . " ><option value=''>( " . lang ( 'ON DELETE' ) . " ) " . optionlist ( explode ( " | " , $on_actions ), $field [ " on_delete " ]) . " </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 ;
2013-08-06 22:48:45 +00:00
return ( preg_match ( " ~^ \\ s* \\ (? \\ s* $enum_length (?: \\ s*, \\ s* $enum_length )*+ \\ s* \\ )? \\ s* \$ ~ " , $length ) && preg_match_all ( " ~ $enum_length ~ " , $length , $matches )
? " ( " . implode ( " , " , $matches [ 0 ]) . " ) "
2013-12-20 02:35:30 +00:00
: preg_replace ( '~^[0-9].*~' , '(\0)' , preg_replace ( '~[^-0-9,+()[\]]~' , '' , $length ))
2013-08-06 22:48:45 +00:00
);
2009-07-27 15:31:11 +00:00
}
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 " ) {
2010-10-13 16:04:40 +00:00
global $unsigned ;
2010-05-25 11:29:53 +00:00
return " $field[type] "
2013-08-06 22:48:45 +00:00
. process_length ( $field [ " length " ])
2018-02-06 13:52:12 +00:00
. ( preg_match ( number_type (), $field [ " type " ]) && in_array ( $field [ " unsigned " ], $unsigned ) ? " $field[unsigned] " : " " )
2013-07-24 23:26:41 +00:00
. ( preg_match ( '~char|text|enum|set~' , $field [ " type " ]) && $field [ " collation " ] ? " $collate " . q ( $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
2010-05-25 11:29:53 +00:00
* @ return array array ( " field " , " type " , " NULL " , " DEFAULT " , " ON UPDATE " , " COMMENT " , " AUTO_INCREMENT " )
2009-10-23 15:43:51 +00:00
*/
2009-09-09 19:47:15 +00:00
function process_field ( $field , $type_field ) {
2010-04-21 12:01:32 +00:00
return array (
2011-09-10 11:06:59 +00:00
idf_escape ( trim ( $field [ " field " ])),
2010-04-21 12:01:32 +00:00
process_type ( $type_field ),
( $field [ " null " ] ? " NULL " : " NOT NULL " ), // NULL for timestamp
2018-02-09 14:29:54 +00:00
default_value ( $field ),
2014-03-15 21:08:34 +00:00
( preg_match ( '~timestamp|datetime~' , $field [ " type " ]) && $field [ " on_update " ] ? " ON UPDATE $field[on_update] " : " " ),
2010-10-13 16:04:40 +00:00
( support ( " comment " ) && $field [ " comment " ] != " " ? " COMMENT " . q ( $field [ " comment " ]) : " " ),
2010-05-05 20:42:25 +00:00
( $field [ " auto_increment " ] ? auto_increment () : null ),
2010-04-21 12:01:32 +00:00
);
2009-09-09 19:47:15 +00:00
}
2018-02-09 14:29:54 +00:00
/** Get default value clause
* @ param array
* @ return string
*/
function default_value ( $field ) {
$default = $field [ " default " ];
return ( $default === null ? " " : " DEFAULT " . ( preg_match ( '~char|binary|text|enum|set~' , $field [ " type " ]) || preg_match ( '~^(?![a-z])~i' , $default ) ? q ( $default ) : $default ));
}
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 ) {
2013-07-24 23:26:41 +00:00
if ( preg_match ( " ~ $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 array returned by referencable_primary ()
2011-06-07 13:00:18 +00:00
* @ param bool display comments column
* @ return null
2009-10-23 15:43:51 +00:00
*/
2013-04-02 01:45:26 +00:00
function edit_fields ( $fields , $collations , $type = " TABLE " , $foreign_keys = array (), $comments = false ) {
2018-01-29 18:49:52 +00:00
global $inout ;
2015-08-06 01:12:36 +00:00
$fields = array_values ( $fields );
2008-03-20 16:17:37 +00:00
?>
2018-02-07 13:22:58 +00:00
< thead >< tr >
2009-08-25 15:42:43 +00:00
< ? php if ( $type == " PROCEDURE " ) { ?> <td> <?php } ?>
2016-09-19 13:27:34 +00:00
< th id = " label-name " >< ? php echo ( $type == " TABLE " ? lang ( 'Column name' ) : lang ( 'Parameter name' )); ?>
2018-01-12 17:34:19 +00:00
< td id = " label-type " >< ? php echo lang ( 'Type' ); ?> <textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("qs('#enum-edit').onblur = editingLengthBlur;"); ?>
2016-09-19 13:27:34 +00:00
< td id = " label-length " >< ? php echo lang ( 'Length' ); ?>
2016-09-28 05:04:44 +00:00
< td >< ? php echo lang ( 'Options' ); /* no label required, options have their own label */ ?>
2007-07-16 22:40:55 +00:00
< ? php if ( $type == " TABLE " ) { ?>
2016-09-19 13:27:34 +00:00
< td id = " label-null " > NULL
< td >< input type = " radio " name = " auto_increment_col " value = " " >< acronym id = " label-ai " title = " <?php echo lang('Auto Increment'); ?> " > AI </ acronym >< ? php echo doc_link ( array (
2013-08-06 02:23:31 +00:00
'sql' => " example-auto-increment.html " ,
2018-02-08 12:56:22 +00:00
'mariadb' => " auto_increment/ " ,
2013-08-06 02:23:31 +00:00
'sqlite' => " autoinc.html " ,
'pgsql' => " datatype.html#DATATYPE-SERIAL " ,
'mssql' => " ms186775.aspx " ,
)); ?>
2016-09-19 13:27:34 +00:00
< td id = " label-default " >< ? php echo lang ( 'Default value' ); ?>
< ? php echo ( support ( " comment " ) ? " <td id='label-comment' " . ( $comments ? " " : " class='hidden' " ) . " > " . lang ( 'Comment' ) : " " ); ?>
2007-07-16 22:40:55 +00:00
< ? php } ?>
2018-01-12 14:27:44 +00:00
< td >< ? php echo " <input type='image' class='icon' name='add[ " . ( support ( " move_col " ) ? 0 : count ( $fields )) . " ]' src='../adminer/static/plus.gif' alt='+' title=' " . lang ( 'Add next' ) . " '> " . script ( " row_count = " . count ( $fields ) . " ; " ); ?>
2009-07-11 20:30:40 +00:00
</ thead >
2018-01-12 17:34:19 +00:00
< tbody >
2011-01-31 10:02:00 +00:00
< ? php
2018-01-12 17:34:19 +00:00
echo script ( " qsl('tbody').onkeydown = editingKeydown; " );
2007-07-16 23:08:55 +00:00
foreach ( $fields as $i => $field ) {
$i ++ ;
2010-05-05 16:27:39 +00:00
$orig = $field [( $_POST ? " orig " : " field " )];
$display = ( isset ( $_POST [ " add " ][ $i - 1 ]) || ( isset ( $field [ " field " ]) && ! $_POST [ " drop_col " ][ $i ])) && ( support ( " drop_col " ) || $orig == " " );
2007-07-16 23:08:55 +00:00
?>
2009-06-11 04:50:35 +00:00
< tr < ? php echo ( $display ? " " : " style='display: none;' " ); ?> >
2011-07-11 14:35:17 +00:00
< ? php echo ( $type == " PROCEDURE " ? " <td> " . html_select ( " fields[ $i ][inout] " , explode ( " | " , $inout ), $field [ " inout " ]) : " " ); ?>
2018-01-13 16:40:21 +00:00
< th >< ? php if ( $display ) { ?> <input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" maxlength="64" autocapitalize="off" aria-labelledby="label-name"><?php echo script("qsl('input').oninput = function () { editingNameChange.call(this);" . ($field["field"] != "" || count($fields) > 1 ? "" : " editingAddRow.call(this);") . " };", ""); ?><?php } ?>
2013-07-07 05:49:39 +00:00
< input type = " hidden " name = " fields[<?php echo $i ; ?>][orig] " value = " <?php echo h( $orig ); ?> " >
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 " ) { ?>
2016-09-19 13:27:34 +00:00
< td >< ? php echo checkbox ( " fields[ $i ][null] " , 1 , $field [ " null " ], " " , " " , " block " , " label-null " ); ?>
2018-01-12 21:18:54 +00:00
< td >< label class = " block " >< input type = " radio " name = " auto_increment_col " value = " <?php echo $i ; ?> " < ? php if ( $field [ " auto_increment " ]) { ?> checked<?php } ?> aria-labelledby="label-ai"><?php echo script("qsl('input').onclick = function () { var field = this.form['fields[' + this.value + '][field]']; if (!field.value) { field.value = 'id'; field.oninput(); } }"); ?></label><td><?php
2018-01-12 21:25:38 +00:00
echo checkbox ( " fields[ $i ][has_default] " , 1 , $field [ " has_default " ], " " , " " , " " , " label-default " ); ?> <input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" aria-labelledby="label-default"><?php echo script("qsl('input').oninput = function () { this.previousSibling.checked = true; }", ""); ?>
2018-01-29 18:49:52 +00:00
< ? php echo ( support ( " comment " ) ? " <td " . ( $comments ? " " : " class='hidden' " ) . " ><input name='fields[ $i ][comment]' value=' " . h ( $field [ " comment " ]) . " ' maxlength=' " . ( min_version ( 5.5 ) ? 1024 : 255 ) . " ' aria-labelledby='label-comment'> " : " " ); ?>
2007-07-16 22:40:55 +00:00
< ? php } ?>
< ? php
2010-05-05 16:27:39 +00:00
echo " <td> " ;
echo ( support ( " move_col " ) ?
2018-01-13 16:40:21 +00:00
" <input type='image' class='icon' name='add[ $i ]' src='../adminer/static/plus.gif' alt='+' title=' " . lang ( 'Add next' ) . " '> " . script ( " qsl('input').onclick = partial(editingAddRow, 1); " , " " )
. " <input type='image' class='icon' name='up[ $i ]' src='../adminer/static/up.gif' alt='^' title=' " . lang ( 'Move up' ) . " '> " . script ( " qsl('input').onclick = partial(editingMoveRow, 1); " , " " )
. " <input type='image' class='icon' name='down[ $i ]' src='../adminer/static/down.gif' alt='v' title=' " . lang ( 'Move down' ) . " '> " . script ( " qsl('input').onclick = partial(editingMoveRow, 0); " , " " )
2010-05-05 16:27:39 +00:00
: " " );
2018-01-12 21:46:16 +00:00
echo ( $orig == " " || support ( " drop_col " ) ? " <input type='image' class='icon' name='drop_col[ $i ]' src='../adminer/static/cross.gif' alt='x' title=' " . lang ( 'Remove' ) . " '> " . script ( " qsl('input').onclick = partial(editingRemoveRow, 'fields \$ 1[field]'); " ) : " " );
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
2013-05-08 18:43:53 +00:00
* @ return bool
2009-10-23 15:43:51 +00:00
*/
2008-05-07 11:22:08 +00:00
function process_fields ( & $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 ++ ;
}
2013-05-08 18:43:53 +00:00
} elseif ( $_POST [ " down " ]) {
2008-05-07 11:22:08 +00:00
$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 ++ ;
}
2013-05-08 18:43:53 +00:00
} elseif ( $_POST [ " add " ]) {
$fields = array_values ( $fields );
2008-05-07 11:22:08 +00:00
array_splice ( $fields , key ( $_POST [ " add " ]), 0 , array ( array ()));
2013-05-08 18:43:53 +00:00
} elseif ( ! $_POST [ " drop_col " ]) {
return false ;
2008-05-07 11:22:08 +00:00
}
2013-05-08 18:43:53 +00:00
return true ;
2008-05-07 11:22:08 +00:00
}
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 ) {
2010-04-21 12:01:32 +00:00
return " ' " . str_replace ( " ' " , " '' " , addcslashes ( stripcslashes ( str_replace ( $match [ 0 ][ 0 ] . $match [ 0 ][ 0 ], $match [ 0 ][ 0 ], substr ( $match [ 0 ], 1 , - 1 ))), '\\' )) . " ' " ;
2007-07-17 09:12:15 +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
2011-02-24 16:30:15 +00:00
* @ return bool
2009-10-23 15:43:51 +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 );
}
2009-10-13 19:33:50 +00:00
2009-10-23 15:43:51 +00:00
/** Drop old object and create a new one
2013-05-13 18:12:28 +00:00
* @ param string drop old object query
* @ param string create new object query
* @ param string drop new object query
* @ param string create test object query
* @ param string drop test object query
* @ param string
2009-10-23 15:43:51 +00:00
* @ param string
* @ param string
* @ param string
* @ param string
* @ param string
2013-01-31 07:40:26 +00:00
* @ return null redirect in success
2009-10-23 15:43:51 +00:00
*/
2013-05-13 18:12:28 +00:00
function drop_create ( $drop , $create , $drop_created , $test , $drop_test , $location , $message_drop , $message_alter , $message_create , $old_name , $new_name ) {
2009-10-13 19:33:50 +00:00
if ( $_POST [ " drop " ]) {
2013-01-31 07:40:26 +00:00
query_redirect ( $drop , $location , $message_drop );
2013-05-13 18:12:28 +00:00
} elseif ( $old_name == " " ) {
query_redirect ( $create , $location , $message_create );
} elseif ( $old_name != $new_name ) {
$created = queries ( $create );
queries_redirect ( $location , $message_alter , $created && queries ( $drop ));
if ( $created ) {
queries ( $drop_created );
}
2013-01-31 07:40:26 +00:00
} else {
2013-05-08 14:55:08 +00:00
queries_redirect (
$location ,
2013-05-13 18:12:28 +00:00
$message_alter ,
queries ( $test ) && queries ( $drop_test ) && queries ( $drop ) && queries ( $create )
2013-05-08 14:55:08 +00:00
);
2009-10-13 19:33:50 +00:00
}
2013-01-31 07:40:26 +00:00
}
/** Generate SQL query for creating trigger
* @ param string
2013-04-26 01:19:27 +00:00
* @ param array result of trigger ()
* @ return string
2013-01-31 07:40:26 +00:00
*/
function create_trigger ( $on , $row ) {
global $jush ;
2014-03-15 17:58:24 +00:00
$timing_event = " $row[Timing] $row[Event] " . ( $row [ " Event " ] == " UPDATE OF " ? " " . idf_escape ( $row [ " Of " ]) : " " );
2013-05-08 18:29:19 +00:00
return " CREATE TRIGGER "
. idf_escape ( $row [ " Trigger " ])
. ( $jush == " mssql " ? $on . $timing_event : $timing_event . $on )
. rtrim ( " $row[Type] \n $row[Statement] " , " ; " )
. " ; "
;
2013-01-31 07:40:26 +00:00
}
/** Generate SQL query for creating routine
* @ param string " PROCEDURE " or " FUNCTION "
* @ param array result of routine ()
* @ return string
*/
function create_routine ( $routine , $row ) {
2018-01-30 14:18:26 +00:00
global $inout , $jush ;
2013-01-31 07:40:26 +00:00
$set = array ();
$fields = ( array ) $row [ " fields " ];
ksort ( $fields ); // enforce fields order
foreach ( $fields as $field ) {
if ( $field [ " field " ] != " " ) {
2013-07-24 23:26:41 +00:00
$set [] = ( preg_match ( " ~^( $inout ) \$ ~ " , $field [ " inout " ]) ? " $field[inout] " : " " ) . idf_escape ( $field [ " field " ]) . process_type ( $field , " CHARACTER SET " );
2013-01-31 07:40:26 +00:00
}
2009-10-13 19:33:50 +00:00
}
2018-01-30 14:18:26 +00:00
$definition = rtrim ( " \n $row[definition] " , " ; " );
2013-05-08 18:29:19 +00:00
return " CREATE $routine "
. idf_escape ( trim ( $row [ " name " ]))
. " ( " . implode ( " , " , $set ) . " ) "
. ( isset ( $_GET [ " function " ]) ? " RETURNS " . process_type ( $row [ " returns " ], " CHARACTER SET " ) : " " )
. ( $row [ " language " ] ? " LANGUAGE $row[language] " : " " )
2018-01-30 14:18:26 +00:00
. ( $jush == " pgsql " ? " AS " . q ( $definition ) : " $definition ; " )
2013-05-08 18:29:19 +00:00
;
2009-10-13 19:33:50 +00:00
}
2010-10-29 15:03:02 +00:00
2012-08-09 16:39:12 +00:00
/** Remove current user definer from SQL command
2017-02-19 13:32:01 +00:00
* @ param string
* @ return string
*/
2012-08-09 16:39:12 +00:00
function remove_definer ( $query ) {
return preg_replace ( '~^([A-Z =]+) DEFINER=`' . preg_replace ( '~@(.*)~' , '`@`(%|\\1)' , logged_user ()) . '`~' , '\\1' , $query ); //! proper escaping of user
}
2013-08-09 22:16:15 +00:00
/** Format foreign key to use in SQL query
* @ param array ( " table " => string , " source " => array , " target " => array , " on_delete " => one of $on_actions , " on_update " => one of $on_actions )
2013-12-20 23:47:01 +00:00
* @ return string
2013-08-09 22:16:15 +00:00
*/
function format_foreign_key ( $foreign_key ) {
global $on_actions ;
return " FOREIGN KEY ( " . implode ( " , " , array_map ( 'idf_escape' , $foreign_key [ " source " ])) . " ) REFERENCES " . table ( $foreign_key [ " table " ])
. " ( " . implode ( " , " , array_map ( 'idf_escape' , $foreign_key [ " target " ])) . " ) " //! reuse $name - check in older MySQL versions
. ( preg_match ( " ~^( $on_actions ) \$ ~ " , $foreign_key [ " on_delete " ]) ? " ON DELETE $foreign_key[on_delete] " : " " )
. ( preg_match ( " ~^( $on_actions ) \$ ~ " , $foreign_key [ " on_update " ]) ? " ON UPDATE $foreign_key[on_update] " : " " )
;
}
2013-05-01 16:33:23 +00:00
/** Add a file to TAR
2010-10-29 15:03:02 +00:00
* @ param string
2013-05-01 16:33:23 +00:00
* @ param TmpFile
2013-04-29 22:45:15 +00:00
* @ return null prints the output
2010-10-29 15:03:02 +00:00
*/
2013-05-01 16:33:23 +00:00
function tar_file ( $filename , $tmp_file ) {
$return = pack ( " a100a8a8a8a12a12 " , $filename , 644 , 0 , 0 , decoct ( $tmp_file -> size ), decoct ( time ()));
2010-10-29 15:03:02 +00:00
$checksum = 8 * 32 ; // space for checksum itself
for ( $i = 0 ; $i < strlen ( $return ); $i ++ ) {
2012-05-16 23:42:45 +00:00
$checksum += ord ( $return [ $i ]);
2010-10-29 15:03:02 +00:00
}
$return .= sprintf ( " %06o " , $checksum ) . " \0 " ;
2013-04-29 22:45:15 +00:00
echo $return ;
echo str_repeat ( " \0 " , 512 - strlen ( $return ));
2013-05-01 16:33:23 +00:00
$tmp_file -> send ();
echo str_repeat ( " \0 " , 511 - ( $tmp_file -> size + 511 ) % 512 );
2010-10-29 15:03:02 +00:00
}
2011-08-24 12:16:11 +00:00
/** Get INI bytes value
* @ param string
* @ return int
*/
function ini_bytes ( $ini ) {
$val = ini_get ( $ini );
switch ( strtolower ( substr ( $val , - 1 ))) {
case 'g' : $val *= 1024 ; // no break
case 'm' : $val *= 1024 ; // no break
case 'k' : $val *= 1024 ;
}
return $val ;
}
2013-07-17 01:37:33 +00:00
/** Create link to database documentation
2013-08-06 01:55:27 +00:00
* @ param array $jush => $path
2018-02-08 10:21:33 +00:00
* @ param string HTML code
2013-07-17 01:37:33 +00:00
* @ return string HTML code
*/
2018-02-08 10:21:33 +00:00
function doc_link ( $paths , $text = " <sup>?</sup> " ) {
2013-07-17 01:37:33 +00:00
global $jush , $connection ;
2018-02-08 12:56:22 +00:00
$server_info = $connection -> server_info ;
$version = preg_replace ( '~^(\\d\\.?\\d).*~s' , '\\1' , $server_info ); // two most significant digits
2013-07-17 01:37:33 +00:00
$urls = array (
2018-02-01 13:02:25 +00:00
'sql' => " https://dev.mysql.com/doc/refman/ $version /en/ " ,
2018-01-14 09:38:01 +00:00
'sqlite' => " https://www.sqlite.org/ " ,
2018-02-01 13:02:25 +00:00
'pgsql' => " https://www.postgresql.org/docs/ $version /static/ " ,
2018-01-14 09:38:01 +00:00
'mssql' => " https://msdn.microsoft.com/library/ " ,
'oracle' => " https://download.oracle.com/docs/cd/B19306_01/server.102/b14200/ " ,
2013-07-17 01:37:33 +00:00
);
2018-02-08 12:56:22 +00:00
if ( preg_match ( '~MariaDB~' , $server_info )) {
$urls [ 'sql' ] = " https://mariadb.com/kb/en/library/ " ;
$paths [ 'sql' ] = ( isset ( $paths [ 'mariadb' ]) ? $paths [ 'mariadb' ] : str_replace ( " .html " , " / " , $paths [ 'sql' ]));
}
2018-02-08 10:21:33 +00:00
return ( $paths [ $jush ] ? " <a href=' $urls[$jush] $paths[$jush] ' " . target_blank () . " > $text </a> " : " " );
2013-07-17 01:37:33 +00:00
}
2014-02-24 02:02:43 +00:00
/** Wrap gzencode () for usage in ob_start ()
* @ param string
* @ return string
*/
function ob_gzencode ( $string ) {
// ob_start() callback recieves an optional parameter $phase but gzencode() accepts optional parameter $level
return gzencode ( $string );
}
2014-03-01 19:38:38 +00:00
/** Compute size of database
* @ param string
* @ return string formatted
*/
function db_size ( $db ) {
global $connection ;
if ( ! $connection -> select_db ( $db )) {
return " ? " ;
}
$return = 0 ;
foreach ( table_status () as $table_status ) {
$return += $table_status [ " Data_length " ] + $table_status [ " Index_length " ];
}
2014-03-20 04:56:42 +00:00
return format_number ( $return );
2014-03-01 19:38:38 +00:00
}
2015-03-06 17:36:20 +00:00
/** Print SET NAMES if utf8mb4 might be needed
* @ param string
* @ return null
*/
function set_utf8mb4 ( $create ) {
2018-01-22 12:51:47 +00:00
global $connection ;
2015-03-06 17:36:20 +00:00
static $set = false ;
if ( ! $set && preg_match ( '~\butf8mb4~i' , $create )) { // possible false positive
$set = true ;
2015-03-06 19:56:04 +00:00
echo " SET NAMES " . charset ( $connection ) . " ; \n \n " ;
2015-03-06 17:36:20 +00:00
}
}