client

package
v82.0.0-...-84d68f0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2017 License: AGPL-3.0, Apache-2.0 Imports: 25 Imported by: 0

README

Go client

GoDoc

This package provides helper function for interacting with the Dgraph server. You can use it to run mutations and queries. You can also use BatchMutation to upload data concurrently. It communicates with the server using gRPC.

Documentation

Overview

Package client is used to interact with a Dgraph server. Queries and mutations can be run from the client. There are essentially two modes of client interaction:

- Request based interaction mode where the user program builds requests and receives responses immediately after running, and

- Batch mode where clients submit many requests and let the client package batch those requests to the server.

Request Mode: User programs create a NewDgraphClient, create a request with req := client.Req{} and then add edges, deletion, schema and queries to the request with Set, Delete, AddSchema/AddSchemaFromString and SetQuery/SetQueryWithVariables. Once the request is built, it is run with Run.

Batch Mode: On creating a new client with NewDgraphClient users submit BatchMutationOptions specifying the size of batches and number of concurrent batches. Edges are added to the batch with BatchSet; deletions are added with BatchDelete; and schema mutations with AddSchema.

Submitted mutations are nondeterministically added to batches and there are no guarantees about which batch a mutation will be scheduled for (e.g. two successive calls to BatchSet won't guarantee the edges to be in the same batch).

Finishing an interaction with BatchFlush flushes all buffers and ends the client interaction.

For more details checkout https://docs.dgraph.io/clients/#go.

Package lru implements an LRU cache.

Index

Examples

Constants

View Source
const (
	// SET indicates a Set mutation.
	SET opType = iota
	// DEL indicates a Delete mutation.
	DEL
)

Variables

View Source
var (
	ErrConnected      = errors.New("Edge already connected to another node.")
	ErrValue          = errors.New("Edge already has a value.")
	ErrEmptyXid       = errors.New("Empty XID node.")
	ErrInvalidType    = errors.New("Invalid value type")
	ErrEmptyVar       = errors.New("Empty variable name.")
	ErrNotConnected   = errors.New("Edge needs to be connected to another node or a value.")
	ErrInvalidSubject = errors.New("Edge should have one of Subject/SubjectVar set.")
	ErrEmptyPredicate = errors.New("Edge should have a predicate set.")
	ErrMaxTries       = errors.New("Max retries exceeded for request while doing batch mutations.")
)
View Source
var DefaultOptions = BatchMutationOptions{
	Size:          100,
	Pending:       100,
	PrintCounters: false,
	MaxRetries:    math.MaxUint32,
}

Functions

func Unmarshal

func Unmarshal(n []*protos.Node, v interface{}) error

Unmarshal is used to unpack a query response into a custom struct. The response from Dgraph.Run (a *protos.Response) has 4 fields, L(Latency), Schema, AssignedUids and N(Nodes). This function takes in the nodes part of the response and tries to unmarshal it into the given struct v.

protos.Response.N is a slice of Nodes, one for each named query block in the request. Each node in that slice has attribute "_root_" and a child for each node returned as a result by that query block. For a response resp, and struct variable v, with a field tagged with the same name as a query block: Unmarshal(resp.N, s) will try to match named query blocks with tags in s and then unmarshall the the matched block into the matched fields of s.

Unmarshal does not have to be called at resp.N. Clients can navigate to a particular part of the response and unmarshal the children.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	req := client.Req{}

	// A mutation as a string, see ExampleReq_NodeUidVar, ExampleReq_SetQuery,
	// etc for examples of mutations using client functions.
	req.SetQuery(`
mutation {
	schema {
		name: string @index .
	}
	set {
		_:person1 <name> "Alex" .
		_:person2 <name> "Beatie" .
		_:person3 <name> "Chris" .

		_:person1 <friend> _:person2 .
		_:person1 <friend> _:person3 .
	}
}
{
	friends(func: eq(name, "Alex")) {
		name
		friend {
			name
		}
	}
}`)

	// Run the request in the Dgraph server.  The mutations are added, then
	// the query is exectuted.
	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	// Unmarshal the response into a custom struct

	// A type representing information in the graph.
	type person struct {
		Name    string   `dgraph:"name"`
		Friends []person `dgraph:"friend"`
	}

	// A helper type matching the query root.
	type friends struct {
		Root person `dgraph:"friends"`
	}

	var f friends
	err = client.Unmarshal(resp.N, &f)
	if err != nil {
		log.Fatal("Couldn't unmarshal response : ", err)
	}

	fmt.Println("Name : ", f.Root.Name)
	fmt.Print("Friends : ")
	for _, p := range f.Root.Friends {
		fmt.Print(p.Name, " ")
	}
	fmt.Println()

	err = dgraphClient.Close()
	x.Check(err)
}
Output:

