Skip to content

Commit

Permalink
Update Go samples to use v5 driver and ExecuteQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
fbiville committed May 4, 2023
1 parent b4dc295 commit 8556d8f
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 118 deletions.
55 changes: 23 additions & 32 deletions code/go/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
package main

import (
"context"
"fmt"
"github.com/neo4j/neo4j-go-driver/v4/neo4j"
"io"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"reflect"
)

Expand All @@ -19,45 +19,36 @@ func main() {
}
}

func runQuery(uri, database, username, password string) (result []string, err error) {
driver, err := neo4j.NewDriver(uri, neo4j.BasicAuth(username, password, ""))
func runQuery(uri, database, username, password string) (_ []string, err error) {
ctx := context.Background()
driver, err := neo4j.NewDriverWithContext(uri, neo4j.BasicAuth(username, password, ""))
if err != nil {
return nil, err
}
defer func() {err = handleClose(driver, err)}()
session := driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeRead, DatabaseName: database})
defer func() {err = handleClose(session, err)}()
results, err := session.ReadTransaction(func(transaction neo4j.Transaction) (interface{}, error) {
result, err := transaction.Run(
`
MATCH (m:Movie {title:$movieTitle})<-[:ACTED_IN]-(a:Person) RETURN a.name as actorName
`, map[string]interface{}{
"movieTitle": "The Matrix",
})
defer func() { err = handleClose(ctx, driver, err) }()
query := "MATCH (m:Movie {title:$movieTitle})<-[:ACTED_IN]-(a:Person) RETURN a.name as actorName"
params := map[string]any{"movieTitle": "The Matrix"}
result, err := neo4j.ExecuteQuery(ctx, driver, query, params,
neo4j.EagerResultTransformer,
neo4j.ExecuteQueryWithDatabase(database),
neo4j.ExecuteQueryWithReadersRouting())
if err != nil {
return nil, err
}
actorNames := make([]string, len(result.Records))
for i, record := range result.Records {
// this assumes all actors have names, hence ignoring the 2nd returned value
name, _, err := neo4j.GetRecordValue[string](record, "actorName")
if err != nil {
return nil, err
}
var arr []string
for result.Next() {
value, found := result.Record().Get("actorName")
if found {
arr = append(arr, value.(string))
}
}
if err = result.Err(); err != nil {
return nil, err
}
return arr, nil
})
if err != nil {
return nil, err
actorNames[i] = name
}
result = results.([]string)
return result, err
return actorNames, nil
}

