Files
urlshort-qr-gen/migrations/001_initial.php
T
florian.wilde 2c9fbdec87 feat(core): Konfiguration, PDO-Datenbankschicht und Migrationen
SQLite als Standard (keine Einrichtung noetig, WAL aktiviert), optional
MySQL/MariaDB. Beide Treiber nutzen dieselben vorbereiteten Statements.

Die Migrationen laufen automatisch beim ersten Request; jede Migration
liefert das SQL je Treiber. Damit entfaellt ein manueller Schritt beim
Deployment ueber FTP.

data/ enthaelt eine eigene .htaccess als zweite Absicherung, falls das
Verzeichnis beim Hoster doch einmal im Webroot landet.
2026-08-03 18:11:38 +02:00

128 lines
5.0 KiB
PHP

<?php
declare(strict_types=1);
/**
* Initiales Schema.
* Zeitstempel werden bewusst als UTC-Strings (Y-m-d H:i:s) gespeichert,
* damit SQLite und MySQL identisch behandelt werden koennen.
*/
return [
'sqlite' => [
'CREATE TABLE IF NOT EXISTS links (
id INTEGER PRIMARY KEY AUTOINCREMENT,
slug TEXT NOT NULL UNIQUE,
target_url TEXT NOT NULL,
title TEXT NULL,
is_active INTEGER NOT NULL DEFAULT 1,
click_count INTEGER NOT NULL DEFAULT 0,
last_clicked_at TEXT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
)',
'CREATE INDEX IF NOT EXISTS idx_links_created_at ON links (created_at)',
'CREATE TABLE IF NOT EXISTS visits (
id INTEGER PRIMARY KEY AUTOINCREMENT,
link_id INTEGER NOT NULL,
visited_at TEXT NOT NULL,
referrer_host TEXT NULL,
referrer_url TEXT NULL,
user_agent TEXT NULL,
device_type TEXT NOT NULL DEFAULT "unknown",
browser TEXT NOT NULL DEFAULT "unknown",
platform TEXT NOT NULL DEFAULT "unknown",
visitor_hash TEXT NULL,
FOREIGN KEY (link_id) REFERENCES links (id) ON DELETE CASCADE
)',
'CREATE INDEX IF NOT EXISTS idx_visits_link_time ON visits (link_id, visited_at)',
'CREATE TABLE IF NOT EXISTS qr_designs (
link_id INTEGER PRIMARY KEY,
foreground_color TEXT NOT NULL DEFAULT "#000000",
background_color TEXT NOT NULL DEFAULT "#ffffff",
size INTEGER NOT NULL DEFAULT 512,
margin INTEGER NOT NULL DEFAULT 4,
error_correction TEXT NOT NULL DEFAULT "M",
logo_path TEXT NULL,
logo_scale INTEGER NOT NULL DEFAULT 22,
logo_punchout INTEGER NOT NULL DEFAULT 1,
updated_at TEXT NOT NULL,
FOREIGN KEY (link_id) REFERENCES links (id) ON DELETE CASCADE
)',
'CREATE TABLE IF NOT EXISTS settings (
key_name TEXT PRIMARY KEY,
value TEXT NULL,
updated_at TEXT NOT NULL
)',
'CREATE TABLE IF NOT EXISTS login_attempts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
identifier TEXT NOT NULL,
attempted_at TEXT NOT NULL,
successful INTEGER NOT NULL DEFAULT 0
)',
'CREATE INDEX IF NOT EXISTS idx_login_attempts ON login_attempts (identifier, attempted_at)',
],
'mysql' => [
'CREATE TABLE IF NOT EXISTS links (
id INT AUTO_INCREMENT PRIMARY KEY,
slug VARCHAR(190) NOT NULL,
target_url TEXT NOT NULL,
title VARCHAR(255) NULL,
is_active TINYINT(1) NOT NULL DEFAULT 1,
click_count INT NOT NULL DEFAULT 0,
last_clicked_at DATETIME NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
UNIQUE KEY uniq_links_slug (slug),
KEY idx_links_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4',
'CREATE TABLE IF NOT EXISTS visits (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
link_id INT NOT NULL,
visited_at DATETIME NOT NULL,
referrer_host VARCHAR(255) NULL,
referrer_url TEXT NULL,
user_agent TEXT NULL,
device_type VARCHAR(20) NOT NULL DEFAULT "unknown",
browser VARCHAR(40) NOT NULL DEFAULT "unknown",
platform VARCHAR(40) NOT NULL DEFAULT "unknown",
visitor_hash VARCHAR(64) NULL,
KEY idx_visits_link_time (link_id, visited_at),
CONSTRAINT fk_visits_link FOREIGN KEY (link_id) REFERENCES links (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4',
'CREATE TABLE IF NOT EXISTS qr_designs (
link_id INT PRIMARY KEY,
foreground_color VARCHAR(7) NOT NULL DEFAULT "#000000",
background_color VARCHAR(7) NOT NULL DEFAULT "#ffffff",
size INT NOT NULL DEFAULT 512,
margin INT NOT NULL DEFAULT 4,
error_correction VARCHAR(1) NOT NULL DEFAULT "M",
logo_path VARCHAR(255) NULL,
logo_scale INT NOT NULL DEFAULT 22,
logo_punchout TINYINT(1) NOT NULL DEFAULT 1,
updated_at DATETIME NOT NULL,
CONSTRAINT fk_qr_link FOREIGN KEY (link_id) REFERENCES links (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4',
'CREATE TABLE IF NOT EXISTS settings (
key_name VARCHAR(190) PRIMARY KEY,
value TEXT NULL,
updated_at DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4',
'CREATE TABLE IF NOT EXISTS login_attempts (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
identifier VARCHAR(64) NOT NULL,
attempted_at DATETIME NOT NULL,
successful TINYINT(1) NOT NULL DEFAULT 0,
KEY idx_login_attempts (identifier, attempted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4',
],
];