Example (FacetsUpdate)
package main

import (
	"context"
	"io/ioutil"
	"log"
	"os"
	"time"

	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	req := client.Req{}

	req.SetQuery(`
mutation {
	schema {
		name: string @index .
	}
	set {
		_:person1 <name> "Alex" .
		_:person2 <name> "Beatie" .
		_:person3 <name> "Chris" .
		_:person4 <name> "David" .

		_:person1 <friend> _:person2 (close=true).
		_:person1 <friend> _:person3 (close=false).
		_:person1 <friend> _:person4 (close=true).
	}
}
{
	friends(func: eq(name, "Alex")) {
		_uid_
		name
		friend @facets {
			_uid_
			name
		}
	}
}`)

	// Run the request in the Dgraph server.  The mutations are added, then
	// the query is exectuted.
	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	// Unmarshal the response into a custom struct

	type friendFacets struct {
		Close bool `dgraph:"close"`
	}

	// A type representing information in the graph.
	type person struct {
		ID           uint64        `dgraph:"_uid_"` // record the UID for our update
		Name         string        `dgraph:"name"`
		Friends      []*person     `dgraph:"friend"` // Unmarshal with pointers to structs
		FriendFacets *friendFacets `dgraph:"@facets"`
	}

	// A helper type matching the query root.
	type friends struct {
		Root person `dgraph:"friends"`
	}

	var f friends
	err = client.Unmarshal(resp.N, &f)
	if err != nil {
		log.Fatal("Couldn't unmarshal response : ", err)
	}

	req = client.Req{}

	// Now update the graph.
	// for the close friends, add the reverse edge and note in a facet when we did this.
	for _, p := range f.Root.Friends {
		if p.FriendFacets.Close {
			n := dgraphClient.NodeUid(p.ID)
			e := n.ConnectTo("friend", dgraphClient.NodeUid(f.Root.ID))
			e.AddFacet("since", time.Now().Format(time.RFC3339))
			req.Set(e)
		}
	}

	resp, err = dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	err = dgraphClient.Close()
	x.Check(err)
}
Output:

Types

type BatchMutationOptions

type BatchMutationOptions struct {
	Size          int
	Pending       int
	PrintCounters bool
	MaxRetries    uint32
	// User could pass a context so that we can stop retrying requests once context is done
	Ctx context.Context
}

BatchMutationOptions sets the clients batch mode to Pending number of buffers each of Size. Running counters of number of rdfs processed, total time and mutations per second are printed if PrintCounters is set true. See Counter.

type Counter

type Counter struct {
	// Number of RDF's processed by server.
	Rdfs uint64
	// Number of mutations processed by the server.
	Mutations uint64
	// Time elapsed sinze the batch started.
	Elapsed time.Duration
}

Counter keeps a track of various parameters about a batch mutation. Running totals are printed if BatchMutationOptions PrintCounters is set to true.

type Dgraph

type Dgraph struct {
	// contains filtered or unexported fields
}

A Dgraph is the data structure held by the user program for all interactions with the Dgraph server. After making grpc connection a new Dgraph is created by function NewDgraphClient.

func NewClient

func NewClient(clients []protos.DgraphClient, opts BatchMutationOptions, clientDir string) *Dgraph

TODO(tzdybal) - hide this function from users

func NewDgraphClient

func NewDgraphClient(conns []*grpc.ClientConn, opts BatchMutationOptions, clientDir string) *Dgraph

NewDgraphClient creates a new Dgraph for interacting with the Dgraph store connected to in conns. The Dgraph client stores blanknode to uid, and XIDnode to uid mappings on disk in clientDir.

The client can be backed by multiple connections (to the same server, or multiple servers in a cluster).

A single client is thread safe for sharing with multiple go routines (though a single Req should not be shared unless the go routines negotiate exclusive assess to the Req functions).

func (*Dgraph) AddSchema

func (d *Dgraph) AddSchema(s protos.SchemaUpdate) error

