Skip to content

Commit

Permalink
Merge pull request #85 from mindstand/nikitawootten/issue71
Browse files Browse the repository at this point in the history
Relationship within a single type
  • Loading branch information
Eric Solender authored Jan 21, 2022
2 parents aebc262 + 2a0fc44 commit 6810ce3
Show file tree
Hide file tree
Showing 20 changed files with 293 additions and 434 deletions.
33 changes: 33 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: Bug
about: Report a new bug
labels: bug
---
# Bug Report:
<!-- Provide a clear description of the issue -->

## Expected Behavior
<!-- Describe the incorrect behavior -->

## Current Behavior
<!-- Describe the correct behavior -->

## Steps to Reproduce
<!-- Example code is appreciated! -->
1.

## Possible Solution
<!-- (if applicable) -->
<!-- Can you identify the location in the source where the problem exists? -->

## Environment
<!-- Please fill out some details about your environment -->
| | Value |
|------------------|-------|
| Go Version | |
| GoGM Version | |
| Neo4J Version | |
| Operating System | |

## Would you be interested in tackling this issue
Yes / No
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: Feature Request
about: Submit a request for a new feature
labels: feature
---
# Feature Request:
<!-- Describe what you would like to add or change about GoGM -->

## Context
<!-- How would you use this feature? Is it something that currently cannot be done? What problem does it solve? -->

## Alternatives
<!-- Can you achieve the same result another way? -->

## Would you be interested in implementing this feature?
Yes / No
7 changes: 7 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Committer Notes
Fixes #

