= $filter_ts_from
&& $timestamp <= $filter_ts_to
&& (in_array('*', $filter_users) || in_array($entry['username'], $filter_users))
) {
$tmp_entries[] = array( 'id' => $id,
'timestamp' => $timestamp,
'username' => $entry['username'],
'statement' => $entry['statement']
);
}
$id++;
}
return($tmp_entries);
}
$entries = array();
// Filtering data definition statements
if ($_REQUEST['logtype'] == 'schema'
|| $_REQUEST['logtype'] == 'schema_and_data'
) {
$entries = array_merge(
$entries,
PMA_filter_tracking(
$data['ddlog'], $filter_ts_from, $filter_ts_to, $filter_users
)
);
}
// Filtering data manipulation statements
if ($_REQUEST['logtype'] == 'data'
|| $_REQUEST['logtype'] == 'schema_and_data'
) {
$entries = array_merge(
$entries,
PMA_filter_tracking(
$data['dmlog'], $filter_ts_from, $filter_ts_to, $filter_users
)
);
}
// Sort it
foreach ($entries as $key => $row) {
$ids[$key] = $row['id'];
$timestamps[$key] = $row['timestamp'];
$usernames[$key] = $row['username'];
$statements[$key] = $row['statement'];
}
array_multisort(
$timestamps, SORT_ASC, $ids, SORT_ASC, $usernames,
SORT_ASC, $statements, SORT_ASC, $entries
);
}
// Export as file download
if (isset($_REQUEST['report_export'])
&& $_REQUEST['export_type'] == 'sqldumpfile'
) {
@ini_set('url_rewriter.tags', '');
// Replace all multiple whitespaces by a single space
$table = htmlspecialchars(preg_replace('/\s+/', ' ', $_REQUEST['table']));
$dump = "# " . sprintf(
__('Tracking report for table `%s`'), $table
)
. "\n" . "# " . date('Y-m-d H:i:s') . "\n";
foreach ($entries as $entry) {
$dump .= $entry['statement'];
}
$filename = 'log_' . $table . '.sql';
PMA_downloadHeader($filename, 'text/x-sql', strlen($dump));
echo $dump;
exit();
}
/**
* Gets tables informations
*/
echo '
';
/**
* Actions
*/
// Create tracking version
if (isset($_REQUEST['submit_create_version'])) {
$tracking_set = '';
if ($_REQUEST['alter_table'] == true) {
$tracking_set .= 'ALTER TABLE,';
}
if ($_REQUEST['rename_table'] == true) {
$tracking_set .= 'RENAME TABLE,';
}
if ($_REQUEST['create_table'] == true) {
$tracking_set .= 'CREATE TABLE,';
}
if ($_REQUEST['drop_table'] == true) {
$tracking_set .= 'DROP TABLE,';
}
if ($_REQUEST['create_index'] == true) {
$tracking_set .= 'CREATE INDEX,';
}
if ($_REQUEST['drop_index'] == true) {
$tracking_set .= 'DROP INDEX,';
}
if ($_REQUEST['insert'] == true) {
$tracking_set .= 'INSERT,';
}
if ($_REQUEST['update'] == true) {
$tracking_set .= 'UPDATE,';
}
if ($_REQUEST['delete'] == true) {
$tracking_set .= 'DELETE,';
}
if ($_REQUEST['truncate'] == true) {
$tracking_set .= 'TRUNCATE,';
}
$tracking_set = rtrim($tracking_set, ',');
$versionCreated = PMA_Tracker::createVersion(
$GLOBALS['db'],
$GLOBALS['table'],
$_REQUEST['version'],
$tracking_set,
PMA_Table::isView($GLOBALS['db'], $GLOBALS['table'])
);
if ($versionCreated) {
$msg = PMA_Message::success(
sprintf(
__('Version %1$s was created, tracking for %2$s is active.'),
htmlspecialchars($_REQUEST['version']),
htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
)
);
$msg->display();
}
}
// Deactivate tracking
if (isset($_REQUEST['submit_deactivate_now'])) {
$deactivated = PMA_Tracker::deactivateTracking(
$GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version']
);
if ($deactivated) {
$msg = PMA_Message::success(
sprintf(
__('Tracking for %1$s was deactivated at version %2$s.'),
htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']),
htmlspecialchars($_REQUEST['version'])
)
);
$msg->display();
}
}
// Activate tracking
if (isset($_REQUEST['submit_activate_now'])) {
$activated = PMA_Tracker::activateTracking(
$GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version']
);
if ($activated) {
$msg = PMA_Message::success(
sprintf(
__('Tracking for %1$s was activated at version %2$s.'),
htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']),
htmlspecialchars($_REQUEST['version'])
)
);
$msg->display();
}
}
// Export as SQL execution
if (isset($_REQUEST['report_export']) && $_REQUEST['export_type'] == 'execution') {
foreach ($entries as $entry) {
$sql_result = PMA_DBI_query("/*NOTRACK*/\n" . $entry['statement']);
}
$msg = PMA_Message::success(__('SQL statements executed.'));
$msg->display();
}
// Export as SQL dump
if (isset($_REQUEST['report_export']) && $_REQUEST['export_type'] == 'sqldump') {
$new_query = "# "
. __('You can execute the dump by creating and using a temporary database. Please ensure that you have the privileges to do so.')
. "\n"
. "# " . __('Comment out these two lines if you do not need them.') . "\n"
. "\n"
. "CREATE database IF NOT EXISTS pma_temp_db; \n"
. "USE pma_temp_db; \n"
. "\n";
foreach ($entries as $entry) {
$new_query .= $entry['statement'];
}
$msg = PMA_Message::success(
__('SQL statements exported. Please copy the dump or execute it.')
);
$msg->display();
$db_temp = $db;
$table_temp = $table;
$db = $table = '';
include_once './libraries/sql_query_form.lib.php';
PMA_sqlQueryForm($new_query, 'sql');
$db = $db_temp;
$table = $table_temp;
}
/*
* Schema snapshot
*/
if (isset($_REQUEST['snapshot'])) {
echo '
';
$data = PMA_Tracker::getTrackedData(
$_REQUEST['db'], $_REQUEST['table'], $_REQUEST['version']
);
// Get first DROP TABLE/VIEW and CREATE TABLE/VIEW statements
$drop_create_statements = $data['ddlog'][0]['statement'];
if (strstr($data['ddlog'][0]['statement'], 'DROP TABLE')
|| strstr($data['ddlog'][0]['statement'], 'DROP VIEW')) {
$drop_create_statements .= $data['ddlog'][1]['statement'];
}
// Print SQL code
echo PMA_Util::getMessage(
sprintf(
__('Version %s snapshot (SQL code)'),
htmlspecialchars($_REQUEST['version'])
),
$drop_create_statements
);
// Unserialize snapshot
$temp = PMA_safeUnserialize($data['schema_snapshot']);
if ($temp === null) {
$temp = array('COLUMNS' => array(), 'INDEXES' => array());
}
$columns = $temp['COLUMNS'];
$indexes = $temp['INDEXES'];
echo '' . __('Structure') . '
';
echo '';
echo '';
echo '';
echo '' . __('Column') . ' | ';
echo '' . __('Type') . ' | ';
echo '' . __('Collation') . ' | ';
echo '' . __('Null') . ' | ';
echo '' . __('Default') . ' | ';
echo '' . __('Extra') . ' | ';
echo '' . __('Comment') . ' | ';
echo '
';
echo '';
echo '';
$style = 'odd';
foreach ($columns as $field_index => $field) {
echo '';
if ($field['Key'] == 'PRI') {
echo '' . htmlspecialchars($field['Field']) . ' | ';
} else {
echo '' . htmlspecialchars($field['Field']) . ' | ';
}
echo "\n";
echo '' . htmlspecialchars($field['Type']) . ' | ';
echo '' . htmlspecialchars($field['Collation']) . ' | ';
echo '' . (($field['Null'] == 'YES') ? __('Yes') : __('No')) . ' | ';
echo '';
if (isset($field['Default'])) {
$extracted_columnspec = PMA_Util::extractColumnSpec($field['Type']);
if ($extracted_columnspec['type'] == 'bit') {
// here, $field['Default'] contains something like b'010'
echo PMA_Util::convertBitDefaultValue($field['Default']);
} else {
echo htmlspecialchars($field['Default']);
}
} else {
if ($field['Null'] == 'YES') {
echo 'NULL';
} else {
echo '' . _pgettext('None for default', 'None') . '';
}
}
echo ' | ';
echo '' . htmlspecialchars($field['Extra']) . ' | ';
echo '' . htmlspecialchars($field['Comment']) . ' | ';
echo '
';
if ($style == 'even') {
$style = 'odd';
} else {
$style = 'even';
}
}
echo '';
echo '
';
if (count($indexes) > 0) {
echo '' . __('Indexes') . '
';
echo '';
echo '';
echo '';
echo '' . __('Keyname') . ' | ';
echo '' . __('Type') . ' | ';
echo '' . __('Unique') . ' | ';
echo '' . __('Packed') . ' | ';
echo '' . __('Column') . ' | ';
echo '' . __('Cardinality') . ' | ';
echo '' . __('Collation') . ' | ';
echo '' . __('Null') . ' | ';
echo '' . __('Comment') . ' | ';
echo '
';
echo '';
$style = 'odd';
foreach ($indexes as $indexes_index => $index) {
if ($index['Non_unique'] == 0) {
$str_unique = __('Yes');
} else {
$str_unique = __('No');
}
if ($index['Packed'] != '') {
$str_packed = __('Yes');
} else {
$str_packed = __('No');
}
echo '';
echo '' . htmlspecialchars($index['Key_name']) . ' | ';
echo '' . htmlspecialchars($index['Index_type']) . ' | ';
echo '' . $str_unique . ' | ';
echo '' . $str_packed . ' | ';
echo '' . htmlspecialchars($index['Column_name']) . ' | ';
echo '' . htmlspecialchars($index['Cardinality']) . ' | ';
echo '' . htmlspecialchars($index['Collation']) . ' | ';
echo '' . htmlspecialchars($index['Null']) . ' | ';
echo '' . htmlspecialchars($index['Comment']) . ' | ';
echo '
';
if ($style == 'even') {
$style = 'odd';
} else {
$style = 'even';
}
}
echo '';
echo '
';
} // endif
echo '
';
}
// end of snapshot report
/*
* Tracking report
*/
if (isset($_REQUEST['report'])
&& (isset($_REQUEST['delete_ddlog']) || isset($_REQUEST['delete_dmlog']))
) {
if (isset($_REQUEST['delete_ddlog'])) {
// Delete ddlog row data
$delete_id = $_REQUEST['delete_ddlog'];
// Only in case of valable id
if ($delete_id == (int)$delete_id) {
unset($data['ddlog'][$delete_id]);
$successfullyDeleted = PMA_Tracker::changeTrackingData(
$_REQUEST['db'], $_REQUEST['table'],
$_REQUEST['version'], 'DDL', $data['ddlog']
);
if ($successfullyDeleted) {
$msg = PMA_Message::success(
__('Tracking data definition successfully deleted')
);
} else {
$msg = PMA_Message::rawError(__('Query error'));
}
$msg->display();
}
}
if (isset($_REQUEST['delete_dmlog'])) {
// Delete dmlog row data
$delete_id = $_REQUEST['delete_dmlog'];
// Only in case of valable id
if ($delete_id == (int)$delete_id) {
unset($data['dmlog'][$delete_id]);
$successfullyDeleted = PMA_Tracker::changeTrackingData(
$_REQUEST['db'], $_REQUEST['table'],
$_REQUEST['version'], 'DML', $data['dmlog']
);
if ($successfullyDeleted) {
$msg = PMA_Message::success(
__('Tracking data manipulation successfully deleted')
);
} else {
$msg = PMA_Message::rawError(__('Query error'));
}
$msg->display();
}
}
}
if (isset($_REQUEST['report']) || isset($_REQUEST['report_export'])) {
echo '';
echo '' . __('Tracking statements') . ' '
. htmlspecialchars($data['tracking']) . '
';
echo '
';
echo '';
echo '';
echo '';
echo "
\n";
} // end of report
/*
* List selectable tables
*/
$sql_query = " SELECT DISTINCT db_name, table_name FROM " .
PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." .
PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
" WHERE db_name = '" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "' " .
" ORDER BY db_name, table_name";
$sql_result = PMA_queryAsControlUser($sql_query);
if (PMA_DBI_num_rows($sql_result) > 0) {
echo '';
}
echo '
';
/*
* List versions of current table
*/
$sql_query = " SELECT * FROM " .
PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." .
PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
" WHERE db_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['db']) . "' ".
" AND table_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['table']) ."' ".
" ORDER BY version DESC ";
$sql_result = PMA_queryAsControlUser($sql_query);
$last_version = 0;
$maxversion = PMA_DBI_fetch_array($sql_result);
$last_version = $maxversion['version'];
if ($last_version > 0) {
echo '';
echo '';
echo '';
echo '' . __('Database') . ' | ';
echo '' . __('Table') . ' | ';
echo '' . __('Version') . ' | ';
echo '' . __('Created') . ' | ';
echo '' . __('Updated') . ' | ';
echo '' . __('Status') . ' | ';
echo '' . __('Show') . ' | ';
echo '
';
echo '';
echo '';
$style = 'odd';
PMA_DBI_data_seek($sql_result, 0);
while ($version = PMA_DBI_fetch_array($sql_result)) {
if ($version['tracking_active'] == 1) {
$version_status = __('active');
} else {
$version_status = __('not active');
}
if ($version['version'] == $last_version) {
if ($version['tracking_active'] == 1) {
$tracking_active = true;
} else {
$tracking_active = false;
}
}
echo '';
echo '' . htmlspecialchars($version['db_name']) . ' | ';
echo '' . htmlspecialchars($version['table_name']) . ' | ';
echo '' . htmlspecialchars($version['version']) . ' | ';
echo '' . htmlspecialchars($version['date_created']) . ' | ';
echo '' . htmlspecialchars($version['date_updated']) . ' | ';
echo '' . $version_status . ' | ';
echo '' . __('Tracking report') . '';
echo '| ' . __('Structure snapshot') . '';
echo ' | ';
echo '
';
if ($style == 'even') {
$style = 'odd';
} else {
$style = 'even';
}
}
echo '';
echo '
';
if ($tracking_active) {
echo '';
echo '';
echo '
';
} else {
echo '';
echo '';
echo '
';
}
}
echo '';
echo '
';