You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.3 KiB
128 lines
3.3 KiB
<?php |
|
|
|
namespace App\Console\Commands; |
|
|
|
use Illuminate\Console\Command; |
|
use Illuminate\Support\Facades\DB; |
|
use Illuminate\Support\Facades\Schema; |
|
use Throwable; |
|
|
|
class ImportSqliteAppDataCommand extends Command |
|
{ |
|
protected $signature = 'app:import-sqlite'; |
|
|
|
protected $description = 'One-time import of app metadata from legacy SQLite to PostgreSQL'; |
|
|
|
/** @var list<string> */ |
|
private const TABLES = [ |
|
'users', |
|
'app_settings', |
|
'email_templates', |
|
'database_connections', |
|
'ldap_user_meta', |
|
'ldap_group_meta', |
|
'api_tokens', |
|
'oauth_auth_codes', |
|
'oauth_access_tokens', |
|
'oauth_refresh_tokens', |
|
'oauth_clients', |
|
'oauth_device_codes', |
|
]; |
|
|
|
public function handle(): int |
|
{ |
|
if (env('DB_CONNECTION') !== 'pgsql') { |
|
return self::SUCCESS; |
|
} |
|
|
|
$marker = storage_path('framework/.app_pg_imported'); |
|
|
|
if (is_file($marker)) { |
|
return self::SUCCESS; |
|
} |
|
|
|
$sqlitePath = database_path('database.sqlite'); |
|
|
|
if (! is_file($sqlitePath)) { |
|
@file_put_contents($marker, now()->toIso8601String()); |
|
|
|
return self::SUCCESS; |
|
} |
|
|
|
config(['database.connections.sqlite_legacy.database' => $sqlitePath]); |
|
|
|
try { |
|
if (! Schema::connection('sqlite_legacy')->hasTable('app_settings')) { |
|
@file_put_contents($marker, now()->toIso8601String()); |
|
|
|
return self::SUCCESS; |
|
} |
|
|
|
foreach (self::TABLES as $table) { |
|
$this->importTable($table); |
|
} |
|
|
|
@file_put_contents($marker, now()->toIso8601String()); |
|
$this->info('Imported app metadata from SQLite to PostgreSQL.'); |
|
|
|
return self::SUCCESS; |
|
} catch (Throwable $e) { |
|
$this->warn('SQLite import failed: ' . $e->getMessage()); |
|
|
|
return self::FAILURE; |
|
} |
|
} |
|
|
|
private function importTable(string $table): void |
|
{ |
|
if (! Schema::connection('sqlite_legacy')->hasTable($table)) { |
|
return; |
|
} |
|
|
|
if (! Schema::hasTable($table)) { |
|
return; |
|
} |
|
|
|
$rows = DB::connection('sqlite_legacy')->table($table)->get(); |
|
|
|
if ($rows->isEmpty()) { |
|
return; |
|
} |
|
|
|
$mergeTables = [ |
|
'app_settings' => 'key', |
|
'email_templates' => 'slug', |
|
'database_connections' => 'id', |
|
'ldap_user_meta' => 'username', |
|
'ldap_group_meta' => 'group_key', |
|
'api_tokens' => 'id', |
|
'oauth_clients' => 'id', |
|
]; |
|
|
|
if (isset($mergeTables[$table])) { |
|
$uniqueKey = $mergeTables[$table]; |
|
|
|
foreach ($rows as $row) { |
|
$data = (array) $row; |
|
DB::table($table)->updateOrInsert( |
|
[$uniqueKey => $data[$uniqueKey]], |
|
$data |
|
); |
|
} |
|
|
|
$this->line(" merged {$table}: {$rows->count()} row(s)"); |
|
|
|
return; |
|
} |
|
|
|
if (DB::table($table)->count() > 0) { |
|
return; |
|
} |
|
|
|
foreach ($rows as $row) { |
|
DB::table($table)->insert((array) $row); |
|
} |
|
|
|
$this->line(" imported {$table}: {$rows->count()} row(s)"); |
|
} |
|
}
|
|
|