From a21ccd43257b40e6110935916c3990cc5b797579 Mon Sep 17 00:00:00 2001 From: Eric Solender Date: Wed, 3 Nov 2021 15:05:23 -0400 Subject: [PATCH] fix index query and added test --- index_v3.go | 4 ++-- index_v4.go | 55 +++++++++++++++++++++++++++------------------ integration_test.go | 27 +++++++++++++++++++++- 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/index_v3.go b/index_v3.go index c60fa9d..b3012f0 100644 --- a/index_v3.go +++ b/index_v3.go @@ -160,7 +160,7 @@ func createAllIndexesAndConstraintsV3(ctx context.Context, gogm *Gogm, mappedTyp Name: node, Type: structConfig.Label, Field: config.Name, - })).Cypher("IF NOT EXISTS").ToCypher() + })).ToCypher() if err != nil { return err } @@ -180,7 +180,7 @@ func createAllIndexesAndConstraintsV3(ctx context.Context, gogm *Gogm, mappedTyp cyp, err := dsl.QB().Create(dsl.NewIndex(&dsl.IndexConfig{ Type: structConfig.Label, Fields: indexFields, - })).Cypher("IF NOT EXISTS").ToCypher() + })).ToCypher() if err != nil { return err } diff --git a/index_v4.go b/index_v4.go index dffc3bb..2c5fc6b 100644 --- a/index_v4.go +++ b/index_v4.go @@ -25,10 +25,40 @@ import ( "fmt" "github.com/adam-hanna/arrayOperations" "github.com/cornelk/hashmap" - dsl "github.com/mindstand/go-cypherdsl" "github.com/neo4j/neo4j-go-driver/v4/neo4j" + "strings" ) +const ( + constraintOnQuery = "CREATE CONSTRAINT IF NOT EXISTS ON (%s:%s) ASSERT " + uniquePart = "%s.%s IS UNIQUE" + notUniquePart = "exists(%s.%s)" + + indexQuery = "CREATE INDEX IF NOT EXISTS FOR (n:%s) ON (" +) + +func buildConstraintQuery(unique bool, name, nodeType, field string) string { + cyp := fmt.Sprintf(constraintOnQuery, name, nodeType) + + if unique { + cyp += fmt.Sprintf(uniquePart, name, field) + } else { + cyp += fmt.Sprintf(notUniquePart, name, field) + } + + return cyp +} + +func buildIndexQuery(indexType string, fields ...string) string { + query := fmt.Sprintf(indexQuery, indexType) + + for _, field := range fields { + query += fmt.Sprintf("n.%s,", field) + } + + return strings.TrimSuffix(query, ",") + ")" +} + func resultToStringArrV4(isConstraint bool, result [][]interface{}) ([]string, error) { if result == nil { return nil, errors.New("result is nil") @@ -173,18 +203,7 @@ func createAllIndexesAndConstraintsV4(ctx context.Context, gogm *Gogm, mappedTyp //pk is a special unique key if config.PrimaryKey != "" || config.Unique { numIndexCreated++ - - cyp, err := dsl.QB().Create(dsl.NewConstraint(&dsl.ConstraintConfig{ - Unique: true, - Name: node, - Type: structConfig.Label, - Field: config.Name, - })).Cypher("IF NOT EXISTS").ToCypher() - if err != nil { - return err - } - - _, _, err = tx.QueryRaw(ctx, cyp, nil) + _, _, err = tx.QueryRaw(ctx, buildConstraintQuery(true, node, structConfig.Label, config.Name), nil) if err != nil { return err } @@ -196,15 +215,7 @@ func createAllIndexesAndConstraintsV4(ctx context.Context, gogm *Gogm, mappedTyp //create composite index if len(indexFields) > 0 { numIndexCreated++ - cyp, err := dsl.QB().Create(dsl.NewIndex(&dsl.IndexConfig{ - Type: structConfig.Label, - Fields: indexFields, - })).Cypher("IF NOT EXISTS").ToCypher() - if err != nil { - return err - } - - _, _, err = tx.QueryRaw(ctx, cyp, nil) + _, _, err = tx.QueryRaw(ctx, buildIndexQuery(structConfig.Label, indexFields...), nil) if err != nil { return err } diff --git a/integration_test.go b/integration_test.go index 2cc2704..9b0e97f 100644 --- a/integration_test.go +++ b/integration_test.go @@ -35,6 +35,12 @@ import ( "github.com/stretchr/testify/suite" ) +type indexTestStruct struct { + BaseUUIDNode + StringIndex string `gogm:"name=string_index;index"` + StringUnique string `gogm:"name=string_unique;unique"` +} + func TestIntegration(t *testing.T) { if testing.Short() { t.Skip() @@ -46,6 +52,7 @@ func TestIntegration(t *testing.T) { type IntegrationTestSuite struct { suite.Suite gogm *Gogm + conf *Config } func (integrationTest *IntegrationTestSuite) TearDownSuite() { @@ -77,6 +84,24 @@ func (integrationTest *IntegrationTestSuite) SetupSuite() { integrationTest.gogm = gogm } +func (integrationTest *IntegrationTestSuite) TestV4Index() { + if integrationTest.gogm.neoVersion < 4 { + integrationTest.T().Log("skipping because of incompatible version", integrationTest.gogm.neoVersion) + integrationTest.T().Skip() + return + } + + assertCopy := *integrationTest.conf + assertCopy.IndexStrategy = ASSERT_INDEX + _, err := New(&assertCopy, UUIDPrimaryKeyStrategy, &indexTestStruct{}) + integrationTest.Assert().Nil(err) + + validateCopy := *integrationTest.conf + validateCopy.IndexStrategy = VALIDATE_INDEX + _, err = New(&validateCopy, UUIDPrimaryKeyStrategy, &indexTestStruct{}) + integrationTest.Assert().Nil(err) +} + func (integrationTest *IntegrationTestSuite) TestSecureConnection() { if integrationTest.gogm.neoVersion < 4 { integrationTest.T().Log("skipping secure test for v3") @@ -96,7 +121,7 @@ func (integrationTest *IntegrationTestSuite) TestSecureConnection() { EnableDriverLogs: true, DefaultTransactionTimeout: 2 * time.Minute, } - + integrationTest.conf = &conf gogm, err := New(&conf, UUIDPrimaryKeyStrategy, &a{}, &b{}, &c{}, &propTest{}) integrationTest.Require().Nil(err) integrationTest.Require().NotNil(gogm)