feature/generador-instaladores-linux-windows

This commit is contained in:
2026-07-01 10:33:05 -06:00
parent 0d8d80d61d
commit 0c14f1166b
17 changed files with 802 additions and 90 deletions

View File

@@ -378,6 +378,24 @@ class SQLServerManager:
except Exception:
app_logger.warning("No se pudo cerrar la conexión SQL tras el RESTORE")
@staticmethod
def _sql_path_sep(data_folder: str) -> str:
"""
Separador de rutas que espera el SQL Server destino, deducido del formato
de data_folder. Windows (C:\\..., o contiene '\\') usa '\\'; SQL Server
sobre Linux (rutas POSIX '/var/opt/mssql/...') usa '/'. Las rutas del MOVE
son del filesystem del SERVIDOR, no de donde corre la app.
"""
if "\\" in data_folder:
return "\\"
# Ruta POSIX explícita ("/...") o sin separador Windows → '/'.
if data_folder.startswith("/"):
return "/"
# Heurística: "C:" u otra letra de unidad ⇒ Windows.
if len(data_folder) >= 2 and data_folder[1] == ":":
return "\\"
return "/"
@staticmethod
def _build_move_clauses(db_name, data_folder, logical_files) -> list:
"""
@@ -386,7 +404,13 @@ class SQLServerManager:
- 1er data → {db}.mdf, siguientes → {db}_N.ndf
- 1er log → {db}_log.ldf, siguientes → {db}_log_N.ldf
- otros tipos (FILESTREAM/full-text) → {db}_{nombre_lógico_saneado}
El separador se adapta al SO del SQL Server destino (deducido de
data_folder), de modo que funciona tanto con SQL Server en Windows
(C:\\...\\db.mdf) como en Linux (/var/opt/mssql/data/db.mdf).
"""
sep = SQLServerManager._sql_path_sep(data_folder)
base = data_folder.rstrip("\\/")
clauses = []
data_idx = 0
log_idx = 0
@@ -394,16 +418,16 @@ class SQLServerManager:
if lf.type == 'D':
suffix = "" if data_idx == 0 else f"_{data_idx}"
ext = "mdf" if data_idx == 0 else "ndf"
new_path = f"{data_folder}\\{db_name}{suffix}.{ext}"
new_path = f"{base}{sep}{db_name}{suffix}.{ext}"
data_idx += 1
elif lf.type == 'L':
suffix = "" if log_idx == 0 else f"_{log_idx}"
new_path = f"{data_folder}\\{db_name}_log{suffix}.ldf"
new_path = f"{base}{sep}{db_name}_log{suffix}.ldf"
log_idx += 1
else:
# No descartar otros tipos: moverlos preservando el nombre lógico.
safe = "".join(c if c.isalnum() else "_" for c in lf.logical_name)
new_path = f"{data_folder}\\{db_name}_{safe}"
new_path = f"{base}{sep}{db_name}_{safe}"
clauses.append(f"MOVE N'{lf.logical_name}' TO N'{new_path}'")
return clauses