## Checklist
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have included new tests that address the changes
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/mindstand/gogm)](https://goreportcard.com/report/github.com/mindstand/gogm)
[![Go Report Card](https://goreportcard.com/badge/github.com/mindstand/gogm/v2)](https://goreportcard.com/report/github.com/mindstand/gogm/v2)
[![Actions Status](https://github.com/mindstand/gogm/workflows/Go/badge.svg)](https://github.com/mindstand/gogm/actions)
[![GoDoc](https://godoc.org/github.com/mindstand/gogm?status.svg)](https://godoc.org/github.com/mindstand/gogm)
[![GoDoc](https://godoc.org/github.com/mindstand/gogm/v2?status.svg)](https://godoc.org/github.com/mindstand/gogm/v2)
# GoGM Golang Object Graph Mapper v2

```
Expand All @@ -25,6 +25,7 @@ go get -u github.com/mindstand/gogm/v2
- Primary Key strategies to use any type of primary key. GoGM is no longer UUID only!
- TLS now supported

| Note: GoGM v1 has been deprecated.

## Usage

Expand Down
30 changes: 15 additions & 15 deletions cmd/gogmcli/gen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ import (
"bytes"
"errors"
"fmt"
dsl "github.com/mindstand/go-cypherdsl"
"github.com/mindstand/gogm/v2/cmd/gogmcli/util"
"go/format"
"html/template"
"log"
"os"
"path"
"path/filepath"
"strings"

dsl "github.com/mindstand/go-cypherdsl"
"github.com/mindstand/gogm/v2/cmd/gogmcli/util"
)

// Generate searches for all go source files, then generates link and unlink functions for all gogm structs
Expand Down Expand Up @@ -120,11 +121,7 @@ func Generate(directory string, debug bool) error {
log.Printf("adding relationship [%s] from field [%s]", field.RelationshipName, field.Field)
}

if _, ok := relations[field.RelationshipName]; ok {
relations[field.RelationshipName] = append(relations[field.RelationshipName], field)
} else {
relations[field.RelationshipName] = []*relConf{field}
}
relations[field.RelationshipName] = append(relations[field.RelationshipName], field)
}
}

Expand All @@ -133,8 +130,15 @@ func Generate(directory string, debug bool) error {
}

// validate relationships (i.e even number)
for name, rel := range relations {
if len(rel)%2 != 0 {
for name, rels := range relations {
nonBothSelfRelCount := 0
for _, rel := range rels {
if rel.Direction != dsl.DirectionBoth || rel.NodeName != rel.Type {
nonBothSelfRelCount += 1
}
}

if nonBothSelfRelCount%2 != 0 {
return fmt.Errorf("relationship [%s] is invalid", name)
}
}
Expand Down Expand Up @@ -166,18 +170,14 @@ func Generate(directory string, debug bool) error {
}

if tplRel.OtherStructField == "" {
return fmt.Errorf("oposite side not found for node [%s] on relationship [%s] and field [%s]", rel.NodeName, rel.RelationshipName, rel.Field)
return fmt.Errorf("opposite side not found for node [%s] on relationship [%s] and field [%s]", rel.NodeName, rel.RelationshipName, rel.Field)
}

if debug {
log.Printf("adding function to node [%s]", rel.NodeName)
}

if _, ok := funcs[rel.NodeName]; ok {
funcs[rel.NodeName] = append(funcs[rel.NodeName], tplRel)
} else {
funcs[rel.NodeName] = []*tplRelConf{tplRel}
}
funcs[rel.NodeName] = append(funcs[rel.NodeName], tplRel)
}
}

Expand Down
15 changes: 3 additions & 12 deletions cmd/gogmcli/gen/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ package gen
import (
"bytes"
"errors"
go_cypherdsl "github.com/mindstand/go-cypherdsl"
"github.com/mindstand/gogm/v2/cmd/gogmcli/util"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"log"
"strings"

go_cypherdsl "github.com/mindstand/go-cypherdsl"
"github.com/mindstand/gogm/v2/cmd/gogmcli/util"
)

type relConf struct {
Expand Down Expand Up @@ -148,22 +149,16 @@ func parseGogmEdge(node *ast.File, label string) (bool, error) {
switch funcDecl.Name.Name {
case "GetStartNode":
GetStartNode = true
break
case "GetStartNodeType":
GetStartNodeType = true
break
case "SetStartNode":
SetStartNode = true
break
case "GetEndNode":
GetEndNode = true
break
case "GetEndNodeType":
GetEndNodeType = true
break
case "SetEndNode":
SetEndNode = true
break
default:
continue
}
Expand Down Expand Up @@ -198,16 +193,12 @@ func parseGogmNode(strType *ast.StructType, confs *map[string][]*relConf, label
switch str {
case "incoming":
dir = go_cypherdsl.DirectionIncoming
break
case "outgoing":
dir = go_cypherdsl.DirectionOutgoing
break
case "both":
dir = go_cypherdsl.DirectionBoth
break
case "none":
dir = go_cypherdsl.DirectionNone
break
default:
log.Printf("direction %s not found", str)
continue fieldLoop
Expand Down
14 changes: 9 additions & 5 deletions decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func toHashmapStructdecconf(m map[string]structDecoratorConfig) *hashmap.HashMap

func TestConvertNodeToValue(t *testing.T) {
req := require.New(t)
gogm, err := getTestGogm()
gogm, err := getTestGogmWithDefaultStructs()
req.Nil(err)
req.NotNil(gogm)
mappedTypes := toHashmapStructdecconf(map[string]structDecoratorConfig{
Expand Down Expand Up @@ -281,7 +281,11 @@ type propsTest struct {
PropsTest8 tdMapTdSliceOfTd `gogm:"name=props8;properties"`
}

func getTestGogm() (*Gogm, error) {
func getTestGogmWithDefaultStructs() (*Gogm, error) {
return getTestGogm(&a{}, &b{}, &c{}, &f{}, &propsTest{})
}

func getTestGogm(types ...interface{}) (*Gogm, error) {
g := &Gogm{
config: &Config{
Logger: GetDefaultLogger(),
Expand All @@ -293,7 +297,7 @@ func getTestGogm() (*Gogm, error) {
mappedTypes: &hashmap.HashMap{},
driver: nil,
mappedRelations: &relationConfigs{},
ogmTypes: []interface{}{&a{}, &b{}, &c{}, &f{}, &propsTest{}},
ogmTypes: types,
isNoOp: false,
}

Expand All @@ -307,7 +311,7 @@ func getTestGogm() (*Gogm, error) {

func TestDecode(t *testing.T) {
req := require.New(t)
gogm, err := getTestGogm()
gogm, err := getTestGogmWithDefaultStructs()
req.Nil(err)
req.NotNil(gogm)

Expand All @@ -326,7 +330,7 @@ func TestDecode(t *testing.T) {
func TestDecode2(t *testing.T) {
req := require.New(t)

gogm, err := getTestGogm()
gogm, err := getTestGogmWithDefaultStructs()
req.Nil(err)
req.NotNil(gogm)

Expand Down
19 changes: 11 additions & 8 deletions decorator.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ type propConfig struct {

//decorator config defines configuration of GoGM field
type decoratorConfig struct {
// ParentType holds the type of the parent object in order to validate some relationships
ParentType reflect.Type
// holds reflect type for the field
Type reflect.Type `json:"-"`
// holds the name of the field for neo4j
Expand Down Expand Up @@ -287,7 +289,7 @@ var edgeType = reflect.TypeOf(new(Edge)).Elem()

// newDecoratorConfig generates decorator config for field
// takes in the raw tag, name of the field and reflect type
func newDecoratorConfig(gogm *Gogm, decorator, name string, varType reflect.Type) (*decoratorConfig, error) {
func newDecoratorConfig(gogm *Gogm, decorator, name string, varType reflect.Type, parentType reflect.Type) (*decoratorConfig, error) {
fields := strings.Split(decorator, deliminator)

if len(fields) == 0 {
Expand All @@ -296,11 +298,12 @@ func newDecoratorConfig(gogm *Gogm, decorator, name string, varType reflect.Type

//init bools to false
toReturn := decoratorConfig{
Unique: false,
Ignore: false,
Direction: 0,
Type: varType,
FieldName: name,
ParentType: parentType,
Unique: false,
Ignore: false,
Direction: 0,
Type: varType,
FieldName: name,
}

for _, field := range fields {
Expand Down Expand Up @@ -535,7 +538,7 @@ func getStructDecoratorConfig(gogm *Gogm, i interface{}, mappedRelations *relati
tag := field.Tag.Get(decoratorName)

if tag != "" {
config, err := newDecoratorConfig(gogm, tag, field.Name, field.Type)
config, err := newDecoratorConfig(gogm, tag, field.Name, field.Type, t)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -564,7 +567,7 @@ func getStructDecoratorConfig(gogm *Gogm, i interface{}, mappedRelations *relati
endType = field.Type
}

endTypeName, err := traverseRelType(gogm, endType, config.Direction)
endTypeName, err := traverseRelType(endType, config.Direction)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 6810ce3

Please sign in to comment.