AddSchema adds the given schema mutation to the batch of schema mutations. If the schema mutation applies an index to a UID edge, or if it adds reverse to a scalar edge, then the mutation is not added to the batch and an error is returned. Once added, the client will apply the schema mutation when it is ready to flush its buffers.

func (*Dgraph) BatchDelete

func (d *Dgraph) BatchDelete(e Edge) error

BatchDelete adds Edge e as a delete to the current batch mutation. Once added, the client will apply the mutation to the Dgraph server when it is ready to flush its buffers. The edge will be added to one of the batches as specified in d's BatchMutationOptions. If that batch fills, it eventually flushes. But there is no guarantee of delivery before BatchFlush() is called.

func (*Dgraph) BatchFlush

func (d *Dgraph) BatchFlush() error

BatchFlush waits for all pending requests to complete. It should always be called after all BatchSet and BatchDeletes have been called. Calling BatchFlush ends the client session and will cause a panic if further AddSchema, BatchSet or BatchDelete functions are called.

func (*Dgraph) BatchSet

func (d *Dgraph) BatchSet(e Edge) error

BatchSet adds Edge e as a set to the current batch mutation. Once added, the client will apply the mutation to the Dgraph server when it is ready to flush its buffers. The edge will be added to one of the batches as specified in d's BatchMutationOptions. If that batch fills, it eventually flushes. But there is no guarantee of delivery before BatchFlush() is called.

Example
package main

import (
	"io/ioutil"
	"log"
	"os"

	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	bmOpts := client.BatchMutationOptions{
		Size:          1000,
		Pending:       100,
		PrintCounters: false,
	}
	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, bmOpts, clientDir)

	// Create a node for person1 (the blank node label "person1" exists
	// client-side so the mutation can correctly link nodes.  It is not
	// persisted in the server)
	person1, err := dgraphClient.NodeBlank("person1")
	if err != nil {
		log.Fatal(err)
	}

	// Add edges for name and salary to the batch mutation
	e := person1.Edge("name")
	e.SetValueString("Steven Spielberg")
	dgraphClient.BatchSet(e)
	e = person1.Edge("salary")
	e.SetValueFloat(13333.6161)
	dgraphClient.BatchSet(e)

	dgraphClient.BatchFlush() // Must be called to flush buffers after all mutations are added.
	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Dgraph) BatchSetWithMark

func (d *Dgraph) BatchSetWithMark(r *Req, file string, line uint64) error

BatchSetWithMark takes a Req which has a batch of edges. It accepts a file to which the edges belong and also the line number of the last line that the batch contains. This is used by the dgraphloader to do checkpointing so that in case the loader crashes, we can skip the lines which the server has already processed. Most users would only need BatchSet which does the batching automatically.

func (*Dgraph) CheckVersion

func (d *Dgraph) CheckVersion(ctx context.Context)

CheckVersion checks if the version of dgraph and dgraphloader are the same. If either the versions don't match or the version information could not be obtained an error message is printed.

func (*Dgraph) Checkpoint

func (d *Dgraph) Checkpoint(file string) (uint64, error)

Get checkpoint for file from Badger.

func (*Dgraph) Close

func (d *Dgraph) Close() error

Close makes sure that the kv-store is closed properly. This should be called after using the Dgraph client.

func (*Dgraph) Counter

func (d *Dgraph) Counter() Counter

Counter returns the current state of the BatchMutation.

func (*Dgraph) NewSyncMarks

func (d *Dgraph) NewSyncMarks(files []string) error

Create syncmarks for files and store them in dgraphClient.

func (*Dgraph) NodeBlank

func (d *Dgraph) NodeBlank(varname string) (Node, error)

NodeBlank creates or returns a Node given a string name for the blank node. Blank nodes do not exist as labelled nodes in Dgraph. Blank nodes are used as labels client side for loading and linking nodes correctly. If the label is new in this session a new UID is allocated and assigned to the label. If the label has already been assigned, the corresponding Node is returned. If the empty string is given as the argument, a new node is allocated and returned but no map is stored, so every call to NodeBlank("") returns a new node.

func (*Dgraph) NodeUid

func (d *Dgraph) NodeUid(uid uint64) Node

NodeUid creates a Node from the given uint64.

func (*Dgraph) NodeUidVar

func (d *Dgraph) NodeUidVar(name string) (Node, error)

