Hi,
sending newer patch. *added mootools_common.js *fixed notices
Please update demo server.
Thank you,
Tomas
Michal Čihař wrote:
Hi
Dne Sat, 11 Jul 2009 19:41:18 +0200 Tomas Srnka toms@linuxos.sk napsal(a):
I'm sending patch against trunk.
As others, it is now available on demo server: http://demo.phpmyadmin.net/gsoc-tomas/
Any feedback or suggests are more than welcomed.
Without any testing, it throws some warnings on demo server:
Notice in ./server_replication.php#44 Undefined index: slave_chagemaster
Backtrace
Notice in ./server_replication.php#51 Undefined index: slave_server_control
Backtrace
Notice in ./libraries/replication_gui.lib.php#18 Undefined variable: multi_values
Backtrace
./server_replication.php#315: PMA_replication_db_multibox() Notice in ./libraries/replication_gui.lib.php#46 Undefined variable: username_length
Backtrace
./server_replication.php#342: PMA_replication_gui_changemaster(string slave_chagemaster) Notice in ./libraries/replication_gui.lib.php#54 Undefined variable: hostname_length
Backtrace
./server_replication.php#342: PMA_replication_gui_changemaster(string slave_chagemaster)
Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge
Phpmyadmin-devel mailing list Phpmyadmin-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/phpmyadmin-devel
Index: server_replication.php =================================================================== --- server_replication.php (revision 0) +++ server_replication.php (revision 0) @@ -0,0 +1,348 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * + * @version $Id: replication.php 12533 2009-06-02 16:53:44Z lem9 $ + * @package phpMyAdmin + */ + +/** + * + */ +require_once './libraries/common.inc.php'; + +/** + * Does the common work + */ +$GLOBALS['js_include'][] = 'server_privileges.js'; +$GLOBALS['js_include'][] = 'functions.js'; +$GLOBALS['js_include'][] = 'mootools.js'; +$GLOBALS['js_include'][] = 'mootools_common.js'; + +require './libraries/server_common.inc.php'; +require './libraries/replication.inc.php'; +require './libraries/replication_gui.lib.php'; + + +/** + * Checks if the user is allowed to do what he tries to... + */ +if (!$is_superuser) { + require './libraries/server_links.inc.php'; + echo '<h2>' . "\n" + . PMA_getIcon('s_replication.png') + . $GLOBALS['strPrivileges'] . "\n" + . '</h2>' . "\n"; + PMA_Message::error('strNoPrivileges')->display(); + require_once './libraries/footer.inc.php'; +} + +/** + * Handling control requests + */ +//TODO: add some global variable, so I do not have add Header("...") after each request to reload all variables. +if (isset($GLOBALS['slave_chagemaster'])) { + // TODO: fix SQL Injection !!! + $link_to_master = PMA_replication_connect_to_master($GLOBALS['username'], $GLOBALS['pma_pw'], $GLOBALS['hostname'], $GLOBALS['port'], $GLOBALS['socket']); + $position = PMA_replication_slave_bin_log_master($link_to_master); + PMA_replication_slave_change_master($GLOBALS['username'], $GLOBALS['pma_pw'], $GLOBALS['hostname'], $GLOBALS['port'], $position, strlen($server_slave_replication[0]['Slave_IO_State'])==0 ? false : true, true); + Header("Location: ". PMA_generate_common_url($_url_params)); +} +if (isset($GLOBALS['slave_server_control'])) { + $action = sprintf("PMA_replication_slave_%s", strlen($server_slave_replication[0]['Slave_IO_State'])==0 ? 'start' : 'stop'); + $action(); + $_url_params = $GLOBALS['url_params']; + Header("Location: ". PMA_generate_common_url($_url_params)); +} + +/** + * Displays the links + */ +require './libraries/server_links.inc.php'; + +/** + * URL for slave start/stop server + */ +$_url_params = $GLOBALS['url_params']; +$_url_params['slave_server_control'] = true; +$slave_control_link = PMA_generate_common_url($_url_params); + +?> +<div id="replication"> + <h2> + <?php //echo ($GLOBALS['cfg']['MainPageIconic']); ?> + <img class="icon" src="<?php echo $GLOBALS['pmaThemeImage']; ?>s_replication.png" width="16" height="16" alt="" /> + Replication + </h2> +<h4> + <a href="#master_configuration" id="master_configuration_href">Master Configuration</a> +</h4> +<div id="master_configuration"> +<script language="JavaScript"> + window.addEvent('domready',function() { + $('master_configuration').setStyle('display', 'none'); + divShowHideFunc('master_configuration_href', 'master_configuration'); + $('slave_configuration').setStyle('display', 'none'); + divShowHideFunc('slave_configuration_href', 'slave_configuration'); + <?php if ($server_slave_status) { ?> + divShowHideFunc('slave_status_href', 'replication_slave_section'); + divShowHideFunc('slave_changemaster_href', 'slave_changemaster_gui'); + <?php + } + if ($server_master_status) { ?> + $('add_user_for_slave').setStyle('display', 'none'); + + divShowHideFunc('rep_add', 'add_user_for_slave'); + divShowHideFunc('rep_master_status', 'replication_master_section'); + <?php } else { ?> + var c_output = ""; + var c_text = "server-id=1<br />log-bin=mysql-bin<br />log-error=mysql-bin.err<br />"; + var c_ignore = "binlog_ignore_db="; + var c_do = "binlog_do_db="; + + $('db_type').addEvent('change',function() { + if ($('db_type').getSelected().get('value')=="all") + $('rep').set('html', c_text+c_ignore+c_output+';'); + else + $('rep').set('html', c_text+c_do+c_output+';'); + }); + + $('db_select').addEvent('change',function() { + var count = 0; + + $('db_select').getSelected().each(function(el) { + if (count==0) + c_output = el.get('value'); + else + c_output = c_output + ',' +el.get('value'); + + count=count+1; + + if ($('db_select').getSelected().length==count) { + if ($('db_type').getSelected().get('value')=="all") + $('rep').set('html', c_text+c_ignore+c_output); + else + $('rep').set('html', c_text+c_do+c_output); + count = 0; + } + }); + }); + <?php } ?> + }); +</script> +<?php +if ($server_master_status) { + echo "Server works as master in replication process. Would you like to:<br />\n"; + echo "<ul>\n"; + if ($server_master_status) { + echo '<li>Check <a href="#" id="rep_master_status">master status</a> </li>'; + PMA_replication_print_status_table('master', true, false); + } + echo '<li><a href="#" id="rep_add">Add slave replication user</a></li>'; + echo "</ul>\n"; + $fields_info = PMA_DBI_get_fields('mysql', 'user'); + $username_length = 16; + $hostname_length = 41; + foreach ($fields_info as $key => $val) { + if ($val['Field'] == 'User') { + strtok($val['Type'], '()'); + $v = strtok('()'); + if (is_int($v)) { + $username_length = $v; + } + } elseif ($val['Field'] == 'Host') { + strtok($val['Type'], '()'); + $v = strtok('()'); + if (is_int($v)) { + $hostname_length = $v; + } + } + } + unset($fields_info); + + if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) { + $GLOBALS['pred_username'] = 'any'; + } +////////////////////////// TODO: REDO ADD USER CODE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + echo '<div id="add_user_for_slave" style="display:none";>'."\n"; + echo '<form autocomplete="off" method="post" action="server_privileges.php" onsubmit="return checkAddUser(this);">'."\n"; + echo '<input type="hidden" name="grant_count" value="' + . (count($privTable[0]) + count($privTable[1]) + count($privTable[2]) - (isset($row['Grant_priv']) ? 1 : 0)) + . '" />' . "\n" + . PMA_generate_common_hidden_inputs('', ''); + echo '<fieldset id="fieldset_add_user_login">' . "\n" +// . '<legend>' . $GLOBALS['strLoginInformation'] . '</legend>' . "\n" + . '<legend>Add replication user</legend>' . "\n" + . '<input id="checkbox_Repl_slave_priv" type="hidden" title="Needed for the replication slaves." value="Y" name="Repl_slave_priv"/>' + + . '<div class="item">' . "\n" + . '<label for="select_pred_username">' . "\n" + . ' ' . $GLOBALS['strUserName'] . ':' . "\n" + . '</label>' . "\n" + . '<span class="options">' . "\n" + . ' <select name="pred_username" id="select_pred_username" title="' . $GLOBALS['strUserName'] . '"' . "\n" + . ' onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">' . "\n" + . ' <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ? ' selected="selected"' : '') . '>' . $GLOBALS['strAnyUser'] . '</option>' . "\n" + . ' <option value="userdefined"' . ((!isset($GLOBALS['pred_username']) || $GLOBALS['pred_username'] == 'userdefined') ? ' selected="selected"' : '') . '>' . $GLOBALS['strUseTextField'] . ':</option>' . "\n" + . ' </select>' . "\n" + . '</span>' . "\n" + . '<input type="text" name="username" maxlength="' + . $username_length . '" title="' . $GLOBALS['strUserName'] . '"' + . (empty($GLOBALS['username']) + ? '' + : ' value="' . (isset($GLOBALS['new_username']) + ? $GLOBALS['new_username'] + : $GLOBALS['username']) . '"') + . ' onchange="pred_username.value = \'userdefined\';" />' . "\n" + . '</div>' . "\n" + . '<div class="item">' . "\n" + . '<label for="select_pred_hostname">' . "\n" + . ' ' . $GLOBALS['strHost'] . ':' . "\n" + . '</label>' . "\n" + . '<span class="options">' . "\n" + . ' <select name="pred_hostname" id="select_pred_hostname" title="' . $GLOBALS['strHost'] . '"' . "\n"; + $_current_user = PMA_DBI_fetch_value('SELECT USER();'); + if (! empty($_current_user)) { + $thishost = str_replace("'", '', substr($_current_user, (strrpos($_current_user, '@') + 1))); + if ($thishost == 'localhost' || $thishost == '127.0.0.1') { + unset($thishost); + } + } + echo ' onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } ' + . (empty($thishost) ? '' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ') + . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n"; + unset($_current_user); + + // when we start editing a user, $GLOBALS['pred_hostname'] is not defined + if (!isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) { + switch (strtolower($GLOBALS['hostname'])) { + case 'localhost': + case '127.0.0.1': + $GLOBALS['pred_hostname'] = 'localhost'; + break; + case '%': + $GLOBALS['pred_hostname'] = 'any'; + break; + default: + $GLOBALS['pred_hostname'] = 'userdefined'; + break; + } + } + echo ' <option value="any"' + . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any') + ? ' selected="selected"' : '') . '>' . $GLOBALS['strAnyHost'] + . '</option>' . "\n" + . ' <option value="localhost"' + . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost') + ? ' selected="selected"' : '') . '>' . $GLOBALS['strLocalhost'] + . '</option>' . "\n"; + if (!empty($thishost)) { + echo ' <option value="thishost"' + . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost') + ? ' selected="selected"' : '') . '>' . $GLOBALS['strThisHost'] + . '</option>' . "\n"; + } + unset($thishost); + echo ' <option value="hosttable"' + . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable') + ? ' selected="selected"' : '') . '>' . $GLOBALS['strUseHostTable'] + . '</option>' . "\n" + . ' <option value="userdefined"' + . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined') + ? ' selected="selected"' : '') + . '>' . $GLOBALS['strUseTextField'] . ':</option>' . "\n" + . ' </select>' . "\n" + . '</span>' . "\n" + . '<input type="text" name="hostname" maxlength="' + . $hostname_length . '" value="' + . (isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '') + . '" title="' . $GLOBALS['strHost'] + . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n" + . PMA_showHint($GLOBALS['strHostTableExplanation']) + . '</div>' . "\n" + . '<div class="item">' . "\n" + . '<label for="select_pred_password">' . "\n" + . ' ' . $GLOBALS['strPassword'] . ':' . "\n" + . '</label>' . "\n" + . '<span class="options">' . "\n" + . ' <select name="pred_password" id="select_pred_password" title="' + . $GLOBALS['strPassword'] . '"' . "\n" + . ' onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">' . "\n" + . ($mode == 'change' ? ' <option value="keep" selected="selected">' . $GLOBALS['strKeepPass'] . '</option>' . "\n" : '') + . ' <option value="none"'; + if (isset($GLOBALS['username']) && $mode != 'change') { + echo ' selected="selected"'; + } + echo '>' . $GLOBALS['strNoPassword'] . '</option>' . "\n" + . ' <option value="userdefined"' . (isset($GLOBALS['username']) ? '' : ' selected="selected"') . '>' . $GLOBALS['strUseTextField'] . ':</option>' . "\n" + . ' </select>' . "\n" + . '</span>' . "\n" + . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . $GLOBALS['strPassword'] . '" onchange="pred_password.value = \'userdefined\';" />' . "\n" + . '</div>' . "\n" + . '<div class="item">' . "\n" + . '<label for="text_pma_pw2">' . "\n" + . ' ' . $GLOBALS['strReType'] . ':' . "\n" + . '</label>' . "\n" + . '<span class="options"> </span>' . "\n" + . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . $GLOBALS['strReType'] . '" onchange="pred_password.value = \'userdefined\';" />' . "\n" + . '</div>' . "\n" + . '<div class="item">' . "\n" + . '<label for="button_generate_password">' . "\n" + . ' ' . $GLOBALS['strGeneratePassword'] . ':' . "\n" + . '</label>' . "\n" + . '<span class="options">' . "\n" + . ' <input type="button" id="button_generate_password" value="' . $GLOBALS['strGenerate'] . '" onclick="suggestPassword()" />' . "\n" + . '</span>' . "\n" + . '<input type="text" name="generated_pw" id="generated_pw" />' . "\n" + . '</div>' . "\n" + . '</fieldset>' . "\n"; + echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n" + . ' <input type="submit" name="adduser_submit" id="adduser_submit" value="' . $GLOBALS['strGo'] . '" />' . "\n" + . '</fieldset>' . "\n"; + echo '</form>'."\n"; + echo '</div>'."\n"; +} else { +?> +<h5>Master Setup</h5> +This server is not configured as master server in replication process. You can choose from either replicating all databases and ignoring certain (useful if you want to replicate majority of databases) or you can choose to ignore all databases by default and allow only certain to be replicated. Please select the mode:<br /><br /> + +<select name="db_type" id="db_type"> + <option value="all">Replicate all databases; Ignore:</option> + <option value="ign">Ignore all databases; Replicate:</option> +</select> +<br /><br /> +Please select databases:<br /> +<?php echo PMA_replication_db_multibox(); ?> +<br /><br /> +Now, add following lines at the end of your my.cnf and please restart the mysql server afterwards.<br /> +<pre><div id="rep">server-id=1<br />log-bin=mysql-bin<br />log-error=mysql-bin.err<br /></div></pre> +<?php +} +?> +</div> +<h4> + <a href="#slave_configuration" id="slave_configuration_href">Slave Configuration</a> +</h4> +<div id="slave_configuration"> +<?php if ($server_slave_status) { ?> + Server is configured as slave in replication process. Would you like to:<br /><br /> + <i><b>TODO:</b> add error/warning message if the slave process is stoped<br /></i> + <ul> + + <li>See <a href="#" id="slave_status_href">slave status</a> table </li> + <?php echo PMA_replication_print_status_table('slave', true, false); ?> + <li><a href="<?php echo $slave_control_link; ?>" id="slave_startstop_href"><?php echo (strlen($server_slave_replication[0]['Slave_IO_State'])==0 ? 'Start' : 'Stop'); ?> slave</a> </li> + <li><a href="#" id="slave_changemaster_href">Change or reconfigure master server</a></li> + <div id="slave_changemaster_gui" style="display: none;"> + <?php PMA_replication_gui_changemaster("slave_chagemaster"); ?> + </div> + </ul> +<?php +} else { + PMA_replication_gui_changemaster("slave_chagemaster"); +} +?> +</div> +<?php +require_once './libraries/footer.inc.php'; +?> Index: js/mootools_common.js =================================================================== --- js/mootools_common.js (revision 0) +++ js/mootools_common.js (revision 0) @@ -0,0 +1,8 @@ +function divShowHideFunc(ahref, id) { + $(ahref).addEvent('click', function() { + if ($(id).getStyle('display')=="none") + $(id).tween('display', 'block'); + else + $(id).tween('display', 'none'); + }); +} Index: db_structure.php =================================================================== --- db_structure.php (revision 12640) +++ db_structure.php (working copy) @@ -42,6 +42,8 @@ // Gets the database structure $sub_part = '_structure'; require './libraries/db_info.inc.php'; + + require_once './libraries/replication.inc.php'; }
// 1. No tables @@ -134,7 +136,7 @@ <?php echo PMA_generate_common_hidden_inputs($db);
-PMA_TableHeader($db_is_information_schema); +PMA_TableHeader($db_is_information_schema, $server_slave_status);
$i = $sum_entries = 0; $sum_size = (double) 0; @@ -321,8 +323,36 @@ </tbody> </table> <?php - PMA_TableHeader(); + PMA_TableHeader(false, $server_slave_status); } + + $ignored = false; + $do = false; + + if ($server_slave_status) { + //////////////////////////////////////////////////////////////// + + if ((strlen(array_search($truename, $server_slave_Do_Table))>0) || (strlen(array_search($db, $server_slave_Do_DB))>0) || (count($server_slave_Do_DB)==1 && count($server_slave_Ignore_DB)==1)) { + $do = true; + } + foreach ($server_slave_Wild_Do_Table as $table) { + if (($db == PMA_replication_strout($table)) && (ereg("^".substr(PMA_replication_strout($table, true), 0, strlen(PMA_replication_strout($table, true))-1), $truename))) + $do = true; + } + //////////////////////////////////////////////////////////////////// + if ((strlen(array_search($truename, $server_slave_Ignore_Table))>0) || (strlen(array_search($db, $server_slave_Ignore_DB))>0)) { + $ignored = true; + } + foreach ($server_slave_Wild_Ignore_Table as $table) { + if (($db == PMA_replication_strout($table)) && (ereg("^".substr(PMA_replication_strout($table, true), 0, strlen(PMA_replication_strout($table, true))-1), $truename))) + $ignored = true; + } + }/* elseif ($server_master_status) { + if ((strlen(array_search($db, $server_master_Do_DB))>0) || count($server_master_Do_DB)==1) + $do = true; + elseif ((strlen(array_search($db, $server_master_Ignore_DB))>0) || count($server_master_Ignore_DB)==1) + $ignored = true; + }*/ ?> <tr class="<?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>"> <td align="center"> @@ -330,8 +360,9 @@ value="<?php echo $each_table['TABLE_NAME']; ?>" id="checkbox_tbl_<?php echo $i; ?>"<?php echo $checked; ?> /></td> <th><label for="checkbox_tbl_<?php echo $i; ?>" - title="<?php echo $alias; ?>"><?php echo $truename; ?></label> + title="<?php echo $alias; ?>" style="<?php echo $ignored ? ' ignored' : ''; ?>"><?php echo $truename; ?></label> </th> + <?php if ($server_slave_status) { ?><td align="center"><?php echo $ignored ? ' <img class="icon" src="' . $pmaThemeImage . 's_cancel.png" width="16" height="16" alt="REPLICATED" />' : ''. $do ? ' <img class="icon" src="' . $pmaThemeImage . 's_success.png" width="16" height="16" alt="REPLICATED" />' : ''; ?></td><?php } ?> <td align="center"><?php echo $browse_table; ?></td> <td align="center"> <a href="tbl_structure.php?<?php echo $tbl_url_query; ?>"> Index: server_status.php =================================================================== --- server_status.php (revision 12640) +++ server_status.php (working copy) @@ -28,6 +28,11 @@ */ require './libraries/server_links.inc.php';
+/** + * Replication library + */ +require './libraries/replication.inc.php'; +require_once './libraries/replication_gui.lib.php';
/** * Displays the sub-page heading @@ -65,17 +70,6 @@ $server_status = PMA_DBI_fetch_result('SHOW GLOBAL STATUS', 0, 1);
/** - * get master status from server - */ -$server_master_status = PMA_DBI_fetch_result('SHOW MASTER STATUS'); - -/** - * get slave status from server - */ -$server_slave_status = PMA_DBI_fetch_result('SHOW SLAVE STATUS'); - - -/** * for some calculations we require also some server settings */ $server_variables = PMA_DBI_fetch_result('SHOW GLOBAL VARIABLES', 0, 1); @@ -263,71 +257,7 @@ 'tc' => array('title' => $strTransactionCoordinator), );
-/** - * replication types - */ -$replication_types = array('master', 'slave'); - /** - * define variables for master status - */ -$master_variables = array( - 'File', - 'Position', - 'Binlog_Do_DB', - 'Binlog_Ignore_DB' -); - -/** - * Define variables for slave status - */ -$slave_variables = array( - 'Slave_IO_State', - 'Master_Host', - 'Master_User', - 'Master_Port', - 'Connect_Retry', - 'Master_Log_File', - 'Read_Master_Log_Pos', - 'Relay_Log_File', - 'Relay_Log_Pos', - 'Relay_Master_Log_File', - 'Slave_IO_Running', - 'Slave_SQL_Running', - 'Replicate_Do_DB', - 'Replicate_Ignore_DB', - 'Replicate_Do_Table', - 'Replicate_Ignore_Table', - 'Replicate_Wild_Do_Table', - 'Replicate_Wild_Ignore_Table', - 'Last_Errno', - 'Last_Error', - 'Skip_Counter', - 'Exec_Master_Log_Pos', - 'Relay_Log_Space', - 'Until_Condition', - 'Until_Log_File', - 'Until_Log_Pos', - 'Master_SSL_Allowed', - 'Master_SSL_CA_File', - 'Master_SSL_CA_Path', - 'Master_SSL_Cert', - 'Master_SSL_Cipher', - 'Master_SSL_Key', - 'Seconds_Behind_Master' -); -/** - * define important variables, which need to be watched for correct running of replication in slave mode - */ -$slave_variables_alerts = array( - 'Slave_IO_Running' => 'No', - 'Slave_SQL_Running' => 'No' - ); -$slave_variables_oks = array( - 'Slave_IO_Running' => 'Yes', - 'Slave_SQL_Running' => 'Yes' - ); -/** * define some needfull links/commands */ // variable or section name => (name => url) @@ -342,9 +272,10 @@ $links['repl'][$strShowSlaveHosts] = 'sql.php?sql_query=' . urlencode('SHOW SLAVE HOSTS') . '&goto=server_status.php&' . PMA_generate_common_url(); -$links['repl'][$strShowSlaveStatus] - = 'sql.php?sql_query=' . urlencode('SHOW SLAVE STATUS') . - '&goto=server_status.php&' . PMA_generate_common_url(); +$links['repl'][$strShowSlaveStatus] = '#replication_slave'; + + /* TODO: REMOVE: 'sql.php?sql_query=' . urlencode('SHOW SLAVE STATUS') . + '&goto=server_status.php&' . PMA_generate_common_url();*/ $links['repl']['doc'] = 'replication';
$links['qcache'][$strFlushQueryCache] @@ -387,14 +318,6 @@ } unset($name, $value, $filter, $section, $allocations);
-// check which replication is available -foreach ($replication_types as $type) -{ - if (count(${"server_{$type}_status"}) > 0) - ${"server_{$type}_status_run"} = true; - else - ${"server_{$type}_status_run"} = false; -} // rest $sections['all']['vars'] =& $server_status;
@@ -423,17 +346,19 @@ </p>
<?php -if ($server_master_status_run || $server_slave_status_run) { - $replicationOut = ""; - foreach ($replication_types as $type) { - if (${"server_{$type}_status_run"}) { - if ($replicationOut != "") { - $replicationOut .= $strAndSmall . ' '; - } - $replicationOut .= '<b>' . $type . '</b> '; - } +if ($server_master_status || $server_slave_status) +{ + $replicationOut = ""; + foreach ($replication_types as $type) + { + if (${"server_{$type}_status"}) + { + if ($replicationOut != "") + $replicationOut .= $strAndSmall . ' '; + $replicationOut .= '<b>' . $type . '</b> '; } - echo sprintf('<p>' . $strReplicationStatusInfo . '</p>', $replicationOut); + } + echo sprintf('<p>' . $strReplicationStatusInfo . '</p>', $replicationOut); } ?>
@@ -696,6 +621,8 @@ if ('doc' == $link_name) { echo PMA_showMySQLDocu($link_url, $link_url); } else { + if (!$server_slave_status && $section_name == 'repl') + continue; echo '<a href="' . $link_url . '">' . $link_name . '</a>' . "\n"; } } @@ -770,7 +697,7 @@ </div> <?php /* if the server works as master or slave in replication process, display useful information */ -if ($server_master_status_run || $server_slave_status_run) +if ($server_master_status || $server_slave_status) { ?> <hr class="clearfloat" /> @@ -778,54 +705,9 @@ <h3><a name="replication"></a><?php echo $strReplicationStatus; ?></h3> <?php
- foreach ($replication_types as $type) - { - if (${"server_{$type}_status_run"}) - { - ?> - <h4><?php echo ${"strReplicationStatus_{$type}"}; ?></h4> - <?php - ?> - <table id="server<?php echo $type; ?>replicationsummary" class="data"> - - <thead> - <tr> - <th><?php echo $strVar; ?></th> - <th><?php echo $strValue; ?></th> - </tr> - </thead> - <tbody> - <?php - $odd_row = true; - foreach(${"{$type}_variables"} as $variable) - { - ?> - <tr class="<?php echo $odd_row ? 'odd' : 'even'; ?>"> - <td class="name"> - <?php echo $variable; ?> - </td> - <td class="value"> - <?php - if (${"{$type}_variables_alerts"}[$variable] == ${"server_{$type}_status"}[0][$variable]) - echo '<span class="attention">'; - if (${"{$type}_variables_oks"}[$variable] == ${"server_{$type}_status"}[0][$variable]) - echo '<span class="allfine">'; - else - echo '<span>'; - echo ${"server_{$type}_status"}[0][$variable]; - echo '</span>'; - ?> - </td> - </tr> - <?php - $odd_row = ! $odd_row; - } - unset(${"server_{$type}_status"}); - ?> - </tbody> - </table> - <?php - } + foreach ($replication_types as $type) { + if (${"server_{$type}_status"}) + PMA_replication_print_status_table($type); } unset($types); } Index: server_databases.php =================================================================== --- server_databases.php (revision 12640) +++ server_databases.php (working copy) @@ -14,6 +14,7 @@
$GLOBALS['js_include'][] = 'functions.js'; require './libraries/server_common.inc.php'; +require './libraries/replication.inc.php';
/** * avoids 'undefined index' errors @@ -34,7 +35,7 @@ $dbstats = empty($_REQUEST['dbstats']) ? 0 : 1; $pos = empty($_REQUEST['pos']) ? 0 : (int) $_REQUEST['pos'];
- + /** * Drops multiple databases */ @@ -104,6 +105,9 @@ */ if ($databases_count > 0) { reset($databases); + /* replication */ + + reset($databases); $first_database = current($databases); // table col order $column_order['DEFAULT_COLLATION_NAME'] = array( @@ -187,6 +191,13 @@ .' </a></th>' . "\n"; } } + + foreach ($replication_types as $type) + { + if (${"server_{$type}_status"}) + echo ' <th>'.${"StrRep{$type}"}.'</th>' . "\n"; + } + if ($is_superuser) { echo ' <th>' . ($cfg['PropertiesIconic'] ? '' : $strAction) . "\n" . ' </th>' . "\n"; @@ -247,7 +258,26 @@ } } } - + /* OK, toto sa mi vcelku pozdava */ + foreach ($replication_types as $type) { + if (${"server_{$type}_status"}) { + echo '<td class="tool" style="text-align: center;">' . "\n"; + + if (strlen(array_search($current["SCHEMA_NAME"], ${"server_{$type}_Ignore_DB"}))>0) { + echo '<img class="icon" src="' . $pmaThemeImage . 's_cancel.png" width="16" height="16" alt="REPLICATED" />' . "\n"; + } else { + $key = array_search($current["SCHEMA_NAME"], ${"server_{$type}_Do_DB"}); + + if (strlen($key)>0 || (${"server_{$type}_Do_DB"}[0]=="" && count(${"server_{$type}_Do_DB"})==1)) // if ($key != null) did not work for index "0" + echo '<img class="icon" src="' . $pmaThemeImage . 's_success.png" width="16" height="16" alt="REPLICATED" />' . "\n"; + else + echo ''; + } + + echo '</td>'; + } + } + if ($is_superuser) { echo ' <td class="tool">' . "\n" . ' <a onclick="' @@ -294,6 +324,13 @@ } } } + + foreach ($replication_types as $type) + { + if (${"server_{$type}_status"}) + echo ' <th></th>' . "\n"; + } + if ($is_superuser) { echo ' <th></th>' . "\n"; } Index: libraries/db_structure.lib.php =================================================================== --- libraries/db_structure.lib.php (revision 12640) +++ libraries/db_structure.lib.php (working copy) @@ -28,8 +28,9 @@ * @uses $GLOBALS['structure_tbl_col_cnt'] * @uses PMA_SortableTableHeader() * @param boolean $db_is_information_schema + * @param boolean $replication */ -function PMA_TableHeader($db_is_information_schema = false) +function PMA_TableHeader($db_is_information_schema = false, $replication = false) { $cnt = 0; // Let's count the columns...
@@ -42,8 +43,13 @@ echo '<table class="data" style="float: left;">' . "\n" .'<thead>' . "\n" .'<tr><th></th>' . "\n" - .' <th>' . PMA_SortableTableHeader($GLOBALS['strTable'], 'table') . '</th>' . "\n" - .' <th colspan="' . $action_colspan . '">' . "\n" + .' <th>' . PMA_SortableTableHeader($GLOBALS['strTable'], 'table') . '</th>' . "\n"; + if ($replication) { + echo ' <th>' . "\n" + .' ' . "Replication" . "\n" + .' </th>'; + } + echo ' <th colspan="' . $action_colspan . '">' . "\n" .' ' . $GLOBALS['strAction'] . "\n" .' </th>' .' <th>' . PMA_SortableTableHeader($GLOBALS['strRecords'], 'records') Index: libraries/server_links.inc.php =================================================================== --- libraries/server_links.inc.php (revision 12640) +++ libraries/server_links.inc.php (working copy) @@ -64,6 +64,10 @@ $tabs['rights']['icon'] = 's_rights.png'; $tabs['rights']['link'] = 'server_privileges.php'; $tabs['rights']['text'] = $strPrivileges; + + $tabs['replication']['icon'] = 's_replication.png'; + $tabs['replication']['link'] = 'server_replication.php'; + $tabs['replication']['text'] = "Replication"; }
if (! empty($binary_logs)) { Index: libraries/replication_gui.lib.php =================================================================== --- libraries/replication_gui.lib.php (revision 0) +++ libraries/replication_gui.lib.php (revision 0) @@ -0,0 +1,133 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * + * @version $Id: replication_gui.lib.php 12533 2009-06-02 16:53:44Z lem9 $ + * @package phpMyAdmin + */ +if (! defined('PHPMYADMIN')) { + exit; +} +/** + * + * + */ +function PMA_replication_db_multibox() +{ + // TODO: add link uncheck all + $multi_values = ''; + $multi_values .= '<select name="db_select[]" size="6" multiple="multiple" id="db_select">'; + $multi_values .= "\n"; + + foreach ($GLOBALS['pma']->databases as $current_db) { + if (!empty($selectall) || (isset($tmp_select) && strpos(' ' . $tmp_select, '|' . $current_db . '|'))) { + $is_selected = ' selected="selected"'; + } else { + $is_selected = ''; + } + $current_db = htmlspecialchars($current_db); + $multi_values .= ' <option value="' . $current_db . '" ' . $is_selected . '>' . $current_db . '</option>' . "\n"; + } // end while + $multi_values .= "\n"; + $multi_values .= '</select>'; + + return $multi_values; +} +/** + * + */ +function PMA_replication_gui_changemaster($submitname) { +?> +<form method="post" action="server_replication.php"> +<?php echo PMA_generate_common_hidden_inputs('', ''); ?> + <fieldset id="fieldset_add_user_login"> + <legend>Configure master settings</legend> + <div class="item"> + <label for="select_pred_username"><?php echo $GLOBALS['strUserName']; ?>:</label> + <input type="text" name="username" maxlength="<?php echo $GLOBALS['username_length'] ; ?>" title="<?php echo $GLOBALS['strUserName']; ?>" onchange="pred_username.value = 'userdefined';" /> + </div> + <div class="item"> + <label for="select_pred_password"><?php echo $GLOBALS['strPassword']; ?>:</label> + <input type="password" id="text_pma_pw" name="pma_pw" title="<?php echo $GLOBALS['strPassword'] ; ?>" onchange="pred_password.value = 'userdefined';" /> + </div> + <div class="item"> + <label for="select_pred_hostname"><?php echo $GLOBALS['strHost']; ?>:</label> + <input type="text" name="hostname" maxlength="<?php echo $GLOBALS['hostname_length']; ?>" value="" /> + </div> + <div class="item"> + <label for="select_pred_hostname" style="text-decoration:line-through;">Port:</label> + <input type="text" name="port" maxlength="6" value="" disabled /> + </div> + <div class="item"> + <label for="select_pred_hostname" style="text-decoration:line-through;">Socket:</label> + <input type="text" name="socket" maxlength="255" value="" disabled /> + </div> + </fieldset> + <fieldset id="fieldset_user_privtable_footer" class="tblFooters"> + <input type="submit" name="<?php echo $submitname ?>" id="confslave_submit" value="<?php echo $GLOBALS['strGo']; ?>" /> + </fieldset> + </form> +<?php +} + +function PMA_replication_print_status_table ($type, $hidden=false, $title=true) { + global ${"{$type}_variables"}; + global ${"{$type}_variables_alerts"}; + global ${"{$type}_variables_oks"}; + global ${"server_{$type}_replication"}; + global ${"strReplicationStatus_{$type}"}; + + if ($hidden) + $style="display: none"; +?> + <div id="replication_<?php echo $type; ?>_section" style="<?php echo $style; ?>"> + <?php if ($title) { ?> + <h4><a name="replication_<?php echo $type;?>"></a><?php echo ${"strReplicationStatus_{$type}"}; ?></h4> + <?php + } else { + echo "<br />\n"; + } + ?> + <table id="server<?php echo $type; ?>replicationsummary" class="data"> + + <thead> + <tr> + <th><?php echo $GLOBALS['strVar']; ?></th> + <th><?php echo $GLOBALS['strValue']; ?></th> + </tr> + </thead> + <tbody> + <?php + $odd_row = true; + foreach(${"{$type}_variables"} as $variable) { + ?> + <tr class="<?php echo $odd_row ? 'odd' : 'even'; ?>"> + <td class="name"> + <?php echo $variable; ?> + </td> + <td class="value"> + <?php + if (${"{$type}_variables_alerts"}[$variable] == ${"server_{$type}_replication"}[0][$variable]) + echo '<span class="attention">'; + if (${"{$type}_variables_oks"}[$variable] == ${"server_{$type}_replication"}[0][$variable]) + echo '<span class="allfine">'; + else + echo '<span>'; + echo ${"server_{$type}_replication"}[0][$variable]; + echo '</span>'; + ?> + </td> + </tr> + <?php + $odd_row = !$odd_row; + } + ?> + </tbody> + </table> + <br /> + </div> + +<?php +} + +?> Index: libraries/replication.inc.php =================================================================== --- libraries/replication.inc.php (revision 0) +++ libraries/replication.inc.php (revision 0) @@ -0,0 +1,178 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * + * @version $Id: replication.inc.php 12506 2009-05-27 17:36:57Z lem9 $ + * @package phpMyAdmin + */ + +if (! defined('PHPMYADMIN')) { + exit; +} +// TEMP STRINGS +$StrRepmaster = "Master Replica"; +$StrRepslave = "Slave Replica"; + +/** + * get master replication from server + */ +$server_master_replication = PMA_DBI_fetch_result('SHOW MASTER STATUS'); + +/** + * get slave replication from server + */ +$server_slave_replication = PMA_DBI_fetch_result('SHOW SLAVE STATUS'); + +/** + * replication types + */ +$replication_types = array('master', 'slave'); + + +/** + * define variables for master status + */ +$master_variables = array( + 'File', + 'Position', + 'Binlog_Do_DB', + 'Binlog_Ignore_DB' +); + +/** + * Define variables for slave status + */ +$slave_variables = array( + 'Slave_IO_State', + 'Master_Host', + 'Master_User', + 'Master_Port', + 'Connect_Retry', + 'Master_Log_File', + 'Read_Master_Log_Pos', + 'Relay_Log_File', + 'Relay_Log_Pos', + 'Relay_Master_Log_File', + 'Slave_IO_Running', + 'Slave_SQL_Running', + 'Replicate_Do_DB', + 'Replicate_Ignore_DB', + 'Replicate_Do_Table', + 'Replicate_Ignore_Table', + 'Replicate_Wild_Do_Table', + 'Replicate_Wild_Ignore_Table', + 'Last_Errno', + 'Last_Error', + 'Skip_Counter', + 'Exec_Master_Log_Pos', + 'Relay_Log_Space', + 'Until_Condition', + 'Until_Log_File', + 'Until_Log_Pos', + 'Master_SSL_Allowed', + 'Master_SSL_CA_File', + 'Master_SSL_CA_Path', + 'Master_SSL_Cert', + 'Master_SSL_Cipher', + 'Master_SSL_Key', + 'Seconds_Behind_Master' +); +/** + * define important variables, which need to be watched for correct running of replication in slave mode + */ +$slave_variables_alerts = array( + 'Slave_IO_Running' => 'No', + 'Slave_SQL_Running' => 'No' + ); +$slave_variables_oks = array( + 'Slave_IO_Running' => 'Yes', + 'Slave_SQL_Running' => 'Yes' + ); + +// check which replication is available and set $server_{master/slave}_status and assign values +foreach ($replication_types as $type) { + if (count(${"server_{$type}_replication"}) > 0) + ${"server_{$type}_status"} = true; + else + ${"server_{$type}_status"} = false; + + if (${"server_{$type}_status"}) { + if ($type=="master") { + ${"server_{$type}_Do_DB"} = split (",", $server_master_replication[0]["Binlog_Do_DB"]); + ${"server_{$type}_Ignore_DB"} = split (",", $server_master_replication[0]["Binlog_Ignore_DB"]); + } elseif ($type=="slave") { + ${"server_{$type}_Do_DB"} = split (",", $server_slave_replication[0]["Replicate_Do_DB"]); + ${"server_{$type}_Ignore_DB"} = split (",", $server_slave_replication[0]["Replicate_Ignore_DB"]); + + ${"server_{$type}_Do_Table"} = split (",", $server_slave_replication[0]["Replicate_Do_Table"]); + ${"server_{$type}_Ignore_Table"} = split (",", $server_slave_replication[0]["Replicate_Ignore_Table"]); + + ${"server_{$type}_Wild_Do_Table"} = split(",", $server_slave_replication[0]["Replicate_Wild_Do_Table"]); + ${"server_{$type}_Wild_Ignore_Table"} = split(",", $server_slave_replication[0]["Replicate_Wild_Ignore_Table"]); + } + } +} + + +/** + * @param $string - + * @param $table - + * @return + */ +function PMA_replication_strout($string, $table=false) { + $list = explode(".", $string); + + return $list[(int)$table]; +} + +function PMA_replication_slave_stop($link=null) +{ + return PMA_DBI_try_query("STOP SLAVE;", $link); +} + +function PMA_replication_slave_start($link=null) +{ + return PMA_DBI_try_query("START SLAVE;", $link); +} +///////////// SQL INJECTION!!!!!!!!!!!!!!!!! +function PMA_replication_slave_change_master($user, $password, $host, $port, $pos, $stop=true, $start=true, $link=null) +{ + if ($stop) + PMA_replication_slave_stop($link); + + $out = PMA_DBI_try_query('CHANGE MASTER TO '. + 'MASTER_HOST=\''.$host.'\','. + // 'MASTER_PORT=\''.$port.'\','. // TODO: add PORT support + 'MASTER_USER=\''.$user.'\','. + 'MASTER_PASSWORD=\''.$password.'\','. + 'MASTER_LOG_FILE=\''.$pos["File"].'\','. + 'MASTER_LOG_POS='.$pos["Position"].';'); + if ($start) + PMA_replication_slave_start($link); + + return $out; +} + +function PMA_replication_connect_to_master($user, $password, $host=null, $port=null, $socket=null) +{ + $server = array(); + $server["host"] = $host; + $server["port"] = $port; + $server["socket"] = $socket; + + return PMA_DBI_connect($user, $password, false, $server); +} + +function PMA_replication_slave_bin_log_master($link) +{ + $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $link); + + $output = array(); + $output["File"] = $data[0]["File"]; + $output["Position"] = $data[0]["Position"]; + + return $output; +} + + +?> Index: libraries/dbi/mysqli.dbi.lib.php =================================================================== --- libraries/dbi/mysqli.dbi.lib.php (revision 12640) +++ libraries/dbi/mysqli.dbi.lib.php (working copy) @@ -54,14 +54,22 @@ * @param string $user mysql user name * @param string $password mysql user password * @param boolean $is_controluser + * @param array $server host/port/socket * @return mixed false on error or a mysqli object on success */ -function PMA_DBI_connect($user, $password, $is_controluser = false) +function PMA_DBI_connect($user, $password, $is_controluser = false, $server = null) { - $server_port = (empty($GLOBALS['cfg']['Server']['port'])) - ? false - : (int) $GLOBALS['cfg']['Server']['port']; + if ($server) { + $server_port = (empty($server['port'])) + ? false + : (int) $server['port']; + } else { + $server_port = (empty($GLOBALS['cfg']['Server']['port'])) + ? false + : (int) $GLOBALS['cfg']['Server']['port']; + }
+ if (strtolower($GLOBALS['cfg']['Server']['connect_type']) == 'tcp') { $GLOBALS['cfg']['Server']['socket'] = ''; } @@ -86,21 +94,25 @@ if ($GLOBALS['cfg']['Server']['ssl'] && defined('MYSQLI_CLIENT_SSL')) { $client_flags |= MYSQLI_CLIENT_SSL; } + + if (!$server) { + $return_value = @mysqli_real_connect($link, $GLOBALS['cfg']['Server']['host'], $user, $password, false, $server_port, $server_socket, $client_flags);
- $return_value = @mysqli_real_connect($link, $GLOBALS['cfg']['Server']['host'], $user, $password, false, $server_port, $server_socket, $client_flags); - - // Retry with empty password if we're allowed to - if ($return_value == false && isset($cfg['Server']['nopassword']) && $cfg['Server']['nopassword'] && !$is_controluser) { - $return_value = @mysqli_real_connect($link, $GLOBALS['cfg']['Server']['host'], $user, '', false, $server_port, $server_socket, $client_flags); + // Retry with empty password if we're allowed to + if ($return_value == false && isset($cfg['Server']['nopassword']) && $cfg['Server']['nopassword'] && !$is_controluser) { + $return_value = @mysqli_real_connect($link, $GLOBALS['cfg']['Server']['host'], $user, '', false, $server_port, $server_socket, $client_flags); + } + } else { + $return_value = @mysqli_real_connect($link, $server['host'], $user, $password, false, $server['port'], $server['socket']); }
if ($return_value == false) { - if ($is_controluser) { - trigger_error($GLOBALS['strControluserFailed'], E_USER_WARNING); - return false; - } - PMA_log_user($user, 'mysql-denied'); - PMA_auth_fails(); + if ($is_controluser) { + trigger_error($GLOBALS['strControluserFailed'], E_USER_WARNING); + return false; + } + PMA_log_user($user, 'mysql-denied'); + PMA_auth_fails(); } // end if
PMA_DBI_postConnect($link, $is_controluser); Index: libraries/dbi/mysql.dbi.lib.php =================================================================== --- libraries/dbi/mysql.dbi.lib.php (revision 12640) +++ libraries/dbi/mysql.dbi.lib.php (working copy) @@ -41,14 +41,26 @@
return $link; } - -function PMA_DBI_connect($user, $password, $is_controluser = false) +/** + * @param string $user mysql user name + * @param string $password mysql user password + * @param boolean $is_controluser + * @param array $server host/port/socket + * @return mixed false on error or a mysqli object on success + */ +function PMA_DBI_connect($user, $password, $is_controluser = false, $server = null) { global $cfg, $php_errormsg; - - $server_port = (empty($cfg['Server']['port'])) + + if ($server) { + $server_port = (empty($server['port'])) ? '' + : ':' . $server['port']; + } else { + $server_port = (empty($cfg['Server']['port'])) + ? '' : ':' . $cfg['Server']['port']; + }
if (strtolower($cfg['Server']['connect_type']) == 'tcp') { $cfg['Server']['socket'] = ''; @@ -74,14 +86,17 @@ if (defined('MYSQL_CLIENT_SSL') && $cfg['Server']['ssl']) { $client_flags |= MYSQL_CLIENT_SSL; } + + if (!$server) { + $link = PMA_DBI_real_connect($cfg['Server']['host'] . $server_port . $server_socket, $user, $password, empty($client_flags) ? NULL : $client_flags);
- $link = PMA_DBI_real_connect($cfg['Server']['host'] . $server_port . $server_socket, $user, $password, empty($client_flags) ? NULL : $client_flags); - - // Retry with empty password if we're allowed to - if (empty($link) && $cfg['Server']['nopassword'] && !$is_controluser) { - $link = PMA_DBI_real_connect($cfg['Server']['host'] . $server_port . $server_socket, $user, '', empty($client_flags) ? NULL : $client_flags); + // Retry with empty password if we're allowed to + if (empty($link) && $cfg['Server']['nopassword'] && !$is_controluser) { + $link = PMA_DBI_real_connect($cfg['Server']['host'] . $server_port . $server_socket, $user, '', empty($client_flags) ? NULL : $client_flags); + } + } else { + $link = PMA_DBI_real_connect($server['host'] . $server_port . $server['socket'], $user, $password, NULL); } - if (empty($link)) { if ($is_controluser) { trigger_error($GLOBALS['strControluserFailed'], E_USER_WARNING); @@ -90,9 +105,9 @@ PMA_log_user($user, 'mysql-denied'); PMA_auth_fails(); } // end if + if (!$server) + PMA_DBI_postConnect($link, $is_controluser);
- PMA_DBI_postConnect($link, $is_controluser); - return $link; }