go/sqlgen/parse.go

145 lines
3.0 KiB
Go
Raw Normal View History

2024-11-11 05:36:55 +00:00
package sqlgen
import (
"errors"
"os"
"strings"
)
2024-11-19 15:30:42 +00:00
func parsePath(driver, filePath string) (*schema, error) {
2024-11-11 05:36:55 +00:00
fileBytes, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
2024-11-19 15:30:42 +00:00
return parseBytes(driver, fileBytes)
2024-11-11 05:36:55 +00:00
}
2024-11-19 15:30:42 +00:00
func parseBytes(driver string, fileBytes []byte) (*schema, error) {
2024-11-11 05:36:55 +00:00
s := string(fileBytes)
for _, c := range []string{",", "(", ")", ";"} {
s = strings.ReplaceAll(s, c, " "+c+" ")
}
var (
tokens = strings.Fields(s)
schema = &schema{}
err error
)
for len(tokens) > 0 {
switch tokens[0] {
case "TABLE":
2024-11-19 15:30:42 +00:00
tokens, err = parseTable(driver, schema, tokens)
2024-11-11 05:36:55 +00:00
if err != nil {
return nil, err
}
default:
return nil, errors.New("invalid token: " + tokens[0])
}
}
return schema, nil
}
2024-11-19 15:30:42 +00:00
func parseTable(driver string, schema *schema, tokens []string) ([]string, error) {
2024-11-11 05:36:55 +00:00
tokens = tokens[1:]
if len(tokens) < 3 {
return tokens, errors.New("incomplete table definition")
}
if tokens[1] != "OF" {
return tokens, errors.New("expected OF in table definition")
}
table := &table{
2024-11-19 15:30:42 +00:00
driver: driver,
Name: tokens[0],
Type: tokens[2],
2024-11-11 05:36:55 +00:00
}
schema.Tables = append(schema.Tables, table)
tokens = tokens[3:]
if len(tokens) == 0 {
return tokens, errors.New("missing table definition body")
}
for len(tokens) > 0 {
switch tokens[0] {
case "NoInsert":
table.NoInsert = true
tokens = tokens[1:]
case "NoUpdate":
table.NoUpdate = true
tokens = tokens[1:]
case "NoDelete":
table.NoDelete = true
tokens = tokens[1:]
case "(":
return parseTableBody(table, tokens[1:])
default:
return tokens, errors.New("unexpected token in table definition: " + tokens[0])
}
}
return tokens, errors.New("incomplete table definition")
}
func parseTableBody(table *table, tokens []string) ([]string, error) {
var err error
for len(tokens) > 0 && tokens[0] != ";" {
tokens, err = parseTableColumn(table, tokens)
if err != nil {
return tokens, err
}
}
if len(tokens) < 1 || tokens[0] != ";" {
return tokens, errors.New("incomplete table column definitions")
}
return tokens[1:], nil
}
func parseTableColumn(table *table, tokens []string) ([]string, error) {
if len(tokens) < 2 {
return tokens, errors.New("incomplete column definition")
}
column := &column{
Name: tokens[0],
Type: tokens[1],
SqlName: tokens[0],
}
table.Columns = append(table.Columns, column)
tokens = tokens[2:]
for len(tokens) > 0 && tokens[0] != "," && tokens[0] != ")" {
switch tokens[0] {
case "AS":
if len(tokens) < 2 {
return tokens, errors.New("incomplete AS clause in column definition")
}
column.Name = tokens[1]
tokens = tokens[2:]
case "PK":
column.PK = true
tokens = tokens[1:]
case "NoInsert":
column.NoInsert = true
tokens = tokens[1:]
case "NoUpdate":
column.NoUpdate = true
tokens = tokens[1:]
default:
return tokens, errors.New("unexpected token in column definition: " + tokens[0])
}
}
if len(tokens) == 0 {
return tokens, errors.New("incomplete column definition")
}
return tokens[1:], nil
}