NodeUidVar creates a Node from a variable name. When building a request, set and delete mutations may depend on the request's query, as in: https://docs.dgraph.io/query-language/#variables-in-mutations Such query variables in mutations could be built into the raw query string, but it is often more convenient to use client functions than manipulate strings.

A request with a query and mutations (including variables in mutations) will run in the same manner as if the query and mutations were set into the query string.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/gogo/protobuf/proto"
	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	req := client.Req{}

	// Add some data
	alice, err := dgraphClient.NodeXid("alice", false)
	if err != nil {
		log.Fatal(err)
	}
	e := alice.Edge("name")
	e.SetValueString("Alice")
	err = req.Set(e)
	x.Check(err)

	req.SetQuery(`mutation { schema { name: string @index(exact) . } }`)

	resp, err := dgraphClient.Run(context.Background(), &req)

	// New request
	req = client.Req{}

	// Now issue a query and mutation using client interface

	req.SetQuery(`{
    a as var(func: eq(name, "Alice"))
    me(func: uid(a)) {
        name
    }
}`)

	// Get a node for the variable a in the query above.
	n, _ := dgraphClient.NodeUidVar("a")
	e = n.Edge("falls.in")
	e.SetValueString("Rabbit hole")
	err = req.Set(e)
	x.Check(err)

	resp, err = dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}
	fmt.Printf("%+v\n", proto.MarshalTextString(resp))

	// This is equivalent to the single query and mutation
	//
	// {
	//		a as var(func: eq(name, "Alice"))
	//		me(func: uid(a)) {
	//			name
	//		}
	// }
	// mutation { set {
	//		var(a) <falls.in> "Rabbit hole" .
	// }}
	//
	// It's often easier to construct such things with client functions that
	// by manipulating raw strings.
	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Dgraph) NodeXid

func (d *Dgraph) NodeXid(xid string, storeXid bool) (Node, error)

NodeXid creates or returns a Node given a string name for an XID node. An XID node identifies a node with an edge xid, as in

node --- xid ---> XID string

See https://docs.dgraph.io/query-language/#external-ids If the XID has already been allocated in this client session the allocated UID is returned, otherwise a new UID is allocated for xid and returned.

func (*Dgraph) Run

func (d *Dgraph) Run(ctx context.Context, req *Req) (*protos.Response, error)

Run runs the request in req and returns with the completed response from the server. Calling Run has no effect on batched mutations.

Mutations in the request are run before a query --- except when query variables link the mutation and query (see for example NodeUidVar) when the query is run first.

Run returns a protos.Response which has the following fields

- L : Latency information

- Schema : Result of a schema query

- AssignedUids : a map[string]uint64 of blank node name to assigned UID (if the query string contained a mutation with blank nodes)

- N : Slice of *protos.Node returned by the query (Note: protos.Node not client.Node).

There is an N[i], with Attribute "_root_", for each named query block in the query added to req. The N[i] also have a slice of nodes, N[i].Children each with Attribute equal to the query name, for every answer to that query block. From there, the Children represent nested blocks in the query, the Attribute is the edge followed and the Properties are the scalar edges.

Print a response with

"github.com/gogo/protobuf/proto"
...
req.SetQuery(`{
	friends(func: eq(name, "Alex")) {
		name
		friend {
			name
		}
	}
}`)
...
resp, err := dgraphClient.Run(context.Background(), &req)
fmt.Printf("%+v\n", proto.MarshalTextString(resp))

Outputs

n: <
  attribute: "_root_"
  children: <
    attribute: "friends"
    properties: <
      prop: "name"
      value: <
        str_val: "Alex"
      >
    >
    children: <
      attribute: "friend"
      properties: <
        prop: "name"
        value: <
          str_val: "Chris"
        >
      >
    >
...

It's often easier to unpack directly into a struct with Unmarshal, than to step through the response.

func (*Dgraph) SetSchemaBlocking

func (d *Dgraph) SetSchemaBlocking(ctx context.Context, q string) error

type Edge

type Edge struct {
	// contains filtered or unexported fields
}

An Edge represents an edge between a source node and a target (either a node or a value). Facets are stored in the edge. See Node.Edge(), Node.ConnectTo(), Edge.ConnecTo(), Edge.AddFacet and the Edge.SetValue...() functions to make a valid edge for a set or delete mutation.

func DeletePredicate

