mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-14 08:06:47 +02:00
191 lines
6.1 KiB
PHP
191 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace App\Database;
|
|
|
|
use PDO;
|
|
use PDOException;
|
|
use Illuminate\Database\Capsule\Manager as Capsule;
|
|
|
|
class Database
|
|
{
|
|
private static ?Capsule $capsule = null;
|
|
private static array $config = [];
|
|
|
|
public static function setConfig(array $config): void
|
|
{
|
|
self::$config = $config;
|
|
}
|
|
|
|
public static function getInstance(): PDO
|
|
{
|
|
if (self::$capsule === null) {
|
|
self::connect();
|
|
}
|
|
|
|
return self::$capsule->getConnection()->getPdo();
|
|
}
|
|
|
|
public static function getCapsule(): Capsule
|
|
{
|
|
if (self::$capsule === null) {
|
|
self::connect();
|
|
}
|
|
|
|
return self::$capsule;
|
|
}
|
|
|
|
private static function connect(): void
|
|
{
|
|
self::$capsule = new Capsule();
|
|
|
|
self::$capsule->addConnection([
|
|
'driver' => self::$config['driver'] ?? 'sqlite',
|
|
'host' => self::$config['host'] ?? '127.0.0.1',
|
|
'port' => self::$config['port'] ?? 3306,
|
|
'database' => self::$config['database'] ?? '',
|
|
'username' => self::$config['username'] ?? '',
|
|
'password' => self::$config['password'] ?? '',
|
|
'charset' => self::$config['charset'] ?? 'utf8mb4',
|
|
'prefix' => self::$config['prefix'] ?? '',
|
|
'schema' => self::$config['schema'] ?? 'public',
|
|
]);
|
|
|
|
// Set as global for Eloquent
|
|
self::$capsule->setAsGlobal();
|
|
|
|
// Boot Eloquent (for schema operations)
|
|
self::$capsule->bootEloquent();
|
|
|
|
// Set up facade application
|
|
if (!self::$capsule->getContainer()->bound('app')) {
|
|
self::$capsule->getContainer()->instance('app', self::$capsule->getContainer());
|
|
}
|
|
}
|
|
|
|
public static function migrate(): void
|
|
{
|
|
$capsule = self::getCapsule();
|
|
|
|
// Create migrations table if it doesn't exist
|
|
if (!$capsule->schema()->hasTable('migrations')) {
|
|
$capsule->schema()->create('migrations', function ($table) {
|
|
$table->unsignedInteger('id', true); // Primary key with AUTO_INCREMENT
|
|
$table->string('migration');
|
|
$table->integer('batch');
|
|
$table->timestamps();
|
|
});
|
|
}
|
|
|
|
// Get list of migration files
|
|
$migrationFiles = glob(__DIR__ . '/../../database/migrations/*.php');
|
|
|
|
foreach ($migrationFiles as $file) {
|
|
$migrationName = basename($file, '.php');
|
|
|
|
// Check if migration has already been run
|
|
$ran = $capsule->table('migrations')->where('migration', $migrationName)->exists();
|
|
|
|
if ($ran) {
|
|
echo "Migration {$migrationName} already run. Skipping.\n";
|
|
continue;
|
|
}
|
|
|
|
// Run the migration
|
|
echo "Running migration {$migrationName}\n";
|
|
|
|
// Include the migration file to make the class available
|
|
require_once $file;
|
|
|
|
$className = self::getMigrationClassName($file);
|
|
$pdo = self::getInstance();
|
|
$migration = new $className($pdo);
|
|
$migration->up();
|
|
|
|
// Record the migration
|
|
$capsule->table('migrations')->insert([
|
|
'migration' => $migrationName,
|
|
'batch' => 1
|
|
]);
|
|
}
|
|
}
|
|
|
|
private static function getMigrationClassName(string $file): string
|
|
{
|
|
$content = file_get_contents($file);
|
|
|
|
// Extract namespace and class name from PHP file
|
|
$namespace = '';
|
|
if (preg_match('/namespace\s+([^;]+);/', $content, $namespaceMatches)) {
|
|
$namespace = $namespaceMatches[1] . '\\';
|
|
}
|
|
|
|
// Extract class name from PHP file
|
|
if (preg_match('/class\s+(\w+)\s+extends\s+Migration/', $content, $matches)) {
|
|
return $namespace . $matches[1];
|
|
}
|
|
|
|
// Fallback: convert filename to class name
|
|
$filename = basename($file, '.php');
|
|
return $namespace . str_replace(' ', '', ucwords(str_replace('_', ' ', $filename)));
|
|
}
|
|
|
|
public static function seed(): void
|
|
{
|
|
$pdo = self::getInstance();
|
|
|
|
// Seed media types
|
|
$mediaTypes = [
|
|
['name' => 'games', 'display_name' => 'Games', 'icon' => 'game-controller'],
|
|
['name' => 'movies', 'display_name' => 'Movies', 'icon' => 'film'],
|
|
['name' => 'tv_shows', 'display_name' => 'TV Shows', 'icon' => 'tv'],
|
|
['name' => 'music', 'display_name' => 'Music', 'icon' => 'musical-notes']
|
|
];
|
|
|
|
foreach ($mediaTypes as $type) {
|
|
$pdo->prepare("INSERT IGNORE INTO media_types (name, display_name, icon) VALUES (?, ?, ?)")
|
|
->execute([$type['name'], $type['display_name'], $type['icon']]);
|
|
}
|
|
|
|
// Seed sources
|
|
$sources = [
|
|
['name' => 'steam', 'display_name' => 'Steam', 'api_url' => null, 'api_key' => null],
|
|
['name' => 'jellyfin', 'display_name' => 'Jellyfin', 'api_url' => null, 'api_key' => null],
|
|
['name' => 'stash', 'display_name' => 'Stash', 'api_url' => null, 'api_key' => null],
|
|
['name' => 'xbvr', 'display_name' => 'XBVR', 'api_url' => null, 'api_key' => null]
|
|
];
|
|
|
|
foreach ($sources as $source) {
|
|
$pdo->prepare("INSERT IGNORE INTO sources (name, display_name, api_url, api_key) VALUES (?, ?, ?, ?)")
|
|
->execute([$source['name'], $source['display_name'], $source['api_url'], $source['api_key']]);
|
|
}
|
|
}
|
|
|
|
public static function reset(): void
|
|
{
|
|
$pdo = self::getInstance();
|
|
|
|
// Drop all tables (in reverse order due to foreign keys)
|
|
$tables = [
|
|
'sync_logs',
|
|
'music_tracks',
|
|
'music_albums',
|
|
'music_artists',
|
|
'tv_episodes',
|
|
'tv_shows',
|
|
'movies',
|
|
'games',
|
|
'sources',
|
|
'media_types',
|
|
'migrations'
|
|
];
|
|
|
|
foreach ($tables as $table) {
|
|
try {
|
|
$pdo->exec("DROP TABLE IF EXISTS {$table}");
|
|
} catch (PDOException $e) {
|
|
// Ignore errors if table doesn't exist
|
|
}
|
|
}
|
|
}
|
|
}
|