-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Adds relationship label types and parser * Lookup label based on pk and fk names; overrides omitting the label and the constraint label * First full working version * Use a map for faster lookup * Fix example labels * Adds comments for label regex * Adds basic tests for relationship label map
- Loading branch information
Showing
12 changed files
with
280 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1.19.6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"regexp" | ||
"strings" | ||
|
||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
type RelationshipLabel struct { | ||
PkName string | ||
FkName string | ||
Label string | ||
} | ||
|
||
func parseLabels(labels []string) []RelationshipLabel { | ||
var relationshipLabels []RelationshipLabel | ||
for _, label := range labels { | ||
parsed, err := parseLabel(label) | ||
if err != nil { | ||
logrus.Warnf("label '%s' is not in the correct format", label) | ||
continue | ||
} | ||
relationshipLabels = append(relationshipLabels, parsed) | ||
} | ||
return relationshipLabels | ||
} | ||
|
||
func parseLabel(label string) (RelationshipLabel, error) { | ||
label = strings.Trim(label, " \t") | ||
matched, groups := match(label) | ||
if !matched { | ||
return RelationshipLabel{}, errors.New("invalid relationship label") | ||
} | ||
|
||
return RelationshipLabel{ | ||
PkName: string(groups[1]), | ||
FkName: string(groups[2]), | ||
Label: string(groups[3]), | ||
}, nil | ||
} | ||
|
||
// The regex works by creating three capture groups | ||
// Each group allows for all word characters, `.`, `_` and `-` any number of times | ||
// The first two groups (the table names) are separated by any amount of whitespace characters | ||
// The table names and label are are separated by | ||
// - any number of whitespace characters | ||
// - a `:` | ||
// - and then any other number of whitespace characters | ||
// The string must start with the first table name and it must end with the label | ||
var labelRegex = regexp.MustCompile(`^([\w\._-]+)[\s]+([\w\._-]+)[\s]+:[\s]+([\w._-]+)$`) | ||
|
||
func match(label string) (bool, [][]byte) { | ||
groups := labelRegex.FindSubmatch([]byte(label)) | ||
if groups == nil { | ||
return false, [][]byte{} | ||
} | ||
return true, groups | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package diagram | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/KarnerTh/mermerd/config" | ||
) | ||
|
||
type RelationshipLabelMap interface { | ||
AddRelationshipLabel(label config.RelationshipLabel) | ||
LookupRelationshipLabel(pkName, fkName string) (label config.RelationshipLabel, found bool) | ||
} | ||
|
||
type relationshipLabelMap struct { | ||
mapping map[string]config.RelationshipLabel | ||
} | ||
|
||
func (r *relationshipLabelMap) AddRelationshipLabel(label config.RelationshipLabel) { | ||
if r.mapping == nil { | ||
r.mapping = make(map[string]config.RelationshipLabel) | ||
} | ||
key := r.buildMapKey(label.PkName, label.FkName) | ||
r.mapping[key] = label | ||
} | ||
|
||
func (r *relationshipLabelMap) LookupRelationshipLabel(pkName, fkName string) (label config.RelationshipLabel, found bool) { | ||
if r.mapping == nil { | ||
return config.RelationshipLabel{}, false | ||
} | ||
key := r.buildMapKey(pkName, fkName) | ||
label, found = r.mapping[key] | ||
return | ||
} | ||
|
||
func (r *relationshipLabelMap) buildMapKey(pkName, fkName string) string { | ||
return fmt.Sprintf("%s-%s", pkName, fkName) | ||
} | ||
|
||
func BuildRelationshipLabelMapFromConfig(c config.MermerdConfig) RelationshipLabelMap { | ||
return BuildRelationshipLabelMap(c.RelationshipLabels()) | ||
} | ||
|
||
func BuildRelationshipLabelMap(labels []config.RelationshipLabel) RelationshipLabelMap { | ||
labelMap := &relationshipLabelMap{} | ||
for _, label := range labels { | ||
labelMap.AddRelationshipLabel(label) | ||
} | ||
return labelMap | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package diagram_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/KarnerTh/mermerd/config" | ||
"github.com/KarnerTh/mermerd/diagram" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestEmptyRelationshipMapDoesNotError(t *testing.T) { | ||
relationshipMap := diagram.BuildRelationshipLabelMap([]config.RelationshipLabel{}) | ||
|
||
_, found := relationshipMap.LookupRelationshipLabel("pk", "fk") | ||
|
||
assert.False(t, found) | ||
} | ||
|
||
func TestRelationshipMapCanAddAndLookupLabel(t *testing.T) { | ||
relationshipMap := diagram.BuildRelationshipLabelMap([]config.RelationshipLabel{}) | ||
|
||
exampleLabel := config.RelationshipLabel{ | ||
PkName: "name", | ||
FkName: "another-name", | ||
Label: "a-label", | ||
} | ||
relationshipMap.AddRelationshipLabel(exampleLabel) | ||
|
||
actual, found := relationshipMap.LookupRelationshipLabel("name", "another-name") | ||
|
||
assert.True(t, found) | ||
assert.Equal(t, actual, exampleLabel) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.