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
|
|
|
|
}
|