func DeletePredicate(pred string) Edge

DeletePredicate is used to delete all the data corresponding to a predicate. Indexes/reverses if any are also deleted while deleting a predicate. Schema for the predicate can be changed after deleting the data for it.

func NewEdge

func NewEdge(nq protos.NQuad) Edge

NewEdge creates an Edge from an NQuad.

func (*Edge) AddFacet

func (e *Edge) AddFacet(key, val string)

AddFacet adds the key, value pair as facets on Edge e. No checking is done.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"time"

	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	req := client.Req{}

	// Create a node for person1 add an edge for name.
	person1, err := dgraphClient.NodeXid("person1", false)
	if err != nil {
		log.Fatal(err)
	}
	e := person1.Edge("name")
	e.SetValueString("Steven Stevenson")

	// Add facets since and alias to the edge.
	e.AddFacet("since", "2006-01-02T15:04:05")
	e.AddFacet("alias", `"Steve"`)

	err = req.Set(e)
	x.Check(err)

	person2, err := dgraphClient.NodeXid("person2", false)
	if err != nil {
		log.Fatal(err)
	}
	e = person2.Edge("name")
	e.SetValueString("William Jones")
	err = req.Set(e)
	x.Check(err)

	e = person1.ConnectTo("friend", person2)

	// Facet on a node-node edge.
	e.AddFacet("close", "true")
	err = req.Set(e)
	x.Check(err)

	req.SetQuery(`mutation { schema { name: string @index(exact) . } }`)

	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	req = client.Req{}
	req.SetQuery(`{
		query(func: eq(name,"Steven Stevenson")) {
			name @facets
			friend @facets {
				name
			}
		}
	}`)

	resp, err = dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	// Types representing information in the graph.
	type nameFacets struct {
		Since time.Time `dgraph:"since"`
		Alias string    `dgraph:"alias"`
	}

	type friendFacets struct {
		Close bool `dgraph:"close"`
	}

	type Person struct {
		Name         string       `dgraph:"name"`
		NameFacets   nameFacets   `dgraph:"name@facets"`
		Friends      []Person     `dgraph:"friend"`
		FriendFacets friendFacets `dgraph:"@facets"`
	}

	// Helper type to unmarshal query
	type Res struct {
		Root Person `dgraph:"query"`
	}

	var pq Res
	err = client.Unmarshal(resp.N, &pq)
	if err != nil {
		log.Fatal("Couldn't unmarshal response : ", err)
	}

	fmt.Println("Found : ", pq.Root.Name)
	fmt.Println("Who likes to be called : ", pq.Root.NameFacets.Alias, " since ", pq.Root.NameFacets.Since)
	fmt.Println("Friends : ")
	for i := range pq.Root.Friends {
		fmt.Print("\t", pq.Root.Friends[i].Name)
		if pq.Root.Friends[i].FriendFacets.Close {
			fmt.Println(" who is a close friend.")
		} else {
			fmt.Println(" who is not a close friend.")
		}
	}
	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Edge) ConnectTo

func (e *Edge) ConnectTo(n Node) error

ConnectTo adds Node n as the target of the edge. If the edge already has a known scalar type, for example if Edge.SetValue...() had been called on the edge, then an error is returned.

func (*Edge) Delete

func (e *Edge) Delete() error

Delete is used to set the edge for deletion. If the edge is already connected to another node then an error is returned. This is equivalent to S P * deletion where an edge can be deleted without knowing giving the Value/Node it is connected to.

func (*Edge) SetValueBool

func (e *Edge) SetValueBool(val bool) error

SetValueBool sets the value of Edge e as bool val and sets the type of the edge to types.BoolID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned.

func (*Edge) SetValueBytes

func (e *Edge) SetValueBytes(val []byte) error

SetValueBytes allows setting the value of an edge to raw bytes and sets the type of the edge to types.BinaryID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned. the bytes are encoded as base64.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	req := client.Req{}

	alice, err := dgraphClient.NodeBlank("alice")
	if err != nil {
		log.Fatal(err)
	}
	e := alice.Edge("name")
	e.SetValueString("Alice")
	err = req.Set(e)
	x.Check(err)

	e = alice.Edge("somestoredbytes")
	err = e.SetValueBytes([]byte(`\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98`))
	x.Check(err)
	err = req.Set(e)
	x.Check(err)

	req.SetQuery(`mutation {
	schema {
		name: string @index(exact) .
	}
}
{
	q(func: eq(name, "Alice")) {
		name
		somestoredbytes
	}
}`)

	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	type Alice struct {
		Name      string `dgraph:"name"`
		ByteValue []byte `dgraph:"somestoredbytes"`
	}

	type Res struct {
		Root Alice `dgraph:"q"`
	}

	var r Res
	err = client.Unmarshal(resp.N, &r)
	x.Check(err)
	fmt.Printf("Alice: %+v\n\n", r.Root)
	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Edge) SetValueDatetime

