Files
CLOAK/lib/Cloak/VisitorLogSchema.php
T

98 lines
3.9 KiB
PHP
Executable File

<?php
/**
* visitor_logs 表结构升级(新增请求头与判定时长字段)
*/
class VisitorLogSchema
{
/** @var bool */
private static $ensured = false;
/** @var bool */
private static $indexesEnsured = false;
/**
* @param mysqli $conn
*/
public static function ensureColumns($conn)
{
if (self::$ensured) {
return;
}
$columns = [
'user_agent' => "ALTER TABLE `visitor_logs` ADD COLUMN `user_agent` TEXT NULL COMMENT 'User-Agent 完整值' AFTER `language`",
'http_referer' => "ALTER TABLE `visitor_logs` ADD COLUMN `http_referer` TEXT NULL COMMENT 'HTTP Referer 完整值' AFTER `user_agent`",
'accept_language_raw' => "ALTER TABLE `visitor_logs` ADD COLUMN `accept_language_raw` TEXT NULL COMMENT 'Accept-Language 完整值' AFTER `http_referer`",
'judge_timing' => "ALTER TABLE `visitor_logs` ADD COLUMN `judge_timing` TEXT NULL COMMENT '判定用时 JSON' AFTER `accept_language_raw`",
'fp_hdata' => "ALTER TABLE `visitor_logs` ADD COLUMN `fp_hdata` TEXT NULL COMMENT '指纹 hdata 解码 JSON' AFTER `judge_timing`",
'api_by_request' => "ALTER TABLE `visitor_logs` ADD COLUMN `api_by_request` TEXT NULL COMMENT 'byApi 请求参数 JSON' AFTER `fp_hdata`",
'api_by_response' => "ALTER TABLE `visitor_logs` ADD COLUMN `api_by_response` TEXT NULL COMMENT 'byApi 响应 JSON' AFTER `api_by_request`",
'api_risk_request' => "ALTER TABLE `visitor_logs` ADD COLUMN `api_risk_request` TEXT NULL COMMENT 'byApiRisk 请求参数 JSON' AFTER `api_by_response`",
'api_risk_response' => "ALTER TABLE `visitor_logs` ADD COLUMN `api_risk_response` TEXT NULL COMMENT 'byApiRisk 响应 JSON' AFTER `api_risk_request`",
];
foreach ($columns as $name => $ddl) {
if (!self::columnExists($conn, 'visitor_logs', $name)) {
@$conn->query($ddl);
}
}
self::$ensured = true;
}
/**
* @param mysqli $conn
*/
public static function ensureIndexes($conn)
{
if (self::$indexesEnsured) {
return;
}
$indexes = [
'idx_visit_date' => 'ALTER TABLE `visitor_logs` ADD INDEX `idx_visit_date` (`visit_date`)',
'idx_result' => 'ALTER TABLE `visitor_logs` ADD INDEX `idx_result` (`result`)',
'idx_domain_date' => 'ALTER TABLE `visitor_logs` ADD INDEX `idx_domain_date` (`domain`, `visit_date`)',
'idx_country' => 'ALTER TABLE `visitor_logs` ADD INDEX `idx_country` (`country`)',
];
foreach ($indexes as $name => $ddl) {
if (!self::indexExists($conn, 'visitor_logs', $name)) {
@$conn->query($ddl);
}
}
self::$indexesEnsured = true;
}
/**
* @param mysqli $conn
* @param string $table
* @param string $indexName
*/
private static function indexExists($conn, $table, $indexName)
{
$tableEsc = cloak_db_escape($conn, $table);
$indexEsc = cloak_db_escape($conn, $indexName);
$sql = "SHOW INDEX FROM `{$tableEsc}` WHERE Key_name = '{$indexEsc}'";
if ($res = $conn->query($sql)) {
$exists = $res->num_rows > 0;
$res->free();
return $exists;
}
return false;
}
/**
* @param mysqli $conn
* @param string $table
* @param string $column
*/
private static function columnExists($conn, $table, $column)
{
$tableEsc = cloak_db_escape($conn, $table);
$columnEsc = cloak_db_escape($conn, $column);
$sql = "SHOW COLUMNS FROM `{$tableEsc}` LIKE '{$columnEsc}'";
if ($res = $conn->query($sql)) {
$exists = $res->num_rows > 0;
$res->free();
return $exists;
}
return false;
}
}