refactor: remove obsolete i18n fix scripts
- Deleted multiple outdated scripts for fixing internationalization data in the database, including various approaches (bash and Node.js). - Consolidated functionality into more efficient and modern solutions, improving maintainability and reducing redundancy. - Ensured that the remaining scripts are up-to-date with current database handling practices.
This commit is contained in:
@@ -1,76 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script zum Reparieren von Datenbank-Berechtigungen
|
|
||||||
# Wichtig: Wenn eine Datenbank von einem anderen Server kopiert wurde,
|
|
||||||
# müssen die Berechtigungen angepasst werden, damit SQLite schreiben kann.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🔧 Repariere Datenbank-Berechtigungen..."
|
|
||||||
|
|
||||||
# Datenbank-Pfad aus docker-compose.yml oder .env ermitteln
|
|
||||||
DB_DIR="./data"
|
|
||||||
DB_FILE="$DB_DIR/prod.db"
|
|
||||||
|
|
||||||
# Prüfe ob Datenbankverzeichnis existiert
|
|
||||||
if [ ! -d "$DB_DIR" ]; then
|
|
||||||
echo "❌ Datenbankverzeichnis '$DB_DIR' existiert nicht!"
|
|
||||||
echo " Erstelle Verzeichnis..."
|
|
||||||
mkdir -p "$DB_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Prüfe ob Datenbankdatei existiert
|
|
||||||
if [ ! -f "$DB_FILE" ]; then
|
|
||||||
echo "⚠️ Datenbankdatei '$DB_FILE' existiert nicht!"
|
|
||||||
echo " Das ist okay, wenn du eine neue Datenbank erstellst."
|
|
||||||
echo ""
|
|
||||||
echo " Setze Berechtigungen für das Verzeichnis..."
|
|
||||||
else
|
|
||||||
echo "✅ Datenbankdatei gefunden: $DB_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setze Berechtigungen für Datenbankverzeichnis
|
|
||||||
# SQLite braucht Schreibrechte auf:
|
|
||||||
# 1. Die Datenbankdatei selbst
|
|
||||||
# 2. Das Verzeichnis (für -wal und -shm Dateien)
|
|
||||||
|
|
||||||
echo "📝 Setze Berechtigungen..."
|
|
||||||
|
|
||||||
# Verzeichnis: Lesen, Schreiben, Ausführen für Owner und Gruppe
|
|
||||||
chmod 775 "$DB_DIR"
|
|
||||||
|
|
||||||
# Datenbankdatei: Lesen und Schreiben für Owner und Gruppe
|
|
||||||
if [ -f "$DB_FILE" ]; then
|
|
||||||
chmod 664 "$DB_FILE"
|
|
||||||
|
|
||||||
# Auch für alle SQLite-temporären Dateien
|
|
||||||
chmod 664 "$DB_DIR"/*.db-wal 2>/dev/null || true
|
|
||||||
chmod 664 "$DB_DIR"/*.db-shm 2>/dev/null || true
|
|
||||||
chmod 664 "$DB_DIR"/*.db-journal 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setze Besitzer: Container läuft als root, aber Datei kann node:node gehören
|
|
||||||
# SQLite funktioniert, solange root die Datei lesen/schreiben kann
|
|
||||||
# Setze Besitzer auf root, damit es definitiv funktioniert
|
|
||||||
echo "👤 Setze Besitzer auf root (Container läuft als root)"
|
|
||||||
chown -R root:root "$DB_DIR" 2>/dev/null || {
|
|
||||||
echo "⚠️ Konnte Besitzer nicht ändern (vielleicht keine sudo-Rechte?)"
|
|
||||||
echo " Versuche mit sudo..."
|
|
||||||
sudo chown -R root:root "$DB_DIR" || echo "❌ Besitzer-Änderung fehlgeschlagen"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Prüfe aktuelle Berechtigungen
|
|
||||||
echo ""
|
|
||||||
echo "📋 Aktuelle Berechtigungen:"
|
|
||||||
ls -lh "$DB_DIR"/*.db* 2>/dev/null || echo " (Keine .db Dateien gefunden)"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "✅ Berechtigungen gesetzt!"
|
|
||||||
echo ""
|
|
||||||
echo "💡 Wichtig für SQLite:"
|
|
||||||
echo " - Die Datenbankdatei braucht Schreibrechte (rw-rw-r--)"
|
|
||||||
echo " - Das Verzeichnis braucht Schreibrechte (rwxrwxr-x)"
|
|
||||||
echo " - SQLite erstellt temporäre Dateien (-wal, -shm) im gleichen Verzeichnis"
|
|
||||||
echo ""
|
|
||||||
echo "🔄 Starte Container neu, damit die Änderungen wirksam werden:"
|
|
||||||
echo " docker compose restart hoerdle"
|
|
||||||
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
// Fix-Skript für i18n-Daten in der bestehenden Datenbank.
|
|
||||||
// Hintergrund: Ältere Datenbanken speichern Genre-/Special-/News-Texte
|
|
||||||
// als einfache Strings ("Rock"), während das aktuelle Schema JSON erwartet,
|
|
||||||
// z.B. { "de": "Rock", "en": "Rock" }.
|
|
||||||
//
|
|
||||||
// Dieses Skript:
|
|
||||||
// - liest alle Datensätze
|
|
||||||
// - erkennt Felder, die noch einfache Strings sind
|
|
||||||
// - konvertiert sie in das erwartete JSON-Format
|
|
||||||
|
|
||||||
const { PrismaClient } = require('@prisma/client');
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
async function fixGenres() {
|
|
||||||
console.log('🔧 Fixing Genre.name / Genre.subtitle ...');
|
|
||||||
const genres = await prisma.genre.findMany();
|
|
||||||
let updated = 0;
|
|
||||||
|
|
||||||
for (const g of genres) {
|
|
||||||
let changed = false;
|
|
||||||
let newName = g.name;
|
|
||||||
let newSubtitle = g.subtitle;
|
|
||||||
|
|
||||||
if (typeof g.name === 'string') {
|
|
||||||
newName = { de: g.name, en: g.name };
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g.subtitle && typeof g.subtitle === 'string') {
|
|
||||||
newSubtitle = { de: g.subtitle, en: g.subtitle };
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
await prisma.genre.update({
|
|
||||||
where: { id: g.id },
|
|
||||||
data: {
|
|
||||||
name: newName,
|
|
||||||
subtitle: newSubtitle,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
updated++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`✅ Genres aktualisiert: ${updated} Einträge geändert.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fixSpecials() {
|
|
||||||
console.log('🔧 Fixing Special.name / Special.subtitle ...');
|
|
||||||
const specials = await prisma.special.findMany();
|
|
||||||
let updated = 0;
|
|
||||||
|
|
||||||
for (const s of specials) {
|
|
||||||
let changed = false;
|
|
||||||
let newName = s.name;
|
|
||||||
let newSubtitle = s.subtitle;
|
|
||||||
|
|
||||||
if (typeof s.name === 'string') {
|
|
||||||
newName = { de: s.name, en: s.name };
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.subtitle && typeof s.subtitle === 'string') {
|
|
||||||
newSubtitle = { de: s.subtitle, en: s.subtitle };
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
await prisma.special.update({
|
|
||||||
where: { id: s.id },
|
|
||||||
data: {
|
|
||||||
name: newName,
|
|
||||||
subtitle: newSubtitle,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
updated++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`✅ Specials aktualisiert: ${updated} Einträge geändert.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fixNews() {
|
|
||||||
console.log('🔧 Fixing News.title / News.content ...');
|
|
||||||
const news = await prisma.news.findMany();
|
|
||||||
let updated = 0;
|
|
||||||
|
|
||||||
for (const n of news) {
|
|
||||||
let changed = false;
|
|
||||||
let newTitle = n.title;
|
|
||||||
let newContent = n.content;
|
|
||||||
|
|
||||||
if (typeof n.title === 'string') {
|
|
||||||
newTitle = { de: n.title, en: n.title };
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof n.content === 'string') {
|
|
||||||
newContent = { de: n.content, en: n.content };
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
await prisma.news.update({
|
|
||||||
where: { id: n.id },
|
|
||||||
data: {
|
|
||||||
title: newTitle,
|
|
||||||
content: newContent,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
updated++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`✅ News aktualisiert: ${updated} Einträge geändert.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
console.log('🚀 Starte Fix für i18n-Daten (JSON-Felder) ...');
|
|
||||||
|
|
||||||
try {
|
|
||||||
await fixGenres();
|
|
||||||
await fixSpecials();
|
|
||||||
await fixNews();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('❌ Fehler beim Fixen der i18n-Daten:', err);
|
|
||||||
process.exitCode = 1;
|
|
||||||
} finally {
|
|
||||||
await prisma.$disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('🎉 Fix für i18n-Daten abgeschlossen.');
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
// Direkter Fix für i18n-Daten in SQLite
|
|
||||||
// Arbeitet direkt mit der Datenbank, umgeht Prisma (da es die Daten nicht lesen kann)
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const { execSync } = require('child_process');
|
|
||||||
|
|
||||||
const DB_PATH = process.env.DATABASE_URL?.replace('file:', '') || '/app/data/prod.db';
|
|
||||||
|
|
||||||
if (!fs.existsSync(DB_PATH)) {
|
|
||||||
console.error(`❌ Datenbank nicht gefunden: ${DB_PATH}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`🔧 Fixe i18n-Daten in: ${DB_PATH}`);
|
|
||||||
|
|
||||||
// SQLite-Befehle zum Fixen
|
|
||||||
const sqlCommands = `
|
|
||||||
-- Backup erstellen
|
|
||||||
.backup ${DB_PATH}.backup
|
|
||||||
|
|
||||||
-- Temporäre Tabellen für Genres
|
|
||||||
BEGIN TRANSACTION;
|
|
||||||
|
|
||||||
-- Prüfe und fixe Genre.name (wenn String statt JSON)
|
|
||||||
UPDATE Genre
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Prüfe und fixe Genre.subtitle
|
|
||||||
UPDATE Genre
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Prüfe und fixe Special.name
|
|
||||||
UPDATE Special
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Prüfe und fixe Special.subtitle
|
|
||||||
UPDATE Special
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Prüfe und fixe News.title
|
|
||||||
UPDATE News
|
|
||||||
SET title = json_object('de', title, 'en', title)
|
|
||||||
WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Prüfe und fixe News.content
|
|
||||||
UPDATE News
|
|
||||||
SET content = json_object('de', content, 'en', content)
|
|
||||||
WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
||||||
-- Zeige Statistiken
|
|
||||||
SELECT 'Genres gefixt:', COUNT(*) FROM Genre WHERE typeof(name) = 'text';
|
|
||||||
SELECT 'Specials gefixt:', COUNT(*) FROM Special WHERE typeof(name) = 'text';
|
|
||||||
SELECT 'News gefixt:', COUNT(*) FROM News WHERE typeof(title) = 'text';
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Führe SQL-Befehle aus
|
|
||||||
try {
|
|
||||||
console.log('📝 Führe SQL-Updates aus...');
|
|
||||||
|
|
||||||
// Installiere sqlite3 falls nicht vorhanden (im Container sollte es nicht da sein)
|
|
||||||
// Wir verwenden stattdessen einen Node.js-Ansatz
|
|
||||||
|
|
||||||
// Einfacher: Nutze Prisma's direkten DB-Zugriff
|
|
||||||
const Database = require('better-sqlite3');
|
|
||||||
const db = new Database(DB_PATH);
|
|
||||||
|
|
||||||
// Prüfe Schema
|
|
||||||
console.log('📊 Prüfe Datenbank-Schema...');
|
|
||||||
const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all();
|
|
||||||
console.log(` Gefundene Tabellen: ${tables.map(t => t.name).join(', ')}`);
|
|
||||||
|
|
||||||
// Fix Genre.name
|
|
||||||
console.log('🔧 Fixe Genre.name...');
|
|
||||||
const genreResult = db.prepare(`
|
|
||||||
UPDATE Genre
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%'
|
|
||||||
`).run();
|
|
||||||
console.log(` ✅ ${genreResult.changes} Genres aktualisiert`);
|
|
||||||
|
|
||||||
// Fix Genre.subtitle
|
|
||||||
const genreSubtitleResult = db.prepare(`
|
|
||||||
UPDATE Genre
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'
|
|
||||||
`).run();
|
|
||||||
console.log(` ✅ ${genreSubtitleResult.changes} Genre-Subtitles aktualisiert`);
|
|
||||||
|
|
||||||
// Fix Special.name
|
|
||||||
console.log('🔧 Fixe Special.name...');
|
|
||||||
const specialResult = db.prepare(`
|
|
||||||
UPDATE Special
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%'
|
|
||||||
`).run();
|
|
||||||
console.log(` ✅ ${specialResult.changes} Specials aktualisiert`);
|
|
||||||
|
|
||||||
// Fix Special.subtitle
|
|
||||||
const specialSubtitleResult = db.prepare(`
|
|
||||||
UPDATE Special
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'
|
|
||||||
`).run();
|
|
||||||
console.log(` ✅ ${specialSubtitleResult.changes} Special-Subtitles aktualisiert`);
|
|
||||||
|
|
||||||
// Fix News.title
|
|
||||||
console.log('🔧 Fixe News.title...');
|
|
||||||
const newsTitleResult = db.prepare(`
|
|
||||||
UPDATE News
|
|
||||||
SET title = json_object('de', title, 'en', title)
|
|
||||||
WHERE typeof(title) = 'text' AND title NOT LIKE '{%'
|
|
||||||
`).run();
|
|
||||||
console.log(` ✅ ${newsTitleResult.changes} News-Titles aktualisiert`);
|
|
||||||
|
|
||||||
// Fix News.content
|
|
||||||
const newsContentResult = db.prepare(`
|
|
||||||
UPDATE News
|
|
||||||
SET content = json_object('de', content, 'en', content)
|
|
||||||
WHERE typeof(content) = 'text' AND content NOT LIKE '{%'
|
|
||||||
`).run();
|
|
||||||
console.log(` ✅ ${newsContentResult.changes} News-Contents aktualisiert`);
|
|
||||||
|
|
||||||
db.close();
|
|
||||||
|
|
||||||
console.log('✅ Alle i18n-Daten wurden gefixt!');
|
|
||||||
console.log('🔄 Bitte starte den Container neu: docker compose restart hoerdle');
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Fehler:', error.message);
|
|
||||||
if (error.message.includes('better-sqlite3')) {
|
|
||||||
console.error('\n💡 better-sqlite3 ist nicht installiert. Verwende stattdessen:');
|
|
||||||
console.error(' docker exec hoerdle sh -c "cd /app && node -e \\"');
|
|
||||||
console.error(' const fs=require(\\"fs\\");');
|
|
||||||
console.error(' const {PrismaClient}=require(\\"@prisma/client\\");');
|
|
||||||
console.error(' // ... alternativer Ansatz');
|
|
||||||
}
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Einfaches Fix-Skript für i18n-Daten
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🔧 Fixe i18n-Daten..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Prüfe ob Container läuft
|
|
||||||
if ! docker ps | grep -q hoerdle; then
|
|
||||||
echo "❌ Container 'hoerdle' läuft nicht!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Backup
|
|
||||||
BACKUP_FILE="./data/prod.db.backup.$(date +%Y%m%d_%H%M%S)"
|
|
||||||
echo "💾 Erstelle Backup..."
|
|
||||||
docker cp hoerdle:/app/data/prod.db "$BACKUP_FILE" || {
|
|
||||||
echo "❌ Backup fehlgeschlagen!"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
echo "✅ Backup: $BACKUP_FILE"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Kopiere DB
|
|
||||||
echo "📥 Kopiere Datenbank lokal..."
|
|
||||||
DB_TMP="./data/prod.db.tmp"
|
|
||||||
docker cp hoerdle:/app/data/prod.db "$DB_TMP"
|
|
||||||
echo "✅ Datenbank kopiert"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Setze Berechtigungen
|
|
||||||
echo "🔐 Setze Berechtigungen..."
|
|
||||||
sudo chmod 666 "$DB_TMP" 2>/dev/null || chmod 666 "$DB_TMP" || {
|
|
||||||
echo "⚠️ Konnte Berechtigungen nicht setzen"
|
|
||||||
}
|
|
||||||
sudo chmod 775 ./data 2>/dev/null || chmod 775 ./data || true
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Prüfe sqlite3
|
|
||||||
if ! command -v sqlite3 &> /dev/null; then
|
|
||||||
echo "❌ sqlite3 nicht gefunden! Installiere es:"
|
|
||||||
echo " sudo apt-get update && sudo apt-get install -y sqlite3"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fixe DB
|
|
||||||
echo "🔧 Führe SQL-Updates aus..."
|
|
||||||
sqlite3 "$DB_TMP" << 'SQL' || {
|
|
||||||
echo "⚠️ Normale Ausführung fehlgeschlagen, versuche mit sudo..."
|
|
||||||
sudo sqlite3 "$DB_TMP" << 'SQL2'
|
|
||||||
UPDATE Genre SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
UPDATE Genre SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
UPDATE Special SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
UPDATE Special SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
UPDATE News SET title = json_object('de', title, 'en', title) WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
|
|
||||||
UPDATE News SET content = json_object('de', content, 'en', content) WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
|
|
||||||
SQL2
|
|
||||||
}
|
|
||||||
UPDATE Genre SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
UPDATE Genre SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
UPDATE Special SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
UPDATE Special SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
UPDATE News SET title = json_object('de', title, 'en', title) WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
|
|
||||||
UPDATE News SET content = json_object('de', content, 'en', content) WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
|
|
||||||
SELECT '✅ Fertig!' as status;
|
|
||||||
SQL
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "✅ Datenbank gefixt"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Kopiere zurück
|
|
||||||
echo "📤 Kopiere Datenbank zurück..."
|
|
||||||
docker cp "$DB_TMP" hoerdle:/app/data/prod.db
|
|
||||||
echo "✅ Zurück kopiert"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Aufräumen
|
|
||||||
rm -f "$DB_TMP"
|
|
||||||
|
|
||||||
echo "🔄 Starte Container neu..."
|
|
||||||
docker compose restart hoerdle
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "✅ Fertig! Prüfe Logs: docker logs hoerdle --tail=50"
|
|
||||||
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Einfaches Fix-Skript für i18n-Daten
|
|
||||||
# Kopiert SQL-Befehle direkt in den Container und führt sie aus
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🔧 Fixe i18n-Daten in der Datenbank..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Prüfe ob Container läuft
|
|
||||||
if ! docker ps | grep -q hoerdle; then
|
|
||||||
echo "❌ Container 'hoerdle' läuft nicht!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Erstelle temporäres SQL-Skript
|
|
||||||
SQL_SCRIPT=$(mktemp)
|
|
||||||
cat > "$SQL_SCRIPT" << 'EOF'
|
|
||||||
-- Backup erstellen (optional, aber empfohlen)
|
|
||||||
.backup /tmp/prod.db.backup
|
|
||||||
|
|
||||||
-- Fix Genre.name: Konvertiere String zu JSON
|
|
||||||
UPDATE Genre
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Genre.subtitle
|
|
||||||
UPDATE Genre
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Special.name
|
|
||||||
UPDATE Special
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Special.subtitle
|
|
||||||
UPDATE Special
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix News.title
|
|
||||||
UPDATE News
|
|
||||||
SET title = json_object('de', title, 'en', title)
|
|
||||||
WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix News.content
|
|
||||||
UPDATE News
|
|
||||||
SET content = json_object('de', content, 'en', content)
|
|
||||||
WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Zeige Erfolg
|
|
||||||
SELECT 'i18n-Daten wurden erfolgreich gefixt!' as status;
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "📝 Kopiere SQL-Skript in Container..."
|
|
||||||
docker cp "$SQL_SCRIPT" hoerdle:/tmp/fix-i18n.sql
|
|
||||||
|
|
||||||
echo "🚀 Führe SQL-Befehle aus..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Prüfe ob sqlite3 im Container verfügbar ist
|
|
||||||
if docker exec hoerdle sh -c "command -v sqlite3" > /dev/null 2>&1; then
|
|
||||||
docker exec hoerdle sqlite3 /app/data/prod.db < /tmp/fix-i18n.sql
|
|
||||||
echo ""
|
|
||||||
echo "✅ i18n-Daten wurden erfolgreich gefixt!"
|
|
||||||
else
|
|
||||||
echo "⚠️ sqlite3 nicht im Container gefunden. Verwende alternativen Ansatz..."
|
|
||||||
|
|
||||||
# Versuche mit Node.js direkt SQL auszuführen
|
|
||||||
cat > /tmp/fix-i18n-node.js << 'NODEJS'
|
|
||||||
const fs = require('fs');
|
|
||||||
const DB_PATH = '/app/data/prod.db';
|
|
||||||
|
|
||||||
// Einfacher: Wir müssen sqlite3 im Container installieren oder einen anderen Weg finden
|
|
||||||
console.log('⚠️ sqlite3 ist nicht verfügbar. Bitte installiere es im Container oder verwende einen anderen Ansatz.');
|
|
||||||
console.log('');
|
|
||||||
console.log('Alternativ: Kopiere die Datenbank lokal, fixe sie dort, und kopiere sie zurück.');
|
|
||||||
process.exit(1);
|
|
||||||
NODEJS
|
|
||||||
|
|
||||||
docker cp /tmp/fix-i18n-node.js hoerdle:/tmp/fix-i18n-node.js
|
|
||||||
docker exec hoerdle node /tmp/fix-i18n-node.js || {
|
|
||||||
echo ""
|
|
||||||
echo "💡 Lösungsvorschlag:"
|
|
||||||
echo "1. Kopiere die Datenbank lokal:"
|
|
||||||
echo " docker cp hoerdle:/app/data/prod.db ./data/prod.db"
|
|
||||||
echo ""
|
|
||||||
echo "2. Führe dieses Skript lokal aus (mit sqlite3):"
|
|
||||||
echo " sqlite3 ./data/prod.db < $SQL_SCRIPT"
|
|
||||||
echo ""
|
|
||||||
echo "3. Kopiere die gefixte DB zurück:"
|
|
||||||
echo " docker cp ./data/prod.db hoerdle:/app/data/prod.db"
|
|
||||||
echo ""
|
|
||||||
echo "4. Starte Container neu:"
|
|
||||||
echo " docker compose restart hoerdle"
|
|
||||||
rm -f "$SQL_SCRIPT"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f "$SQL_SCRIPT"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🔄 Starte Container neu..."
|
|
||||||
docker compose restart hoerdle 2>/dev/null || echo " (Bitte manuell: docker compose restart hoerdle)"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "✅ Fertig! Prüfe die Logs:"
|
|
||||||
echo " docker logs hoerdle --tail=50"
|
|
||||||
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Direkter SQL-Fix für i18n-Daten in SQLite
|
|
||||||
# Konvertiert String-Werte zu JSON-Format
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
DB_PATH="./data/prod.db"
|
|
||||||
BACKUP_PATH="./data/prod.db.backup.$(date +%Y%m%d_%H%M%S)"
|
|
||||||
|
|
||||||
if [ ! -f "$DB_PATH" ]; then
|
|
||||||
echo "❌ Datenbank nicht gefunden: $DB_PATH"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "🔧 Fixe i18n-Daten in SQLite-Datenbank..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Backup erstellen
|
|
||||||
echo "💾 Erstelle Backup..."
|
|
||||||
cp "$DB_PATH" "$BACKUP_PATH"
|
|
||||||
echo "✅ Backup erstellt: $BACKUP_PATH"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Prüfe ob sqlite3 verfügbar ist
|
|
||||||
if ! command -v sqlite3 &> /dev/null; then
|
|
||||||
echo "⚠️ sqlite3 nicht gefunden. Versuche im Container..."
|
|
||||||
|
|
||||||
# Führe SQL-Befehle im Container aus
|
|
||||||
docker exec hoerdle sh << 'EOF'
|
|
||||||
# SQL-Befehle
|
|
||||||
sqlite3 /app/data/prod.db << 'SQL'
|
|
||||||
-- Backup erstellen
|
|
||||||
.backup /app/data/prod.db.backup
|
|
||||||
|
|
||||||
-- Fix Genre.name
|
|
||||||
UPDATE Genre
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Genre.subtitle
|
|
||||||
UPDATE Genre
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Special.name
|
|
||||||
UPDATE Special
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Special.subtitle
|
|
||||||
UPDATE Special
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix News.title
|
|
||||||
UPDATE News
|
|
||||||
SET title = json_object('de', title, 'en', title)
|
|
||||||
WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix News.content
|
|
||||||
UPDATE News
|
|
||||||
SET content = json_object('de', content, 'en', content)
|
|
||||||
WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Zeige Änderungen
|
|
||||||
SELECT 'Genre.name gefixt:' as status, COUNT(*) as count
|
|
||||||
FROM Genre WHERE typeof(name) = 'text' AND name LIKE '{%';
|
|
||||||
SQL
|
|
||||||
EOF
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "✅ i18n-Daten wurden erfolgreich gefixt!"
|
|
||||||
else
|
|
||||||
echo "❌ Fehler beim Ausführen der SQL-Befehle"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Führe direkt auf dem Host aus
|
|
||||||
sqlite3 "$DB_PATH" << 'SQL'
|
|
||||||
-- Fix Genre.name
|
|
||||||
UPDATE Genre
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Genre.subtitle
|
|
||||||
UPDATE Genre
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Special.name
|
|
||||||
UPDATE Special
|
|
||||||
SET name = json_object('de', name, 'en', name)
|
|
||||||
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix Special.subtitle
|
|
||||||
UPDATE Special
|
|
||||||
SET subtitle = json_object('de', subtitle, 'en', subtitle)
|
|
||||||
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix News.title
|
|
||||||
UPDATE News
|
|
||||||
SET title = json_object('de', title, 'en', title)
|
|
||||||
WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
|
|
||||||
|
|
||||||
-- Fix News.content
|
|
||||||
UPDATE News
|
|
||||||
SET content = json_object('de', content, 'en', content)
|
|
||||||
WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
|
|
||||||
|
|
||||||
SELECT 'Fertig!' as status;
|
|
||||||
SQL
|
|
||||||
|
|
||||||
echo "✅ i18n-Daten wurden erfolgreich gefixt!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🔄 Bitte starte den Container neu:"
|
|
||||||
echo " docker compose restart hoerdle"
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user