# multisql - narzędzie do masowego uruchamiania skryptów SQL na wielu bazach ## Opis multisql - uruchamia zestaw skryptów na skonfigurowanej liście baz danych. Program, dla każdej z baz wskazanych w konfiguracji, uruchamia kolejno każdy z plików sql wskazanych parametrem lub w pliku konfiguracji poprzez uruchomienie narzędzia psql: ``` psql -f skrypt.sql -w -L log.txt _szczegóły_połaczenia_ 2>stderr.txt > stdout.txt ``` Skrypty mogą mieć dowolne rozszerzenia ale podkatalogi nie są obsługiwane. Pliki wynikowe zapisywane są do katalogu wskazanego w outdir w strukturze o postaci output: ``` -> data-godzina-pid -> host-port-baza-user -> skrypt.sql -> log.txt -> stdout.txt -> stderr.txt ``` ## Użycie ``` multisql -outdir /tmp -sqldir /data/skrypty -passfile ./hasla ``` ## Opis flag ``` -config string Plik konfiguracji (default "multisql.conf") -log string Plik, do którego zostanie dopisany log programu -outdir string Katalog (istniejący i z prawem do zapisu), do którego generowane są wyniki -passfile string Plik pgpass z hasłami do baz -sqldir string Katalog, w którym znajdują się skrypty do uruchomienia (default "scripts") -verbose Dodatkowe komunkaty diagnostyczne ``` Plik passfile ma standardowy format .pgpass PostgreSQLa. Plik multisql.conf ma format JSON, np: ```json { "Passfile": "mypgpass", "PsqlExec": "/usr/local/bin/psql", "SqlDir": "/data/skrypty-sql", "Defaults": { "User": "myapp", "Port": 5433, "DbName": "moja-db" }, "Connections": [ { "Host": "10.20.30.01" }, { "Host": "10.20.30.02", "User": "innyuser", "DbName": "innadb" } ] } ``` PsqlExec jest opcjonalny - jesli nie zostanie podany wyszukuje się programu psql.exe w PATH. Każde połączenie w tablicy Connections może zawierać Host, Port, User i DbName. Brakujące wartości są uzupełniane z sekcji Defaults (która ma taki sam format jak obiekt w Connections). Parametry mają pierwszeństwo przed wartościami w konfiguracji. Format pliku passfile jest następujący: ``` hostname:port:database:username:password ``` W szczegółach opisano go na https://www.postgresql.org/docs/current/libpq-pgpass.html. W skryptach można korzystać ze wszystkich funkcji psqla, np: ```sql select true as warunek \gset \if :warunek \o ekstra.txt select 'Warunek został spełniony!!!'; \endif ``` Powyższy select (dzieki \gset) zapamięta pozyskaną wartość (w tym wypadku prymitywne true) do zmiennej warunek. Sekcja if / endif wykona się tylko wtedy, jeśli warunek był true i operacja `\o`, która tworzy nowy plik i resztę wyników kieruje do niego, też wykonuje się warunkowo. W efekcie, jeśli warunek jest spełniony, w katalogu wynikowym działania skryptu pojawi się dodatkowy plik (ekstra.txt) co pozwoli łatwo wychwycić, dla których baz ów warunek występuje. ## Obsługa plików szyfrowanych Od wersji 0.2.1 plik z hasłami (pgpass) musi być zaszyforwany. Szyfrowanie można wykonać następującym poleceniem: ```sh multisql encrypt pgpass.sec pgpass ``` Program zapyta o nowe hasło a następnie zaszyfruje treść pliku pgpass i zapisze go do pliku pgpass.sec. W konfiguracji należy ustawić plik wartość `"Passfile"` na `pgpass.sec`. Zaszyfrowany plik można odszyfrować i zapisać do pliku jawnego lub podejrzeć: ```bash multisql -P decrypt pgpass.sec # po udanym odszyfrowaniu wyświetli treść pliku # lub multisql -P decryp pgpass.sec newpgpass # w tym wariancie odszyfrowana treść zostanie zapisana do newpgpass ``` Opcja `-P` powoduje, że program pyta o hasło. Jeśli nie podano tej opcji, program próbuje użyć hasła ustawionego w zmiennej środowiskowej `MULTISQLPASS`. Zmienną można ustawić w następujący sposób: Linux: ```bash export MULTISQLPASS=abc ``` Windows cmd: ```cmd set MULTISQLPASS=abc ``` Windows, powershell: ```powershell $env:MULTISQLPASS = "abc" ``` Użycie opcji `-P` powoduje, że zmienna środowiskowa jest ignorowana i hasło pobierane jest z klawiatury. > Uwaga: Od wersji 0.2.3 wykorzystywany jest format szyfrowania > [age-encryption](https://age-encryption.org/). > Plik haseł można więc szyfrować i deszyftować również narzędziem > `age` (https://github.com/FiloSottile/age/releases/tag/v1.0.0)