wip
This commit is contained in:
143
sqlgen/parse.go
Normal file
143
sqlgen/parse.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package sqlgen
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parsePath(filePath string) (*schema, error) {
|
||||
fileBytes, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseBytes(fileBytes)
|
||||
}
|
||||
|
||||
func parseBytes(fileBytes []byte) (*schema, error) {
|
||||
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":
|
||||
tokens, err = parseTable(schema, tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, errors.New("invalid token: " + tokens[0])
|
||||
}
|
||||
}
|
||||
|
||||
return schema, nil
|
||||
}
|
||||
|
||||
func parseTable(schema *schema, tokens []string) ([]string, error) {
|
||||
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{
|
||||
Name: tokens[0],
|
||||
Type: tokens[2],
|
||||
}
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user