func (e *Edge) SetValueDatetime(dateTime time.Time) error

SetValueDatetime sets the value of Edge e as time.Time dateTime and sets the type of the edge to types.DateTimeID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned.

func (*Edge) SetValueDefault

func (e *Edge) SetValueDefault(val string) error

SetValueDefault sets the value of Edge e as string val and sets the type of the edge to types.DefaultID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned. The string must escape " with \, otherwise the edge and type are left unchanged and an error returned.

func (*Edge) SetValueFloat

func (e *Edge) SetValueFloat(val float64) error

SetValueFloat sets the value of Edge e as float64 val and sets the type of the edge to types.FloatID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned.

func (*Edge) SetValueGeoGeometry

func (e *Edge) SetValueGeoGeometry(g geom.T) error

SetValueGeoGeometry sets the value of Edge e as the marshalled value of the geometry g and sets the type of the edge to types.GeoID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned. If the geometry fails to be marshalled with wkb.Marshal() the edge is left unchanged and an error returned.

func (*Edge) SetValueGeoJson

func (e *Edge) SetValueGeoJson(json string) error

SetValueGeoJson sets the value of Edge e as the GeoJSON object parsed from json string and sets the type of the edge to types.GeoID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned. If the string fails to parse with geojson.Unmarshal() the edge is left unchanged and an error returned.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/twpayne/go-geom/encoding/wkb"
	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	req := client.Req{}

	alice, err := dgraphClient.NodeBlank("alice")
	if err != nil {
		log.Fatal(err)
	}
	e := alice.Edge("name")
	e.SetValueString("Alice")
	err = req.Set(e)
	x.Check(err)

	e = alice.Edge("loc")
	err = e.SetValueGeoJson(`{"Type":"Point", "Coordinates":[1.1,2.0]}`)
	x.Check(err)
	err = req.Set(e)
	x.Check(err)

	e = alice.Edge("city")
	err = e.SetValueGeoJson(`{"Type":"Polygon", "Coordinates":[[[0.0,0.0], [2.0,0.0], [2.0, 2.0], [0.0, 2.0], [0.0, 0.0]]]}`)
	x.Check(err)
	err = req.Set(e)
	x.Check(err)

	req.SetQuery(`mutation {
	schema {
		name: string @index(exact) .
	}
}
{
	q(func: eq(name, "Alice")) {
		name
		loc
		city
	}
}`)

	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	type Alice struct {
		Name string `dgraph:"name"`
		Loc  []byte `dgraph:"loc"`
		City []byte `dgraph:"city"`
	}

	type Res struct {
		Root Alice `dgraph:"q"`
	}

	var r Res
	err = client.Unmarshal(resp.N, &r)
	x.Check(err)
	fmt.Printf("Alice: %+v\n\n", r.Root)
	loc, err := wkb.Unmarshal(r.Root.Loc)
	x.Check(err)
	city, err := wkb.Unmarshal(r.Root.City)
	x.Check(err)

	fmt.Printf("Loc: %+v\n\n", loc)
	fmt.Printf("City: %+v\n\n", city)
	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Edge) SetValueInt

func (e *Edge) SetValueInt(val int64) error

SetValueInt sets the value of Edge e as int64 val and sets the type of the edge to types.IntID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned.

func (*Edge) SetValuePassword

func (e *Edge) SetValuePassword(val string) error

SetValuePassword sets the value of Edge e as password string val and sets the type of the edge to types.PasswordID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned.

func (*Edge) SetValueString

func (e *Edge) SetValueString(val string) error

SetValueString sets the value of Edge e as string val and sets the type of the edge to types.StringID. If the edge had previous been assigned another value (even of another type), the value and type are overwritten. If the edge has previously been connected to a node, the edge and type are left unchanged and ErrConnected is returned. The string must escape " with \, otherwise the edge and type are left unchanged and an error returned.

