feat: split into code for buffer and vm
This commit is contained in:
+2
-105
@@ -1,112 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"godb/internals/repl"
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
. "godb/internals/repl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type metaCommandResults int
|
|
||||||
|
|
||||||
const (
|
|
||||||
metaCommandSuccess metaCommandResults = iota
|
|
||||||
metaCommandUnrecognised
|
|
||||||
)
|
|
||||||
|
|
||||||
type prepareResults int
|
|
||||||
|
|
||||||
const (
|
|
||||||
prepareSuccess prepareResults = iota
|
|
||||||
prepareUnrecognised
|
|
||||||
prepareSyntaxError
|
|
||||||
)
|
|
||||||
|
|
||||||
type statementType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
statementSelect statementType = iota
|
|
||||||
statementInsert
|
|
||||||
)
|
|
||||||
|
|
||||||
type row struct {
|
|
||||||
id uint
|
|
||||||
username string
|
|
||||||
email string
|
|
||||||
}
|
|
||||||
|
|
||||||
type statement struct {
|
|
||||||
stype statementType
|
|
||||||
row row
|
|
||||||
}
|
|
||||||
|
|
||||||
func doMetaCommands(inputBuffer *InputBuffer) metaCommandResults {
|
|
||||||
metacommand := metaCommandUnrecognised
|
|
||||||
if inputBuffer.Buffer == ".exit" {
|
|
||||||
fmt.Println("bye!")
|
|
||||||
os.Exit(0)
|
|
||||||
} else {
|
|
||||||
metacommand = metaCommandUnrecognised
|
|
||||||
}
|
|
||||||
return metacommand
|
|
||||||
}
|
|
||||||
|
|
||||||
func prepareStatements(inputBuffer *InputBuffer, statement *statement) prepareResults {
|
|
||||||
if strings.HasPrefix(inputBuffer.Buffer, "insert") {
|
|
||||||
argsAssigned, err := fmt.Sscanf(inputBuffer.Buffer, "insert %d %s %s", &statement.row.id, &statement.row.username, &statement.row.email)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("error parsing insert statement")
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
}
|
|
||||||
if argsAssigned > 3 {
|
|
||||||
return prepareSyntaxError
|
|
||||||
}
|
|
||||||
statement.stype = statementInsert
|
|
||||||
return prepareSuccess
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(inputBuffer.Buffer, "select") {
|
|
||||||
statement.stype = statementSelect
|
|
||||||
return prepareSuccess
|
|
||||||
}
|
|
||||||
return prepareUnrecognised
|
|
||||||
}
|
|
||||||
|
|
||||||
func executeStatement(statement *statement) {
|
|
||||||
switch statement.stype {
|
|
||||||
case statementInsert:
|
|
||||||
fmt.Println("This is where the logic of insert statement should go")
|
|
||||||
case statementSelect:
|
|
||||||
fmt.Println("This is where the logic of select statement should go")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
inputBuffer := NewInputBuffer()
|
repl.Run()
|
||||||
statement := statement{0, row{0, "", ""}}
|
|
||||||
for {
|
|
||||||
PrintConsole()
|
|
||||||
inputBuffer.ReadConsole()
|
|
||||||
if strings.HasPrefix(inputBuffer.Buffer, ".") {
|
|
||||||
switch doMetaCommands(inputBuffer) {
|
|
||||||
case metaCommandSuccess:
|
|
||||||
continue
|
|
||||||
case metaCommandUnrecognised:
|
|
||||||
fmt.Printf("unrecognised comma%v\n", inputBuffer.Buffer)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch prepareStatements(inputBuffer, &statement) {
|
|
||||||
case prepareSuccess:
|
|
||||||
//todo
|
|
||||||
case prepareUnrecognised:
|
|
||||||
fmt.Printf("Unrecognised keyword at the start of '%s'.\n", inputBuffer.Buffer)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
executeStatement(&statement)
|
|
||||||
fmt.Println("Executed")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package buffer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InputBuffer struct {
|
||||||
|
Buffer string
|
||||||
|
Reader *bufio.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInputBuffer() *InputBuffer {
|
||||||
|
return &InputBuffer{
|
||||||
|
Buffer: "",
|
||||||
|
Reader: bufio.NewReader(os.Stdin),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (inputBuffer *InputBuffer) ReadConsole() {
|
||||||
|
line, err := inputBuffer.Reader.ReadString('\n')
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
|
fmt.Println("Error reading input", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
inputBuffer.Buffer = strings.TrimSpace(line)
|
||||||
|
}
|
||||||
+31
-21
@@ -1,34 +1,44 @@
|
|||||||
package repl
|
package repl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
. "godb/internals/buffer"
|
||||||
|
. "godb/internals/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InputBuffer struct {
|
|
||||||
Buffer string
|
|
||||||
Reader *bufio.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewInputBuffer() *InputBuffer {
|
|
||||||
return &InputBuffer{
|
|
||||||
Buffer: "",
|
|
||||||
Reader: bufio.NewReader(os.Stdin),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintConsole() {
|
func PrintConsole() {
|
||||||
fmt.Print("godb > ")
|
fmt.Print("godb > ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inputBuffer *InputBuffer) ReadConsole() {
|
func Run() {
|
||||||
line, err := inputBuffer.Reader.ReadString('\n')
|
|
||||||
if err != nil && err != io.EOF {
|
inputBuffer := NewInputBuffer()
|
||||||
fmt.Println("Error reading input", err)
|
statement := NewStatement()
|
||||||
os.Exit(1)
|
for {
|
||||||
|
PrintConsole()
|
||||||
|
inputBuffer.ReadConsole()
|
||||||
|
if len(inputBuffer.Buffer) > 0 && strings.HasPrefix(inputBuffer.Buffer, ".") {
|
||||||
|
switch DoMetaCommands(inputBuffer) {
|
||||||
|
case MetaCommandSuccess:
|
||||||
|
continue
|
||||||
|
case MetaCommandUnrecognised:
|
||||||
|
fmt.Printf("unrecognised command %v\n", inputBuffer.Buffer)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch statement.PrepareStatements(inputBuffer) {
|
||||||
|
case PrepareSuccess:
|
||||||
|
//todo
|
||||||
|
case PrepareUnrecognised:
|
||||||
|
fmt.Printf("Unrecognised keyword at the start of '%s'.\n", inputBuffer.Buffer)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
statement.ExecuteStatement()
|
||||||
|
fmt.Println("Executed")
|
||||||
|
|
||||||
}
|
}
|
||||||
inputBuffer.Buffer = strings.TrimSpace(line)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package vm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
. "godb/internals/buffer"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MetaCommandResults int
|
||||||
|
|
||||||
|
const (
|
||||||
|
MetaCommandSuccess MetaCommandResults = iota
|
||||||
|
MetaCommandUnrecognised
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrepareResults int
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrepareSuccess PrepareResults = iota
|
||||||
|
PrepareUnrecognised
|
||||||
|
PrepareSyntaxError
|
||||||
|
)
|
||||||
|
|
||||||
|
type statementType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
StatementSelect statementType = iota
|
||||||
|
StatementInsert
|
||||||
|
)
|
||||||
|
|
||||||
|
type row struct {
|
||||||
|
id uint
|
||||||
|
username string
|
||||||
|
email string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Statement struct {
|
||||||
|
stype statementType
|
||||||
|
row row
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStatement() *Statement {
|
||||||
|
return &Statement{0, row{0, "", ""}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DoMetaCommands(inputBuffer *InputBuffer) MetaCommandResults {
|
||||||
|
metacommand := MetaCommandUnrecognised
|
||||||
|
if inputBuffer.Buffer == ".exit" {
|
||||||
|
fmt.Println("bye!")
|
||||||
|
os.Exit(0)
|
||||||
|
} else {
|
||||||
|
metacommand = MetaCommandUnrecognised
|
||||||
|
}
|
||||||
|
return metacommand
|
||||||
|
}
|
||||||
|
|
||||||
|
func (statement *Statement) PrepareStatements(inputBuffer *InputBuffer) PrepareResults {
|
||||||
|
if strings.HasPrefix(inputBuffer.Buffer, "insert") {
|
||||||
|
argsAssigned, err := fmt.Sscanf(inputBuffer.Buffer, "insert %d %s %s", &statement.row.id, &statement.row.username, &statement.row.email)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error parsing insert statement")
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
if argsAssigned > 3 {
|
||||||
|
return PrepareSyntaxError
|
||||||
|
}
|
||||||
|
statement.stype = StatementInsert
|
||||||
|
return PrepareSuccess
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(inputBuffer.Buffer, "select") {
|
||||||
|
statement.stype = StatementSelect
|
||||||
|
return PrepareSuccess
|
||||||
|
}
|
||||||
|
return PrepareUnrecognised
|
||||||
|
}
|
||||||
|
|
||||||
|
func (statement *Statement) ExecuteStatement() {
|
||||||
|
switch statement.stype {
|
||||||
|
case StatementInsert:
|
||||||
|
fmt.Println("This is where the logic of insert statement should go")
|
||||||
|
case StatementSelect:
|
||||||
|
fmt.Println("This is where the logic of select statement should go")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user