Skip to content

Commit 137583e

Browse files
committed
Expose database in summary
1 parent 55c00c1 commit 137583e

File tree

5 files changed

+157
-51
lines changed

5 files changed

+157
-51
lines changed

neo4j/db/summary.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,5 @@ type Summary struct {
132132
Plan *Plan
133133
ProfiledPlan *ProfiledPlan
134134
Notifications []Notification
135+
Database string
135136
}

neo4j/internal/bolt/hydrator.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ func (s *success) summary() *db.Summary {
7575
Plan: s.plan,
7676
ProfiledPlan: s.profile,
7777
Notifications: s.notifications,
78+
Database: s.db,
7879
}
7980
}
8081

neo4j/resultsummary.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ type ResultSummary interface {
6060
ResultAvailableAfter() time.Duration
6161
// ResultConsumedAfter returns the time it took the server to consume the result.
6262
ResultConsumedAfter() time.Duration
63+
// Database returns information about the database where the result is obtained from
64+
Database() DatabaseInfo
6365
}
6466

6567
// Counters contains statistics about the changes made to the database made as part
@@ -108,6 +110,11 @@ type ServerInfo interface {
108110
ProtocolVersion() db.ProtocolVersion
109111
}
110112

113+
// DatabaseInfo contains basic information of the database the query result has been obtained from.
114+
type DatabaseInfo interface {
115+
Name() string
116+
}
117+
111118
// Plan describes the actual plan that the database planner produced and used (or will use) to execute your statement.
112119
// This can be extremely helpful in understanding what a statement is doing, and how to optimize it. For more details,
113120
// see the Neo4j Manual. The plan for the statement is a tree of plans - each sub-tree containing zero or more child
@@ -295,6 +302,22 @@ func (s *resultSummary) Plan() Plan {
295302
return &plan{plan: s.sum.Plan}
296303
}
297304

305+
func (s *resultSummary) Database() DatabaseInfo {
306+
database := s.sum.Database
307+
if database == "" {
308+
return nil
309+
}
310+
return &databaseInfo{name: database}
311+
}
312+
313+
type databaseInfo struct {
314+
name string
315+
}
316+
317+
func (d *databaseInfo) Name() string {
318+
return d.name
319+
}
320+
298321
type plan struct {
299322
plan *db.Plan
300323
}

neo4j/test-integration/dbserver/version.go

Lines changed: 25 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,8 @@ import (
2323
"fmt"
2424
"regexp"
2525
"strconv"
26-
27-
"github.com/neo4j/neo4j-go-driver/v4/neo4j"
28-
)
29-
30-
var (
31-
// V340 identifies server version 3.4.0
32-
V340 = VersionOf("3.4.0")
33-
// V350 identifies server version 3.5.0
34-
V350 = VersionOf("3.5.0")
3526
)
3627

