Merging into main #1
@@ -38,8 +38,12 @@ func Run() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.ExecuteStatement(table)
|
switch statement.ExecuteStatement(table) {
|
||||||
fmt.Println("Executed")
|
case ExecuteSuccess:
|
||||||
|
fmt.Println("Executed.")
|
||||||
|
case ExecuteTableFull:
|
||||||
|
fmt.Println("Error: Table is full")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+84
-8
@@ -1,6 +1,7 @@
|
|||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -30,6 +31,29 @@ const (
|
|||||||
StatementInsert
|
StatementInsert
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
idSize = 8
|
||||||
|
usernameSize = 32
|
||||||
|
emailSize = 255
|
||||||
|
|
||||||
|
idOffset = 0
|
||||||
|
usernameOffset = idOffset + idSize
|
||||||
|
emailOffset = usernameOffset + usernameSize
|
||||||
|
|
||||||
|
pageSize = 4096
|
||||||
|
maxPages = 100
|
||||||
|
rowSize = idSize + usernameSize + emailSize
|
||||||
|
rowsPerPage = pageSize / rowSize
|
||||||
|
maxRows = rowsPerPage * maxPages
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExecuteResult int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ExecuteSuccess ExecuteResult = iota
|
||||||
|
ExecuteTableFull
|
||||||
|
)
|
||||||
|
|
||||||
type row struct {
|
type row struct {
|
||||||
id uint
|
id uint
|
||||||
username string
|
username string
|
||||||
@@ -41,11 +65,6 @@ type Statement struct {
|
|||||||
row row
|
row row
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
_pageSize = 4096
|
|
||||||
maxPages = 100
|
|
||||||
)
|
|
||||||
|
|
||||||
type Table struct {
|
type Table struct {
|
||||||
numOfRows uint
|
numOfRows uint
|
||||||
pages [maxPages]any
|
pages [maxPages]any
|
||||||
@@ -63,6 +82,61 @@ func NewTable() *Table {
|
|||||||
return &newTable
|
return &newTable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func rowToUse(table *Table, rowNo uint) []byte {
|
||||||
|
pageNo := rowNo / rowsPerPage
|
||||||
|
var page []byte
|
||||||
|
if table.pages[pageNo] == nil {
|
||||||
|
page = make([]byte, pageSize)
|
||||||
|
table.pages[pageNo] = page
|
||||||
|
} else {
|
||||||
|
i := table.pages[pageNo]
|
||||||
|
if t, ok := i.([]byte); !ok {
|
||||||
|
page = []byte(t)
|
||||||
|
} else {
|
||||||
|
page = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rowOffset := rowNo % rowsPerPage
|
||||||
|
byteOffset := rowOffset * rowSize
|
||||||
|
return page[byteOffset : byteOffset+rowSize]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (row *row) seralizeRow(page []byte) {
|
||||||
|
binary.NativeEndian.PutUint64(page[idOffset:], uint64(row.id))
|
||||||
|
|
||||||
|
usernameBuff := page[usernameOffset : usernameOffset+usernameSize]
|
||||||
|
clear(usernameBuff)
|
||||||
|
copy(usernameBuff, row.username)
|
||||||
|
|
||||||
|
emailBuff := page[emailOffset : emailOffset+emailSize]
|
||||||
|
clear(emailBuff)
|
||||||
|
copy(emailBuff, row.email)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (row *row) deSeralizeRow(page []byte) {
|
||||||
|
row.id = uint(binary.NativeEndian.Uint64(page[idOffset:idSize]))
|
||||||
|
row.username = string(page[usernameOffset : usernameOffset+usernameSize])
|
||||||
|
row.email = string(page[emailOffset : emailOffset+emailSize])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (statement *Statement) execInsert(table *Table) ExecuteResult {
|
||||||
|
if table.numOfRows >= maxRows {
|
||||||
|
return ExecuteTableFull
|
||||||
|
}
|
||||||
|
statement.row.seralizeRow(rowToUse(table, table.numOfRows))
|
||||||
|
table.numOfRows += 1
|
||||||
|
return ExecuteSuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
func (statement *Statement) execSelect(table *Table) ExecuteResult {
|
||||||
|
var row row
|
||||||
|
for i := range table.numOfRows {
|
||||||
|
row.deSeralizeRow(rowToUse(table, i))
|
||||||
|
fmt.Printf("%v\n", row)
|
||||||
|
}
|
||||||
|
return ExecuteSuccess
|
||||||
|
}
|
||||||
|
|
||||||
func DoMetaCommands(inputBuffer *InputBuffer) MetaCommandResults {
|
func DoMetaCommands(inputBuffer *InputBuffer) MetaCommandResults {
|
||||||
metacommand := MetaCommandUnrecognised
|
metacommand := MetaCommandUnrecognised
|
||||||
if inputBuffer.Buffer == ".exit" {
|
if inputBuffer.Buffer == ".exit" {
|
||||||
@@ -94,11 +168,13 @@ func (statement *Statement) PrepareStatements(inputBuffer *InputBuffer) PrepareR
|
|||||||
return PrepareUnrecognised
|
return PrepareUnrecognised
|
||||||
}
|
}
|
||||||
|
|
||||||
func (statement *Statement) ExecuteStatement(table *Table) {
|
func (statement *Statement) ExecuteStatement(table *Table) ExecuteResult {
|
||||||
|
var result ExecuteResult
|
||||||
switch statement.stype {
|
switch statement.stype {
|
||||||
case StatementInsert:
|
case StatementInsert:
|
||||||
fmt.Println("This is where the logic of insert statement should go")
|
result = statement.execInsert(table)
|
||||||
case StatementSelect:
|
case StatementSelect:
|
||||||
fmt.Println("This is where the logic of select statement should go")
|
result = statement.execSelect(table)
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user