Initial giu version, not very good looking, maybe prefer CharmBracelet Tea

This commit is contained in:
Pablu
2025-10-28 19:13:43 +01:00
parent 396b531013
commit e2d39f715f
10 changed files with 313 additions and 56 deletions

138
manager.go Normal file
View File

@@ -0,0 +1,138 @@
package engine
import (
"errors"
"fmt"
"io"
"log"
"slices"
"strings"
"git.pablu.de/pablu/sqv-engine/sql"
)
type Manager struct {
parser *sql.Parser
tables []Table
}
func NewManagerFromFile(sqlTxt string) *Manager {
return &Manager{
parser: sql.NewParser(strings.NewReader(sqlTxt)),
}
}
func (m *Manager) Start() error {
for {
stmt, err := m.parser.Parse()
if err != nil && errors.Is(err, io.EOF) {
fmt.Println("Finished parsing")
break
} else if err != nil {
log.Fatal(err)
}
switch v := stmt.(type) {
case *sql.CreateTableStatement:
t, err := m.convertCreateTableStatementToTable(v)
if err != nil {
return err
}
m.tables = append(m.tables, t)
default:
panic("NOT IMPLEMENTED")
}
}
return nil
}
func (m *Manager) Refresh(sqlTxt string) error {
m.parser = sql.NewParser(strings.NewReader(sqlTxt))
m.tables = make([]Table, 0)
return m.Start()
}
func (m *Manager) GetTables() []Table {
return m.tables
}
func (m *Manager) GetTable(name string) (Table, bool) {
index := slices.IndexFunc(m.tables, func(t Table) bool {
return t.Name == name
})
if index >= 0 {
return m.tables[index], true
}
return Table{}, false
}
func (m *Manager) convertCreateTableStatementToTable(cts *sql.CreateTableStatement) (Table, error) {
res := Table{
Name: cts.TableName,
Columns: make([]Column, len(cts.Columns)),
Rows: make([]Row, 0),
}
for i, column := range cts.Columns {
flags := extrasToFlags(column.Extra)
var ref *Column = nil
if flags.Has(FOREIGN_KEY) {
index := slices.IndexFunc(column.Extra, func(c string) bool {
return strings.HasPrefix(c, "ref")
})
refExtra := column.Extra[index]
refStr := strings.Split(refExtra, " ")[1]
s := strings.Split(refStr, ".")
tableName := s[0]
columnName := s[1]
refTable, ok := m.GetTable(tableName)
if !ok {
fmt.Println(m.tables)
return Table{}, fmt.Errorf("Reference table '%v' not found", tableName)
}
colIndex := slices.IndexFunc(refTable.Columns, func(c Column) bool {
return c.Name == columnName
})
ref = &refTable.Columns[colIndex]
}
res.Columns[i] = Column{
Type: column.Type,
Name: column.Name,
Reference: ref,
Flags: flags,
}
}
return res, nil
}
func extrasToFlags(extras []string) ColumnFlag {
res := NONE
for _, extra := range extras {
// This is not good
switch strings.Split(extra, " ")[0] {
case "PRIMARY_KEY":
res |= PRIMARY_KEY
case "ref":
res |= FOREIGN_KEY
case "NOT_NULL":
res |= NOT_NULL
default:
log.Panicf("NOT IMPLEMENTED EXTRA: %v", extra)
}
}
return res
}