docs & tools: Actualización de informes y scripts de migración DASUTEN
This commit is contained in:
@@ -50,9 +50,10 @@ module ADN
|
||||
|
||||
nodo = tarea[:nodo] || detectar_nodo(tarea[:id])
|
||||
nota = tarea[:texto] || "DASUTEN: #{tarea[:id]}"
|
||||
ambito = tarea[:ambito] || 'dtic-DASUTEN'
|
||||
|
||||
# Lanzar dron con bitácora automática
|
||||
cmd = "#{@dron_runner} dron lanzar --nota #{Shellwords.escape(nota)} --nodo #{Shellwords.escape(nodo)} -- ruby #{script_path}"
|
||||
cmd = "#{@dron_runner} dron lanzar --nota #{Shellwords.escape(nota)} --nodo #{Shellwords.escape(nodo)} --ambito #{Shellwords.escape(ambito)} -- ruby #{script_path}"
|
||||
|
||||
@logger.info("Ejecutando dron: #{nota}")
|
||||
@logger.debug("Comando: #{cmd}")
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# Configurar zona horaria Argentina en dasu-sql4
|
||||
# ==========================================================
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== CONFIGURAR ZONA HORARIA - ARGENTINA (UTC-3) ==="
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$JSON_PATH = "C:\\temp\\timezone_config_output.json"
|
||||
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\\temp"
|
||||
|
||||
Write-Host "[1/4] Zona horaria ACTUAL:"
|
||||
$tz = Get-TimeZone
|
||||
Write-Host " ID: $($tz.Id)"
|
||||
Write-Host " DisplayName: $($tz.DisplayName)"
|
||||
Write-Host " BaseUtcOffset: $($tz.BaseUtcOffset)"
|
||||
|
||||
Write-Host "`n[2/4] Configurando zona horaria ARGENTINA (UTC-3)..."
|
||||
|
||||
# Argentina Standard Time es el ID correcto para UTC-3
|
||||
try {
|
||||
Set-TimeZone -Id "Argentina Standard Time"
|
||||
Write-Host " ✅ Zona horaria configurada correctamente"
|
||||
} catch {
|
||||
Write-Host " ERROR: $_"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "`n[3/4] Verificando nueva configuración:"
|
||||
$tz = Get-TimeZone
|
||||
Write-Host " ID: $($tz.Id)"
|
||||
Write-Host " DisplayName: $($tz.DisplayName)"
|
||||
Write-Host " BaseUtcOffset: $($tz.BaseUtcOffset)"
|
||||
|
||||
Write-Host "`n[4/4] Fecha/hora actual:"
|
||||
Write-Host " Get-Date: $(Get-Date)"
|
||||
Write-Host " Get-Date -Format 'o': $(Get-Date -Format 'o')"
|
||||
Write-Host " UTC: $(Get-Date -AsUtc)"
|
||||
|
||||
# Verificar si SQL Server necesita reinicio
|
||||
Write-Host "`n[5/5] Verificando SQL Server:"
|
||||
$connString = "Server=localhost;Database=master;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT GETDATE() as fecha_sql, SYSUTCDATETIME() as utc_sql", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$row = $ds.Tables[0].Rows[0]
|
||||
Write-Host " GETDATE(): $($row.fecha_sql)"
|
||||
Write-Host " SYSUTCDATETIME(): $($row.utc_sql)"
|
||||
Write-Host " Diferencia con UTC: $([DateTime]::Now - [DateTime]::UtcNow)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
|
||||
$resultado = @{
|
||||
paso = "timezone_configurado"
|
||||
timezone_id = $tz.Id
|
||||
timezone_display = $tz.DisplayName
|
||||
utc_offset = $tz.BaseUtcOffset.ToString()
|
||||
timestamp = (Get-Date -Format "o")
|
||||
}
|
||||
|
||||
$resultado | ConvertTo-Json | Out-File -FilePath $JSON_PATH -Encoding utf8
|
||||
PSCMD
|
||||
|
||||
puts "\n[1/2] Configurando zona horaria..."
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script, output_path: 'C:\temp\timezone_config_output.json')
|
||||
|
||||
puts "\n[2/2] Leyendo resultado..."
|
||||
begin
|
||||
resultado = DasuExecutor.read_json_from_dasu('C:\temp\timezone_config_output.json')
|
||||
puts "\n=== RESULTADO ==="
|
||||
puts " Timezone ID: #{resultado['timezone_id']}"
|
||||
puts " Display: #{resultado['timezone_display']}"
|
||||
puts " UTC Offset: #{resultado['utc_offset']}"
|
||||
rescue => e
|
||||
puts "[!] Error leyendo resultado: #{e.message}"
|
||||
end
|
||||
|
||||
puts "\n✅ Configuración completada"
|
||||
puts "\n⚠️ NOTA: SQL Server puede necesitar reinicio para aplicar completamente la nueva zona horaria."
|
||||
@@ -114,7 +114,8 @@ module Dron
|
||||
evento_id: opciones[:evento_id],
|
||||
timeout: opciones[:timeout],
|
||||
flujo_id: opciones[:flujo_id],
|
||||
nodo: opciones[:nodo]
|
||||
nodo: opciones[:nodo],
|
||||
ambito: opciones[:ambito]
|
||||
)
|
||||
|
||||
# Mostrar resultado
|
||||
@@ -136,6 +137,7 @@ module Dron
|
||||
timeout: 3600,
|
||||
flujo_id: nil,
|
||||
nodo: nil,
|
||||
ambito: nil,
|
||||
cmd: nil
|
||||
}
|
||||
|
||||
@@ -153,6 +155,8 @@ module Dron
|
||||
opciones[:flujo_id] = args.shift
|
||||
when '--nodo'
|
||||
opciones[:nodo] = args.shift
|
||||
when '--ambito'
|
||||
opciones[:ambito] = args.shift
|
||||
when '--help', '-h'
|
||||
Dispatcher.mostrar_ayuda
|
||||
exit 0
|
||||
|
||||
@@ -24,14 +24,14 @@ module Dron
|
||||
HEARTBEAT_INTERVAL = 30
|
||||
|
||||
class << self
|
||||
def lanzar(cmd:, nota: nil, evento_id: nil, timeout: DEFAULT_TIMEOUT, flujo_id: nil, nodo: nil)
|
||||
def lanzar(cmd:, nota: nil, evento_id: nil, timeout: DEFAULT_TIMEOUT, flujo_id: nil, nodo: nil, ambito: nil)
|
||||
Base.logger.info("🛠️ Dron Ejecutor iniciado: #{Process.pid}")
|
||||
inicio = Time.now
|
||||
|
||||
# 1. Registrar en tablas internas (dron_logs)
|
||||
resultado_inicio = ADN::DB::DronDB.registrar_inicio(
|
||||
tipo: 'ejecutor', cmd: cmd, flujo_id: flujo_id,
|
||||
metadata: { nota: nota, evento_id: evento_id, timeout: timeout, nodo: nodo }
|
||||
metadata: { nota: nota, evento_id: evento_id, timeout: timeout, nodo: nodo, ambito: ambito }
|
||||
)
|
||||
dron_id = resultado_inicio[:dron_id]
|
||||
|
||||
@@ -42,7 +42,7 @@ module Dron
|
||||
)
|
||||
|
||||
# 2. Crear/vincular evento en Bitácora Web (visible)
|
||||
evento_id = crear_o_vincular_evento_web(dron_id, nota, evento_id, cmd, nodo)
|
||||
evento_id = crear_o_vincular_evento_web(dron_id, nota, evento_id, cmd, nodo, ambito)
|
||||
|
||||
# 3. Ejecutar comando con heartbeat que actualiza AMBAS capas
|
||||
resultado = ejecutar_comando(cmd, dron_id, timeout, evento_id, nota, inicio)
|
||||
@@ -161,10 +161,11 @@ module Dron
|
||||
|
||||
# ─── Bitácora Web: Crear/Vincular evento ─────────────────────
|
||||
|
||||
def crear_o_vincular_evento_web(dron_id, nota, evento_id, cmd, nodo)
|
||||
def crear_o_vincular_evento_web(dron_id, nota, evento_id, cmd, nodo, ambito = nil)
|
||||
return nil unless nota # Sin nota = sin registro en web
|
||||
|
||||
nodo_id = detectar_nodo_id(nodo)
|
||||
ambito_id = detectar_ambito_id(ambito)
|
||||
|
||||
BitacorasDB::BitacoraDB.with_connection do |db|
|
||||
if evento_id.to_i > 0
|
||||
@@ -196,12 +197,14 @@ module Dron
|
||||
estado: '⏳',
|
||||
modo: 'P',
|
||||
bitacora_id: bitacora_hoy['id'],
|
||||
nodo_id: nodo_id
|
||||
nodo_id: nodo_id,
|
||||
ambito_id: ambito_id
|
||||
)
|
||||
entrada['id']
|
||||
else
|
||||
evento = db.crear_evento(
|
||||
nodo_id: nodo_id,
|
||||
ambito_id: ambito_id,
|
||||
descripcion: descripcion,
|
||||
inicio: Time.now.strftime('%H:%M'),
|
||||
estado: '⏳',
|
||||
@@ -307,6 +310,21 @@ module Dron
|
||||
Base.logger.warn("⚠️ Error detectando nodo: #{e.message}, usando default (1)")
|
||||
1
|
||||
end
|
||||
|
||||
def detectar_ambito_id(ambito)
|
||||
return ambito if ambito.is_a?(Integer)
|
||||
return nil if ambito.nil? || ambito.empty?
|
||||
|
||||
resultado = nil
|
||||
BitacorasDB::BitacoraDB.with_connection do |db|
|
||||
resultado = db.execute('SELECT id FROM bitacoras.ambitos WHERE LOWER(nombre) = $1 LIMIT 1', [ambito.downcase])
|
||||
end
|
||||
|
||||
resultado&.any? ? resultado.first['id'] : nil
|
||||
rescue StandardError => e
|
||||
Base.logger.warn("⚠️ Error detectando ámbito: #{e.message}, usando default (nil)")
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
# adn/tools/cli/drones/dasuten_download_drive-dasu-sql4.rb
|
||||
# ==========================================================
|
||||
# Dron: Download desde Google Drive a dasu-sql4
|
||||
# Flujo: Google Drive → F:\BACKUP\sysdasuten_compressed_ADN.bak
|
||||
# Usa: Invoke-WebRequest (sin rclone)
|
||||
# Flujo: Google Drive → F:\BACKUP\sysdasuten_FULL_YYYYMMDD_HHMMSS.bak
|
||||
# Usa: rclone copy (mantiene nombre original del backup)
|
||||
# ==========================================================
|
||||
|
||||
require 'time'
|
||||
@@ -27,9 +27,12 @@ end.parse!(ARGV)
|
||||
|
||||
BACKUP_DIR_WINDOWS = "F:\\BACKUP"
|
||||
BACKUP_NAME_DEFAULT = "sysdasuten_compressed_ADN.bak"
|
||||
JSON_PATH = "C:\temp\dron_download_output.json"
|
||||
JSON_PATH = "C:\\temp\\dron_download_output.json"
|
||||
|
||||
# Determinar archivo a descargar
|
||||
backup_name = nil
|
||||
file_id = nil
|
||||
|
||||
if opciones[:test_file]
|
||||
puts "[*] Dron: Download desde Google Drive"
|
||||
puts " Nodo: dasu-sql4"
|
||||
@@ -52,10 +55,20 @@ else
|
||||
if File.exist?(UPLOAD_OUTPUT)
|
||||
upload_data = JSON.parse(File.read(UPLOAD_OUTPUT))
|
||||
drive_ruta = upload_data['drive_ruta']
|
||||
file_id = File.basename(drive_ruta)
|
||||
# Extraer el nombre EXACTO del archivo desde drive_ruta (ej: "rmonla-GDrive:drive_bkps-dasu/sysdasuten_FULL_20260415_121943.bak")
|
||||
backup_name = File.basename(drive_ruta)
|
||||
|
||||
puts "[*] Dron: Buscando Google Drive ID real (rclone)..."
|
||||
raw_json = `rclone lsjson '#{drive_ruta}' 2>/dev/null`.strip
|
||||
begin
|
||||
parsed = JSON.parse(raw_json).first
|
||||
file_id = parsed['ID']
|
||||
rescue
|
||||
puts "[!] Error al parsear ID de Google Drive. rclone regresó vacio."
|
||||
exit 1
|
||||
end
|
||||
|
||||
download_url = "https://drive.google.com/uc?export=download&id=#{file_id}"
|
||||
puts "[*] Dron: Download desde Google Drive"
|
||||
puts " Nodo: dasu-sql4"
|
||||
puts " Drive ruta: #{drive_ruta}"
|
||||
puts " File ID: #{file_id}"
|
||||
@@ -66,55 +79,44 @@ else
|
||||
end
|
||||
end
|
||||
|
||||
# Validar que backup_name tenga el formato correcto (FULL o DIF con fecha)
|
||||
unless backup_name =~ /sysdasuten_(FULL|DIF)_\d{8}_\d{6}\.bak/
|
||||
puts "[!] Advertencia: El nombre del backup '#{backup_name}' no sigue el formato esperado (sysdasuten_FULL_YYYYMMDD_HHMMSS.bak)"
|
||||
end
|
||||
|
||||
# PowerShell script para download
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$BACKUP_DIR = "F:\\BACKUP"
|
||||
$DOWNLOAD_URL = "#{download_url}"
|
||||
$BACKUP_NAME = "#{backup_name}"
|
||||
$LOCAL_BACKUP = "$BACKUP_DIR\\$BACKUP_NAME"
|
||||
$JSON_PATH = "C:\\temp\\dron_download_output.json"
|
||||
$REMOTE_RCLONE_PATH = "#{drive_ruta}"
|
||||
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\\temp"
|
||||
$null = New-Item -ItemType Directory -Force -Path $BACKUP_DIR
|
||||
|
||||
Write-Host "[1/3] Iniciando descarga..."
|
||||
Write-Host " URL: $DOWNLOAD_URL"
|
||||
Write-Host "[1/3] Iniciando descarga con Rclone Nativo..."
|
||||
Write-Host " Origen: $REMOTE_RCLONE_PATH"
|
||||
Write-Host " Destino: $LOCAL_BACKUP"
|
||||
|
||||
Write-Host "[2/3] Descargando..."
|
||||
$start = Get-Date
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri $DOWNLOAD_URL -UseBasicParsing -Headers @{
|
||||
"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
||||
}
|
||||
|
||||
$html = $response.Content
|
||||
$fileId = ""
|
||||
$uuid = ""
|
||||
$confirm = "t"
|
||||
if ($html -match 'name="id" value="([^"]+)"') { $fileId = $matches[1] }
|
||||
if ($html -match 'name="uuid" value="([^"]+)"') { $uuid = $matches[1] }
|
||||
if ($html -match 'name="confirm" value="([^"]+)"') { $confirm = $matches[1] }
|
||||
# Limpiamos el ultimo archivo varado (por si el anterior dejo su esqueleto de 0 bytes)
|
||||
if (Test-Path $LOCAL_BACKUP) { Remove-Item $LOCAL_BACKUP -Force }
|
||||
|
||||
Write-Host " File ID: $fileId"
|
||||
Write-Host " UUID: $uuid"
|
||||
# Llamamos al rclone binario local apuntando al config
|
||||
& C:\\rclone\\rclone.exe copy "$REMOTE_RCLONE_PATH" "$BACKUP_DIR\\" --config "C:\\rclone\\rclone.conf" --stats-one-line --stats 1s
|
||||
|
||||
$downloadConfirmUrl = "https://drive.usercontent.google.com/download?id=$fileId&export=download&confirm=$confirm&uuid=$uuid"
|
||||
Write-Host " URL confirmada: $downloadConfirmUrl"
|
||||
|
||||
$finalResponse = Invoke-WebRequest -Uri $downloadConfirmUrl -UseBasicParsing -Headers @{
|
||||
"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
||||
}
|
||||
|
||||
[System.IO.File]::WriteAllBytes($LOCAL_BACKUP, $finalResponse.Content)
|
||||
|
||||
$dur = (New-TimeSpan -Start $start -End (Get-Date)).TotalSeconds
|
||||
Write-Host "[+] Descarga en $([math]::Round($dur, 2))s"
|
||||
} catch {
|
||||
Write-Host "[!] Error: $_"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[!] Error: Falló la descarga de rclone (Código exit: $LASTEXITCODE)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$dur = (New-TimeSpan -Start $start -End (Get-Date)).TotalSeconds
|
||||
Write-Host "[+] Descarga en $([math]::Round($dur, 2))s"
|
||||
|
||||
Write-Host "[3/3] Verificando..."
|
||||
if (Test-Path $LOCAL_BACKUP) {
|
||||
$tam = (Get-Item $LOCAL_BACKUP).Length
|
||||
@@ -131,6 +133,7 @@ ps_script = <<~PSCMD.strip
|
||||
$res = @{
|
||||
paso = "download_complete"
|
||||
backup_local = $LOCAL_BACKUP
|
||||
backup_name = $BACKUP_NAME
|
||||
drive_origen = "Google Drive"
|
||||
nodo = "dasu-sql4"
|
||||
duracion = [math]::Round($dur, 2)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
require 'tiny_tds'
|
||||
require 'time'
|
||||
require 'json'
|
||||
require 'base64'
|
||||
require_relative 'lib/dasu_executor'
|
||||
|
||||
# Nombre del archivo con timestamp
|
||||
@@ -33,6 +34,10 @@ begin
|
||||
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
smb_user = 'rmonla'
|
||||
smb_server = 'srv-ns8'
|
||||
smb_share = 'bkps-dasuten'
|
||||
smb_path = "\\\\#{smb_server}\\#{smb_share}"
|
||||
|
||||
if sql_pass.empty?
|
||||
puts "[!] Error: No se pudo obtener credencial de candados"
|
||||
@@ -47,8 +52,24 @@ begin
|
||||
)
|
||||
puts "[+] Conectado a SQL Server en #{sql_host} (auth: Windows)"
|
||||
|
||||
# Mapear share SMB con credenciales usando PowerShell
|
||||
puts "\n[0/3] Mapeando share SMB #{smb_path}..."
|
||||
# Escapar password para PowerShell
|
||||
sql_pass_escaped = sql_pass.gsub("'", "''")
|
||||
ps_map = "net use X: #{smb_path} #{sql_pass_escaped} /user:#{smb_user} /persistent:no"
|
||||
map_result = client.execute("EXEC xp_cmdshell '#{ps_map}'")
|
||||
map_output = []
|
||||
map_result.each { |r| map_output << r['output'] if r['output'] && !r['output'].strip.empty? }
|
||||
puts " #{map_output.join("\n ")}"
|
||||
puts "[+] Share mapeado en X: -> #{smb_path}"
|
||||
|
||||
# Crear directorio en share si no existe
|
||||
puts "\n[1/3] Verificando directorio en share..."
|
||||
client.execute("EXEC master.sys.xp_create_subdir 'X:\\'").each { |r| }
|
||||
puts "[+] Directorio share asegurado: X:\\"
|
||||
|
||||
# Generar backup diferencial directamente en share X:
|
||||
puts "\n[0/2] Generando backup diferencial en share X:..."
|
||||
puts "[2/3] Generando backup diferencial en share X:..."
|
||||
start = Time.now
|
||||
|
||||
sql = <<~SQL.strip
|
||||
@@ -65,19 +86,22 @@ begin
|
||||
duracion = (Time.now - start).round(2)
|
||||
puts "[+] Backup diferencial generado en #{duracion} segundos"
|
||||
|
||||
# Verificar archivo en share usando módulo común
|
||||
puts "\n[1/2] Verificando archivo en share..."
|
||||
file_info = DasuExecutor.get_file_info_on_fenix(client, BACKUP_FILE)
|
||||
|
||||
if file_info[:exists]
|
||||
puts "[+] Archivo verificado: #{BACKUP_FILE} (#{file_info[:size_mb]} MB)"
|
||||
# Verificar archivo en share directamente en srv-ns8 vía SSH
|
||||
puts "\n[3/3] Verificando archivo en share..."
|
||||
backup_unix = BACKUP_FILE.gsub('X:\\', '/mnt/ns8Disco2/bkps-dasuten/')
|
||||
ls_result = `ssh rmonla@10.0.10.8 "ls -l '#{backup_unix}' 2>&1"`.strip
|
||||
if $?.success? && ls_result.include?(File.basename(backup_unix))
|
||||
# Extraer tamaño del output de ls -l
|
||||
file_size = ls_result.split[4].to_i
|
||||
puts "[+] Archivo verificado: #{backup_unix} (#{file_size.to_i / 1024 / 1024} MB)"
|
||||
else
|
||||
puts "[!] Error: No existe el archivo en #{BACKUP_FILE}"
|
||||
puts "[!] Error: No existe el archivo en #{backup_unix}"
|
||||
puts " SSH output: #{ls_result}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
# Tamaño aproximado de la BD base
|
||||
puts "\n[2/2] Información de tamaño..."
|
||||
puts "\n[4/3] Información de tamaño..."
|
||||
begin
|
||||
size_info = client.execute("SELECT size_bytes = (SELECT size * 8192 FROM sys.database_files WHERE name = 'sysdasuten')")
|
||||
puts " Tamaño BD base: #{size_info.to_a.first['size_bytes'].to_i / 1024 / 1024} MB"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
require 'tiny_tds'
|
||||
require 'time'
|
||||
require 'json'
|
||||
require 'base64'
|
||||
require_relative 'lib/dasu_executor'
|
||||
|
||||
# Nombre del archivo con timestamp
|
||||
@@ -34,6 +35,10 @@ begin
|
||||
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
smb_user = 'rmonla'
|
||||
smb_server = 'srv-ns8'
|
||||
smb_share = 'bkps-dasuten'
|
||||
smb_path = "\\\\#{smb_server}\\#{smb_share}"
|
||||
|
||||
if sql_pass.empty?
|
||||
puts "[!] Error: No se pudo obtener credencial de candados"
|
||||
@@ -48,13 +53,23 @@ begin
|
||||
)
|
||||
puts "[+] Conectado a SQL Server en #{sql_host} (auth: Windows)"
|
||||
|
||||
# Mapear share SMB con credenciales usando net use
|
||||
puts "\n[0/3] Mapeando share SMB #{smb_path}..."
|
||||
sql_pass_escaped = sql_pass.gsub("'", "''")
|
||||
ps_map = "net use X: #{smb_path} #{sql_pass_escaped} /user:#{smb_user} /persistent:no"
|
||||
map_result = client.execute("EXEC xp_cmdshell '#{ps_map}'")
|
||||
map_output = []
|
||||
map_result.each { |r| map_output << r['output'] if r['output'] && !r['output'].strip.empty? }
|
||||
puts " #{map_output.join("\n ")}"
|
||||
puts "[+] Share mapeado en X: -> #{smb_path}"
|
||||
|
||||
# Crear directorio en share si no existe
|
||||
puts "\n[0/2] Verificando directorio en share..."
|
||||
client.execute("EXEC master.sys.xp_create_subdir 'X:\\'")
|
||||
puts "\n[1/3] Verificando directorio en share..."
|
||||
client.execute("EXEC master.sys.xp_create_subdir 'X:\\'").each { |r| }
|
||||
puts "[+] Directorio share asegurado: X:\\"
|
||||
|
||||
# Generar backup comprimido directamente en share X:
|
||||
puts "[1/2] Generando backup en share X: (srv-ns8)..."
|
||||
puts "[2/3] Generando backup en share X: (srv-ns8)..."
|
||||
start = Time.now
|
||||
|
||||
result = client.execute("BACKUP DATABASE sysdasuten TO DISK = '#{BACKUP_NS8}' WITH INIT, COMPRESSION, STATS=10")
|
||||
@@ -63,14 +78,17 @@ begin
|
||||
duracion = (Time.now - start).round(2)
|
||||
puts "[+] Backup generado en #{duracion} segundos"
|
||||
|
||||
# Verificar archivo en share usando módulo común
|
||||
puts "[2/2] Verificando archivo en share..."
|
||||
file_info = DasuExecutor.get_file_info_on_fenix(client, BACKUP_NS8)
|
||||
|
||||
if file_info[:exists]
|
||||
puts "[+] Archivo verificado: #{BACKUP_NS8} (#{file_info[:size_mb]} MB)"
|
||||
# Verificar archivo en share directamente en srv-ns8 vía SSH
|
||||
puts "[3/3] Verificando archivo en share..."
|
||||
backup_unix = BACKUP_NS8.gsub('X:\\', '/mnt/ns8Disco2/bkps-dasuten/')
|
||||
ls_result = `ssh rmonla@10.0.10.8 "ls -l '#{backup_unix}' 2>&1"`.strip
|
||||
if $?.success? && ls_result.include?(File.basename(backup_unix))
|
||||
# Extraer tamaño del output de ls -l
|
||||
file_size = ls_result.split[4].to_i
|
||||
puts "[+] Archivo verificado: #{backup_unix} (#{file_size.to_i / 1024 / 1024} MB)"
|
||||
else
|
||||
puts "[!] Error: No existe el archivo en #{BACKUP_NS8}"
|
||||
puts "[!] Error: No existe el archivo en #{backup_unix}"
|
||||
puts " SSH output: #{ls_result}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
|
||||
@@ -22,48 +22,60 @@ JSON_PATH = 'C:\temp\dron_restore_output.json'
|
||||
if File.exist?(DOWNLOAD_OUTPUT)
|
||||
output = JSON.parse(File.read(DOWNLOAD_OUTPUT))
|
||||
backup_local = output['backup_local']
|
||||
backup_name = File.basename(backup_local)
|
||||
LOCAL_BACKUP = "#{BACKUP_DIR_WINDOWS}\\#{backup_name}"
|
||||
backup_name = output['backup_name'] || File.basename(backup_local)
|
||||
LOCAL_BACKUP = backup_local # Usar la ruta EXACTA que viene del download
|
||||
puts "[*] Dron: Restaurar backup DASUTEN"
|
||||
puts " Nodo: dasu-sql4"
|
||||
puts " Backup: #{LOCAL_BACKUP} (desde download)"
|
||||
puts " Nombre: #{backup_name}"
|
||||
else
|
||||
LOCAL_BACKUP = "#{BACKUP_DIR_WINDOWS}\\sysdasuten_FULL_*.bak"
|
||||
puts "[*] Dron: Restaurar backup DASUTEN (buscar más reciente)"
|
||||
puts " Nodo: dasu-sql4"
|
||||
puts " Backup: #{LOCAL_BACKUP} (búsqueda por patrón)"
|
||||
end
|
||||
|
||||
puts " Nodo: dasu-sql4"
|
||||
puts " Backup: #{LOCAL_BACKUP}"
|
||||
|
||||
# PowerShell script para restore
|
||||
ps_script = <<~'PSCMD'.strip
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$BACKUP_DIR = "F:\BACKUP"
|
||||
$BACKUP_PATTERN = "sysdasuten_FULL_*.bak"
|
||||
$JSON_PATH = "C:\temp\dron_restore_output.json"
|
||||
$BACKUP_DIR = "F:\\BACKUP"
|
||||
$BACKUP_NAME = "#{backup_name}"
|
||||
$LOCAL_BACKUP = "$BACKUP_DIR\\$BACKUP_NAME"
|
||||
$JSON_PATH = "C:\\temp\\dron_restore_output.json"
|
||||
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\temp"
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\\temp"
|
||||
|
||||
Write-Host "[0/1] Buscando backup completo más reciente..."
|
||||
$backupFile = Get-ChildItem "$BACKUP_DIR\$BACKUP_PATTERN" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
if (-not $backupFile) {
|
||||
Write-Host "[!] No se encontró backup completo en $BACKUP_DIR"
|
||||
exit 1
|
||||
Write-Host "[0/1] Verificando backup específico..."
|
||||
Write-Host " Archivo esperado: $LOCAL_BACKUP"
|
||||
|
||||
if (-not (Test-Path $LOCAL_BACKUP)) {
|
||||
Write-Host "[!] No se encontró backup en $LOCAL_BACKUP"
|
||||
Write-Host " Buscando backup más reciente como fallback..."
|
||||
$BACKUP_PATTERN = "sysdasuten_FULL_*.bak"
|
||||
$backupFile = Get-ChildItem "$BACKUP_DIR\\$BACKUP_PATTERN" | Sort-Object Name -Descending | Select-Object -First 1
|
||||
if (-not $backupFile) {
|
||||
Write-Host "[!] No se encontró ningún backup en $BACKUP_DIR"
|
||||
exit 1
|
||||
}
|
||||
$LOCAL_BACKUP = $backupFile.FullName
|
||||
Write-Host " Fallback: $LOCAL_BACKUP"
|
||||
}
|
||||
$LOCAL_BACKUP = $backupFile.FullName
|
||||
Write-Host " Archivo: $LOCAL_BACKUP"
|
||||
|
||||
$backupFile = Get-Item $LOCAL_BACKUP
|
||||
Write-Host " Tamaño: $([math]::Round($backupFile.Length / 1MB, 2)) MB"
|
||||
|
||||
Write-Host "[1/1] Ejecutando RESTORE DATABASE..."
|
||||
$start = Get-Date
|
||||
|
||||
$sqlcmd = "C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\sqlcmd.exe"
|
||||
$sqlcmd = "C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\170\\Tools\\Binn\\sqlcmd.exe"
|
||||
|
||||
$restoreSql = @"
|
||||
RESTORE DATABASE sysdasuten
|
||||
FROM DISK = '$LOCAL_BACKUP'
|
||||
WITH REPLACE,
|
||||
MOVE 'sysdasuten' TO 'F:\DATA\sysdasuten.mdf',
|
||||
MOVE 'sysdasuten_log' TO 'F:\LOG\sysdasuten_log.ldf'
|
||||
"@
|
||||
MOVE 'sysdasuten' TO 'F:\\DATA\\sysdasuten.mdf',
|
||||
MOVE 'sysdasuten_log' TO 'F:\\LOG\\sysdasuten_log.ldf'
|
||||
"@
|
||||
|
||||
Write-Host " SQL: $restoreSql"
|
||||
|
||||
@@ -82,6 +94,7 @@ ps_script = <<~'PSCMD'.strip
|
||||
$res = @{
|
||||
paso = "restore_complete"
|
||||
backup_ruta = $LOCAL_BACKUP
|
||||
backup_name = $BACKUP_NAME
|
||||
nodo = "dasu-sql4"
|
||||
duracion_total = $duracionRestore
|
||||
duracion_restore = $duracionRestore
|
||||
|
||||
@@ -16,17 +16,28 @@ require 'shellwords'
|
||||
|
||||
REMOTE_DRIVE = "rmonla-GDrive:drive_bkps-dasu"
|
||||
|
||||
# Leer ruta del backup desde el output de la transferencia
|
||||
# Archivos de output de los pasos anteriores
|
||||
TRANSFER_OUTPUT = '/tmp/dron_transfer_output.json'
|
||||
if File.exist?(TRANSFER_OUTPUT)
|
||||
EXPORT_OUTPUT = '/tmp/dron_export_output.json'
|
||||
|
||||
# Determinar cuál es el más reciente (si existen)
|
||||
archivos_output = [TRANSFER_OUTPUT, EXPORT_OUTPUT].select { |f| File.exist?(f) }
|
||||
output_reciente = archivos_output.max_by { |f| File.mtime(f) }
|
||||
|
||||
if output_reciente == TRANSFER_OUTPUT
|
||||
output = JSON.parse(File.read(TRANSFER_OUTPUT))
|
||||
BACKUP_LOCAL = output['backup_local']
|
||||
BACKUP_LOCAL = output['backup_local'] || output['backup_ruta_unix']
|
||||
BACKUP_NAME = File.basename(BACKUP_LOCAL)
|
||||
puts "[*] Dron: Upload a Google Drive (DIFERENCIAL)"
|
||||
puts "[*] Dron: Upload a Google Drive (Desde TRANSFERENCIA)"
|
||||
elsif output_reciente == EXPORT_OUTPUT
|
||||
output = JSON.parse(File.read(EXPORT_OUTPUT))
|
||||
BACKUP_LOCAL = output['backup_ruta_unix']
|
||||
BACKUP_NAME = File.basename(BACKUP_LOCAL)
|
||||
puts "[*] Dron: Upload a Google Drive (Desde EXPORTACIÓN DIRECTA)"
|
||||
else
|
||||
BACKUP_LOCAL = "/var/tmp/sysdasuten_compressed_ADN.bak"
|
||||
BACKUP_NAME = "sysdasuten_compressed_ADN_#{Time.now.strftime('%Y%m%d_%H%M%S')}.bak"
|
||||
puts "[*] Dron: Upload a Google Drive (COMPLETO)"
|
||||
puts "[*] Dron: Upload a Google Drive (COMPLETO FALLBACK)"
|
||||
end
|
||||
|
||||
puts " Nodo: srv-ns8"
|
||||
|
||||
@@ -108,8 +108,15 @@ module DasuExecutor
|
||||
|
||||
# Ejecutar script
|
||||
ssh_cmd = "ssh srv-dasu 'bash #{remote_path}'"
|
||||
output = `#{ssh_cmd}`
|
||||
output = output.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?') if output
|
||||
output_buffer = ""
|
||||
IO.popen(ssh_cmd, err: [:child, :out]) do |io|
|
||||
io.each_line do |line|
|
||||
safe_line = line.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
|
||||
print safe_line
|
||||
output_buffer += safe_line
|
||||
end
|
||||
end
|
||||
output = output_buffer
|
||||
|
||||
# Limpieza
|
||||
bash_file.unlink
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== LIMPIEZA DE BACKUPS EN DASU-SQL4 ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$JSON_PATH = "C:\\temp\\limpieza_output.json"
|
||||
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\\temp"
|
||||
|
||||
# Listar todos los backups
|
||||
$backups = Get-ChildItem "F:\\BACKUP\\sysdasuten*.bak" | Sort-Object LastWriteTime -Descending
|
||||
|
||||
Write-Host "=== ANTES DE LIMPIEZA ==="
|
||||
Write-Host "Total archivos: $($backups.Count)"
|
||||
$totalSize = ($backups | Measure-Object -Property Length -Sum).Sum / 1MB
|
||||
Write-Host "Total tamaño: $([math]::Round($totalSize, 2)) MB"
|
||||
|
||||
Write-Host "`nArchivos:"
|
||||
$backups | ForEach-Object {
|
||||
$sizeMB = [math]::Round($_.Length / 1MB, 2)
|
||||
Write-Host " $($_.Name) - ${sizeMB} MB - $($_.LastWriteTime)"
|
||||
}
|
||||
|
||||
# Mantener solo el más reciente
|
||||
if ($backups.Count -gt 1) {
|
||||
$aEliminar = $backups | Select-Object -Skip 1
|
||||
|
||||
Write-Host "`n=== ELIMINANDO $($aEliminar.Count) ARCHIVOS ==="
|
||||
$aEliminar | ForEach-Object {
|
||||
Write-Host " Eliminando: $($_.Name)..."
|
||||
Remove-Item $_.FullName -Force
|
||||
}
|
||||
|
||||
# Verificar resultado
|
||||
$restantes = Get-ChildItem "F:\\BACKUP\\sysdasuten*.bak" | Sort-Object LastWriteTime -Descending
|
||||
Write-Host "`n=== DESPUÉS DE LIMPIEZA ==="
|
||||
Write-Host "Total archivos: $($restantes.Count)"
|
||||
$totalSize = ($restantes | Measure-Object -Property Length -Sum).Sum / 1MB
|
||||
Write-Host "Total tamaño: $([math]::Round($totalSize, 2)) MB"
|
||||
|
||||
$restantes | ForEach-Object {
|
||||
$sizeMB = [math]::Round($_.Length / 1MB, 2)
|
||||
Write-Host " $($_.Name) - ${sizeMB} MB - $($_.LastWriteTime)"
|
||||
}
|
||||
|
||||
$resultado = @{
|
||||
eliminados = $aEliminar.Count
|
||||
restantes = $restantes.Count
|
||||
espacio_libre_mb = [math]::Round($totalSize, 2)
|
||||
timestamp = (Get-Date -Format "o")
|
||||
}
|
||||
} else {
|
||||
Write-Host "`n=== NO HAY NADA QUE ELIMINAR ==="
|
||||
$resultado = @{
|
||||
eliminados = 0
|
||||
restantes = $backups.Count
|
||||
timestamp = (Get-Date -Format "o")
|
||||
}
|
||||
}
|
||||
|
||||
$resultado | ConvertTo-Json | Out-File -FilePath $JSON_PATH -Encoding utf8
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script, output_path: 'C:\temp\limpieza_output.json')
|
||||
resultado = DasuExecutor.read_json_from_dasu('C:\temp\limpieza_output.json')
|
||||
|
||||
puts "\n=== RESUMEN ==="
|
||||
puts " Archivos eliminados: #{resultado['eliminados']}"
|
||||
puts " Archivos restantes: #{resultado['restantes']}"
|
||||
puts " Espacio usado: #{resultado['espacio_libre_mb']} MB" if resultado['espacio_libre_mb']
|
||||
|
||||
puts "\n✅ Limpieza completada"
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'tiny_tds'
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== VERIFICANDO BACKUPS EN FENIX (E:\\BK_SQL\\sysdasuten\\) ==="
|
||||
puts ""
|
||||
|
||||
pass_cmd = `ruby adn/tools/candados/candados.rb get utnlarioja.intranet:monlaricardo 2>/dev/null`.strip
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
|
||||
client = TinyTds::Client.new(
|
||||
username: sql_user,
|
||||
password: pass_cmd,
|
||||
host: sql_host,
|
||||
timeout: 600,
|
||||
database: 'sysdasuten'
|
||||
)
|
||||
|
||||
# Listar backups en E:\BK_SQL\sysdasuten\
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$path = "E:\\BK_SQL\\sysdasuten"
|
||||
|
||||
if (Test-Path $path) {
|
||||
$backups = Get-ChildItem "$path\\sysdasuten*.bak" | Sort-Object LastWriteTime -Descending
|
||||
|
||||
Write-Host "Archivos encontrados:"
|
||||
$backups | ForEach-Object {
|
||||
$sizeMB = [math]::Round($_.Length / 1MB, 2)
|
||||
Write-Host " $($_.Name) - ${sizeMB} MB - $($_.LastWriteTime)"
|
||||
}
|
||||
|
||||
Write-Host "`nTotal archivos: $($backups.Count)"
|
||||
$totalSize = ($backups | Measure-Object -Property Length -Sum).Sum / 1MB
|
||||
Write-Host "Total tamaño: $([math]::Round($totalSize, 2)) MB"
|
||||
|
||||
# Si hay más de 1, eliminar los viejos
|
||||
if ($backups.Count -gt 1) {
|
||||
$aEliminar = $backups | Select-Object -Skip 1
|
||||
Write-Host "`n=== ELIMINANDO $($aEliminar.Count) ARCHIVOS ==="
|
||||
$aEliminar | ForEach-Object {
|
||||
Write-Host " Eliminando: $($_.Name)"
|
||||
Remove-Item $_.FullName -Force
|
||||
}
|
||||
|
||||
$restantes = Get-ChildItem "$path\\sysdasuten*.bak" | Sort-Object LastWriteTime -Descending
|
||||
Write-Host "`nRestantes: $($restantes.Count)"
|
||||
}
|
||||
} else {
|
||||
Write-Host "El directorio no existe"
|
||||
}
|
||||
PSCMD
|
||||
|
||||
result = client.execute("EXEC xp_cmdshell 'powershell -Command \"' + ps_script.gsub('\"', '\"\"') + '\"'")
|
||||
result.each { |r| puts r['output'] if r['output'] }
|
||||
|
||||
client.close
|
||||
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# Restauración COMPLETA desde backup local en dasu-sql4
|
||||
# ==========================================================
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== RESTAURACIÓN COMPLETA DESDE BACKUP LOCAL ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
# Script PowerShell para restore (sin drop, la BD ya no existe)
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$JSON_PATH = "C:\\temp\\restaurar_completo_output.json"
|
||||
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\\temp"
|
||||
|
||||
# Encontrar el backup más reciente
|
||||
Write-Host "[0/5] Buscando backup más reciente..."
|
||||
$backupFile = Get-ChildItem "F:\\BACKUP\\sysdasuten_FULL_*.bak" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
if (-not $backupFile) {
|
||||
Write-Host "[!] No se encontró backup en F:\\BACKUP\\"
|
||||
exit 1
|
||||
}
|
||||
$BACKUP_FILE = $backupFile.FullName
|
||||
Write-Host " Backup: $($backupFile.Name)"
|
||||
Write-Host " Tamaño: $([math]::Round($backupFile.Length / 1MB, 2)) MB"
|
||||
|
||||
# Ver archivos lógicos en el backup
|
||||
Write-Host "`n[1/5] Leyendo archivos lógicos del backup..."
|
||||
$connString = "Server=localhost;Database=master;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("RESTORE FILELISTONLY FROM DISK = '$BACKUP_FILE'", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
|
||||
$logicalNames = @{}
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
Write-Host " Archivos en el backup:"
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " Tipo: $($_.Type) | Lógico: $($_.LogicalName) | Físico: $($_.PhysicalName)"
|
||||
if ($_.Type -eq 'D') {
|
||||
$logicalNames['data'] = $_.LogicalName
|
||||
} elseif ($_.Type -eq 'L') {
|
||||
$logicalNames['log'] = $_.LogicalName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n[2/5] Restaurando desde backup..."
|
||||
Write-Host " Backup: $BACKUP_FILE"
|
||||
Write-Host " LogicalName data: $($logicalNames['data'])"
|
||||
Write-Host " LogicalName log: $($logicalNames['log'])"
|
||||
|
||||
$restoreSql = @"
|
||||
RESTORE DATABASE sysdasuten
|
||||
FROM DISK = '$BACKUP_FILE'
|
||||
WITH REPLACE, RECOVERY,
|
||||
MOVE '$($logicalNames['data'])' TO 'F:\\DATA\\sysdasuten.mdf',
|
||||
MOVE '$($logicalNames['log'])' TO 'F:\\LOG\\sysdasuten_log.ldf'
|
||||
"@
|
||||
|
||||
Write-Host " SQL: $restoreSql"
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand($restoreSql, $conn)
|
||||
$cmd.CommandTimeout = 600
|
||||
|
||||
$start = Get-Date
|
||||
try {
|
||||
$cmd.ExecuteNonQuery() | Out-Null
|
||||
$duracion = [math]::Round((New-TimeSpan -Start $start -End (Get-Date)).TotalSeconds, 2)
|
||||
Write-Host " Restore completado en ${duracion}s"
|
||||
} catch {
|
||||
Write-Host " ERROR en restore: $_"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "`n[3/5] Poniendo BD en línea..."
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
ALTER DATABASE sysdasuten SET MULTI_USER
|
||||
", $conn)
|
||||
$cmd.ExecuteNonQuery() | Out-Null
|
||||
Write-Host " BD en línea"
|
||||
|
||||
# Verificar restore
|
||||
Write-Host "`n[4/5] Verificando cantidad de registros..."
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT COUNT(*) as total FROM sysdasuten.dbo.BonosAfiliado
|
||||
", $conn)
|
||||
$total = $cmd.ExecuteScalar()
|
||||
Write-Host " Total registros en BonosAfiliado: $total"
|
||||
|
||||
Write-Host "`n[5/5] Verificando IDs y fechas..."
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT MAX(idsolicitud) as max_id FROM sysdasuten.dbo.BonosAfiliado
|
||||
", $conn)
|
||||
$maxId = $cmd.ExecuteScalar()
|
||||
Write-Host " MAX(idsolicitud): $maxId"
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT MAX(fecha) as ultima_fecha FROM sysdasuten.dbo.BonosAfiliado
|
||||
", $conn)
|
||||
$ultimaFecha = $cmd.ExecuteScalar()
|
||||
Write-Host " Última fecha: $ultimaFecha"
|
||||
|
||||
# Verificar registros con idsolicitud = 0 vs > 0
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT
|
||||
SUM(CASE WHEN idsolicitud = 0 THEN 1 ELSE 0 END) as con_cero,
|
||||
SUM(CASE WHEN idsolicitud > 0 THEN 1 ELSE 0 END) as con_mayor_cero
|
||||
FROM sysdasuten.dbo.BonosAfiliado
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$row = $ds.Tables[0].Rows[0]
|
||||
Write-Host " Con idsolicitud=0: $($row.con_cero)"
|
||||
Write-Host " Con idsolicitud>0: $($row.con_mayor_cero)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
|
||||
$resultado = @{
|
||||
paso = "restore_completo"
|
||||
backup = $BACKUP_FILE
|
||||
total_registros = $total
|
||||
max_idsolicitud = $maxId
|
||||
ultima_fecha = $ultimaFecha
|
||||
timestamp = (Get-Date -Format "o")
|
||||
}
|
||||
|
||||
$resultado | ConvertTo-Json | Out-File -FilePath $JSON_PATH -Encoding utf8
|
||||
PSCMD
|
||||
|
||||
puts "\n[1/2] Ejecutando restauración..."
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script, output_path: 'C:\temp\restaurar_completo_output.json')
|
||||
|
||||
puts "\n[2/2] Leyendo resultado..."
|
||||
begin
|
||||
resultado = DasuExecutor.read_json_from_dasu('C:\temp\restaurar_completo_output.json')
|
||||
puts "\n=== RESULTADO ==="
|
||||
puts " Backup: #{resultado['backup']}"
|
||||
puts " Total registros: #{resultado['total_registros']}"
|
||||
puts " MAX(idsolicitud): #{resultado['max_idsolicitud']}"
|
||||
puts " Última fecha: #{resultado['ultima_fecha']}"
|
||||
rescue => e
|
||||
puts "[!] Error leyendo resultado: #{e.message}"
|
||||
end
|
||||
|
||||
puts "\n✅ Restauración completada"
|
||||
@@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# Verificación Final Comparativa - FENIX vs DASU-SQL4
|
||||
# ==========================================================
|
||||
|
||||
require 'tiny_tds'
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "═" * 70
|
||||
puts " VERIFICACIÓN FINAL - FENIX (PRODUCCIÓN) vs DASU-SQL4"
|
||||
puts " Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts "═" * 70
|
||||
|
||||
# ==========================================
|
||||
# 1. FENIX - Obtener datos
|
||||
# ==========================================
|
||||
puts "\n[1] Conectando a FENIX (PRODUCCIÓN)..."
|
||||
|
||||
begin
|
||||
pass_cmd = `ruby adn/tools/candados/candados.rb get utnlarioja.intranet:monlaricardo 2>/dev/null`.strip
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
|
||||
client_fenix = TinyTds::Client.new(
|
||||
username: sql_user,
|
||||
password: pass_cmd,
|
||||
host: sql_host,
|
||||
timeout: 600,
|
||||
database: 'sysdasuten'
|
||||
)
|
||||
puts "[+] Conectado a FENIX"
|
||||
|
||||
# Consultas a FENIX
|
||||
puts "\n[2] Obteniendo datos de FENIX..."
|
||||
|
||||
fenix_data = {}
|
||||
|
||||
# Total BonosAfiliado
|
||||
result = client_fenix.execute("SELECT COUNT(*) as c FROM BonosAfiliado")
|
||||
fenix_data[:total_bonos] = result.first['c']
|
||||
|
||||
# Registros por día (últimos 5 días)
|
||||
result = client_fenix.execute("
|
||||
SELECT TOP 5
|
||||
CAST(fecha AS DATE) as dia,
|
||||
COUNT(*) as c
|
||||
FROM BonosAfiliado
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY dia DESC
|
||||
")
|
||||
fenix_data[:por_dia] = {}
|
||||
result.each { |r| fenix_data[:por_dia][r['dia']] = r['c'] }
|
||||
|
||||
# Última fecha
|
||||
result = client_fenix.execute("SELECT MAX(fecha) as ultima FROM BonosAfiliado")
|
||||
fenix_data[:ultima_fecha] = result.first['ultima']
|
||||
|
||||
# MAX(idsolicitud)
|
||||
result = client_fenix.execute("SELECT MAX(idsolicitud) as max_id FROM BonosAfiliado")
|
||||
fenix_data[:max_idsolicitud] = result.first['max_id']
|
||||
|
||||
# AutorizacionBonosExcepcion
|
||||
result = client_fenix.execute("SELECT COUNT(*) as c FROM AutorizacionBonosExcepcion")
|
||||
fenix_data[:total_aut] = result.first['c']
|
||||
|
||||
result = client_fenix.execute("SELECT MAX(fechasolicitud) as ultima FROM AutorizacionBonosExcepcion")
|
||||
fenix_data[:ultima_fecha_aut] = result.first['ultima']
|
||||
|
||||
client_fenix.close
|
||||
|
||||
puts " Total BonosAfiliado: #{fenix_data[:total_bonos]}"
|
||||
puts " Última fecha: #{fenix_data[:ultima_fecha]}"
|
||||
puts " MAX(idsolicitud): #{fenix_data[:max_idsolicitud]}"
|
||||
puts " Total AutorizacionBonosExcepcion: #{fenix_data[:total_aut]}"
|
||||
|
||||
rescue => e
|
||||
puts "[!] Error conectando a FENIX: #{e.message}"
|
||||
fenix_data = {}
|
||||
end
|
||||
|
||||
# ==========================================
|
||||
# 2. DASU-SQL4 - Obtener datos
|
||||
# ==========================================
|
||||
puts "\n[3] Conectando a DASU-SQL4..."
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$JSON_PATH = "C:\\temp\\verificacion_final_output.json"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
$data = @{}
|
||||
|
||||
# Total BonosAfiliado
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) as c FROM BonosAfiliado", $conn)
|
||||
$data.total_bonos = $cmd.ExecuteScalar()
|
||||
|
||||
# Por día
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 5
|
||||
CONVERT(varchar, CAST(fecha AS DATE), 120) as dia,
|
||||
COUNT(*) as c
|
||||
FROM BonosAfiliado
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY dia DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$por_dia = @{}
|
||||
$ds.Tables[0].Rows | ForEach-Object { $por_dia[$($_.dia)] = $($_.c) }
|
||||
$data.por_dia = $por_dia
|
||||
|
||||
# Última fecha
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(fecha) as ultima FROM BonosAfiliado", $conn)
|
||||
$data.ultima_fecha = $cmd.ExecuteScalar()
|
||||
|
||||
# MAX(idsolicitud)
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(idsolicitud) as max_id FROM BonosAfiliado", $conn)
|
||||
$data.max_idsolicitud = $cmd.ExecuteScalar()
|
||||
|
||||
# AutorizacionBonosExcepcion
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) as c FROM AutorizacionBonosExcepcion", $conn)
|
||||
$data.total_aut = $cmd.ExecuteScalar()
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(fechasolicitud) as ultima FROM AutorizacionBonosExcepcion", $conn)
|
||||
$data.ultima_fecha_aut = $cmd.ExecuteScalar()
|
||||
|
||||
$conn.Close()
|
||||
|
||||
$data | ConvertTo-Json -Depth 5 | Out-File -FilePath $JSON_PATH -Encoding utf8
|
||||
PSCMD
|
||||
|
||||
begin
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script, output_path: 'C:\temp\verificacion_final_output.json')
|
||||
dasu_data = DasuExecutor.read_json_from_dasu('C:\temp\verificacion_final_output.json')
|
||||
puts "[+] Conectado a DASU-SQL4"
|
||||
|
||||
puts " Total BonosAfiliado: #{dasu_data['total_bonos']}"
|
||||
puts " Última fecha: #{dasu_data['ultima_fecha']}"
|
||||
puts " MAX(idsolicitud): #{dasu_data['max_idsolicitud']}"
|
||||
puts " Total AutorizacionBonosExcepcion: #{dasu_data['total_aut']}"
|
||||
|
||||
rescue => e
|
||||
puts "[!] Error consultando DASU-SQL4: #{e.message}"
|
||||
dasu_data = {}
|
||||
end
|
||||
|
||||
# ==========================================
|
||||
# 3. COMPARAR
|
||||
# ==========================================
|
||||
puts "\n" + "═" * 70
|
||||
puts " COMPARACIÓN"
|
||||
puts "═" * 70
|
||||
|
||||
def comparar(nombre, fenix, dasu, formato = nil)
|
||||
fenix_val = fenix.nil? ? "N/A" : (formato ? formato.call(fenix) : fenix.to_s)
|
||||
dasu_val = dasu.nil? ? "N/A" : (formato ? formato.call(dasu) : dasu.to_s)
|
||||
|
||||
coincide = fenix.to_s == dasu.to_s
|
||||
estado = coincide ? "✅" : "⚠️"
|
||||
|
||||
puts " #{estado} #{nombre}:"
|
||||
puts " FENIX: #{fenix_val}"
|
||||
puts " DASU: #{dasu_val}"
|
||||
|
||||
coincide
|
||||
end
|
||||
|
||||
todos_coinciden = true
|
||||
|
||||
# Comparar totales
|
||||
todos_coinciden &= comparar("Total BonosAfiliado", fenix_data[:total_bonos], dasu_data['total_bonos'])
|
||||
|
||||
# Comparar última fecha
|
||||
todos_coinciden &= comparar("Última fecha", fenix_data[:ultima_fecha], dasu_data['ultima_fecha'])
|
||||
|
||||
# Comparar MAX(idsolicitud)
|
||||
todos_coinciden &= comparar("MAX(idsolicitud)", fenix_data[:max_idsolicitud], dasu_data['max_idsolicitud'])
|
||||
|
||||
# Comparar total autorizaciones
|
||||
todos_coinciden &= comparar("Total AutorizacionBonosExcepcion", fenix_data[:total_aut], dasu_data['total_aut'])
|
||||
|
||||
# Comparar por día
|
||||
puts "\n Registros por día (últimos 5 días):"
|
||||
if fenix_data[:por_dia] && dasu_data['por_dia']
|
||||
fenix_data[:por_dia].each do |dia, count|
|
||||
dasu_count = dasu_data['por_dia'][dia.to_s]
|
||||
coincide = count == dasu_count
|
||||
estado = coincide ? "✅" : "⚠️"
|
||||
puts " #{estado} #{dia}: FENIX=#{count} | DASU=#{dasu_count}"
|
||||
todos_coinciden = false unless coincide
|
||||
end
|
||||
end
|
||||
|
||||
puts "\n" + "═" * 70
|
||||
if todos_coinciden
|
||||
puts " ✅ TODOS LOS DATOS COINCIDEN - EL SISTEMA ESTÁ ACTUALIZADO"
|
||||
else
|
||||
puts " ⚠️ HAY DIFERENCIAS - REVISAR"
|
||||
end
|
||||
puts "═" * 70
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== DASU-SQL4 - Registros de ABRIL 2026 ==="
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] Registros de abril 2026 ordenados por fecha:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 30 idsolicitud, fecha, codigoafiliado, dependencia
|
||||
FROM BonosAfiliado
|
||||
WHERE fecha >= '2026-04-01'
|
||||
ORDER BY fecha DESC, idsolicitud DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " ID: $($_.idsolicitud) | fecha: $($_.fecha) | afiliado: $($_.codigoafiliado)"
|
||||
}
|
||||
|
||||
Write-Host "`n[2] Cantidad de registros por día (abril 2026):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT CAST(fecha AS DATE) as dia, COUNT(*) as c
|
||||
FROM BonosAfiliado
|
||||
WHERE fecha >= '2026-04-01'
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY dia DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " $($_.dia): $($_.c) registros"
|
||||
}
|
||||
|
||||
Write-Host "`n[3] IDs mínimos y máximos por día (abril 2026):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT
|
||||
CAST(fecha AS DATE) as dia,
|
||||
MIN(idsolicitud) as min_id,
|
||||
MAX(idsolicitud) as max_id,
|
||||
COUNT(*) as c
|
||||
FROM BonosAfiliado
|
||||
WHERE fecha >= '2026-04-01'
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY dia DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " $($_.dia): IDs [$($_.min_id) - $($_.max_id)] | c: $($_.c)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# Verificar backup en DASU-SQL4 - qué archivo hay y qué fecha tiene
|
||||
# ==========================================================
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== VERIFICANDO BACKUP EN DASU-SQL4 ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$JSON_PATH = "C:\\temp\\backup_info_output.json"
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\\temp"
|
||||
|
||||
# Listar backups en F:\\BACKUP
|
||||
Write-Host "=== ARCHIVOS EN F:\\BACKUP ==="
|
||||
$backups = Get-ChildItem "F:\\BACKUP\\*.bak" | Sort-Object LastWriteTime -Descending
|
||||
$backups | ForEach-Object {
|
||||
Write-Host " Archivo: $($_.Name)"
|
||||
Write-Host " Tamaño: $([math]::Round($_.Length / 1MB, 2)) MB"
|
||||
Write-Host " LastWriteTime: $($_.LastWriteTime)"
|
||||
Write-Host " CreationTime: $($_.CreationTime)"
|
||||
}
|
||||
|
||||
# Si hay backup, verificar fecha de los datos dentro
|
||||
if ($backups.Count -gt 0) {
|
||||
$backupMasReciente = $backups[0]
|
||||
Write-Host "`n=== INFORMACIÓN DEL BACKUP MÁS RECIENTE ==="
|
||||
Write-Host " Archivo: $($backupMasReciente.Name)"
|
||||
|
||||
# Conectar a SQL y verificar fecha máxima en BonosAfiliado
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(fecha) as ultima_fecha FROM [BonosAfiliado]", $conn)
|
||||
try {
|
||||
$ultimaFecha = $cmd.ExecuteScalar()
|
||||
Write-Host " ÚLTIMA FECHA EN BonosAfiliado: $ultimaFecha"
|
||||
} catch {
|
||||
Write-Host " ERROR al obtener fecha: $_"
|
||||
}
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM [BonosAfiliado] WHERE fecha >= '2026-04-15'", $conn)
|
||||
try {
|
||||
$count15 = $cmd.ExecuteScalar()
|
||||
Write-Host " Registros el 2026-04-15: $count15"
|
||||
} catch {
|
||||
Write-Host " ERROR al contar registros del 15: $_"
|
||||
}
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM [BonosAfiliado] WHERE fecha >= '2026-04-14'", $conn)
|
||||
try {
|
||||
$count14 = $cmd.ExecuteScalar()
|
||||
Write-Host " Registros desde 2026-04-14: $count14"
|
||||
} catch {
|
||||
Write-Host " ERROR al contar registros desde 14: $_"
|
||||
}
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM [BonosAfiliado] WHERE fecha >= '2026-04-13'", $conn)
|
||||
try {
|
||||
$count13 = $cmd.ExecuteScalar()
|
||||
Write-Host " Registros desde 2026-04-13: $count13"
|
||||
} catch {
|
||||
Write-Host " ERROR al contar registros desde 13: $_"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
}
|
||||
|
||||
# Verificar fecha de restore en msdb
|
||||
Write-Host "`n=== FECHA DE RESTORE EN msdb ==="
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 5 destination_database_name, restore_date, backup_start_date FROM msdb.dbo.restorehistory WHERE destination_database_name = 'sysdasuten' ORDER BY restore_date DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " Restore: $($_.restore_date)"
|
||||
Write-Host " Backup de: $($_.backup_start_date)"
|
||||
Write-Host " BD: $($_.destination_database_name)"
|
||||
}
|
||||
} else {
|
||||
Write-Host " No hay registros de restore"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'tiny_tds'
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== VERIFICANDO BACKUP EN DASU-SQL4 ==="
|
||||
puts ""
|
||||
|
||||
# ==========================================
|
||||
# 1. FENIX - Verificar datos actuales
|
||||
# ==========================================
|
||||
puts "[1] FENIX - Estado actual de BonosAfiliado:"
|
||||
|
||||
pass_cmd = `ruby adn/tools/candados/candados.rb get utnlarioja.intranet:monlaricardo 2>/dev/null`.strip
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
|
||||
client_fenix = TinyTds::Client.new(
|
||||
username: sql_user,
|
||||
password: pass_cmd,
|
||||
host: sql_host,
|
||||
timeout: 600,
|
||||
database: 'sysdasuten'
|
||||
)
|
||||
|
||||
# Última fecha y registros del 15
|
||||
result = client_fenix.execute("SELECT MAX(fecha) as ultima FROM BonosAfiliado")
|
||||
puts " Última fecha: #{result.first['ultima']}"
|
||||
|
||||
result = client_fenix.execute("SELECT COUNT(*) as c FROM BonosAfiliado WHERE fecha = '2026-04-15'")
|
||||
puts " Registros el 2026-04-15: #{result.first['c']}"
|
||||
|
||||
# Ver IDs máximos
|
||||
result = client_fenix.execute("SELECT MAX(idsolicitud) as max_id FROM BonosAfiliado")
|
||||
puts " ID máximo en FENIX: #{result.first['max_id']}"
|
||||
|
||||
client_fenix.close
|
||||
|
||||
# ==========================================
|
||||
# 2. DASU-SQL4 - Verificar datos del backup
|
||||
# ==========================================
|
||||
puts "\n[2] DASU-SQL4 - Datos del backup restaurado:"
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host " Última fecha en BonosAfiliado:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(fecha) as ultima FROM BonosAfiliado", $conn)
|
||||
try {
|
||||
$ultima = $cmd.ExecuteScalar()
|
||||
Write-Host " $ultima"
|
||||
} catch {
|
||||
Write-Host " ERROR: $_"
|
||||
}
|
||||
|
||||
Write-Host " Registros el 2026-04-15:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) as c FROM BonosAfiliado WHERE fecha = '2026-04-15'", $conn)
|
||||
try {
|
||||
$c = $cmd.ExecuteScalar()
|
||||
Write-Host " $c"
|
||||
} catch {
|
||||
Write-Host " ERROR: $_"
|
||||
}
|
||||
|
||||
Write-Host " ID máximo en BonosAfiliado:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(idsolicitud) as max_id FROM BonosAfiliado", $conn)
|
||||
try {
|
||||
$maxId = $cmd.ExecuteScalar()
|
||||
Write-Host " $maxId"
|
||||
} catch {
|
||||
Write-Host " ERROR: $_"
|
||||
}
|
||||
|
||||
# Ver fecha de restore en msdb
|
||||
Write-Host "`n Último restore:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 1 restore_date, backup_start_date FROM msdb.dbo.restorehistory WHERE destination_database_name = 'sysdasuten' ORDER BY restore_date DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$row = $ds.Tables[0].Rows[0]
|
||||
Write-Host " Restore date: $($row.restore_date)"
|
||||
Write-Host " Backup start: $($row.backup_start_date)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n[3] ARCHIVOS DE BACKUP EN DASU-SQL4:"
|
||||
ps_script = <<~PSCMD.strip
|
||||
Get-ChildItem "F:\\BACKUP\\*.bak" | ForEach-Object {
|
||||
Write-Host " $($_.Name)"
|
||||
Write-Host " LastWriteTime: $($_.LastWriteTime)"
|
||||
Write-Host " CreationTime: $($_.CreationTime)"
|
||||
}
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,214 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# Verificación específica de BONOS - FENIX vs DASU-SQL4
|
||||
# ==========================================================
|
||||
|
||||
require 'tiny_tds'
|
||||
require 'json'
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== VERIFICACIÓN DE BONOS (venta de bonos) ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
# ==========================================
|
||||
# 1. FENIX - BonosAfiliado y AutorizacionBonosExcepcion
|
||||
# ==========================================
|
||||
puts "\n[1] FENIX (PRODUCCIÓN) - BonosAfiliado..."
|
||||
|
||||
pass_cmd = `ruby adn/tools/candados/candados.rb get utnlarioja.intranet:monlaricardo 2>/dev/null`.strip
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
|
||||
client_fenix = TinyTds::Client.new(
|
||||
username: sql_user,
|
||||
password: pass_cmd,
|
||||
host: sql_host,
|
||||
timeout: 600,
|
||||
database: 'sysdasuten'
|
||||
)
|
||||
|
||||
# BonosAfiliado - verificar columna de fecha
|
||||
puts " Buscando columna de fecha en BonosAfiliado..."
|
||||
cols = client_fenix.execute("
|
||||
SELECT COLUMN_NAME, DATA_TYPE
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = 'BonosAfiliado'
|
||||
AND DATA_TYPE IN ('datetime', 'datetime2', 'date', 'smalldatetime')
|
||||
").to_a
|
||||
|
||||
puts " Columnas fecha encontradas: #{cols.map { |c| "#{c['COLUMN_NAME']} (#{c['DATA_TYPE']})" }.join(', ')}"
|
||||
|
||||
# Usar la primera columna fecha encontrada
|
||||
if cols.any?
|
||||
col_fecha = cols.first['COLUMN_NAME']
|
||||
puts " Usando columna: #{col_fecha}"
|
||||
|
||||
# Última fecha exacta
|
||||
ultima = client_fenix.execute("SELECT MAX(#{col_fecha}) as ultima FROM BonosAfiliado").first['ultima']
|
||||
puts " Última fecha: #{ultima}"
|
||||
|
||||
# Registros desde abril 13
|
||||
count_13 = client_fenix.execute("SELECT COUNT(*) as c FROM BonosAfiliado WHERE #{col_fecha} >= '2026-04-13'").first['c']
|
||||
puts " Registros desde 2026-04-13: #{count_13}"
|
||||
|
||||
# Registros por día desde abril 13
|
||||
puts "\n Registros por día (desde 2026-04-13):"
|
||||
por_dia = client_fenix.execute("
|
||||
SELECT CAST(#{col_fecha} AS DATE) as dia, COUNT(*) as cantidad
|
||||
FROM BonosAfiliado
|
||||
WHERE #{col_fecha} >= '2026-04-13'
|
||||
GROUP BY CAST(#{col_fecha} AS DATE)
|
||||
ORDER BY dia DESC
|
||||
")
|
||||
por_dia.each { |r| puts " #{r['dia']}: #{r['cantidad']} registros" }
|
||||
|
||||
# Últimos 10 registros
|
||||
puts "\n Últimos 10 registros de BonosAfiliado:"
|
||||
ultimos = client_fenix.execute("SELECT TOP 10 * FROM BonosAfiliado ORDER BY #{col_fecha} DESC").to_a
|
||||
ultimos.each_with_index do |r, i|
|
||||
puts " #{i+1}. #{col_fecha}=#{r[col_fecha]} - #{r.select { |k,v| k != col_fecha }.to_a.first(3).map { |k,v| "#{k}: #{v}" }.join(', ')}"
|
||||
end
|
||||
end
|
||||
|
||||
# AutorizacionBonosExcepcion
|
||||
puts "\n[2] FENIX (PRODUCCIÓN) - AutorizacionBonosExcepcion..."
|
||||
|
||||
cols = client_fenix.execute("
|
||||
SELECT COLUMN_NAME, DATA_TYPE
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = 'AutorizacionBonosExcepcion'
|
||||
AND DATA_TYPE IN ('datetime', 'datetime2', 'date', 'smalldatetime')
|
||||
").to_a
|
||||
|
||||
if cols.any?
|
||||
col_fecha = cols.first['COLUMN_NAME']
|
||||
puts " Usando columna: #{col_fecha}"
|
||||
|
||||
ultima = client_fenix.execute("SELECT MAX(#{col_fecha}) as ultima FROM AutorizacionBonosExcepcion").first['ultima']
|
||||
puts " Última fecha: #{ultima}"
|
||||
|
||||
count_13 = client_fenix.execute("SELECT COUNT(*) as c FROM AutorizacionBonosExcepcion WHERE #{col_fecha} >= '2026-04-13'").first['c']
|
||||
puts " Registros desde 2026-04-13: #{count_13}"
|
||||
|
||||
puts "\n Registros por día (desde 2026-04-13):"
|
||||
por_dia = client_fenix.execute("
|
||||
SELECT CAST(#{col_fecha} AS DATE) as dia, COUNT(*) as cantidad
|
||||
FROM AutorizacionBonosExcepcion
|
||||
WHERE #{col_fecha} >= '2026-04-13'
|
||||
GROUP BY CAST(#{col_fecha} AS DATE)
|
||||
ORDER BY dia DESC
|
||||
")
|
||||
por_dia.each { |r| puts " #{r['dia']}: #{r['cantidad']} registros" }
|
||||
|
||||
puts "\n Últimos 10 registros:"
|
||||
ultimos = client_fenix.execute("SELECT TOP 10 * FROM AutorizacionBonosExcepcion ORDER BY #{col_fecha} DESC").to_a
|
||||
ultimos.each_with_index do |r, i|
|
||||
puts " #{i+1}. #{col_fecha}=#{r[col_fecha]} - #{r.to_a.first(5).map { |k,v| "#{k}: #{v}" }.join(', ')}"
|
||||
end
|
||||
end
|
||||
|
||||
client_fenix.close
|
||||
|
||||
# ==========================================
|
||||
# 2. DASU-SQL4 - Mismas consultas
|
||||
# ==========================================
|
||||
puts "\n[3] DASU-SQL4 - BonosAfiliado..."
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$JSON_PATH = "C:\\temp\\bonos_dasu_output.json"
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\\temp"
|
||||
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
# BonosAfiliado
|
||||
Write-Host " Buscando columna de fecha en BonosAfiliado..."
|
||||
$cmdCol = New-Object System.Data.SqlClient.SqlCommand("SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'BonosAfiliado' AND DATA_TYPE IN ('datetime', 'datetime2', 'date', 'smalldatetime')", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmdCol)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$cols = $ds.Tables[0].Rows
|
||||
|
||||
if ($cols.Count -gt 0) {
|
||||
$colFecha = $cols[0].COLUMN_NAME
|
||||
Write-Host " Usando columna: $colFecha"
|
||||
|
||||
# Última fecha
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX([$colFecha]) as ultima FROM [BonosAfiliado]", $conn)
|
||||
$ultima = $cmd.ExecuteScalar()
|
||||
Write-Host " Última fecha: $ultima"
|
||||
|
||||
# Registros desde abril 13
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM [BonosAfiliado] WHERE [$colFecha] >= '2026-04-13'", $conn)
|
||||
$count13 = $cmd.ExecuteScalar()
|
||||
Write-Host " Registros desde 2026-04-13: $count13"
|
||||
|
||||
# Por día
|
||||
Write-Host " Registros por día:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT CAST([$colFecha] AS DATE) as dia, COUNT(*) as cantidad FROM [BonosAfiliado] WHERE [$colFecha] >= '2026-04-13' GROUP BY CAST([$colFecha] AS DATE) ORDER BY dia DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object { Write-Host " $($_.dia): $($_.cantidad) registros" }
|
||||
|
||||
# Últimos 10
|
||||
Write-Host " Últimos 10 registros:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 10 * FROM [BonosAfiliado] ORDER BY [$colFecha] DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
for ($i = 0; $i -lt $ds.Tables[0].Rows.Count; $i++) {
|
||||
$row = $ds.Tables[0].Rows[$i]
|
||||
Write-Host " $($i+1). $($colFecha)=$($row.$colFecha)"
|
||||
}
|
||||
}
|
||||
|
||||
# AutorizacionBonosExcepcion
|
||||
Write-Host "`n[4] DASU-SQL4 - AutorizacionBonosExcepcion..."
|
||||
$cmdCol = New-Object System.Data.SqlClient.SqlCommand("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'AutorizacionBonosExcepcion' AND DATA_TYPE IN ('datetime', 'datetime2', 'date', 'smalldatetime')", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmdCol)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$cols = $ds.Tables[0].Rows
|
||||
|
||||
if ($cols.Count -gt 0) {
|
||||
$colFecha = $cols[0].COLUMN_NAME
|
||||
Write-Host " Usando columna: $colFecha"
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX([$colFecha]) as ultima FROM [AutorizacionBonosExcepcion]", $conn)
|
||||
$ultima = $cmd.ExecuteScalar()
|
||||
Write-Host " Última fecha: $ultima"
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM [AutorizacionBonosExcepcion] WHERE [$colFecha] >= '2026-04-13'", $conn)
|
||||
$count13 = $cmd.ExecuteScalar()
|
||||
Write-Host " Registros desde 2026-04-13: $count13"
|
||||
|
||||
Write-Host " Registros por día:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT CAST([$colFecha] AS DATE) as dia, COUNT(*) as cantidad FROM [AutorizacionBonosExcepcion] WHERE [$colFecha] >= '2026-04-13' GROUP BY CAST([$colFecha] AS DATE) ORDER BY dia DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object { Write-Host " $($_.dia): $($_.cantidad) registros" }
|
||||
|
||||
Write-Host " Últimos 10 registros:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 10 * FROM [AutorizacionBonosExcepcion] ORDER BY [$colFecha] DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
for ($i = 0; $i -lt $ds.Tables[0].Rows.Count; $i++) {
|
||||
$row = $ds.Tables[0].Rows[$i]
|
||||
Write-Host " $($i+1). $($colFecha)=$($row.$colFecha)"
|
||||
}
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,319 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# adn/tools/cli/verificar_datos_fenix_dasu.rb
|
||||
# ==========================================================
|
||||
# Verificación minuciosa de datos entre FENIX (producción)
|
||||
# y DASU-SQL4 (nuevo sistema) - desde abril 13
|
||||
# ==========================================================
|
||||
|
||||
require 'tiny_tds'
|
||||
require 'json'
|
||||
require 'base64'
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== COMPARACIÓN FENIX vs DASU-SQL4 ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
# ==========================================
|
||||
# 1. CONEXIÓN A FENIX (PRODUCCIÓN)
|
||||
# ==========================================
|
||||
puts "\n[1] Conectando a srvv-fenix (PRODUCCIÓN)..."
|
||||
|
||||
# Autorizar candados primero
|
||||
system("ruby adn/tools/candados/candados.rb authorize >/dev/null 2>&1")
|
||||
|
||||
# Obtener credencial de candados
|
||||
pass_cmd = `ruby adn/tools/candados/candados.rb get utnlarioja.intranet:monlaricardo 2>/dev/null`.strip
|
||||
|
||||
if pass_cmd.empty?
|
||||
puts "[!] Error: No se pudo obtener credencial de candados"
|
||||
exit 1
|
||||
end
|
||||
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
|
||||
begin
|
||||
client_fenix = TinyTds::Client.new(
|
||||
username: sql_user,
|
||||
password: pass_cmd,
|
||||
host: sql_host,
|
||||
timeout: 600,
|
||||
database: 'sysdasuten'
|
||||
)
|
||||
puts "[+] Conectado a srvv-fenix"
|
||||
rescue => e
|
||||
puts "[!] Error conectando a fenix: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
# ==========================================
|
||||
# 2. TABLAS PRINCIPALES PARA VERIFICAR
|
||||
# ==========================================
|
||||
# El usuario mencionó "venta de bonos" como tarea repetitiva
|
||||
# Verificamos tablas relacionadas con bonos y afiliados
|
||||
|
||||
tablas_principales = [
|
||||
'Bonos',
|
||||
'BonosAfiliado',
|
||||
'AutorizacionGasto',
|
||||
'AutorizacionBonosExcepcion',
|
||||
'afiliados',
|
||||
'ControlPrestaciones',
|
||||
'usuarios',
|
||||
'transacciones'
|
||||
]
|
||||
|
||||
puts "\n[2] Verificando tablas principales..."
|
||||
|
||||
# ==========================================
|
||||
# 3. OBTENER DATOS DE FENIX
|
||||
# ==========================================
|
||||
datos_fenix = {}
|
||||
|
||||
tablas_principales.each do |tabla|
|
||||
begin
|
||||
# Verificar si existe
|
||||
existe = client_fenix.execute("
|
||||
SELECT TOP 1 1
|
||||
FROM sys.objects
|
||||
WHERE name = '#{tabla}' AND type = 'U'
|
||||
").to_a.any?
|
||||
|
||||
unless existe
|
||||
puts " #{tabla}: NO EXISTE"
|
||||
next
|
||||
end
|
||||
|
||||
# Buscar columna de fecha
|
||||
cols = client_fenix.execute("
|
||||
SELECT TOP 1 COLUMN_NAME, DATA_TYPE
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = '#{tabla}'
|
||||
AND DATA_TYPE IN ('datetime', 'datetime2', 'date', 'smalldatetime')
|
||||
").to_a
|
||||
|
||||
if cols.empty?
|
||||
# Sin columna de fecha, solo contar total
|
||||
count_total = client_fenix.execute("SELECT COUNT(*) as total FROM #{tabla}").first['total']
|
||||
datos_fenix[tabla] = { total: count_total, col_fecha: nil }
|
||||
puts " #{tabla}: #{count_total} registros (sin fecha)"
|
||||
next
|
||||
end
|
||||
|
||||
col_fecha = cols.first['COLUMN_NAME']
|
||||
|
||||
# Contar total y desde abril 13
|
||||
count_total = client_fenix.execute("SELECT COUNT(*) as total FROM #{tabla}").first['total']
|
||||
count_desde_13 = client_fenix.execute("
|
||||
SELECT COUNT(*) as total
|
||||
FROM #{tabla}
|
||||
WHERE #{col_fecha} >= '2026-04-13'
|
||||
").first['total']
|
||||
|
||||
# Última fecha
|
||||
ultima_fecha = client_fenix.execute("
|
||||
SELECT MAX(#{col_fecha}) as ultima
|
||||
FROM #{tabla}
|
||||
").first['ultima']
|
||||
|
||||
# Últimos 5 registros
|
||||
ultimos = client_fenix.execute("
|
||||
SELECT TOP 5 *
|
||||
FROM #{tabla}
|
||||
ORDER BY #{col_fecha} DESC
|
||||
").to_a
|
||||
|
||||
datos_fenix[tabla] = {
|
||||
total: count_total,
|
||||
desde_13: count_desde_13,
|
||||
col_fecha: col_fecha,
|
||||
ultima_fecha: ultima_fecha,
|
||||
ultimos: ultimos
|
||||
}
|
||||
|
||||
puts " #{tabla}: #{count_desde_13} desde 2026-04-13 (total: #{count_total}) - última: #{ultima_fecha}"
|
||||
rescue => e
|
||||
puts " #{tabla}: ERROR - #{e.message}"
|
||||
end
|
||||
end
|
||||
|
||||
# ==========================================
|
||||
# 4. CONSULTAR DASU-SQL4
|
||||
# ==========================================
|
||||
puts "\n[3] Consultando DASU-SQL4..."
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$JSON_PATH = "C:\\temp\\comparacion_dasu_output.json"
|
||||
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\\temp"
|
||||
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
$tablasPrincipales = @('Bonos', 'BonosAfiliado', 'AutorizacionGasto', 'AutorizacionBonosExcepcion', 'afiliados', 'ControlPrestaciones', 'usuarios', 'transacciones')
|
||||
|
||||
$datos = @{}
|
||||
|
||||
foreach ($tabla in $tablasPrincipales) {
|
||||
try {
|
||||
# Verificar si existe
|
||||
$check = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 1 1 FROM sys.objects WHERE name = '$tabla' AND type = 'U'", $conn)
|
||||
$existe = $check.ExecuteScalar()
|
||||
|
||||
if ($existe) {
|
||||
# Buscar columna fecha
|
||||
$cmdCol = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$tabla' AND DATA_TYPE IN ('datetime', 'datetime2', 'date', 'smalldatetime')", $conn)
|
||||
$colFecha = $cmdCol.ExecuteScalar()
|
||||
|
||||
if ($colFecha) {
|
||||
# Count total
|
||||
$cmdTotal = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM [$tabla]", $conn)
|
||||
$countTotal = $cmdTotal.ExecuteScalar()
|
||||
|
||||
# Count desde abril 13
|
||||
$cmd13 = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM [$tabla] WHERE [$colFecha] >= '2026-04-13'", $conn)
|
||||
$count13 = $cmd13.ExecuteScalar()
|
||||
|
||||
# Última fecha
|
||||
$cmdMax = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX([$colFecha]) as ultima FROM [$tabla]", $conn)
|
||||
$ultima = $cmdMax.ExecuteScalar()
|
||||
|
||||
# Últimos 5
|
||||
$cmdUltimos = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 5 * FROM [$tabla] ORDER BY [$colFecha] DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmdUltimos)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ultimos = $ds.Tables[0].Rows | ForEach-Object {
|
||||
$row = @{}
|
||||
$_.Table.Columns | ForEach-Object { $row[$_.ColumnName] = $_.($_) }
|
||||
$row
|
||||
}
|
||||
|
||||
$datos[$tabla] = @{
|
||||
total = $countTotal
|
||||
desde_13 = $count13
|
||||
col_fecha = $colFecha
|
||||
ultima_fecha = $ultima
|
||||
ultimos = $ultimos
|
||||
}
|
||||
|
||||
Write-Host " $tabla : $count13 desde 2026-04-13 (total: $countTotal) - última: $ultima"
|
||||
} else {
|
||||
$cmdTotal = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM [$tabla]", $conn)
|
||||
$countTotal = $cmdTotal.ExecuteScalar()
|
||||
$datos[$tabla] = @{ total = $countTotal; col_fecha = $null }
|
||||
Write-Host " $tabla : $countTotal registros (sin fecha)"
|
||||
}
|
||||
} else {
|
||||
Write-Host " $tabla : NO EXISTE"
|
||||
}
|
||||
} catch {
|
||||
Write-Host " $tabla : ERROR - $_"
|
||||
}
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
|
||||
$resultado = @{
|
||||
datos = $datos
|
||||
timestamp = (Get-Date -Format "o")
|
||||
}
|
||||
|
||||
$resultado | ConvertTo-Json -Depth 10 | Out-File -FilePath $JSON_PATH -Encoding utf8
|
||||
PSCMD
|
||||
|
||||
begin
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script, output_path: 'C:\temp\comparacion_dasu_output.json')
|
||||
resultado_dasu = DasuExecutor.read_json_from_dasu('C:\temp\comparacion_dasu_output.json')
|
||||
datos_dasu = resultado_dasu['datos']
|
||||
|
||||
rescue => e
|
||||
puts "[!] Error consultando dasu-sql4: #{e.message}"
|
||||
puts e.backtrace.first(5).join("\n")
|
||||
datos_dasu = {}
|
||||
end
|
||||
|
||||
# ==========================================
|
||||
# 5. COMPARAR RESULTADOS
|
||||
# ==========================================
|
||||
puts "\n[4] COMPARACIÓN FENIX vs DASU-SQL4:"
|
||||
puts "=" * 60
|
||||
|
||||
tablas_comunes = datos_fenix.keys & (datos_dasu || {}).keys
|
||||
|
||||
if tablas_comunes.empty?
|
||||
puts " ⚠️ No hay tablas comunes para comparar"
|
||||
else
|
||||
puts " Tablas a comparar: #{tablas_comunes.join(', ')}"
|
||||
puts ""
|
||||
|
||||
todas_coinciden = true
|
||||
|
||||
tablas_comunes.each do |tabla|
|
||||
fenix = datos_fenix[tabla]
|
||||
dasu = datos_dasu[tabla]
|
||||
|
||||
puts " === #{tabla} ==="
|
||||
puts " Columna fecha: #{fenix[:col_fecha] || dasu['col_fecha'] || 'N/A'}"
|
||||
puts " FENIX total: #{fenix[:total]} | DASU total: #{dasu['total']}"
|
||||
puts " FENIX desde_13: #{fenix[:desde_13]} | DASU desde_13: #{dasu['desde_13']}"
|
||||
puts " FENIX última: #{fenix[:ultima_fecha]} | DASU última: #{dasu['ultima_fecha']}"
|
||||
|
||||
# Verificar coincidencia
|
||||
if fenix[:total] == dasu['total'] && fenix[:desde_13] == dasu['desde_13']
|
||||
# Comparar fechas como strings
|
||||
fenix_fecha = fenix[:ultima_fecha].to_s.strip
|
||||
dasu_fecha = dasu['ultima_fecha'].to_s.strip
|
||||
|
||||
if fenix_fecha == dasu_fecha
|
||||
puts " ✅ COINCIDE"
|
||||
else
|
||||
puts " ⚠️ FECHAS DIFIEREN"
|
||||
puts " FENIX: #{fenix_fecha}"
|
||||
puts " DASU: #{dasu_fecha}"
|
||||
todas_coinciden = false
|
||||
end
|
||||
else
|
||||
puts " ⚠️ NO COINCIDE - Diferencia en cantidades"
|
||||
todas_coinciden = false
|
||||
end
|
||||
puts ""
|
||||
end
|
||||
|
||||
puts "=" * 60
|
||||
if todas_coinciden
|
||||
puts " ✅ TODOS LOS DATOS COINCIDEN - El restore fue exitoso"
|
||||
else
|
||||
puts " ⚠️ HAY DIFERENCIAS - El restore puede estar incompleto"
|
||||
end
|
||||
end
|
||||
|
||||
# ==========================================
|
||||
# 6. DETALLE ÚLTIMOS REGISTROS (BONOS)
|
||||
# ==========================================
|
||||
puts "\n[5] DETALLE ÚLTIMOS REGISTROS DE BONOS:"
|
||||
puts "=" * 60
|
||||
|
||||
if datos_fenix['Bonos'] && datos_fenix['Bonos'][:ultimos]
|
||||
puts " FENIX - Últimos 5 bonos:"
|
||||
datos_fenix['Bonos'][:ultimos].each_with_index do |registro, i|
|
||||
puts " #{i+1}. #{registro}"
|
||||
end
|
||||
end
|
||||
|
||||
if datos_dasu && datos_dasu['Bonos'] && datos_dasu['Bonos']['ultimos']
|
||||
puts "\n DASU-SQL4 - Últimos 5 bonos:"
|
||||
datos_dasu['Bonos']['ultimos'].each_with_index do |registro, i|
|
||||
puts " #{i+1}. #{registro}"
|
||||
end
|
||||
end
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
|
||||
client_fenix.close
|
||||
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== DASU-SQL4 - Estructura de tabla BonosAfiliado ==="
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] Estructura de la columna idsolicitud:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT
|
||||
COLUMN_NAME,
|
||||
DATA_TYPE,
|
||||
COLUMN_DEFAULT,
|
||||
IS_NULLABLE
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = 'BonosAfiliado' AND COLUMN_NAME = 'idsolicitud'
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$row = $ds.Tables[0].Rows[0]
|
||||
Write-Host " Columna: $($row.COLUMN_NAME)"
|
||||
Write-Host " Tipo: $($row.DATA_TYPE)"
|
||||
Write-Host " Default: $($row.COLUMN_DEFAULT)"
|
||||
Write-Host " Nullable: $($row.IS_NULLABLE)"
|
||||
} else {
|
||||
Write-Host " Columna no encontrada"
|
||||
}
|
||||
|
||||
Write-Host "`n[2] ¿Es idsolicitud una columna IDENTITY?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT
|
||||
c.name AS column_name,
|
||||
t.name AS table_name,
|
||||
COLUMNPROPERTY(OBJECT_ID(t.schema_name + '.' + t.name), c.name, 'IsIdentity') AS is_identity,
|
||||
IDENT_CURRENT(t.schema_name + '.' + t.name) AS current_identity,
|
||||
IDENT_INCR(t.schema_name + '.' + t.name) AS identity_increment,
|
||||
IDENT_SEED(t.schema_name + '.' + t.name) AS identity_seed
|
||||
FROM sys.columns c
|
||||
JOIN sys.tables t ON c.object_id = t.object_id
|
||||
WHERE t.name = 'BonosAfiliado' AND c.name = 'idsolicitud'
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$row = $ds.Tables[0].Rows[0]
|
||||
Write-Host " ¿Es Identity?: $($row.is_identity)"
|
||||
Write-Host " Seed (valor inicial): $($row.identity_seed)"
|
||||
Write-Host " Incremento: $($row.identity_increment)"
|
||||
Write-Host " Valor actual (IDENT_CURRENT): $($row.current_identity)"
|
||||
} else {
|
||||
Write-Host " No es columna IDENTITY o no existe"
|
||||
}
|
||||
|
||||
Write-Host "`n[3] Valores reales de idsolicitud en últimos registros:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 20 idsolicitud, fecha, codigoafiliado
|
||||
FROM BonosAfiliado
|
||||
ORDER BY idsolicitud DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " idsolicitud=$($_.idsolicitud) | fecha=$($_.fecha) | afiliado=$($_.codigoafiliado)"
|
||||
}
|
||||
|
||||
Write-Host "`n[4] ¿Hay registros con idsolicitud > 0?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT COUNT(*) as c FROM BonosAfiliado WHERE idsolicitud > 0
|
||||
", $conn)
|
||||
$c = $cmd.ExecuteScalar()
|
||||
Write-Host " Cantidad: $c"
|
||||
|
||||
Write-Host "`n[5] ¿Hay registros con idsolicitud = 0?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT COUNT(*) as c FROM BonosAfiliado WHERE idsolicitud = 0
|
||||
", $conn)
|
||||
$c = $cmd.ExecuteScalar()
|
||||
Write-Host " Cantidad: $c"
|
||||
|
||||
Write-Host "`n[6] Máximo valor de idsolicitud:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT MAX(idsolicitud) as max_id FROM BonosAfiliado
|
||||
", $conn)
|
||||
$max = $cmd.ExecuteScalar()
|
||||
Write-Host " MAX(idsolicitud): $max"
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== VERIFICAR FECHAS DESPUÉS DEL CAMBIO DE ZONA HORARIA ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] Zona horaria actual del sistema:"
|
||||
$tz = Get-TimeZone
|
||||
Write-Host " ID: $($tz.Id)"
|
||||
Write-Host " DisplayName: $($tz.DisplayName)"
|
||||
Write-Host " BaseUtcOffset: $($tz.BaseUtcOffset)"
|
||||
|
||||
Write-Host "`n[2] Fecha/hora actual:"
|
||||
Write-Host " Get-Date: $(Get-Date)"
|
||||
Write-Host " UTC: $([DateTime]::UtcNow)"
|
||||
|
||||
Write-Host "`n[3] Última fecha en BonosAfiliado:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(fecha) as ultima FROM BonosAfiliado", $conn)
|
||||
$ultima = $cmd.ExecuteScalar()
|
||||
Write-Host " MAX(fecha): $ultima"
|
||||
|
||||
Write-Host "`n[4] Últimos 10 registros (ordenados por fecha):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 10
|
||||
idsolicitud,
|
||||
CONVERT(varchar, fecha, 103) as fecha_ddmmaaaa,
|
||||
codigoafiliado,
|
||||
dependencia,
|
||||
bono,
|
||||
CONVERT(varchar, __tiempo, 103) + ' ' + CONVERT(varchar, __tiempo, 108) as tiempo_completo
|
||||
FROM BonosAfiliado
|
||||
WHERE fecha IS NOT NULL
|
||||
ORDER BY fecha DESC, idsolicitud DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
Write-Host " idsol | fecha (dd/mm/aaaa) | afiliado | dep | bono | __tiempo"
|
||||
Write-Host " " + ("-" * 80)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " $($_.idsolicitud.ToString().PadLeft(5)) | $($_.fecha_ddmmaaaa) | $($_.codigoafiliado.ToString().PadLeft(5)) | $($_.dependencia.ToString().PadLeft(2)) | $($_.bono) | $($_.tiempo_completo)"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n[5] Registros por día (últimos 5 días):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 5
|
||||
CONVERT(varchar, CAST(fecha AS DATE), 103) as dia_ddmmaaaa,
|
||||
COUNT(*) as cantidad,
|
||||
MIN(idsolicitud) as min_id,
|
||||
MAX(idsolicitud) as max_id
|
||||
FROM BonosAfiliado
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY CAST(fecha AS DATE) DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " $($_.dia_ddmmaaaa): $($_.cantidad) registros | IDs: [$($_.min_id) - $($_.max_id)]"
|
||||
}
|
||||
|
||||
Write-Host "`n[6] Verificando formato de fecha ISO:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 3
|
||||
fecha,
|
||||
CONVERT(varchar, fecha, 120) as formato_iso,
|
||||
__tiempo
|
||||
FROM BonosAfiliado
|
||||
ORDER BY fecha DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " fecha=$($_.fecha) | ISO=$($_.formato_iso)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# Verificar FENIX - qué datos hay ACTUALMENTE (abril 15)
|
||||
# ==========================================================
|
||||
|
||||
require 'tiny_tds'
|
||||
|
||||
puts "=== FENIX (PRODUCCIÓN) - ESTADO ACTUAL ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
pass_cmd = `ruby adn/tools/candados/candados.rb get utnlarioja.intranet:monlaricardo 2>/dev/null`.strip
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
|
||||
client = TinyTds::Client.new(
|
||||
username: sql_user,
|
||||
password: pass_cmd,
|
||||
host: sql_host,
|
||||
timeout: 600,
|
||||
database: 'sysdasuten'
|
||||
)
|
||||
|
||||
puts "[1] BonosAfiliado - Registros por día (últimos 5 días):"
|
||||
result = client.execute("
|
||||
SELECT CAST(fecha AS DATE) as dia, COUNT(*) as cantidad
|
||||
FROM BonosAfiliado
|
||||
WHERE fecha >= DATEADD(DAY, -5, GETDATE())
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY dia DESC
|
||||
")
|
||||
|
||||
result.each { |r| puts " #{r['dia']}: #{r['cantidad']} registros" }
|
||||
|
||||
puts "\n[2] BonosAfiliado - Última fecha exacta:"
|
||||
result = client.execute("SELECT MAX(fecha) as ultima FROM BonosAfiliado")
|
||||
puts " #{result.first['ultima']}"
|
||||
|
||||
puts "\n[3] BonosAfiliado - Registros del 2026-04-15:"
|
||||
result = client.execute("SELECT COUNT(*) as c FROM BonosAfiliado WHERE fecha >= '2026-04-15'")
|
||||
puts " #{result.first['c']} registros"
|
||||
|
||||
puts "\n[4] AutorizacionBonosExcepcion - Registros por día:"
|
||||
result = client.execute("
|
||||
SELECT CAST(fechasolicitud AS DATE) as dia, COUNT(*) as cantidad
|
||||
FROM AutorizacionBonosExcepcion
|
||||
WHERE fechasolicitud >= DATEADD(DAY, -5, GETDATE())
|
||||
GROUP BY CAST(fechasolicitud AS DATE)
|
||||
ORDER BY dia DESC
|
||||
")
|
||||
|
||||
result.each { |r| puts " #{r['dia']}: #{r['cantidad']} registros" }
|
||||
|
||||
puts "\n[5] AutorizacionBonosExcepcion - Última fecha:"
|
||||
result = client.execute("SELECT MAX(fechasolicitud) as ultima FROM AutorizacionBonosExcepcion")
|
||||
puts " #{result.first['ultima']}"
|
||||
|
||||
puts "\n[6] AutorizacionBonosExcepcion - Registros del 2026-04-15:"
|
||||
result = client.execute("SELECT COUNT(*) as c FROM AutorizacionBonosExcepcion WHERE fechasolicitud >= '2026-04-15'")
|
||||
puts " #{result.first['c']} registros"
|
||||
|
||||
puts "\n[7] IDs más altos en BonosAfiliado (para ver si hay datos nuevos):"
|
||||
result = client.execute("SELECT TOP 5 idsolicitud FROM BonosAfiliado ORDER BY idsolicitud DESC")
|
||||
puts " Últimos IDs: #{result.to_a.map { |r| r['idsolicitud'] }.join(', ')}"
|
||||
|
||||
client.close
|
||||
|
||||
puts "\n✅ Verificación FENIX completada"
|
||||
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'tiny_tds'
|
||||
|
||||
puts "=== FENIX - Verificando fechas de últimos registros ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
pass_cmd = `ruby adn/tools/candados/candados.rb get utnlarioja.intranet:monlaricardo 2>/dev/null`.strip
|
||||
sql_user = 'UTNlarioja\\monlaricardo'
|
||||
sql_host = '10.0.10.200'
|
||||
|
||||
client = TinyTds::Client.new(
|
||||
username: sql_user,
|
||||
password: pass_cmd,
|
||||
host: sql_host,
|
||||
timeout: 600,
|
||||
database: 'sysdasuten'
|
||||
)
|
||||
|
||||
puts "[1] Últimos 10 registros de BonosAfiliado (por ID):"
|
||||
result = client.execute("
|
||||
SELECT TOP 10 idsolicitud, fecha, codigoafiliado, dependencia,
|
||||
CONVERT(datetime, fecha) as fecha_dt,
|
||||
GETDATE() as ahora
|
||||
FROM BonosAfiliado
|
||||
ORDER BY idsolicitud DESC
|
||||
")
|
||||
|
||||
result.each do |r|
|
||||
puts " ID: #{r['idsolicitud']} | fecha: #{r['fecha']} | afiliado: #{r['codigoafiliado']}"
|
||||
end
|
||||
|
||||
puts "\n[2] Registros con fecha 2026-04-15:"
|
||||
result = client.execute("
|
||||
SELECT TOP 10 idsolicitud, fecha, codigoafiliado
|
||||
FROM BonosAfiliado
|
||||
WHERE fecha >= '2026-04-15'
|
||||
ORDER BY idsolicitud DESC
|
||||
")
|
||||
|
||||
if result.to_a.empty?
|
||||
puts " No hay registros con fecha >= 2026-04-15"
|
||||
else
|
||||
result.each do |r|
|
||||
puts " ID: #{r['idsolicitud']} | fecha: #{r['fecha']}"
|
||||
end
|
||||
end
|
||||
|
||||
puts "\n[3] Verificando diferencia entre MAX(idsolicitud) y MAX(fecha):"
|
||||
result = client.execute("
|
||||
SELECT
|
||||
MAX(idsolicitud) as max_id,
|
||||
(SELECT MAX(fecha) FROM BonosAfiliado) as max_fecha,
|
||||
(SELECT fecha FROM BonosAfiliado WHERE idsolicitud = (SELECT MAX(idsolicitud) FROM BonosAfiliado)) as fecha_del_max_id
|
||||
FROM BonosAfiliado
|
||||
")
|
||||
|
||||
r = result.first
|
||||
puts " ID máximo: #{r['max_id']}"
|
||||
puts " Fecha máxima: #{r['max_fecha']}"
|
||||
puts " Fecha del ID máximo: #{r['fecha_del_max_id']}"
|
||||
|
||||
puts "\n[4] ¿Hay registros creados el 15/04 con fecha 14/04?"
|
||||
puts " (comparando IDs altos con fecha 14 vs fecha 15)"
|
||||
|
||||
# IDs del 15 de abril (por fecha de creación del registro, no la columna fecha)
|
||||
# Usamos una columna de auditoría si existe, sino comparamos por rango de IDs
|
||||
result = client.execute("
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM BonosAfiliado WHERE fecha = '2026-04-15') as con_fecha_15,
|
||||
(SELECT COUNT(*) FROM BonosAfiliado WHERE fecha = '2026-04-14') as con_fecha_14,
|
||||
(SELECT COUNT(*) FROM BonosAfiliado WHERE idsolicitud > 30000000) as con_id_alto
|
||||
")
|
||||
|
||||
r = result.first
|
||||
puts " Registros con fecha=2026-04-15: #{r['con_fecha_15']}"
|
||||
puts " Registros con fecha=2026-04-14: #{r['con_fecha_14']}"
|
||||
puts " Registros con ID > 30000000: #{r['con_id_alto']}"
|
||||
|
||||
client.close
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== VERIFICACIÓN FINAL DASU-SQL4 ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] Última fecha en BonosAfiliado (formato ISO):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT CONVERT(varchar, MAX(fecha), 120) as ultima FROM BonosAfiliado", $conn)
|
||||
$ultima = $cmd.ExecuteScalar()
|
||||
Write-Host " $ultima"
|
||||
|
||||
Write-Host "`n[2] Registros por día (últimos 5 días):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 5
|
||||
CONVERT(varchar, CAST(fecha AS DATE), 120) as dia,
|
||||
COUNT(*) as cantidad,
|
||||
MIN(idsolicitud) as min_id,
|
||||
MAX(idsolicitud) as max_id
|
||||
FROM BonosAfiliado
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY dia DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " $($_.dia): $($_.cantidad) registros | IDs: [$($_.min_id) - $($_.max_id)]"
|
||||
}
|
||||
|
||||
Write-Host "`n[3] ¿La suma de registros coincide con el total?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM BonosAfiliado", $conn)
|
||||
$total = $cmd.ExecuteScalar()
|
||||
Write-Host " Total: $total"
|
||||
|
||||
Write-Host "`n[4] Muestra de 5 registros recientes (con todos sus campos):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 5 idsolicitud, fecha, codigoafiliado, dependencia, bono
|
||||
FROM BonosAfiliado
|
||||
ORDER BY fecha DESC, idsolicitud DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " ids=$($_.idsolicitud) | fecha=$($_.fecha) | afiliado=$($_.codigoafiliado) | dep=$($_.dependencia) | bono=$($_.bono)"
|
||||
}
|
||||
|
||||
Write-Host "`n[5] Verificando si hay datos del 15 de abril de 2026:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT COUNT(*) as c FROM BonosAfiliado
|
||||
WHERE YEAR(fecha) = 2026 AND MONTH(fecha) = 4 AND DAY(fecha) = 15
|
||||
", $conn)
|
||||
$c = $cmd.ExecuteScalar()
|
||||
Write-Host " Registros el 2026-04-15: $c"
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== DASU-SQL4 - Verificar si idsolicitud es IDENTITY ==="
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] ¿Es idsolicitud una columna IDENTITY?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT COLUMNPROPERTY(OBJECT_ID('dbo.BonosAfiliado'), 'idsolicitud', 'IsIdentity')
|
||||
", $conn)
|
||||
$is_identity = $cmd.ExecuteScalar()
|
||||
if ($is_identity -eq 1) {
|
||||
Write-Host " SI, es columna IDENTITY"
|
||||
} else {
|
||||
Write-Host " NO, no es columna IDENTITY (valor: $is_identity)"
|
||||
}
|
||||
|
||||
Write-Host "`n[2] Valor actual de IDENT_CURRENT:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT IDENT_CURRENT('dbo.BonosAfiliado')
|
||||
", $conn)
|
||||
try {
|
||||
$current = $cmd.ExecuteScalar()
|
||||
Write-Host " IDENT_CURRENT: $current"
|
||||
} catch {
|
||||
Write-Host " ERROR: $_"
|
||||
}
|
||||
|
||||
Write-Host "`n[3] Contar registros con idsolicitud = 0 vs > 0:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT
|
||||
SUM(CASE WHEN idsolicitud = 0 THEN 1 ELSE 0 END) as con_cero,
|
||||
SUM(CASE WHEN idsolicitud > 0 THEN 1 ELSE 0 END) as con_mayor_cero
|
||||
FROM BonosAfiliado
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$row = $ds.Tables[0].Rows[0]
|
||||
Write-Host " Con idsolicitud=0: $($row.con_cero)"
|
||||
Write-Host " Con idsolicitud>0: $($row.con_mayor_cero)"
|
||||
}
|
||||
|
||||
Write-Host "`n[4] Máximo idsolicitud:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT MAX(idsolicitud) as max_id FROM BonosAfiliado
|
||||
", $conn)
|
||||
$max = $cmd.ExecuteScalar()
|
||||
Write-Host " MAX(idsolicitud): $max"
|
||||
|
||||
Write-Host "`n[5] Últimos 5 registros por fecha (ver idsolicitud):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 5 idsolicitud, fecha, codigoafiliado
|
||||
FROM BonosAfiliado
|
||||
ORDER BY fecha DESC, idsolicitud DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " idsolicitud=$($_.idsolicitud) | fecha=$($_.fecha)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== DASU-SQL4 - Relación IDs vs Fechas ==="
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] Últimos 20 registros por ID:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 20 idsolicitud, fecha FROM BonosAfiliado ORDER BY idsolicitud DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " ID: $($_.idsolicitud) | fecha: $($_.fecha)"
|
||||
}
|
||||
|
||||
Write-Host "`n[2] Máximo ID por fecha (últimos 5 días):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 5 CAST(fecha AS DATE) as dia, MAX(idsolicitud) as max_id
|
||||
FROM BonosAfiliado
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY dia DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " $($_.dia): ID máximo = $($_.max_id)"
|
||||
}
|
||||
|
||||
Write-Host "`n[3] Rango de IDs por fecha:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT
|
||||
CAST(fecha AS DATE) as dia,
|
||||
MIN(idsolicitud) as min_id,
|
||||
MAX(idsolicitud) as max_id,
|
||||
COUNT(*) as cantidad
|
||||
FROM BonosAfiliado
|
||||
WHERE fecha >= '2026-04-10'
|
||||
GROUP BY CAST(fecha AS DATE)
|
||||
ORDER BY dia DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " $($_.dia): IDs [$($_.min_id) - $($_.max_id)] | cantidad: $($_.cantidad)"
|
||||
}
|
||||
|
||||
Write-Host "`n[4] ¿Hay IDs > 30000000 con fecha 14?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT COUNT(*) as c
|
||||
FROM BonosAfiliado
|
||||
WHERE idsolicitud > 30000000 AND fecha = '2026-04-14'
|
||||
", $conn)
|
||||
$c = $cmd.ExecuteScalar()
|
||||
Write-Host " Cantidad: $c"
|
||||
|
||||
Write-Host "`n[5] Últimos 5 IDs > 30000000:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 5 idsolicitud, fecha
|
||||
FROM BonosAfiliado
|
||||
WHERE idsolicitud > 30000000
|
||||
ORDER BY idsolicitud DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " ID: $($_.idsolicitud) | fecha: $($_.fecha)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== DASU-SQL4 - Verificar clave primaria en BonosAfiliado ==="
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] ¿Hay clave primaria en BonosAfiliado?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT i.name as index_name, i.is_primary_key, i.is_unique
|
||||
FROM sys.indexes i
|
||||
WHERE i.object_id = OBJECT_ID('dbo.BonosAfiliado') AND i.is_primary_key = 1
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$row = $ds.Tables[0].Rows[0]
|
||||
Write-Host " PK: $($row.index_name) (unique: $($row.is_unique))"
|
||||
} else {
|
||||
Write-Host " NO HAY CLAVE PRIMARIA"
|
||||
}
|
||||
|
||||
Write-Host "`n[2] ¿Hay índices únicos?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT i.name as index_name, i.is_unique
|
||||
FROM sys.indexes i
|
||||
WHERE i.object_id = OBJECT_ID('dbo.BonosAfiliado') AND i.is_unique = 1
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " Índice: $($_.index_name) (unique: $($_.is_unique))"
|
||||
}
|
||||
} else {
|
||||
Write-Host " NO HAY ÍNDICES ÚNICOS"
|
||||
}
|
||||
|
||||
Write-Host "`n[3] Columnas de la tabla:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT c.name, t.name as type_name, c.is_nullable
|
||||
FROM sys.columns c
|
||||
JOIN sys.types t ON c.user_type_id = t.user_type_id
|
||||
WHERE c.object_id = OBJECT_ID('dbo.BonosAfiliado')
|
||||
ORDER BY c.column_id
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " $($_.name) ($($_.type_name)) nullable=$($_.is_nullable)"
|
||||
}
|
||||
|
||||
Write-Host "`n[4] ¿Hay registros duplicados por (fecha, codigoafiliado, dependencia)?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT fecha, codigoafiliado, dependencia, COUNT(*) as duplicados
|
||||
FROM BonosAfiliado
|
||||
GROUP BY fecha, codigoafiliado, dependencia
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY duplicados DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
Write-Host " Hay $($ds.Tables[0].Rows.Count) combinaciones duplicadas"
|
||||
$ds.Tables[0].Rows | Select-Object -First 5 | ForEach-Object {
|
||||
Write-Host " fecha=$($_.fecha) | afiliado=$($_.codigoafiliado) | dep=$($_.dependencia) | count=$($_.duplicados)"
|
||||
}
|
||||
} else {
|
||||
Write-Host " NO HAY DUPLICADOS"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== VERIFICANDO DATOS EN DASU-SQL4 ==="
|
||||
puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] BonosAfiliado - Última fecha:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(fecha) as ultima FROM BonosAfiliado", $conn)
|
||||
$ultima = $cmd.ExecuteScalar()
|
||||
Write-Host " $ultima"
|
||||
|
||||
Write-Host "`n[2] BonosAfiliado - ID máximo:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(idsolicitud) as max_id FROM BonosAfiliado", $conn)
|
||||
$maxId = $cmd.ExecuteScalar()
|
||||
Write-Host " $maxId"
|
||||
|
||||
Write-Host "`n[3] BonosAfiliado - Registros por fecha:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT CAST(fecha AS DATE) as dia, COUNT(*) as c FROM BonosAfiliado GROUP BY CAST(fecha AS DATE) ORDER BY dia DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object { Write-Host " $($_.dia): $($_.c) registros" }
|
||||
|
||||
Write-Host "`n[4] AutorizacionBonosExcepcion - ID máximo:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(idsolicitud) as max_id FROM AutorizacionBonosExcepcion", $conn)
|
||||
$maxId = $cmd.ExecuteScalar()
|
||||
Write-Host " $maxId"
|
||||
|
||||
Write-Host "`n[5] AutorizacionBonosExcepcion - Última fecha:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT MAX(fechasolicitud) as ultima FROM AutorizacionBonosExcepcion", $conn)
|
||||
$ultima = $cmd.ExecuteScalar()
|
||||
Write-Host " $ultima"
|
||||
|
||||
Write-Host "`n[6] Fecha del último restore:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT TOP 1 restore_date FROM msdb.dbo.restorehistory WHERE destination_database_name = 'sysdasuten' ORDER BY restore_date DESC", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
Write-Host " Restore: $($ds.Tables[0].Rows[0].restore_date)"
|
||||
}
|
||||
|
||||
Write-Host "`n[7] Archivos en F:\\BACKUP:"
|
||||
Get-ChildItem "F:\\BACKUP\\*.bak" | ForEach-Object {
|
||||
Write-Host " $($_.Name)"
|
||||
Write-Host " LastWriteTime: $($_.LastWriteTime)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== DASU-SQL4 - Verificar triggers y constraints en BonosAfiliado ==="
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$connString = "Server=localhost;Database=sysdasuten;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
Write-Host "[1] ¿Hay triggers en BonosAfiliado?"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT name, type_desc
|
||||
FROM sys.triggers
|
||||
WHERE parent_id = OBJECT_ID('dbo.BonosAfiliado')
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " Trigger: $($_.name) ($($_.type_desc))"
|
||||
}
|
||||
} else {
|
||||
Write-Host " No hay triggers"
|
||||
}
|
||||
|
||||
Write-Host "`n[2] Constraints DEFAULT en idsolicitud:"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT dc.name, dc.definition
|
||||
FROM sys.default_constraints dc
|
||||
JOIN sys.columns c ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id
|
||||
WHERE OBJECT_NAME(dc.parent_object_id) = 'BonosAfiliado' AND c.name = 'idsolicitud'
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " Constraint: $($_.name) = $($_.definition)"
|
||||
}
|
||||
} else {
|
||||
Write-Host " No hay constraints DEFAULT"
|
||||
}
|
||||
|
||||
Write-Host "`n[3] Verificar columna idsolicitud (detalles):"
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT
|
||||
c.name,
|
||||
c.is_nullable,
|
||||
c.is_identity,
|
||||
c.default_object_id,
|
||||
t.name as type_name
|
||||
FROM sys.columns c
|
||||
JOIN sys.types t ON c.user_type_id = t.user_type_id
|
||||
WHERE c.object_id = OBJECT_ID('dbo.BonosAfiliado') AND c.name = 'idsolicitud'
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
if ($ds.Tables[0].Rows.Count -gt 0) {
|
||||
$row = $ds.Tables[0].Rows[0]
|
||||
Write-Host " name: $($row.name)"
|
||||
Write-Host " is_nullable: $($row.is_nullable)"
|
||||
Write-Host " is_identity: $($row.is_identity)"
|
||||
Write-Host " default_object_id: $($row.default_object_id)"
|
||||
Write-Host " type: $($row.type_name)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'drones/lib/dasu_executor'
|
||||
|
||||
puts "=== DASU-SQL4 - Verificar Zona Horaria ==="
|
||||
puts ""
|
||||
|
||||
ps_script = <<~PSCMD.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Write-Host "[1] Zona horaria del sistema:"
|
||||
$tz = Get-TimeZone
|
||||
Write-Host " ID: $($tz.Id)"
|
||||
Write-Host " DisplayName: $($tz.DisplayName)"
|
||||
Write-Host " BaseUtcOffset: $($tz.BaseUtcOffset)"
|
||||
|
||||
Write-Host "`n[2] Fecha/hora actual del sistema:"
|
||||
Write-Host " Get-Date: $(Get-Date)"
|
||||
Write-Host " Get-Date -Format 'o': $(Get-Date -Format 'o')"
|
||||
Write-Host " [DateTime]::Now: $([DateTime]::Now)"
|
||||
Write-Host " [DateTime]::UtcNow: $([DateTime]::UtcNow)"
|
||||
|
||||
Write-Host "`n[3] Fecha/hora en SQL Server:"
|
||||
$connString = "Server=localhost;Database=master;Integrated Security=true;TrustServerCertificate=yes;"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT GETDATE() as fecha_sql", $conn)
|
||||
$fecha = $cmd.ExecuteScalar()
|
||||
Write-Host " GETDATE(): $fecha"
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT SYSUTCDATETIME() as utc_sql", $conn)
|
||||
$utc = $cmd.ExecuteScalar()
|
||||
Write-Host " SYSUTCDATETIME(): $utc"
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("SELECT SYSDATETIMEOFFSET() as offset_sql", $conn)
|
||||
$offset = $cmd.ExecuteScalar()
|
||||
Write-Host " SYSDATETIMEOFFSET(): $offset"
|
||||
|
||||
$conn.Close()
|
||||
|
||||
Write-Host "`n[4] Verificando fecha en BonosAfiliado:"
|
||||
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
|
||||
$conn.Open()
|
||||
$conn.ChangeDatabase("sysdasuten")
|
||||
|
||||
$cmd = New-Object System.Data.SqlClient.SqlCommand("
|
||||
SELECT TOP 5 fecha, __tiempo, impresion
|
||||
FROM BonosAfiliado
|
||||
WHERE fecha IS NOT NULL
|
||||
ORDER BY fecha DESC
|
||||
", $conn)
|
||||
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
|
||||
$ds = New-Object System.Data.DataSet
|
||||
$adapter.Fill($ds)
|
||||
$ds.Tables[0].Rows | ForEach-Object {
|
||||
Write-Host " fecha=$($_.fecha) | __tiempo=$($_.__tiempo) | impresion=$($_.impresion)"
|
||||
}
|
||||
|
||||
$conn.Close()
|
||||
PSCMD
|
||||
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script)
|
||||
|
||||
puts "\n✅ Verificación completada"
|
||||
@@ -4,6 +4,15 @@
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
-- Agregar columna 'codigo' a ambitos si no existe
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'bitacoras' AND table_name = 'ambitos' AND column_name = 'codigo'
|
||||
) THEN
|
||||
ALTER TABLE bitacoras.ambitos ADD COLUMN codigo VARCHAR(10);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_ambitos_codigo ON bitacoras.ambitos(codigo);
|
||||
END IF;
|
||||
|
||||
-- Crear tabla planes (dentro de un ámbito)
|
||||
CREATE TABLE IF NOT EXISTS bitacoras.planes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
@@ -38,24 +47,23 @@ BEGIN
|
||||
-- Mantener fase_id por compatibilidad temporal (se deprecará en el futuro)
|
||||
-- Los nuevos hitos deben usar plan_id
|
||||
|
||||
-- Crear vista resumen_planes para métricas
|
||||
CREATE OR REPLACE VIEW bitacoras.resumen_planes AS
|
||||
SELECT
|
||||
p.id AS plan_id,
|
||||
p.codigo,
|
||||
p.titulo,
|
||||
p.estado,
|
||||
a.codigo AS ambito_codigo,
|
||||
a.nombre AS ambito_nombre,
|
||||
COUNT(h.id) AS total_hitos,
|
||||
COUNT(CASE WHEN h.estado = '✅' THEN 1 END) AS hitos_completados,
|
||||
COALESCE(SUM(h.horas_presencial), 0) AS total_horas_presencial,
|
||||
COALESCE(SUM(h.horas_remoto), 0) AS total_horas_remoto,
|
||||
MIN(h.fecha) AS fecha_inicio_real,
|
||||
MAX(h.fecha) AS fecha_fin_real
|
||||
FROM bitacoras.planes p
|
||||
LEFT JOIN bitacoras.ambitos a ON p.ambito_id = a.id
|
||||
LEFT JOIN bitacoras.hitos h ON p.id = h.plan_id
|
||||
GROUP BY p.id, p.codigo, p.titulo, p.estado, a.codigo, a.nombre;
|
||||
|
||||
END $$;
|
||||
|
||||
-- Crear vista resumen_planes para métricas (fuera del bloque DO)
|
||||
CREATE OR REPLACE VIEW bitacoras.resumen_planes AS
|
||||
SELECT
|
||||
p.id AS plan_id,
|
||||
p.codigo,
|
||||
p.titulo,
|
||||
p.estado,
|
||||
a.nombre AS ambito_nombre,
|
||||
COUNT(h.id) AS total_hitos,
|
||||
COUNT(CASE WHEN h.estado = '✅' THEN 1 END) AS hitos_completados,
|
||||
COALESCE(SUM(h.horas_presencial), 0) AS total_horas_presencial,
|
||||
COALESCE(SUM(h.horas_remoto), 0) AS total_horas_remoto,
|
||||
MIN(h.fecha) AS fecha_inicio_real,
|
||||
MAX(h.fecha) AS fecha_fin_real
|
||||
FROM bitacoras.planes p
|
||||
LEFT JOIN bitacoras.ambitos a ON p.ambito_id = a.id
|
||||
LEFT JOIN bitacoras.hitos h ON p.id = h.plan_id
|
||||
GROUP BY p.id, p.codigo, p.titulo, p.estado, a.nombre;
|
||||
|
||||
Reference in New Issue
Block a user