GOOGLE ADS

jueves, 28 de abril de 2022

El decodificador gob devuelve solo el primer elemento de la matriz

Entonces, estaba tratando de crear una base de datos simulada, y en la implementación actual, estoy tratando de hacer un inserty selectque inserta filas y selectlas devuelve. Decidí usar a bytes.Bufferpara ayudar a mantener un bloque de memoria en el que podría insertar una porción de filas y deserializar ese bloque de memoria cuando llamo select, pero parece que selectsolo devuelve la primera fila en lugar de todas las filas pasadas a la matriz.

principal.ir


func main() {
inputBuffer:= compiler.NewInputBuffer()
scanner:= bufio.NewScanner(os.Stdin)
for {
PrintPrompt()
scanner.Scan()
command:= scanner.Text()
inputBuffer.Buffer = command
if strings.HasPrefix(inputBuffer.Buffer, ".") {
switch compiler.DoMetaCommand(inputBuffer) {
case compiler.MetaCommandSuccess:
continue
case compiler.MetaCommandUnrecognizedCommand:
fmt.Printf("Unrecognized command %q \n", inputBuffer.Buffer)
continue
}
}
var statement compiler.Statement
switch compiler.PrepareStatement(inputBuffer, &statement) {
case compiler.PrepareSuccess:
case compiler.PrepareUnrecognizedStatement:
fmt.Printf("Unrecognized command at start of %q \n", inputBuffer.Buffer)
continue
case compiler.PrepareSyntaxError:
fmt.Println("Syntax error. Could not parse statement.")
continue
}
compiler.ExecuteStatement(statement)
fmt.Println("Executed")
}
}
func PrintPrompt() {
fmt.Printf("db > ")
}

Arriba está el código responsable de recopilar la entrada del usuario, etc.

package compiler
import (
"bytes"
"log"
"os"
"strconv"
"strings"
)
type Row struct {
ID int32
Username string
Email string
}
type Statement struct {
RowToInsert Row
Type StatementType
}
var (
RowsTable = make([]Row, 0)
RowsTableBuffer bytes.Buffer
)
func DoMetaCommand(buffer InputBuffer) MetaCommandResult {
if buffer.Buffer == ".exit" {
os.Exit(0)
} else {
return MetaCommandUnrecognizedCommand
}
return MetaCommandSuccess
}
func PrepareStatement(buffer InputBuffer, statement *Statement) PrepareResult {
if len(buffer.Buffer) > 6 {
bufferArguments:= strings.Fields(buffer.Buffer)
if bufferArguments[0] == "insert" {
statement.Type = StatementInsert
if len(bufferArguments) < 4 {
return PrepareSyntaxError
} else {
i, err:= strconv.Atoi(bufferArguments[1])
if err!= nil {
log.Printf("%q is not a valid id\n", bufferArguments[1])
return PrepareSyntaxError
} else {
statement.RowToInsert.ID = int32(i)
}
statement.RowToInsert.Username = bufferArguments[2]
statement.RowToInsert.Email = bufferArguments[3]
}
RowsTable = append(RowsTable, statement.RowToInsert)

return PrepareSuccess
}
}
if buffer.Buffer == "select" {
statement.Type = StatementSelect
return PrepareSuccess
}
return PrepareUnrecognizedStatement
}
func ExecuteStatement(statement Statement) {
switch statement.Type {
case (StatementInsert):
SerializeRow(RowsTable)
case (StatementSelect):
DeserializeRow()
}
}

El código anterior es para analizar y agregar las entradas en declaraciones y, según las palabras clave, es un inserto select[Tomó el código para definir enumeraciones y dejó la lógica central]


func SerializeRow(r []Row) {
encoder:= gob.NewEncoder(&RowsTableBuffer)
err:= encoder.Encode(r)
if err!= nil {
log.Println("encode error:", err)
}
}
func DeserializeRow() {
var rowsBuffer = RowsTableBuffer
rowsTable:= make([]Row, 0)
decoder:= gob.NewDecoder(&rowsBuffer)
err:= decoder.Decode(&rowsTable)
if err!= nil {
log.Println("decode error:", err)
}
fmt.Println(rowsTable)
}

Entonces, el código anterior usa un global bufferen el que se codificará el sliceser agregado después de que se complete un. A debería devolver el segmento de todas las filas, pero solo devuelve el primer elemento por alguna razón.PrepareStatement()insertselect

Ejemplo (en terminal): Si hago 2 inserciones:
db > insert 1 john c@mail.com db > insert 2 collins k@mail.com

Luego hago una selección:
select => solo devuelve [{1 john c@mail.com}].

¿Hay algo que me estoy perdiendo aquí? Gracias por su apoyo.


Solución del problema

Así que la respuesta fue bastante simple. Estábamos creando una nueva encoderen la SerializeRowfunción en lugar de crearla una vez. Lo sacamos de la función y creamos un archivo global.

var (
encoder = gob.NewEncoder(&RowsTableBuffer)
decoder = gob.NewDecoder(&RowsTableBuffer)
)
func SerializeRow(r Row) {
err:= encoder.Encode(r)
if err!= nil {
log.Println("encode error:", err)
}
}
func DeserializeRow() {
var rows Row
err:= decoder.Decode(&rows)
for err == nil {
if err!= nil {
log.Fatal("decode error:", err)
}
fmt.Printf("%d %s %s\n", rows.ID, rows.Username, rows.Email)
err = decoder.Decode(&rows)
}
}

No hay comentarios:

Publicar un comentario

Regla de Firestore para acceder a la generación de subcolección Permisos faltantes o insuficientes

Tengo problemas con las reglas de Firestore para permitir el acceso a algunos recursos en una subcolección. Tengo algunos requests document...