37-
func versionOfDriver(driver neo4j.Driver) Version {
38-
session := driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeRead})
39-
defer session.Close()
40-
41-
result, err := session.Run("RETURN 1", nil)
42-
if err != nil {
43-
panic(err)
44-
}
45-
46-
summary, err := result.Consume()
47-
if err != nil {
48-
panic(err)
49-
}
50-
51-
return VersionOf(summary.Server().Version())
52-
}
53-
5428
const (
5529
versionPattern = "(Neo4j/)?(\\d+)\\.(\\d+)(?:\\.)?(\\d*)(\\.|-|\\+)?([0-9A-Za-z-.]*)?"
5630
versionInDev = "Neo4j/dev"
@@ -67,11 +41,33 @@ type Version struct {
6741
}
6842

6943
var (
70-
noVersion Version = Version{-1, -1, -1}
71-
inDevVersion Version = Version{0, 0, 0}
72-
defaultVersion Version = Version{3, 0, 0}
44+
noVersion = Version{-1, -1, -1}
45+
inDevVersion = Version{0, 0, 0}
46+
defaultVersion = Version{3, 0, 0}
7347
)
7448

49+
func VersionOf(server string) Version {
50+
if server == "" {
51+
return defaultVersion
52+
} else {
53+
if versionMatcher == nil {
54+
versionMatcher = regexp.MustCompile(versionPattern)
55+
}
56+
matches := versionMatcher.FindStringSubmatch(server)
57+
if matches != nil {
58+
major, _ := strconv.Atoi(matches[2])
59+
minor, _ := strconv.Atoi(matches[3])
60+
patch, _ := strconv.Atoi(matches[4])
61+
62+
return Version{major, minor, patch}
63+
} else if server == versionInDev {
64+
return inDevVersion
65+
}
66+
}
67+
68+
return noVersion
69+
}
70+
7571
func compareInt(num1 int, num2 int) int {
7672
if num1 == num2 {
7773
return 0
@@ -96,28 +92,6 @@ func compareVersions(version1 Version, version2 Version) int {
9692
return comp
9793
}
9894

99-
func VersionOf(server string) Version {
100-
if server == "" {
101-
return defaultVersion
102-
} else {
103-
if versionMatcher == nil {
104-
versionMatcher = regexp.MustCompile(versionPattern)
105-
}
106-
matches := versionMatcher.FindStringSubmatch(server)
107-
if matches != nil {
108-
major, _ := strconv.Atoi(matches[2])
109-
minor, _ := strconv.Atoi(matches[3])
110-
patch, _ := strconv.Atoi(matches[4])
111-
112-
return Version{major, minor, patch}
113-
} else if server == versionInDev {
114-
return inDevVersion
115-
}
116-
}
117-
118-
return noVersion
119-
}
120-
12195
func (version Version) String() string {
12296
return fmt.Sprintf("%d.%d.%d", version.major, version.minor, version.patch)
12397
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package test_integration
2+
3+
import (
4+
"fmt"
5+
"github.com/neo4j/neo4j-go-driver/v4/neo4j"
6+
"github.com/neo4j/neo4j-go-driver/v4/neo4j/test-integration/dbserver"
7+
"io"
8+
9+
. "github.com/onsi/ginkgo"
10+
. "github.com/onsi/gomega"
11+
)
12+
13+
var _ = Describe("Result Summary", func() {
14+
15+
const extraDatabase = "extra"
16+
17+
var server dbserver.DbServer
18+
var driver neo4j.Driver
19+
var bookmark string
20+
noParams := map[string]interface{}{}
21+
22+
BeforeEach(func() {
23+
server = dbserver.GetDbServer()
24+
driver = server.Driver()
25+
Expect(driver).NotTo(BeNil())
26+
})
27+
28+
Context("from single-tenant Neo4j servers", func() {
29+
BeforeEach(func() {
30+
if isMultiTenant(server) {
31+
Skip(`Multi-tenant servers are covered in other tests`)
32+
}
33+
})
34+
35+
It("does not include any database information", func() {
36+
session := driver.NewSession(neo4j.SessionConfig{Bookmarks: []string{bookmark}})
37+
defer assertCloses(session)
38+
result, err := session.Run("RETURN 42", noParams)
39+
Expect(err).NotTo(HaveOccurred())
40+
41+
summary, err := result.Consume()
42+
Expect(err).NotTo(HaveOccurred())
43+
if server.Version.GreaterThanOrEqual(V4) {
44+
Expect(summary.Database().Name()).To(Equal("neo4j"))
45+
} else {
46+
Expect(summary.Database()).To(BeNil())
47+
}
48+
})
49+
})
50+
51+
Context("from multi-tenant Neo4j servers", func() {
52+
BeforeEach(func() {
53+
if !isMultiTenant(server) {
54+
Skip("Multi-tenancy is a Neo4j 4+ feature")
55+
}
56+
})
57+
58+
BeforeEach(func() {
59+
session := driver.NewSession(neo4j.SessionConfig{DatabaseName: "system"})
60+
defer assertCloses(session)
61+
_, err := session.Run(fmt.Sprintf("CREATE DATABASE %s", extraDatabase), map[string]interface{}{})
62+
Expect(err).NotTo(HaveOccurred())
63+
bookmark = session.LastBookmark()
64+
})
65+
66+
AfterEach(func() {
67+
session := driver.NewSession(neo4j.SessionConfig{DatabaseName: "system", Bookmarks: []string{bookmark}})
68+
defer assertCloses(session)
69+
_, err := session.Run(fmt.Sprintf("DROP DATABASE %s", extraDatabase), map[string]interface{}{})
70+
Expect(err).NotTo(HaveOccurred())
71+
bookmark = ""
72+
})
73+
74+
It("includes the default database information", func() {
75+
session := driver.NewSession(neo4j.SessionConfig{Bookmarks: []string{bookmark}})
76+
defer assertCloses(session)
77+
result, err := session.Run("RETURN 42", noParams)
78+
Expect(err).NotTo(HaveOccurred())
79+
80+
summary, err := result.Consume()
81+
Expect(err).NotTo(HaveOccurred())
82+
Expect(summary.Database().Name()).To(Equal("neo4j"))
83+
})
84+
85+
It("includes the database information, based on session configuration", func() {
86+
session := driver.NewSession(neo4j.SessionConfig{DatabaseName: extraDatabase, Bookmarks: []string{bookmark}})
87+
defer assertCloses(session)
88+
result, err := session.Run("RETURN 42", noParams)
89+
Expect(err).NotTo(HaveOccurred())
90+
91+
summary, err := result.Consume()
92+
Expect(err).NotTo(HaveOccurred())
93+
Expect(summary.Database().Name()).To(Equal(extraDatabase))
94+
})
95+
})
96+
97+
98+
})
99+
100+
func isMultiTenant(server dbserver.DbServer) bool {
101+
return server.Version.GreaterThanOrEqual(V4) && server.IsEnterprise
102+
}
103+
104+
func assertCloses(closer io.Closer) {
105+
err := closer.Close()
106+
Expect(err).NotTo(HaveOccurred())
107+
}

0 commit comments

Comments
 (0)