Skip to content

Commit 03b8efd

Browse files
Merge pull request #18320 from kamil-tekiela/Refactor-Tracker
Move some methods from Tracker to Tracking
2 parents 6564741 + 1e307a0 commit 03b8efd

8 files changed

Lines changed: 467 additions & 530 deletions

File tree

libraries/classes/Controllers/Database/TrackingController.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use PhpMyAdmin\Query\Utilities;
1414
use PhpMyAdmin\ResponseRenderer;
1515
use PhpMyAdmin\Template;
16-
use PhpMyAdmin\Tracking\Tracker;
1716
use PhpMyAdmin\Tracking\Tracking;
1817
use PhpMyAdmin\Url;
1918
use PhpMyAdmin\Util;
@@ -61,7 +60,7 @@ public function __invoke(ServerRequest $request): void
6160
$isSystemSchema = Utilities::isSystemSchema($GLOBALS['db']);
6261

6362
if ($request->hasBodyParam('delete_tracking') && $request->hasBodyParam('table')) {
64-
Tracker::deleteTracking($GLOBALS['db'], $request->getParsedBodyParam('table'));
63+
$this->tracking->deleteTracking($GLOBALS['db'], $request->getParsedBodyParam('table'));
6564
echo Message::success(
6665
__('Tracking data deleted successfully.'),
6766
)->getDisplay();
@@ -84,7 +83,7 @@ public function __invoke(ServerRequest $request): void
8483
if (! empty($selectedTable)) {
8584
if ($request->getParsedBodyParam('submit_mult') === 'delete_tracking') {
8685
foreach ($selectedTable as $table) {
87-
Tracker::deleteTracking($GLOBALS['db'], $table);
86+
$this->tracking->deleteTracking($GLOBALS['db'], $table);
8887
}
8988

9089
echo Message::success(
@@ -111,7 +110,7 @@ public function __invoke(ServerRequest $request): void
111110
}
112111

113112
// Get tracked data about the database
114-
$trackedData = Tracker::getTrackedData($GLOBALS['db'], '', '1');
113+
$trackedData = $this->tracking->getTrackedData($GLOBALS['db'], '', '1');
115114

116115
// No tables present and no log exist
117116
if ($numTables == 0 && count($trackedData['ddlog']) === 0) {

libraries/classes/Controllers/Table/TrackingController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function __invoke(ServerRequest $request): void
105105

106106
// Init vars for tracking report
107107
if ($report || $reportExport !== null) {
108-
$trackedData = Tracker::getTrackedData($GLOBALS['db'], $GLOBALS['table'], $versionParam);
108+
$trackedData = $this->tracking->getTrackedData($GLOBALS['db'], $GLOBALS['table'], $versionParam);
109109

110110
$dateFrom = $this->validateDateTimeParam(
111111
$request->getParsedBodyParam('date_from', $trackedData['date_from']),

libraries/classes/Tracking/Tracker.php

Lines changed: 0 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,12 @@
2727

2828
use function array_values;
2929
use function count;
30-
use function explode;
3130
use function intval;
32-
use function is_array;
33-
use function mb_strpos;
3431
use function mb_strstr;
35-
use function mb_substr;
3632
use function preg_quote;
3733
use function preg_replace;
38-
use function rtrim;
3934
use function serialize;
4035
use function sprintf;
41-
use function str_replace;
42-
use function strtotime;
4336
use function substr;
4437
use function trim;
4538

@@ -90,30 +83,6 @@ public static function isActive(): bool
9083
return $relationParameters->trackingFeature !== null;
9184
}
9285

93-
/**
94-
* Parses the name of a table from a SQL statement substring.
95-
*
96-
* @param string $string part of SQL statement
97-
*
98-
* @return string the name of table
99-
*/
100-
protected static function getTableName(string $string): string
101-
{
102-
if (mb_strstr($string, '.')) {
103-
$temp = explode('.', $string);
104-
$tableName = $temp[1];
105-
} else {
106-
$tableName = $string;
107-
}
108-
109-
$str = explode("\n", $tableName);
110-
$tableName = $str[0];
111-
112-
$tableName = str_replace([';', '`'], '', $tableName);
113-
114-
return trim($tableName);
115-
}
116-
11786
/**
11887
* Gets the tracking status of a table, is it active or disabled ?
11988
*
@@ -267,35 +236,6 @@ public static function createVersion(
267236
return self::deactivateTracking($dbName, $tableName, (string) ((int) $version - 1));
268237
}
269238

270-
/**
271-
* Removes all tracking data for a table or a version of a table
272-
*
273-
* @param string $dbName name of database
274-
* @param string $tableName name of table
275-
* @param string $version version
276-
*/
277-
public static function deleteTracking(string $dbName, string $tableName, string $version = ''): bool
278-
{
279-
$relation = new Relation($GLOBALS['dbi']);
280-
$trackingFeature = $relation->getRelationParameters()->trackingFeature;
281-
if ($trackingFeature === null) {
282-
return false;
283-
}
284-
285-
$sqlQuery = sprintf(
286-
'/*NOTRACK*/' . "\n" . 'DELETE FROM %s.%s WHERE `db_name` = %s AND `table_name` = %s',
287-
Util::backquote($trackingFeature->database),
288-
Util::backquote($trackingFeature->tracking),
289-
$GLOBALS['dbi']->quoteString($dbName, Connection::TYPE_CONTROL),
290-
$GLOBALS['dbi']->quoteString($tableName, Connection::TYPE_CONTROL),
291-
);
292-
if ($version) {
293-
$sqlQuery .= ' AND `version` = ' . $GLOBALS['dbi']->quoteString($version, Connection::TYPE_CONTROL);
294-
}
295-
296-
return (bool) $GLOBALS['dbi']->queryAsControlUser($sqlQuery);
297-
}
298-
299239
/**
300240
* Creates tracking version of a database
301241
* (in other words: create a job to track future changes on the database).
@@ -387,64 +327,6 @@ private static function changeTracking(
387327
return (bool) $GLOBALS['dbi']->queryAsControlUser($sqlQuery);
388328
}
389329

390-
/**
391-
* Changes tracking data of a table.
392-
*
393-
* @param string $dbName name of database
394-
* @param string $tableName name of table
395-
* @param string $version version
396-
* @param string $type type of data(DDL || DML)
397-
* @param string|mixed[] $newData the new tracking data
398-
*/
399-
public static function changeTrackingData(
400-
string $dbName,
401-
string $tableName,
402-
string $version,
403-
string $type,
404-
string|array $newData,
405-
): bool {
406-
$relation = new Relation($GLOBALS['dbi']);
407-
408-
if ($type === 'DDL') {
409-
$saveTo = 'schema_sql';
410-
} elseif ($type === 'DML') {
411-
$saveTo = 'data_sql';
412-
} else {
413-
return false;
414-
}
415-
416-
$date = Util::date('Y-m-d H:i:s');
417-
418-
$newDataProcessed = '';
419-
if (is_array($newData)) {
420-
foreach ($newData as $data) {
421-
$newDataProcessed .= '# log ' . $date . ' ' . $data['username'] . $data['statement'] . "\n";
422-
}
423-
} else {
424-
$newDataProcessed = $newData;
425-
}
426-
427-
$trackingFeature = $relation->getRelationParameters()->trackingFeature;
428-
if ($trackingFeature === null) {
429-
return false;
430-
}
431-
432-
$sqlQuery = sprintf(
433-
'UPDATE %s.%s SET `%s` = %s WHERE `db_name` = %s AND `table_name` = %s AND `version` = %s',
434-
Util::backquote($trackingFeature->database),
435-
Util::backquote($trackingFeature->tracking),
436-
$saveTo,
437-
$GLOBALS['dbi']->quoteString($newDataProcessed, Connection::TYPE_CONTROL),
438-
$GLOBALS['dbi']->quoteString($dbName, Connection::TYPE_CONTROL),
439-
$GLOBALS['dbi']->quoteString($tableName, Connection::TYPE_CONTROL),
440-
$GLOBALS['dbi']->quoteString($version, Connection::TYPE_CONTROL),
441-
);
442-
443-
$result = $GLOBALS['dbi']->queryAsControlUser($sqlQuery);
444-
445-
return (bool) $result;
446-
}
447-
448330
/**
449331
* Activates tracking of a table.
450332
*
@@ -510,139 +392,6 @@ private static function getVersion(string $dbname, string $tablename, string|nul
510392
return intval($row[0] ?? -1);
511393
}
512394

513-
/**
514-
* Gets the record of a tracking job.
515-
*
516-
* @param string $dbname name of database
517-
* @param string $tablename name of table
518-
* @param string $version version number
519-
*
520-
* @return array<string, array<int, array<string, string>>|string|null>
521-
* @psalm-return array{
522-
* date_from: string,
523-
* date_to: string,
524-
* ddlog: list<array{date: string, username: string, statement: string}>,
525-
* dmlog: list<array{date: string, username: string, statement: string}>,
526-
* tracking: string|null,
527-
* schema_snapshot: string|null
528-
* }|array<never, never>
529-
*/
530-
public static function getTrackedData(string $dbname, string $tablename, string $version): array
531-
{
532-
$relation = new Relation($GLOBALS['dbi']);
533-
$trackingFeature = $relation->getRelationParameters()->trackingFeature;
534-
if ($trackingFeature === null) {
535-
return [];
536-
}
537-
538-
$sqlQuery = sprintf(
539-
'SELECT * FROM %s.%s WHERE `db_name` = %s',
540-
Util::backquote($trackingFeature->database),
541-
Util::backquote($trackingFeature->tracking),
542-
$GLOBALS['dbi']->quoteString($dbname, Connection::TYPE_CONTROL),
543-
);
544-
if ($tablename !== '') {
545-
$sqlQuery .= ' AND `table_name` = '
546-
. $GLOBALS['dbi']->quoteString($tablename, Connection::TYPE_CONTROL) . ' ';
547-
}
548-
549-
$sqlQuery .= ' AND `version` = ' . $GLOBALS['dbi']->quoteString($version, Connection::TYPE_CONTROL)
550-
. ' ORDER BY `version` DESC LIMIT 1';
551-
552-
$mixed = $GLOBALS['dbi']->queryAsControlUser($sqlQuery)->fetchAssoc();
553-
554-
// PHP 7.4 fix for accessing array offset on null
555-
if ($mixed === []) {
556-
$mixed = ['schema_sql' => null, 'data_sql' => null, 'tracking' => null, 'schema_snapshot' => null];
557-
}
558-
559-
// Parse log
560-
$logSchemaEntries = explode('# log ', (string) $mixed['schema_sql']);
561-
$logDataEntries = explode('# log ', (string) $mixed['data_sql']);
562-
563-
$ddlDateFrom = $date = Util::date('Y-m-d H:i:s');
564-
565-
$ddlog = [];
566-
$firstIteration = true;
567-
568-
// Iterate tracked data definition statements
569-
// For each log entry we want to get date, username and statement
570-
foreach ($logSchemaEntries as $logEntry) {
571-
if (trim($logEntry) == '') {
572-
continue;
573-
}
574-
575-
$date = mb_substr($logEntry, 0, 19);
576-
$username = mb_substr(
577-
$logEntry,
578-
20,
579-
mb_strpos($logEntry, "\n") - 20,
580-
);
581-
if ($firstIteration) {
582-
$ddlDateFrom = $date;
583-
$firstIteration = false;
584-
}
585-
586-
$statement = rtrim((string) mb_strstr($logEntry, "\n"));
587-
588-
$ddlog[] = ['date' => $date, 'username' => $username, 'statement' => $statement];
589-
}
590-
591-
$dateFrom = $ddlDateFrom;
592-
$ddlDateTo = $date;
593-
594-
$dmlDateFrom = $dateFrom;
595-
596-
$dmlog = [];
597-
$firstIteration = true;
598-
599-
// Iterate tracked data manipulation statements
600-
// For each log entry we want to get date, username and statement
601-
foreach ($logDataEntries as $logEntry) {
602-
if (trim($logEntry) == '') {
603-
continue;
604-
}
605-
606-
$date = mb_substr($logEntry, 0, 19);
607-
$username = mb_substr(
608-
$logEntry,
609-
20,
610-
mb_strpos($logEntry, "\n") - 20,
611-
);
612-
if ($firstIteration) {
613-
$dmlDateFrom = $date;
614-
$firstIteration = false;
615-
}
616-
617-
$statement = rtrim((string) mb_strstr($logEntry, "\n"));
618-
619-
$dmlog[] = ['date' => $date, 'username' => $username, 'statement' => $statement];
620-
}
621-
622-
$dmlDateTo = $date;
623-
624-
// Define begin and end of date range for both logs
625-
$data = [];
626-
if (strtotime($ddlDateFrom) <= strtotime($dmlDateFrom)) {
627-
$data['date_from'] = $ddlDateFrom;
628-
} else {
629-
$data['date_from'] = $dmlDateFrom;
630-
}
631-
632-
if (strtotime($ddlDateTo) >= strtotime($dmlDateTo)) {
633-
$data['date_to'] = $ddlDateTo;
634-
} else {
635-
$data['date_to'] = $dmlDateTo;
636-
}
637-
638-
$data['ddlog'] = $ddlog;
639-
$data['dmlog'] = $dmlog;
640-
$data['tracking'] = $mixed['tracking'];
641-
$data['schema_snapshot'] = $mixed['schema_snapshot'];
642-
643-
return $data;
644-
}
645-
646395
/**
647396
* Parses a query. Gets
648397
* - statement identifier (UPDATE, ALTER TABLE, ...)

0 commit comments

Comments
 (0)