func (*Edge) SetValueStringWithLang

func (e *Edge) SetValueStringWithLang(val string, lang string) error

SetValueStringWithLang has same behavior as SetValueString along with the ability to set the language tag as lang.

type Node

type Node struct {
	// contains filtered or unexported fields
}

Node represents a single node in the graph.

func (*Node) ConnectTo

func (n *Node) ConnectTo(pred string, n1 Node) Edge

ConnectTo creates an edge labelled pred from Node n to Node n1

func (*Node) Delete

func (n *Node) Delete() Edge

Delete is used to delete all outgoing edges for a node. It is equivalent to performing a S * * deletion.

func (*Node) Edge

func (n *Node) Edge(pred string) Edge

Edge create an edge with source Node n and predicate pred, but without a target. The edge needs to be completed by calling Edge.ConnectTo() if the edge is a UID edge, or one of the Edge.SetValue...() functions if the edge is of a scalar type. The edge can't be committed to the store --- calling Req.Set() to add the edge to a request will result in an error --- until it is completed.

func (Node) String

func (n Node) String() string

String returns Node n as a string

type Req

type Req struct {
	// contains filtered or unexported fields
}

A Req represents a single request to the backend Dgraph instance. Each request may contain multiple set, delete and schema mutations, and a single GraphQL+- query. If the query contains GraphQL variables, then it must be set with SetQueryWithVariables rather than SetQuery.

func (*Req) AddSchema

func (req *Req) AddSchema(s protos.SchemaUpdate) error

AddSchema adds the single schema mutation s to the request.

func (*Req) Delete

func (req *Req) Delete(e Edge) error

Delete adds edge e to the delete mutation of request req, thus scheduling the edge to be removed from the graph when the request is run. The edge must have a valid target (a Node or value), otherwise an error is returned. The edge need not represent an edge in the graph --- applying such a mutation simply has no effect.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/gogo/protobuf/proto"
	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	// Create new request
	req := client.Req{}

	// Create a node for person1 (the blank node label "person1" exists
	// client-side so the mutation can correctly link nodes.  It is not
	// persisted in the server)
	person1, err := dgraphClient.NodeBlank("person1")
	if err != nil {
		log.Fatal(err)
	}
	person2, err := dgraphClient.NodeBlank("person2")
	if err != nil {
		log.Fatal(err)
	}

	e := person1.Edge("name")
	e.SetValueString("Steven Spallding")
	err = req.Set(e)
	x.Check(err)

	e = person2.Edge("name")
	e.SetValueString("Steven Stevenson")
	err = req.Set(e)
	x.Check(err)

	e = person1.ConnectTo("friend", person2)

	// Add person1, person2 and friend edge to store
	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}
	fmt.Printf("%+v\n", proto.MarshalTextString(resp))

	// Now remove the friend edge

	// If the old variable was written over or out of scope we can lookup person1 again,
	// the string->node mapping is remembered by the client for this session.
	p1, err := dgraphClient.NodeBlank("person1")
	p2, err := dgraphClient.NodeBlank("person2")

	e = p1.ConnectTo("friend", p2)
	req = client.Req{}
	req.Delete(e)

	// Run the mutation to delete the edge
	resp, err = dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}
	fmt.Printf("%+v\n", proto.MarshalTextString(resp))
	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Req) Request

func (req *Req) Request() *protos.Request

Request returns the protos.Request backing the Req.

func (*Req) Set

func (req *Req) Set(e Edge) error

Set adds edge e to the set mutation of request req, thus scheduling the edge to be added to the graph when the request is run. The edge must have a valid target (a Node or value), otherwise an error is returned. The edge is not checked agaist the schema until the request is run --- so setting a UID edge to a value, for example, doesn't result in an error until the request is run.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/gogo/protobuf/proto"
	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	// Create new request
	req := client.Req{}

	// Create a node for person1 (the blank node label "person1" exists
	// client-side so the mutation can correctly link nodes.  It is not
	// persisted in the server)
	person1, err := dgraphClient.NodeBlank("person1")
	if err != nil {
		log.Fatal(err)
	}

	// Add edges for name and salary to person1
	e := person1.Edge("name")
	e.SetValueString("Steven Spielberg")
	err = req.Set(e)
	x.Check(err)

	// If the old variable was written over or out of scope we can lookup person1 again,
	// the string->node mapping is remembered by the client for this session.
	p, err := dgraphClient.NodeBlank("person1")
	e = p.Edge("salary")
	e.SetValueFloat(13333.6161)
	err = req.Set(e)
	x.Check(err)

	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	// proto.MarshalTextString(resp) can be used to print the raw response as text.  Client
	// programs usually use Umarshal to unpack query responses to a struct (or the protocol
	// buffer can be accessed with resp.N)
	fmt.Printf("%+v\n", proto.MarshalTextString(resp))

	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Req) SetQuery

