2008-08-16 12:28:31 +00:00
< ? php
2009-09-09 11:03:03 +00:00
function tar_file ( $filename , $contents ) {
$return = pack ( " a100a8a8a8a12a12 " , $filename , 644 , 0 , 0 , decoct ( strlen ( $contents )), decoct ( time ()));
$checksum = 8 * 32 ; // space for checksum itself
for ( $i = 0 ; $i < strlen ( $return ); $i ++ ) {
$checksum += ord ( $return { $i });
}
$return .= sprintf ( " %06o " , $checksum ) . " \0 " ;
return $return . str_repeat ( " \0 " , 512 - strlen ( $return )) . $contents . str_repeat ( " \0 " , 511 - ( strlen ( $contents ) + 511 ) % 512 );
}
function dump_triggers ( $table , $style ) {
global $dbh ;
if ( $_POST [ " format " ] == " sql " && $style && $dbh -> server_info >= 5 ) {
$result = $dbh -> query ( " SHOW TRIGGERS LIKE " . $dbh -> quote ( addcslashes ( $table , " %_ " )));
if ( $result -> num_rows ) {
$s = " \n DELIMITER ;; \n " ;
while ( $row = $result -> fetch_assoc ()) {
$s .= " \n " . ( $style == 'CREATE+ALTER' ? " DROP TRIGGER IF EXISTS " . idf_escape ( $row [ " Trigger " ]) . " ;; \n " : " " )
. " CREATE TRIGGER " . idf_escape ( $row [ " Trigger " ]) . " $row[Timing] $row[Event] ON " . idf_escape ( $row [ " Table " ]) . " FOR EACH ROW \n $row[Statement] ;; \n " ;
}
dump ( " $s\nDELIMITER ; \n " );
}
}
}
2008-08-19 10:32:34 +00:00
function dump_table ( $table , $style , $is_view = false ) {
2009-05-08 05:23:03 +00:00
global $dbh ;
2008-08-18 22:40:45 +00:00
if ( $_POST [ " format " ] == " csv " ) {
2009-08-28 11:49:57 +00:00
dump ( " \xef \xbb \xbf " ); // UTF-8 byte order mark
2008-08-18 22:40:45 +00:00
if ( $style ) {
dump_csv ( array_keys ( fields ( $table )));
}
} elseif ( $style ) {
2009-05-08 05:23:03 +00:00
$result = $dbh -> query ( " SHOW CREATE TABLE " . idf_escape ( $table ));
2008-08-18 22:40:45 +00:00
if ( $result ) {
2009-06-01 12:53:19 +00:00
if ( $style == " DROP+CREATE " ) {
2009-08-28 11:49:57 +00:00
dump ( " DROP " . ( $is_view ? " VIEW " : " TABLE " ) . " IF EXISTS " . idf_escape ( $table ) . " ; \n " );
2008-08-18 22:40:45 +00:00
}
2009-05-08 05:23:03 +00:00
$create = $dbh -> result ( $result , 1 );
2009-08-28 11:49:57 +00:00
dump (( $style != " CREATE+ALTER " ? $create : ( $is_view ? substr_replace ( $create , " OR REPLACE " , 6 , 0 ) : substr_replace ( $create , " IF NOT EXISTS " , 12 , 0 ))) . " ; \n \n " );
2008-08-18 22:40:45 +00:00
}
2009-06-01 12:53:19 +00:00
if ( $style == " CREATE+ALTER " && ! $is_view ) {
2009-06-21 23:20:32 +00:00
// create procedure which iterates over original columns and adds new and removes old
2009-06-22 00:53:51 +00:00
$query = " SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLLATION_NAME, COLUMN_TYPE, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . $dbh -> quote ( $table ) . " ORDER BY ORDINAL_POSITION " ;
2009-08-28 11:49:57 +00:00
dump ( " DELIMITER ;;
2009-08-29 13:51:32 +00:00
CREATE PROCEDURE adminer_alter ( INOUT alter_command text ) BEGIN
2008-08-19 10:50:04 +00:00
DECLARE _column_name , _collation_name , _column_type , after varchar ( 64 ) DEFAULT '' ;
DECLARE _column_default longtext ;
DECLARE _is_nullable char ( 3 );
DECLARE _extra varchar ( 20 );
DECLARE _column_comment varchar ( 255 );
DECLARE done , set_after bool DEFAULT 0 ;
2009-08-28 11:49:57 +00:00
DECLARE add_columns text DEFAULT ' " );
2009-06-22 00:53:51 +00:00
$fields = array ();
$result = $dbh -> query ( $query );
$after = " " ;
while ( $row = $result -> fetch_assoc ()) {
$row [ " default " ] = ( isset ( $row [ " COLUMN_DEFAULT " ]) ? $dbh -> quote ( $row [ " COLUMN_DEFAULT " ]) : " NULL " );
$row [ " after " ] = $dbh -> quote ( $after ); //! rgt AFTER lft, lft AFTER id doesn't work
$row [ " alter " ] = escape_string ( idf_escape ( $row [ " COLUMN_NAME " ])
. " $row[COLUMN_TYPE] "
. ( $row [ " COLLATION_NAME " ] ? " COLLATE $row[COLLATION_NAME] " : " " )
. ( isset ( $row [ " COLUMN_DEFAULT " ]) ? " DEFAULT $row[default] " : " " )
. ( $row [ " IS_NULLABLE " ] == " YES " ? " " : " NOT NULL " )
. ( $row [ " EXTRA " ] ? " $row[EXTRA] " : " " )
. ( $row [ " COLUMN_COMMENT " ] ? " COMMENT " . $dbh -> quote ( $row [ " COLUMN_COMMENT " ]) : " " )
. ( $after ? " AFTER " . idf_escape ( $after ) : " FIRST " )
);
2009-08-28 11:49:57 +00:00
dump ( " , ADD $row[alter] " );
2009-06-22 00:53:51 +00:00
$fields [] = $row ;
$after = $row [ " COLUMN_NAME " ];
}
2009-08-28 11:49:57 +00:00
dump ( " ';
DECLARE columns CURSOR FOR $query ;
2008-08-19 10:50:04 +00:00
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1 ;
SET @ alter_table = '' ;
OPEN columns ;
REPEAT
FETCH columns INTO _column_name , _column_default , _is_nullable , _collation_name , _column_type , _extra , _column_comment ;
IF NOT done THEN
SET set_after = 1 ;
2009-08-28 11:49:57 +00:00
CASE _column_name " );
2009-06-22 00:53:51 +00:00
foreach ( $fields as $row ) {
2009-08-28 11:49:57 +00:00
dump ( "
2009-06-22 00:53:51 +00:00
WHEN " . $dbh->quote ( $row["COLUMN_NAME"] ) . " THEN
2008-08-19 10:50:04 +00:00
SET add_columns = REPLACE ( add_columns , ', ADD $row[alter]' , '' );
2009-06-22 00:53:51 +00:00
IF NOT ( _column_default <=> $row [ default ]) OR _is_nullable != '$row[IS_NULLABLE]' OR _collation_name != '$row[COLLATION_NAME]' OR _column_type != '$row[COLUMN_TYPE]' OR _extra != '$row[EXTRA]' OR _column_comment != " . $dbh->quote ( $row["COLUMN_COMMENT"] ) . " OR after != $row [ after ] THEN
2008-08-19 10:50:04 +00:00
SET @ alter_table = CONCAT ( @ alter_table , ', MODIFY $row[alter]' );
2009-08-28 11:49:57 +00:00
END IF ; " ); //! don't replace in comment
2009-06-22 00:53:51 +00:00
}
2009-08-28 11:49:57 +00:00
dump ( "
2008-08-19 10:50:04 +00:00
ELSE
SET @ alter_table = CONCAT ( @ alter_table , ', DROP ' , _column_name );
SET set_after = 0 ;
END CASE ;
IF set_after THEN
SET after = _column_name ;
END IF ;
END IF ;
UNTIL done END REPEAT ;
CLOSE columns ;
IF @ alter_table != '' OR add_columns != '' THEN
2009-08-29 13:51:32 +00:00
SET alter_command = CONCAT ( alter_command , 'ALTER TABLE " . idf_escape($table) . "' , SUBSTR ( CONCAT ( add_columns , @ alter_table ), 2 ), ';\\n' );
2008-08-19 10:50:04 +00:00
END IF ;
END ;;
DELIMITER ;
2009-08-29 13:51:32 +00:00
CALL adminer_alter ( @ adminer_alter );
2009-06-08 19:02:30 +00:00
DROP PROCEDURE adminer_alter ;
2008-08-19 10:50:04 +00:00
2009-08-28 11:49:57 +00:00
" );
2009-06-01 12:53:19 +00:00
//! indexes
}
2008-08-18 22:40:45 +00:00
}
}
2009-06-13 17:20:29 +00:00
function dump_data ( $table , $style , $select = " " ) {
2009-05-08 05:23:03 +00:00
global $dbh , $max_packet ;
2008-08-16 12:28:31 +00:00
if ( $style ) {
2009-06-01 12:53:19 +00:00
if ( $_POST [ " format " ] != " csv " && $style == " TRUNCATE+INSERT " ) {
2009-08-28 11:49:57 +00:00
dump ( " TRUNCATE " . idf_escape ( $table ) . " ; \n " );
2008-08-16 12:28:31 +00:00
}
2009-09-11 18:53:39 +00:00
$fields = fields ( $table );
2009-08-28 15:29:42 +00:00
$result = $dbh -> query (( $select ? $select : " SELECT * FROM " . idf_escape ( $table )), 1 ); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers, microtime
2008-08-16 12:28:31 +00:00
if ( $result ) {
2009-08-28 13:16:54 +00:00
$insert = " " ;
$buffer = " " ;
2008-08-16 12:28:31 +00:00
while ( $row = $result -> fetch_assoc ()) {
if ( $_POST [ " format " ] == " csv " ) {
dump_csv ( $row );
} else {
2009-08-28 13:16:54 +00:00
if ( ! $insert ) {
$insert = " INSERT INTO " . idf_escape ( $table ) . " ( " . implode ( " , " , array_map ( 'idf_escape' , array_keys ( $row ))) . " ) VALUES " ;
}
2008-08-16 12:28:31 +00:00
foreach ( $row as $key => $val ) {
2009-09-11 18:53:39 +00:00
$row [ $key ] = ( isset ( $val ) ? ( ereg ( 'int|float|double|decimal' , $fields [ $key ][ " type " ]) ? $val : $dbh -> quote ( $val )) : " NULL " ); //! columns looking like functions
2008-08-16 12:28:31 +00:00
}
2009-09-11 18:53:39 +00:00
$s = implode ( " , \t " , $row );
2009-06-13 17:20:29 +00:00
if ( $style == " INSERT+UPDATE " ) {
$set = array ();
2009-09-11 18:53:39 +00:00
foreach ( $row as $key => $val ) {
2009-08-04 11:13:35 +00:00
$set [] = idf_escape ( $key ) . " = $val " ;
2009-06-13 17:20:29 +00:00
}
2009-08-28 11:49:57 +00:00
dump ( " $insert ( $s ) ON DUPLICATE KEY UPDATE " . implode ( " , " , $set ) . " ; \n " );
2008-08-16 12:28:31 +00:00
} else {
2009-08-04 11:13:35 +00:00
$s = " \n ( $s ) " ;
2009-08-28 13:16:54 +00:00
if ( ! $buffer ) {
$buffer = $insert . $s ;
2009-08-28 14:44:43 +00:00
} elseif ( strlen ( $buffer ) + 1 + strlen ( $s ) < $max_packet ) { // 1 - separator length
$buffer .= " , $s " ;
2009-06-13 17:20:29 +00:00
} else {
2009-08-28 14:44:43 +00:00
$buffer .= " ; \n " ;
dump ( $buffer );
$buffer = $insert . $s ;
2008-08-16 12:28:31 +00:00
}
}
}
}
2009-08-28 13:16:54 +00:00
if ( $_POST [ " format " ] != " csv " && $style != " INSERT+UPDATE " && $buffer ) {
2009-08-28 14:44:43 +00:00
$buffer .= " ; \n " ;
dump ( $buffer );
2008-08-16 12:28:31 +00:00
}
}
}
}
2008-08-16 21:15:46 +00:00
2008-08-18 15:18:16 +00:00
function dump_headers ( $identifier , $multi_table = false ) {
2009-08-28 14:44:43 +00:00
$compress = $_POST [ " compress " ];
2009-06-11 05:18:40 +00:00
$filename = ( strlen ( $identifier ) ? friendly_url ( $identifier ) : " dump " );
2009-06-21 23:20:32 +00:00
$ext = ( $_POST [ " format " ] == " sql " ? " sql " : ( $multi_table ? " tar " : " csv " )); // multiple CSV packed to TAR
2009-08-28 14:44:43 +00:00
header ( " Content-Type: " .
( $compress == " bz2 " ? " application/x-bzip " :
( $compress == " gz " ? " application/x-gzip " :
( $ext == " tar " ? " application/x-tar " :
( $ext == " sql " || $_POST [ " output " ] != " file " ? " text/plain " : " text/csv " ) . " ; charset=utf-8 "
))));
if ( $_POST [ " output " ] == " file " || $compress ) {
header ( " Content-Disposition: attachment; filename= $filename . $ext " . ( ereg ( '[0-9a-z]' , $compress ) ? " . $compress " : " " ));
2009-06-15 10:57:43 +00:00
}
2009-09-01 13:05:50 +00:00
session_write_close ();
2008-08-18 15:18:16 +00:00
return $ext ;
}
2009-08-28 11:49:57 +00:00
$compress = array ();
if ( function_exists ( 'gzencode' )) {
2009-08-28 14:44:43 +00:00
$compress [ 'gz' ] = 'gzip' ;
}
if ( function_exists ( 'bzcompress' )) {
$compress [ 'bz2' ] = 'bzip2' ;
2009-08-28 11:49:57 +00:00
}
// ZipArchive requires temporary file, ZIP can be created by gzcompress - see PEAR File_Archive
2009-08-27 08:22:07 +00:00
$dump_output = " <select name='output'> " . optionlist ( array ( 'text' => lang ( 'open' ), 'file' => lang ( 'save' ))) . " </select> " ;
$dump_format = " <select name='format'> " . optionlist ( array ( 'sql' => 'SQL' , 'csv' => 'CSV' )) . " </select> " ;
2009-08-28 11:49:57 +00:00
$dump_compress = ( $compress ? " <select name='compress'><option> " . optionlist ( $compress ) . " </select> " : " " );
2009-06-15 10:01:55 +00:00
$max_packet = 1048576 ; // default, minimum is 1024