84 lines
4.9 KiB
Markdown
84 lines
4.9 KiB
Markdown
# Publicarea scripturilor de baza de date catre clienti
|
|
|
|
Scriptul: `COMUN\utile\publicare_scripturi.ps1`. Inlocuieste pasii manuali din `tasks.exe`
|
|
(`D:\PROIECTE\fox\tasks`, formularul din `clase\generare_script.vcx`), care raman varianta de rezerva.
|
|
Cum se scrie un script de migrare: `scripturi-migrare-db.md`.
|
|
|
|
```powershell
|
|
powershell -File COMUN\utile\publicare_scripturi.ps1 -DryRun # ce ar face pe luna curenta
|
|
powershell -File COMUN\utile\publicare_scripturi.ps1 # luna curenta, tot fluxul
|
|
powershell -File COMUN\utile\publicare_scripturi.ps1 -Luna 2026-08 # alta luna
|
|
powershell -File COMUN\utile\publicare_scripturi.ps1 -Fisier a.sql,b.sql # doar scripturile date
|
|
```
|
|
|
|
Alte optiuni: `-DoarImport` (fara arhiva), `-DoarArhiva` (doar regenerare arhiva), `-Toate`
|
|
(republica si scripturile identice), `-FaraVerificareZip`, `-Settings`, `-ZipPath`, `-DirScripturi`,
|
|
`-Alias`, `-User`, `-Password`, `-SqlPlus`.
|
|
|
|
## Configurarea
|
|
|
|
Se citeste din `settings.ini`-ul lui `tasks.exe` (`D:\PROIECTE\fox\tasks\settings.ini`, schimbabil
|
|
cu `-Settings`), aceleasi chei pe care le foloseste formularul; orice parametru dat explicit bate
|
|
ini-ul.
|
|
|
|
| din ini | ce devine |
|
|
|---|---|
|
|
| `[connection] host_database` | nume de **DSN ODBC** — aliasul TNS e cheia `ServerName` a DSN-ului din registri (`CENTRAL` → `ROA_CENTRAL`) |
|
|
| `[connection] username_database` / `password_database` | utilizatorul Oracle |
|
|
| `[folder] script_folder` | directorul scripturilor, cu `\SCRIPTURI\` → `\SCRIPTURI_CLAR\` (+ `\<an>\<luna>\`) |
|
|
| `[folder] roa_output` | + `_UPDATE\` = directorul arhivelor |
|
|
| `[folder] sqlplus_exe` | clientul Oracle (si `TNS_ADMIN` = directorul lui) |
|
|
| `[script]` | prefixele valide (`CO_`, `FF_`, `RF_`, `SYS_`, `JCS_`) — prefix necunoscut = avertisment |
|
|
|
|
`sqlplus_exe` arata spre `instantclient_19_18`; `instantclient_11_2_0_2` (valoarea de dinainte) are
|
|
un `tnsnames.ora` vechi, cu `ROA_CENTRAL` pe `10.0.20.122` in loc de `.121`, deci conexiunea expira.
|
|
`settings.ini` e local (ignorat de SVN).
|
|
|
|
## Cei doi pasi
|
|
|
|
**1. Import** — fiecare `.sql` intra ca un rand in `CONTAFIN_ORACLE.UPD_DATABASE` de pe `ROA_CENTRAL`,
|
|
cu `SCRIPT_ORDER = 0` (randul contine scriptul intreg, nu instructiuni parsate), `SCRIPT_NAME` cu
|
|
MAJUSCULE si `.SQL`, `SCRIPT_TYPE` = ce urmeaza dupa `NN_`, `SCRIPT_CONTENT` = fisierul in clar.
|
|
`ID` vine din trigger, `DATAORA` din `SYSDATE` implicit, `SCRIPT_APPVER`/`SCRIPT_EXTRA_FILE` raman
|
|
goale. Daca `SCRIPT_NAME` exista deja, se face **update pe acelasi `id`** — asa se republica un
|
|
script corectat, pentru ca clientul face `MERGE ... on (a.id = b.id)`.
|
|
|
|
**2. Arhiva lunara** — in `Y:\ROAUPDATE\_UPDATE\` se scriu `database_YYYYMMDD_YYYYMMDD.zip` **si**
|
|
`databasen_...zip` (identice azi: `database_` era varianta criptata cu `wrap.exe`, nu se mai
|
|
foloseste). Fiecare contine XML-ul cu acelasi nume ca zip-ul (format `VFPData`/`crsxml`,
|
|
Windows-1252, CRLF, tab-uri, `script_content` gol) plus cate un `<STEM_MAJUSCULE>.sql` per script.
|
|
Indexii `roa_database.xml` / `roa_databasen.xml` listeaza arhivele existente si se schimba doar
|
|
cand apare o luna noua.
|
|
|
|
Continutul din arhiva se citeste **inapoi din baza**, nu de pe disc — deci arhiva contine exact ce
|
|
va primi clientul.
|
|
|
|
## Verificari facute automat
|
|
|
|
- fisier cu sfarsituri de linie LF: **refuzat** (parsarea pe client se face pe `CHR(13)+CHR(10)`);
|
|
- dupa import, continutul e citit inapoi din CLOB si comparat octet cu octet cu fisierul; la
|
|
diferenta se opreste inainte de arhiva;
|
|
- scripturile deja publicate cu acelasi continut se sar (`-Toate` forteaza republicarea);
|
|
- arhiva generata se citeste inapoi cu cititorul clientului (`pack_utils.decodebase64` +
|
|
`zip_util_pkg.get_file`) si se compara lungime + MD5 per fisier — o arhiva facuta din PowerShell
|
|
este citita corect de `zip_util_pkg`;
|
|
- fisierele inlocuite din `_UPDATE` se copiaza intai in `_UPDATE\_backup\<data_ora>\`.
|
|
|
|
`Y:\ROAUPDATE\_UPDATE\` e **live**: clientii descarca de acolo imediat ce fisierul e pus.
|
|
|
|
## Ce face clientul
|
|
|
|
`PACK_UPDATE.UpdateScripts` (`COMUN\docs\PACK_UPDATE.pck`) descarca indexul, apoi arhivele care
|
|
acopera perioada neaplicata, extrage XML-ul cu `zip_util_pkg.get_file`, face `MERGE` in
|
|
`UPD_DATABASE` pe `id`, apoi pentru fiecare rand cu `script_extra_file` pune continutul fisierului
|
|
in `script_content` — pentru `.sql` text clar, fara base64 (base64 e doar pentru instructiunile
|
|
parsate, alta ramura). Actualizare blocata: `depanare-pack-update.md`.
|
|
|
|
## Detalii de implementare
|
|
|
|
Continutul circula **hexazecimal** in ambele sensuri (`utl_i18n.raw_to_char` / `string_to_raw` cu
|
|
`WE8MSWIN1252`), pe bucati de 900 de octeti, in blocuri PL/SQL de cate 15 bucati. Motivul: baza e
|
|
`AL32UTF8`, fisierele sunt CP1252, iar comanda trimisa lui `sqlplus` ramane ASCII pur — nu depinde
|
|
de `NLS_LANG` si nu poate strica octetii >= 0x80. Consecinta utila: comparatia dintre fisier si
|
|
CLOB e exacta, nu pe lungime.
|