func (req *Req) SetQuery(q string)

SetQuery sets the query in req to the given string. The query string is not checked until the request is run, when it is parsed and checked server-side.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	req := client.Req{}
	alice, err := dgraphClient.NodeXid("alice", false)
	if err != nil {
		log.Fatal(err)
	}
	e := alice.Edge("name")
	e.SetValueString("Alice")
	err = req.Set(e)
	x.Check(err)

	e = alice.Edge("falls.in")
	e.SetValueString("Rabbit hole")
	err = req.Set(e)
	x.Check(err)

	req.SetQuery(`mutation { schema { name: string @index(exact) . } }`)
	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	req = client.Req{}

	req.SetQuery(`{
		me(func: eq(name, "Alice")) {
			name
			falls.in
		}
	}`)
	resp, err = dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	type Alice struct {
		Name         string `dgraph:"name"`
		WhatHappened string `dgraph:"falls.in"`
	}

	type Res struct {
		Root Alice `dgraph:"me"`
	}

	var r Res
	err = client.Unmarshal(resp.N, &r)
	x.Check(err)
	fmt.Printf("Alice: %+v\n\n", r.Root)
	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Req) SetQueryWithVariables

func (req *Req) SetQueryWithVariables(q string, vars map[string]string)

SetQueryWithVariables sets query q (which contains graphQL variables mapped in vars) as the query in req and sets vars as the corresponding query variables. Neither the query string nor the variables are checked until the request is run, when it is parsed and checked server-side.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"google.golang.org/grpc"
	"gopkg.in/adibiarsotp/dgraph.v82/client"
	"gopkg.in/adibiarsotp/dgraph.v82/x"
)

func main() {
	conn, err := grpc.Dial("127.0.0.1:9080", grpc.WithInsecure())
	x.Checkf(err, "While trying to dial gRPC")
	defer conn.Close()

	clientDir, err := ioutil.TempDir("", "client_")
	x.Check(err)
	defer os.RemoveAll(clientDir)

	dgraphClient := client.NewDgraphClient([]*grpc.ClientConn{conn}, client.DefaultOptions, clientDir)

	req := client.Req{}

	alice, err := dgraphClient.NodeXid("alice", false)
	if err != nil {
		log.Fatal(err)
	}
	e := alice.Edge("name")
	e.SetValueString("Alice")
	err = req.Set(e)
	x.Check(err)

	e = alice.Edge("falls.in")
	e.SetValueString("Rabbit hole")
	err = req.Set(e)
	x.Check(err)

	req.SetQuery(`mutation { schema { name: string @index(exact) . } }`)
	resp, err := dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	req = client.Req{}
	variables := make(map[string]string)
	variables["$a"] = "Alice"
	req.SetQueryWithVariables(`{
		me(func: eq(name, $a)) {
			name
			falls.in
		}
	}`, variables)

	resp, err = dgraphClient.Run(context.Background(), &req)
	if err != nil {
		log.Fatalf("Error in getting response from server, %s", err)
	}

	type Alice struct {
		Name         string `dgraph:"name"`
		WhatHappened string `dgraph:"falls.in"`
	}

	type Res struct {
		Root Alice `dgraph:"me"`
	}

	var r Res
	err = client.Unmarshal(resp.N, &r)
	x.Check(err)
	fmt.Printf("Alice: %+v\n\n", r.Root)
	err = dgraphClient.Close()
	x.Check(err)
}
Output:

func (*Req) SetSchema

func (req *Req) SetSchema(q string)

SetSchema sets schema mutation in req with the given schema The schema is not checked until the request is run, when it is parsed and checked server-side

func (*Req) Size

func (req *Req) Size() int

Size returns the total number of Set, Delete and Schema mutations that are part of the request.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL