56 lines
2.4 KiB
PHP
56 lines
2.4 KiB
PHP
<?php
|
|
|
|
function mysqlMirrorConnection(): PDO {
|
|
$dsn = trim((string)getConfigVal('database.mysql.dsn', ''));
|
|
if ($dsn === '') throw new RuntimeException('MySQL DSN is missing');
|
|
$pdo = new PDO(
|
|
$dsn,
|
|
(string)getConfigVal('database.mysql.username', ''),
|
|
(string)getConfigVal('database.mysql.password', ''),
|
|
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
|
);
|
|
$pdo->exec("CREATE TABLE IF NOT EXISTS sqlite_mirror_rows (
|
|
source_db VARCHAR(255) NOT NULL,
|
|
table_name VARCHAR(128) NOT NULL,
|
|
row_key VARCHAR(255) NOT NULL,
|
|
row_json LONGTEXT NOT NULL,
|
|
synced_at BIGINT NOT NULL,
|
|
PRIMARY KEY(source_db,table_name,row_key)
|
|
)");
|
|
return $pdo;
|
|
}
|
|
|
|
function mirrorAllSQLiteDatabases(): array {
|
|
$main = storagePath((string)getConfigVal('database.main_db', 'db/chat.sqlite'));
|
|
$files = is_file($main) ? [$main] : [];
|
|
$archiveRoot = storagePath((string)getConfigVal('archive.archive_dir', 'archive'));
|
|
foreach (glob($archiveRoot . '/*/*/*.sqlite') ?: [] as $file) $files[] = $file;
|
|
$mysql = mysqlMirrorConnection();
|
|
$upsert = $mysql->prepare("INSERT INTO sqlite_mirror_rows
|
|
(source_db,table_name,row_key,row_json,synced_at) VALUES (?,?,?,?,?)
|
|
ON DUPLICATE KEY UPDATE row_json=VALUES(row_json),synced_at=VALUES(synced_at)");
|
|
$count = 0;
|
|
foreach ($files as $file) {
|
|
$sqlite = new PDO('sqlite:' . $file);
|
|
$sqlite->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|
$tables = $sqlite->query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
|
|
->fetchAll(PDO::FETCH_COLUMN);
|
|
foreach ($tables as $table) {
|
|
$quoted = '"' . str_replace('"', '""', $table) . '"';
|
|
foreach ($sqlite->query("SELECT rowid AS _mirror_rowid,* FROM $quoted") as $row) {
|
|
$key = (string)($row['id'] ?? $row['_mirror_rowid']);
|
|
unset($row['_mirror_rowid']);
|
|
$source = str_starts_with($file, ROOT_DIR . '/')
|
|
? substr($file, strlen(ROOT_DIR) + 1)
|
|
: $file;
|
|
$upsert->execute([
|
|
$source, $table, $key,
|
|
json_encode($row, JSON_UNESCAPED_SLASHES), time(),
|
|
]);
|
|
$count++;
|
|
}
|
|
}
|
|
}
|
|
return ['databases' => count($files), 'rows' => $count];
|
|
}
|