Created
June 4, 2025 08:21
-
-
Save NeilMasters/ac3aa70613c244c8e61784189ad07aa8 to your computer and use it in GitHub Desktop.
Locate all datetime fields that should be date fields.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This fairly basic script will connect to a MySQL database and check all timestamp fields | |
* for zero time values. It will log the results to the console. | |
* | |
* The purpose of this is to highlight fields that should be a DATE field instead of a | |
* DATETIME field. | |
* | |
* usage: | |
* php check-for-zero-time-values.php <host> <port> <schema> <user> <password> [<exceptions>] | |
*/ | |
$host = $argv[1]; | |
$port = $argv[2]; | |
$schema = $argv[3]; | |
$user = $argv[4]; | |
$password = $argv[5]; | |
$exceptions = explode(',', $argv[6] ?? ''); | |
$log = function(string $level, string $message): void | |
{ | |
echo sprintf("[%s] %s: %s\n", date('Y-m-d H:i:s'), strtoupper($level), $message); | |
}; | |
$initConnection = function() use ($log, $host, $port, $schema, $user, $password): \PDO | |
{ | |
$log( | |
'info', | |
sprintf( | |
'Attempting to create database connection to host %s on port %s for database %s', | |
$host, | |
$port, | |
$schema | |
) | |
); | |
try { | |
return new \PDO( | |
sprintf( | |
"mysql:host=%s;port=%s;dbname=%s;", | |
$host, | |
$port, | |
$schema | |
), | |
$user, | |
$password | |
); | |
} catch (\PDOException $e) { | |
$log('error', 'Database connection failed: ' . $e->getMessage()); | |
} | |
}; | |
$connection = $initConnection(); | |
$getAllTimestampFields = function() use ($connection, $schema): array | |
{ | |
$query = <<<SQL | |
select | |
col.table_schema as schemaName, | |
col.table_name as tableName, | |
col.column_name as columnName | |
from information_schema.columns col | |
join information_schema.tables tab on | |
tab.table_schema = col.table_schema | |
and tab.table_name = col.table_name | |
and tab.table_type = 'BASE TABLE' | |
where | |
col.data_type in ('date', 'datetime', 'timestamp') | |
and | |
col.table_schema not in ('information_schema', 'sys', 'performance_schema', 'mysql') | |
and | |
col.table_schema = '$schema' | |
order by | |
col.table_schema, col.table_name, col.ordinal_position; | |
SQL; | |
return $connection->query($query)->fetchAll(\PDO::FETCH_ASSOC); | |
}; | |
$checkForZeroTimeValues = function(array $tablesAndFields) use($connection, $log, $exceptions): array | |
{ | |
$columnsWithOnlyZeroValues = []; | |
foreach ($tablesAndFields as $index => $tableField) { | |
$columnName = $tableField['columnName']; | |
$tableName = $tableField['tableName']; | |
if (in_array($columnName, $exceptions)) { | |
$log( | |
'info', | |
sprintf( | |
'%s of %s Skipping column %s in table %s as it is a known timestamp field', | |
$index + 1, | |
count($tablesAndFields), | |
$columnName, | |
$tableName | |
) | |
); | |
continue; | |
} | |
$log( | |
'info', | |
sprintf( | |
'%s of %s Checking table %s for column %s for only zero time values', | |
$index + 1, | |
count($tablesAndFields), | |
$tableName, | |
$columnName | |
) | |
); | |
$zeroTimeValuesQuery = sprintf( | |
"select count(*) from $tableName where time(%s) = '00:00:00' and %s is not null", | |
$columnName, | |
$columnName | |
); | |
$numberOfRowsWithZeroValues = $connection->query($zeroTimeValuesQuery)->fetchColumn(0); | |
$rowCountQuery = sprintf("select count(*) from %s", $tableName); | |
$rowCount = $connection->query($rowCountQuery)->fetchColumn(0); | |
if ($rowCount === $numberOfRowsWithZeroValues && $rowCount !== 0) { | |
$log( | |
'warn', | |
sprintf( | |
'Table %s has only zero time values in column %s', | |
$tableName, | |
$columnName | |
) | |
); | |
$columnsWithOnlyZeroValues[$tableName][] = $columnName; | |
} | |
} | |
return $columnsWithOnlyZeroValues; | |
}; | |
$fieldsToInspectForZerodTimes = $getAllTimestampFields(); | |
$tablesThatHaveZeroValues = $checkForZeroTimeValues($fieldsToInspectForZerodTimes); | |
var_dump($tablesThatHaveZeroValues); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment