Entonces, estaba tratando de crear una base de datos simulada, y en la implementación actual, estoy tratando de hacer un insert
y select
que inserta filas y select
las devuelve. Decidí usar a bytes.Buffer
para 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 select
solo 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 insert
o 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 buffer
en el que se codificará el slice
ser 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()
insert
select
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 encoder
en la SerializeRow
funció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