func handleClose(closer io.Closer, previousError error) error {
err := closer.Close()
func handleClose(ctx context.Context, closer interface{ Close(context.Context) error }, previousError error) error {
err := closer.Close(ctx)
if err == nil {
return previousError
}
Expand Down
91 changes: 41 additions & 50 deletions code/go/example_aura.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
package main

import (
"context"
"fmt"
"github.com/neo4j/neo4j-go-driver/neo4j"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
)

func main() {
var driver neo4j.Driver
var err error
// Aura requires you to use "bolt+routing" protocol, and process your queries using an encrypted connection
ctx := context.Background()
// Aura requires you to use "neo4j+s" scheme, so that your queries are processed using an encrypted connection
// (You may need to replace your connection details, username and password)
boltURL := "bolt+routing://<Bolt url for Neo4j Aura database>"
uri := "neo4j+s://<Bolt url for Neo4j Aura database>"
auth := neo4j.BasicAuth("<Username for Neo4j Aura database>", "<Password for Neo4j Aura database>", "")

configurers := []func(*neo4j.Config){
func (config *neo4j.Config) {
config.Encrypted = true
},
}
if driver, err = neo4j.NewDriver(boltURL, auth, configurers...); err != nil {
driver, err := neo4j.NewDriverWithContext(uri, auth)
if err != nil {
panic(err)
}

// Don't forget to close the driver connection when you are finished with it
defer driver.Close()

var writeSession neo4j.Session
// Using write transactions allow the driver to handle retries and transient errors for you
if writeSession, err = driver.Session(neo4j.AccessModeWrite); err != nil {
panic(err)
}
defer writeSession.Close()
defer closeResource(ctx, driver)

// To learn more about the Cypher syntax, see https://neo4j.com/docs/cypher-manual/current/
// The Reference Card is also a good resource for keywords https://neo4j.com/docs/cypher-refcard/current/
Expand All @@ -37,52 +26,54 @@ func main() {
MERGE (p2:Person { name: $person2_name })
MERGE (p1)-[:KNOWS]->(p2)
RETURN p1, p2`

var result neo4j.Result
result, err = writeSession.Run(createRelationshipBetweenPeopleQuery, map[string]interface{}{
params := map[string]any{
"person1_name": "Alice",
"person2_name": "David",
})
}

// Using ExecuteQuery allows the driver to handle retries and transient errors for you
result, err := neo4j.ExecuteQuery(ctx, driver, createRelationshipBetweenPeopleQuery, params,
neo4j.EagerResultTransformer)
if err != nil {
panic(err)
}

// You should capture any errors along with the query and data for traceability
if result.Err() != nil {
panic(result.Err())
for _, record := range result.Records {
fmt.Printf("First: '%s'\n", getPersonName(record, "p1"))
fmt.Printf("Second: '%s'\n", getPersonName(record, "p2"))
}

for result.Next() {
firstPerson := result.Record().GetByIndex(0).(neo4j.Node)
fmt.Printf("First: '%s'\n", firstPerson.Props()["name"].(string))
secondPerson := result.Record().GetByIndex(1).(neo4j.Node)
fmt.Printf("Second: '%s'\n", secondPerson.Props()["name"].(string))
}

var readSession neo4j.Session

if readSession, err = driver.Session(neo4j.AccessModeRead); err != nil {
panic(err)
}
defer readSession.Close()

readPersonByName := `
MATCH (p:Person)
WHERE p.name = $person_name
RETURN p.name AS name`

result, err = readSession.Run(readPersonByName, map[string]interface{}{"person_name": "Alice"})

result, err = neo4j.ExecuteQuery(ctx, driver, readPersonByName, map[string]any{"person_name": "Alice"},
neo4j.EagerResultTransformer)
if err != nil {
panic(err)
}
for _, record := range result.Records {
name, _, err := neo4j.GetRecordValue[string](record, "name")
if err != nil {
panic(err)
}
fmt.Printf("Person name: '%s' \n", name)
}
}

if result.Err() != nil {
panic(result.Err())
func closeResource(ctx context.Context, closer interface{ Close(context.Context) error }) {
if err := closer.Close(ctx); err != nil {
panic(err)
}
}

for result.Next() {
fmt.Printf("Person name: '%s' \n", result.Record().GetByIndex(0).(string))
func getPersonName(record *neo4j.Record, key string) string {
firstPerson, _, err := neo4j.GetRecordValue[neo4j.Node](record, key)
if err != nil {
panic(err)
}
firstPersonName, err := neo4j.GetProperty[string](firstPerson, "name")
if err != nil {
panic(err)
}
return firstPersonName
}
4 changes: 2 additions & 2 deletions code/go/go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module example

go 1.14
go 1.20

require github.com/neo4j/neo4j-go-driver v1.8.0
require github.com/neo4j/neo4j-go-driver/v5 v5.8.0
36 changes: 2 additions & 34 deletions code/go/go.sum
Original file line number Diff line number Diff line change
@@ -1,34 +1,2 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/neo4j/neo4j-go-driver v1.8.0 h1:YRp9jsFcF9k/AnvbcqFCN9OMeIT2XTJgxOpp2Puq7OE=
github.com/neo4j/neo4j-go-driver v1.8.0/go.mod h1:0A49wIv0oP3uQdnbceK7Kc+snlY5B0F6dmtYArM0ltk=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
github.com/neo4j/neo4j-go-driver/v5 v5.8.0 h1:I+jtnFbbN9FvRP5etOsrdJNNEThHUCe6pO0MFk1md04=
github.com/neo4j/neo4j-go-driver/v5 v5.8.0/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k=

0 comments on commit 8556d8f

Please sign in to comment.