feat:backup und restore der contao Datenbank über sql file
This commit is contained in:
1 parent
1c1bf84b7a
commit
e44b16e523
6 files changed
+237
-1
No files matched your search
@@ -17,10 +17,18 @@ docker compose exec app vendor/bin/contao-setup --no-interaction --env=dev
|
|||||||
docker compose exec app chown -R www-data:www-data var public
|
docker compose exec app chown -R www-data:www-data var public
|
||||||
docker compose exec app vendor/bin/contao-console contao:migrate --no-interaction
|
docker compose exec app vendor/bin/contao-console contao:migrate --no-interaction
|
||||||
|
|
||||||
neuen admin account anlegen:
|
Neuen Admin-Account anlegen:
|
||||||
|
|
||||||
|
```powershell
|
||||||
docker compose exec app vendor/bin/contao-console contao:user:create --admin
|
docker compose exec app vendor/bin/contao-console contao:user:create --admin
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Danach den versionierten Seitenzustand importieren:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\scripts\Import-ContaoBaseline.ps1
|
||||||
|
```
|
||||||
|
|
||||||
- Website/CMS: <http://localhost:8080>
|
- Website/CMS: <http://localhost:8080>
|
||||||
- Contao-Login: <http://localhost:8080/contao/login>
|
- Contao-Login: <http://localhost:8080/contao/login>
|
||||||
- Datenbankinspektor: <http://localhost:8081> (Server `db`, Benutzer `perspektivwerk`, Passwort `perspektivwerk`, Datenbank `perspektivwerk`)
|
- Datenbankinspektor: <http://localhost:8081> (Server `db`, Benutzer `perspektivwerk`, Passwort `perspektivwerk`, Datenbank `perspektivwerk`)
|
||||||
@@ -45,3 +53,13 @@ http://localhost:8080/perspektivwerk/
|
|||||||
Die genaue Contao-, PHP- und Template-Version der öffentlichen Seite ist nicht verlässlich aus dem ausgelieferten HTML ableitbar. Das Setup bildet daher die wahrscheinlichste Komponentenfamilie nach; es ist kein Dump der Produktivinstallation. IONOS/Hosting, Matomo-Konfiguration, Inhalte, Templates und Erweiterungen müssen bei Bedarf separat ergänzt werden.
|
Die genaue Contao-, PHP- und Template-Version der öffentlichen Seite ist nicht verlässlich aus dem ausgelieferten HTML ableitbar. Das Setup bildet daher die wahrscheinlichste Komponentenfamilie nach; es ist kein Dump der Produktivinstallation. IONOS/Hosting, Matomo-Konfiguration, Inhalte, Templates und Erweiterungen müssen bei Bedarf separat ergänzt werden.
|
||||||
|
|
||||||
Die Terminlogik liegt zunächst in `src/booking.ts`. Eine spätere Google-Calendar- oder Exchange-Anbindung sollte über eine Backend-API erfolgen, damit keine Secrets im Browser landen.
|
Die Terminlogik liegt zunächst in `src/booking.ts`. Eine spätere Google-Calendar- oder Exchange-Anbindung sollte über eine Backend-API erfolgen, damit keine Secrets im Browser landen.
|
||||||
|
|
||||||
|
## Versionierter Contao-Seitenzustand
|
||||||
|
|
||||||
|
Die Contao-Seiten, Artikel und Layouts liegen in MariaDB und werden deshalb zusätzlich als bereinigter SQL-Seed versioniert. Details zu Export, Import und den bewusst ausgeschlossenen Daten stehen in [database/README.md](database/README.md).
|
||||||
|
|
||||||
|
Die Seed-Integritätsprüfungen ausführen:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Invoke-Pester .\tests\ContaoBaseline.Tests.ps1
|
||||||
|
```
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Versionierter Contao-Seitenzustand
|
||||||
|
|
||||||
|
`contao-baseline.sql` ist der versionierte Ausgangszustand für Theme, Layout, Seiten, Artikel, Inhaltselemente und später auch Formulare. Er ist für eine frische Contao-Datenbank bestimmt und enthält keine Benutzer, Passworthashes, Sitzungen, Logs, Cache-Daten oder Zugangsdaten.
|
||||||
|
|
||||||
|
## Nach einer redaktionellen Änderung exportieren
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cd development-system
|
||||||
|
.\scripts\Export-ContaoBaseline.ps1
|
||||||
|
git diff -- database/contao-baseline.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Bei einer vorhandenen Datei fragt das Skript vor dem Überschreiben nach. Für einen bewusst nicht-interaktiven Export, z. B. in einer Automatisierung, `-Force` ergänzen. Den Diff vor dem Commit prüfen. Die Exportdatei enthält keine `tl_user`-Daten.
|
||||||
|
|
||||||
|
## In eine frische Datenbank importieren
|
||||||
|
|
||||||
|
Nach `contao-setup` und `contao:migrate`:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cd development-system
|
||||||
|
.\scripts\Import-ContaoBaseline.ps1
|
||||||
|
docker compose exec app vendor/bin/contao-console contao:user:create --admin
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Import bricht ab, wenn die versionierten Contao-Tabellen bereits Inhalte enthalten. Das verhindert ein versehentliches Überschreiben. Nur für ein bewusstes Zurücksetzen auf den Git-Stand ist Folgendes vorgesehen:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\scripts\Import-ContaoBaseline.ps1 -ReplaceExisting
|
||||||
|
```
|
||||||
|
|
||||||
|
`-ReplaceExisting` löscht ausschließlich Theme-, Layout-, Modul-, Seiten-, Artikel-, Inhaltselement- und Formulardaten. Benutzerkonten bleiben erhalten.
|
||||||
|
|
||||||
|
## Medien
|
||||||
|
|
||||||
|
Medien gehören als Dateien nach `development-system/files/` und werden in Git eingecheckt. Sobald Contao-Medien verwendet werden, muss der Seed zusätzlich die Metadaten aus `tl_files` enthalten. Das ist absichtlich noch nicht automatisiert, weil die aktuelle Datenbank nur Verweise auf nicht versionierte lokale Dateien enthält.
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
-- Contao website baseline for local development.
|
||||||
|
--
|
||||||
|
-- Contains only versionable website data. It deliberately excludes users,
|
||||||
|
-- credentials, sessions, logs, cache entries and file metadata.
|
||||||
|
-- Generated with scripts/Export-ContaoBaseline.ps1.
|
||||||
|
|
||||||
|
/*M!999999\- enable the sandbox mode */
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||||
|
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||||
|
|
||||||
|
INSERT INTO `tl_theme` (`id`, `tstamp`, `name`, `author`, `folders`, `screenshot`, `templates`) VALUES (1,1786708968,'Lokales PerspektivWerk-Theme','Lokale Entwicklung',NULL,NULL,'');
|
||||||
|
|
||||||
|
INSERT INTO `tl_layout` (`type`, `combineScripts`, `minifyMarkup`, `lightboxSize`, `addJQuery`, `addMooTools`, `static`, `id`, `pid`, `tstamp`, `name`, `rows`, `headerHeight`, `footerHeight`, `cols`, `widthLeft`, `widthRight`, `sections`, `framework`, `external`, `modules`, `template`, `defaultImageDensities`, `viewport`, `titleTag`, `cssClass`, `onload`, `head`, `jquery`, `mootools`, `analytics`, `externalJs`, `scripts`, `script`, `width`, `align`, `newsfeeds`, `calendarfeeds`) VALUES ('default',1,1,'',0,0,0,2,1,1787041994,'PerspektivWerk Standardlayout','2rwh','','','1cl','','',NULL,'a:2:{i:0;s:10:\"layout.css\";i:1;s:14:\"responsive.css\";}',NULL,0x613A313A7B693A303B613A333A7B733A333A226D6F64223B693A303B733A333A22636F6C223B733A343A226D61696E223B733A363A22656E61626C65223B693A313B7D7D,'fe_page','','width=device-width,initial-scale=1.0,shrink-to-fit=no','','','','<style>body.perspektivwerk-page { background-color: #159A34; }</style>',NULL,NULL,NULL,NULL,NULL,NULL,'','center',NULL,NULL);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO `tl_page` (`requireItem`, `alwaysForward`, `redirectBack`, `target`, `fallback`, `disableLanguageRedirect`, `maintenanceMode`, `enableCanonical`, `useFolderUrl`, `useSSL`, `autoforward`, `protected`, `includeLayout`, `includeCache`, `alwaysLoadFromCache`, `includeChmod`, `hide`, `guests`, `published`, `enforceTwoFactor`, `enableCsp`, `csp`, `cspReportOnly`, `cspReportLog`, `imgSize`, `feedSource`, `feedFeatured`, `eventCalendars`, `feedRecurrenceLimit`, `id`, `pid`, `sorting`, `tstamp`, `title`, `type`, `alias`, `routePriority`, `pageTitle`, `language`, `robots`, `description`, `redirect`, `jumpTo`, `url`, `dns`, `staticFiles`, `staticPlugins`, `favicon`, `robotsTxt`, `mailerTransport`, `canonicalLink`, `canonicalKeepParams`, `adminEmail`, `dateFormat`, `timeFormat`, `datimFormat`, `validAliasCharacters`, `urlPrefix`, `urlSuffix`, `groups`, `layout`, `subpageLayout`, `cache`, `clientCache`, `cuser`, `cgroup`, `chmod`, `cssClass`, `sitemap`, `searchIndexer`, `accesskey`, `start`, `stop`, `twoFactorJumpTo`, `feedFormat`, `maxFeedItems`, `feedDescription`, `newsArchives`) VALUES (0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,'default-src \'self\'',0,0,'','source_teaser','all_items',NULL,25,5,0,128,1786715837,'Homepage','root','home',0,'Homepage','de','',NULL,'permanent',0,'','','','',NULL,NULL,'','','','','','','','','','',NULL,2,2,0,0,0,0,'a:9:{i:0;s:2:\"u1\";i:1;s:2:\"u2\";i:2;s:2:\"u3\";i:3;s:2:\"u4\";i:4;s:2:\"u5\";i:5;s:2:\"u6\";i:6;s:2:\"g4\";i:7;s:2:\"g5\";i:8;s:2:\"g6\";}','','','','','','',0,'rss',25,NULL,NULL);
|
||||||
|
INSERT INTO `tl_page` (`requireItem`, `alwaysForward`, `redirectBack`, `target`, `fallback`, `disableLanguageRedirect`, `maintenanceMode`, `enableCanonical`, `useFolderUrl`, `useSSL`, `autoforward`, `protected`, `includeLayout`, `includeCache`, `alwaysLoadFromCache`, `includeChmod`, `hide`, `guests`, `published`, `enforceTwoFactor`, `enableCsp`, `csp`, `cspReportOnly`, `cspReportLog`, `imgSize`, `feedSource`, `feedFeatured`, `eventCalendars`, `feedRecurrenceLimit`, `id`, `pid`, `sorting`, `tstamp`, `title`, `type`, `alias`, `routePriority`, `pageTitle`, `language`, `robots`, `description`, `redirect`, `jumpTo`, `url`, `dns`, `staticFiles`, `staticPlugins`, `favicon`, `robotsTxt`, `mailerTransport`, `canonicalLink`, `canonicalKeepParams`, `adminEmail`, `dateFormat`, `timeFormat`, `datimFormat`, `validAliasCharacters`, `urlPrefix`, `urlSuffix`, `groups`, `layout`, `subpageLayout`, `cache`, `clientCache`, `cuser`, `cgroup`, `chmod`, `cssClass`, `sitemap`, `searchIndexer`, `accesskey`, `start`, `stop`, `twoFactorJumpTo`, `feedFormat`, `maxFeedItems`, `feedDescription`, `newsArchives`) VALUES (0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,'default-src \'self\'',0,0,'','source_teaser','all_items',NULL,25,7,5,128,1787041994,'default','regular','default',0,'Perspektivwerk Default','','index,follow',NULL,'permanent',0,'','','','',NULL,NULL,'','','','','','','','','','',NULL,0,0,0,0,0,0,'a:9:{i:0;s:2:\"u1\";i:1;s:2:\"u2\";i:2;s:2:\"u3\";i:3;s:2:\"u4\";i:4;s:2:\"u5\";i:5;s:2:\"u6\";i:6;s:2:\"g4\";i:7;s:2:\"g5\";i:8;s:2:\"g6\";}','perspektivwerk-page','map_default','','','','',0,'rss',25,NULL,NULL);
|
||||||
|
|
||||||
|
INSERT INTO `tl_article` (`showTeaser`, `protected`, `published`, `id`, `pid`, `sorting`, `tstamp`, `title`, `alias`, `author`, `inColumn`, `teaserCssID`, `teaser`, `printable`, `customTpl`, `groups`, `cssID`, `start`, `stop`) VALUES (0,0,1,3,7,128,1786716736,'default','default',3,'main','a:2:{i:0;s:0:\"\";i:1;s:0:\"\";}',NULL,'','',NULL,'a:2:{i:0;s:0:\"\";i:1;s:0:\"\";}','','');
|
||||||
|
INSERT INTO `tl_article` (`showTeaser`, `protected`, `published`, `id`, `pid`, `sorting`, `tstamp`, `title`, `alias`, `author`, `inColumn`, `teaserCssID`, `teaser`, `printable`, `customTpl`, `groups`, `cssID`, `start`, `stop`) VALUES (0,0,1,5,7,256,1786716203,'Artikel2','Artikel2',3,'main','a:2:{i:0;s:0:\"\";i:1;s:0:\"\";}',NULL,'','',NULL,'a:2:{i:0;s:0:\"\";i:1;s:0:\"\";}','','');
|
||||||
|
|
||||||
|
INSERT INTO `tl_content` (`title`, `type`, `addImage`, `showPreview`, `inline`, `overwriteMeta`, `size`, `fullsize`, `thead`, `tfoot`, `tleft`, `sortable`, `closeSections`, `target`, `overwriteLink`, `useImage`, `useHomeDir`, `metaIgnore`, `splashImage`, `sliderContinuous`, `protected`, `jumpTo`, `redirectBack`, `autologin`, `pwResetPage`, `invisible`, `com_moderate`, `com_bbcode`, `com_disableCaptcha`, `com_requireLogin`, `jsonData`, `id`, `pid`, `ptable`, `sorting`, `tstamp`, `headline`, `sectionHeadline`, `text`, `singleSRC`, `alt`, `imageTitle`, `imageUrl`, `caption`, `floating`, `html`, `unfilteredHtml`, `listtype`, `listitems`, `tableitems`, `summary`, `sortIndex`, `sortOrder`, `mooHeadline`, `mooStyle`, `mooClasses`, `highlight`, `markdownSource`, `code`, `url`, `titleText`, `linkTitle`, `embed`, `rel`, `multiSRC`, `perRow`, `perPage`, `numberOfItems`, `sortBy`, `galleryTpl`, `customTpl`, `playerSRC`, `youtube`, `vimeo`, `posterSRC`, `playerSize`, `playerOptions`, `playerStart`, `playerStop`, `playerTitle`, `playerCaption`, `playerAspect`, `textTrackSRC`, `playerPreload`, `playerColor`, `youtubeOptions`, `vimeoOptions`, `sliderDelay`, `sliderSpeed`, `sliderStartSlide`, `data`, `cteAlias`, `articleAlias`, `article`, `form`, `module`, `groups`, `cssID`, `start`, `stop`, `com_order`, `com_perPage`, `com_template`) VALUES ('','headline',0,0,0,0,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,NULL,2,5,'tl_article',128,1786716133,'a:2:{s:4:\"unit\";s:2:\"h2\";s:5:\"value\";s:14:\"Perspektivwerk\";}','a:2:{s:5:\"value\";s:0:\"\";s:4:\"unit\";s:2:\"h2\";}',NULL,NULL,NULL,NULL,NULL,NULL,'above',NULL,NULL,'',NULL,NULL,'',0,'ascending','','','','','sourceText',NULL,NULL,'','','','',NULL,4,0,0,'','','',NULL,'','',NULL,'',NULL,'','','','','',NULL,'','',NULL,NULL,0,300,0,NULL,0,0,0,0,0,NULL,'a:2:{i:0;s:0:\"\";i:1;s:0:\"\";}','','','ascending',0,'');
|
||||||
|
INSERT INTO `tl_content` (`title`, `type`, `addImage`, `showPreview`, `inline`, `overwriteMeta`, `size`, `fullsize`, `thead`, `tfoot`, `tleft`, `sortable`, `closeSections`, `target`, `overwriteLink`, `useImage`, `useHomeDir`, `metaIgnore`, `splashImage`, `sliderContinuous`, `protected`, `jumpTo`, `redirectBack`, `autologin`, `pwResetPage`, `invisible`, `com_moderate`, `com_bbcode`, `com_disableCaptcha`, `com_requireLogin`, `jsonData`, `id`, `pid`, `ptable`, `sorting`, `tstamp`, `headline`, `sectionHeadline`, `text`, `singleSRC`, `alt`, `imageTitle`, `imageUrl`, `caption`, `floating`, `html`, `unfilteredHtml`, `listtype`, `listitems`, `tableitems`, `summary`, `sortIndex`, `sortOrder`, `mooHeadline`, `mooStyle`, `mooClasses`, `highlight`, `markdownSource`, `code`, `url`, `titleText`, `linkTitle`, `embed`, `rel`, `multiSRC`, `perRow`, `perPage`, `numberOfItems`, `sortBy`, `galleryTpl`, `customTpl`, `playerSRC`, `youtube`, `vimeo`, `posterSRC`, `playerSize`, `playerOptions`, `playerStart`, `playerStop`, `playerTitle`, `playerCaption`, `playerAspect`, `textTrackSRC`, `playerPreload`, `playerColor`, `youtubeOptions`, `vimeoOptions`, `sliderDelay`, `sliderSpeed`, `sliderStartSlide`, `data`, `cteAlias`, `articleAlias`, `article`, `form`, `module`, `groups`, `cssID`, `start`, `stop`, `com_order`, `com_perPage`, `com_template`) VALUES ('','headline',0,0,0,0,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,NULL,3,3,'tl_article',128,1786716801,'a:2:{s:4:\"unit\";s:2:\"h2\";s:5:\"value\";s:83:\"PerspektivWerk ÔÇô Br├╝cke zwischen Diagnostik, Begleitung und betrieblicher Praxis\";}','a:2:{s:5:\"value\";s:0:\"\";s:4:\"unit\";s:2:\"h2\";}',NULL,NULL,NULL,NULL,NULL,NULL,'above',NULL,NULL,'',NULL,NULL,'',0,'ascending','','','','','sourceText',NULL,NULL,'','','','',NULL,4,0,0,'','','',NULL,'','',NULL,'',NULL,'','','','','',NULL,'','',NULL,NULL,0,300,0,NULL,0,0,0,0,0,NULL,'a:2:{i:0;s:0:\"\";i:1;s:0:\"\";}','','','ascending',0,'');
|
||||||
|
|
||||||
|
|
||||||
|
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[string]$ComposeFile = (Join-Path $PSScriptRoot '..\docker-compose.yml'),
|
||||||
|
[string]$OutputPath = (Join-Path $PSScriptRoot '..\database\contao-baseline.sql'),
|
||||||
|
[switch]$Force
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$tables = @('tl_theme', 'tl_layout', 'tl_module', 'tl_page', 'tl_article', 'tl_content', 'tl_form', 'tl_form_field')
|
||||||
|
|
||||||
|
if ((Test-Path -LiteralPath $OutputPath) -and -not $Force) {
|
||||||
|
$confirmation = Read-Host "Die Datei '$OutputPath' existiert bereits. Überschreiben? [j/N]"
|
||||||
|
if ($confirmation.Trim().ToLowerInvariant() -notin @('j', 'ja', 'y', 'yes')) {
|
||||||
|
Write-Host 'Export nicht überschrieben.'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$composeFile = (Resolve-Path -LiteralPath $ComposeFile).Path
|
||||||
|
$outputDirectory = Split-Path -Parent $OutputPath
|
||||||
|
New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null
|
||||||
|
|
||||||
|
# Credentials bleiben im Compose-Service und werden nicht in den Export geschrieben.
|
||||||
|
$command = 'exec mariadb-dump -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" --no-tablespaces --no-create-info --skip-comments --skip-triggers --skip-add-locks --skip-disable-keys --complete-insert --skip-extended-insert --order-by-primary --hex-blob "$MARIADB_DATABASE" tl_theme tl_layout tl_module tl_page tl_article tl_content tl_form tl_form_field'
|
||||||
|
$dump = & docker compose -f $composeFile exec -T db sh -lc $command
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw 'Der Contao-Baseline-Export ist fehlgeschlagen.'
|
||||||
|
}
|
||||||
|
|
||||||
|
$header = @(
|
||||||
|
'-- Contao website baseline for local development.',
|
||||||
|
'--',
|
||||||
|
'-- Contains only versionable website data. It deliberately excludes users,',
|
||||||
|
'-- credentials, sessions, logs, cache entries and file metadata.',
|
||||||
|
'-- Generated with scripts/Export-ContaoBaseline.ps1.',
|
||||||
|
''
|
||||||
|
)
|
||||||
|
|
||||||
|
$utf8WithoutBom = New-Object System.Text.UTF8Encoding($false)
|
||||||
|
[System.IO.File]::WriteAllText(
|
||||||
|
(Resolve-Path -LiteralPath $outputDirectory).Path + [System.IO.Path]::DirectorySeparatorChar + (Split-Path -Leaf $OutputPath),
|
||||||
|
(($header + $dump) -join [Environment]::NewLine) + [Environment]::NewLine,
|
||||||
|
$utf8WithoutBom
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Host "Contao-Baseline exportiert nach $OutputPath"
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[string]$ComposeFile = (Join-Path $PSScriptRoot '..\docker-compose.yml'),
|
||||||
|
[string]$SeedPath = (Join-Path $PSScriptRoot '..\database\contao-baseline.sql'),
|
||||||
|
[switch]$ReplaceExisting
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$tables = @('tl_theme', 'tl_layout', 'tl_module', 'tl_page', 'tl_article', 'tl_content', 'tl_form', 'tl_form_field')
|
||||||
|
|
||||||
|
if (-not (Test-Path -LiteralPath $SeedPath)) {
|
||||||
|
throw "Der Baseline-Seed '$SeedPath' wurde nicht gefunden."
|
||||||
|
}
|
||||||
|
|
||||||
|
$composeFile = (Resolve-Path -LiteralPath $ComposeFile).Path
|
||||||
|
$countQuery = ($tables | ForEach-Object { "SELECT COUNT(*) FROM $_" }) -join ' UNION ALL '
|
||||||
|
$checkCommand = "mariadb -N -u`"`$MARIADB_USER`" -p`"`$MARIADB_PASSWORD`" `"`$MARIADB_DATABASE`" -e `"$countQuery`""
|
||||||
|
$existingRows = (& docker compose -f $composeFile exec -T db sh -lc $checkCommand | ForEach-Object { [int]$_ } | Measure-Object -Sum).Sum
|
||||||
|
|
||||||
|
if ($existingRows -gt 0 -and -not $ReplaceExisting) {
|
||||||
|
throw 'Die versionierten Contao-Tabellen enthalten bereits Daten. Der Import wurde nicht ausgeführt. Nutze -ReplaceExisting nur, wenn du die aktuelle Seitenstruktur bewusst durch den Git-Stand ersetzen möchtest.'
|
||||||
|
}
|
||||||
|
|
||||||
|
$seed = Get-Content -LiteralPath $SeedPath -Raw
|
||||||
|
if ($ReplaceExisting) {
|
||||||
|
$deleteStatements = @(
|
||||||
|
'SET FOREIGN_KEY_CHECKS=0;',
|
||||||
|
'DELETE FROM tl_content;',
|
||||||
|
'DELETE FROM tl_article;',
|
||||||
|
'DELETE FROM tl_form_field;',
|
||||||
|
'DELETE FROM tl_form;',
|
||||||
|
'DELETE FROM tl_module;',
|
||||||
|
'DELETE FROM tl_page;',
|
||||||
|
'DELETE FROM tl_layout;',
|
||||||
|
'DELETE FROM tl_theme;',
|
||||||
|
'SET FOREIGN_KEY_CHECKS=1;',
|
||||||
|
''
|
||||||
|
) -join [Environment]::NewLine
|
||||||
|
$seed = $deleteStatements + $seed
|
||||||
|
}
|
||||||
|
|
||||||
|
$utf8WithoutBom = New-Object System.Text.UTF8Encoding($false)
|
||||||
|
[Console]::OutputEncoding = $utf8WithoutBom
|
||||||
|
$seed | & docker compose -f $composeFile exec -T db sh -lc 'exec mariadb -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE"'
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw 'Der Contao-Baseline-Import ist fehlgeschlagen.'
|
||||||
|
}
|
||||||
|
|
||||||
|
& docker compose -f $composeFile exec -T app sh -lc 'runuser -u www-data -- vendor/bin/contao-console cache:clear --env=dev'
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw 'Der Import war erfolgreich, aber der Contao-Cache konnte nicht geleert werden.'
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host 'Contao-Baseline importiert und Cache geleert.'
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
$projectRoot = Split-Path -Parent $PSScriptRoot
|
||||||
|
$seedPath = Join-Path $projectRoot 'database\contao-baseline.sql'
|
||||||
|
$exportScriptPath = Join-Path $projectRoot 'scripts\Export-ContaoBaseline.ps1'
|
||||||
|
$importScriptPath = Join-Path $projectRoot 'scripts\Import-ContaoBaseline.ps1'
|
||||||
|
|
||||||
|
Describe 'Contao baseline' {
|
||||||
|
$seed = Get-Content -LiteralPath $seedPath -Raw
|
||||||
|
|
||||||
|
It 'contains the page-specific PerspektivWerk background rule' {
|
||||||
|
$seed | Should Match 'body\.perspektivwerk-page \{ background-color: #159A34; \}'
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'contains the versioned Contao website tables' {
|
||||||
|
foreach ($table in @('tl_theme', 'tl_layout', 'tl_page', 'tl_article', 'tl_content')) {
|
||||||
|
$seed | Should Match "INSERT INTO ``$table``"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'does not contain user, runtime or unversioned file metadata' {
|
||||||
|
$seed | Should Not Match 'INSERT INTO `tl_(user|session|log|lock|files)'
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'uses the same approved table list in export and import scripts' {
|
||||||
|
$export = Get-Content -LiteralPath $exportScriptPath -Raw
|
||||||
|
$import = Get-Content -LiteralPath $importScriptPath -Raw
|
||||||
|
|
||||||
|
foreach ($table in @('tl_theme', 'tl_layout', 'tl_module', 'tl_page', 'tl_article', 'tl_content', 'tl_form', 'tl_form_field')) {
|
||||||
|
$export | Should Match $table
|
||||||
|
$import | Should Match $table
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'asks before overwriting an existing baseline export' {
|
||||||
|
$export = Get-Content -LiteralPath $exportScriptPath -Raw
|
||||||
|
|
||||||
|
$export | Should Match 'Read-Host'
|
||||||
|
$export | Should Match 'überschreiben'
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user