fix(query-runner): "conx_db_id inválido" al correr un .sql, y el parser que se comía el script
Dos bugs encadenados. El segundo es mucho peor que el que se veía.
1. EL ERROR VISIBLE. RunBatchQuery leía conx_db_id del formulario y lo guardaba
bien, y después lo pisaba con cero. El struct del body solo tenía etiquetas
json, pero en multipart Fiber mapea por la etiqueta form: no encontraba
conx_db_id, dejaba el campo en cero — y BodyParser NO devuelve error cuando
no mapea nada, así que la rama se ejecutaba igual y sobreescribía el valor
bueno. De ahí el "conx_db_id inválido" con la conexión bien elegida en
pantalla. Reproducido con un test antes de tocar nada.
2. EL QUE NO SE VEÍA. El script se partía con split(';') y se descartaba todo
trozo que empezara con "--". En un script documentado, donde cada sentencia
va debajo de su encabezado en comentarios, eso se saltaba casi todo el
archivo en silencio. Con el .sql que lo destapó: de 10 sentencias reales
pasaban 3 — y una de esas tres era un fragmento corrupto, porque un punto y
coma dentro de un comentario había partido una sentencia al medio. Se
perdían los dos INSERT de alta y el ALTER TABLE, que era el único cambio
estructural del script.
Es decir: arreglar solo el bug 1 habría sido peor que dejarlo. El usuario
habría leído "3 consultas ejecutadas" y se habría ido tranquilo con la
migración a medio aplicar.
DividirSentenciasSQL parte respetando dónde el punto y coma no separa nada:
comentarios de línea (-- y #), de bloque, y cadenas con ' " ` incluyendo
escapes con barra y comillas duplicadas. Y en vez de descartar lo que empieza
con "--", pregunta si al trozo le queda SQL después de sacarle los comentarios
— un "--" adentro de una cadena ya no oculta la sentencia.
Mismo criterio en los dos lados: el front arma las sentencias y el backend
divide los archivos subidos, y las dos implementaciones dan las mismas 10 sobre
el archivo real.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b7c52f174a
commit
93f5fdec7a
@@ -196,26 +196,26 @@ func RunBatchQuery(c *fiber.Ctx) error {
|
||||
defer f.Close()
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(f)
|
||||
content := buf.String()
|
||||
// Dividir por ;
|
||||
for _, stmt := range strings.Split(content, ";") {
|
||||
stmt = strings.TrimSpace(stmt)
|
||||
if stmt != "" {
|
||||
statements = append(statements, stmt)
|
||||
}
|
||||
}
|
||||
statements = append(statements, services.DividirSentenciasSQL(buf.String())...)
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Si no hay archivo, leer del body JSON
|
||||
if len(statements) == 0 {
|
||||
var body struct {
|
||||
ConxDbID uint `json:"conx_db_id"`
|
||||
Database string `json:"database"`
|
||||
SQLs []string `json:"sqls"`
|
||||
ConxDbID uint `json:"conx_db_id" form:"conx_db_id"`
|
||||
Database string `json:"database" form:"database"`
|
||||
SQLs []string `json:"sqls" form:"sqls"`
|
||||
}
|
||||
if err := c.BodyParser(&body); err == nil {
|
||||
conxDbIDStr = strconv.Itoa(int(body.ConxDbID))
|
||||
// Solo se pisa si el body trae algo. BodyParser NO falla cuando no
|
||||
// mapea nada —en multipart, sin la etiqueta form: no encontraba
|
||||
// conx_db_id— y este cero borraba la conexión que el formulario sí
|
||||
// había mandado: de ahí el "conx_db_id inválido" con la conexión
|
||||
// bien elegida en pantalla.
|
||||
if body.ConxDbID != 0 {
|
||||
conxDbIDStr = strconv.Itoa(int(body.ConxDbID))
|
||||
}
|
||||
if body.Database != "" {
|
||||
database = body.Database
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user