Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use a word scanner for flag and param comment line parsing
  • Loading branch information
andrewmbenton committed Oct 13, 2023
commit 2fdb3fa6e70a27aec8adafea81f46bbd94f24298
57 changes: 39 additions & 18 deletions internal/metadata/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,32 +123,53 @@ func ParseQueryMetadata(rawSql string, commentStyle CommentSyntax) (Metadata, er
}

md.Comments = comments
md.Params, md.Flags = parseParamsAndFlags(md.Comments)

var err error
md.Params, md.Flags, err = parseParamsAndFlags(md.Comments)
if err != nil {
return md, err
}

return md, s.Err()
}

func parseParamsAndFlags(comments []string) (map[string]string, map[string]bool) {
func parseParamsAndFlags(comments []string) (map[string]string, map[string]bool, error) {
params := make(map[string]string)
flags := make(map[string]bool)

for _, line := range comments {
cleanLine := strings.TrimPrefix(line, "--")
cleanLine = strings.TrimPrefix(cleanLine, "/*")
cleanLine = strings.TrimPrefix(cleanLine, "#")
cleanLine = strings.TrimSuffix(cleanLine, "*/")
cleanLine = strings.TrimSpace(cleanLine)
if strings.HasPrefix(cleanLine, "@") {
parts := strings.SplitN(cleanLine, " ", 2)
name := parts[0]
switch name {
case "@param":
paramParts := strings.SplitN(parts[1], " ", 2)
params[paramParts[0]] = paramParts[1]
default:
flags[name] = true
}
s := bufio.NewScanner(strings.NewReader(line))
s.Split(bufio.ScanWords)

s.Scan() // The first token is always the comment indicator, e.g. "--"
s.Scan()
token := s.Text()

if !strings.HasPrefix(token, "@") {
continue
}

switch token {
case "@param":
s.Scan()
name := s.Text()
var rest []string
for s.Scan() {
paramToken := s.Text()
if paramToken == "*/" {
break
}
rest = append(rest, paramToken)
}
params[name] = strings.Join(rest, " ")
default:
flags[token] = true
}

if s.Err() != nil {
return params, flags, s.Err()
}
}
return params, flags

return params, flags, nil
}
32 changes: 29 additions & 3 deletions internal/metadata/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ func TestParseQueryParams(t *testing.T) {
"-- name: CreateFoo :one",
"-- @param foo_id UUID",
},
{
"/* name: CreateFoo :one */",
"/* @param foo_id UUID */",
},
{
"# name: CreateFoo :one",
"# @param foo_id UUID",
},
{
"-- name: CreateFoo :one",
"-- @param foo_id UUID",
Expand All @@ -76,13 +84,20 @@ func TestParseQueryParams(t *testing.T) {
"-- @param @invalid UUID",
},
} {
params, _ := parseParamsAndFlags(comments)
params, _, err := parseParamsAndFlags(comments)
if err != nil {
t.Error("expected comments to parse:", err)
}

_, ok := params["foo_id"]
pt, ok := params["foo_id"]
if !ok {
t.Errorf("expected param not found")
}

if pt != "UUID" {
t.Error("unexpected param metadata:", pt)
}

_, ok = params["invalid"]
if ok {
t.Errorf("unexpected param found")
Expand All @@ -96,6 +111,14 @@ func TestParseQueryFlags(t *testing.T) {
"-- name: CreateFoo :one",
"-- @flag-foo",
},
{
"/* name: CreateFoo :one */",
"/* @flag-foo */",
},
{
"# name: CreateFoo :one",
"# @flag-foo",
},
{
"-- name: CreateFoo :one",
"-- @flag-foo @flag-bar",
Expand All @@ -106,7 +129,10 @@ func TestParseQueryFlags(t *testing.T) {
"-- @flag-foo",
},
} {
_, flags := parseParamsAndFlags(comments)
_, flags, err := parseParamsAndFlags(comments)
if err != nil {
t.Error("expected comments to parse:", err)
}

if !flags["@flag-foo"] {
t.Errorf("expected flag not found")
Expand Down