ag

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 14, 2018 License: Apache-2.0 Imports: 10 Imported by: 2

README

ag - Go driver support for AgensGraph

Documentation

Please see the package documentation at https://godoc.org/github.com/bitnine-oss/agensgraph-golang for the detailed documentation and basic usage examples.

Tests

You may run go test with the optional -ag.test.server flag for server test.

For the server test, the environment variables listed at here can be used to set connection parameter values. There are two environment variables set by the test code; PGDATABASE=postgres and PGSSLMODE=disable.

License

Go driver support for AgensGraph is licensed under the Apache License, Version 2.0.

Documentation

Overview

Package ag is a set of types that implements the Scanner and Valuer interfaces and supports additional methods for AgensGraph.

These types are intended to use with github.com/lib/pq in text format mode.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Array

func Array(dest interface{}) interface {
	sql.Scanner
	driver.Valuer
}

Array returns database/sql Scanner and database/sql/driver Valuer for dest that is a slice or an array of the following types; GraphId, and entities for vertex and edge.

If the type of dest is not *[]GraphId and []GraphId, Value of Array returns an error since passing entities as parameters is not allowed.

Example (BasicEdge)
var es []ag.BasicEdge
err := db.QueryRow(`MATCH p=(:v)-[:e]->(:v)-[:e]->(:v) RETURN relationships(p) LIMIT 1`).Scan(ag.Array(&es))
if err == nil && es != nil {
	// Valid _edge
} else {
	// An error occurred or the _edge is NULL
}
Output:

Example (BasicVertex)
var vs []ag.BasicVertex
err := db.QueryRow(`MATCH p=(:v)-[:e]->(:v) RETURN nodes(p) LIMIT 1`).Scan(ag.Array(&vs))
if err == nil && vs != nil {
	// Valid _vertex
} else {
	// An error occurred or the _vertex is NULL
}
Output:

Example (GraphId)
var gids []ag.GraphId

// Scan()
db.QueryRow(`MATCH ()-[es*]->() RETURN [e IN es | id(e)] LIMIT 1`).Scan(ag.Array(&gids))

// Value()
gid0, _ := ag.NewGraphId("1.1")
gid1, _ := ag.NewGraphId("65535.281474976710655")
gids = []ag.GraphId{gid0, gid1}
db.QueryRow(`MATCH (n) WHERE id(n) IN $1 RETURN n LIMIT 1`, ag.Array(gids))
Output:

func ScanEntity

func ScanEntity(src interface{}, entity Entity) error

ScanEntity reads an entity for vertex or edge from src and stores the result in the given entity.

An error will be returned if the type of src is not []byte, or src is invalid for the given entity.

Example
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/bitnine-oss/agensgraph-golang"
)

type knows struct {
	ag.Edge
	meta struct {
		null bool
		id   ag.GraphId
	}
	who   ag.GraphId
	whom  ag.GraphId
	since yearMonth
}

type knowsBody struct {
	Type  string
	Since json.RawMessage
}

type yearMonth struct {
	Year  int
	Month int
}

func (e knows) String() string {
	if e.meta.null {
		return "NULL"
	} else {
		return fmt.Sprintf("%s knows %s since %d, %d", e.who, e.whom, e.since.Month, e.since.Year)
	}
}

func (e *knows) SaveEntity(valid bool, core interface{}) error {
	e.meta.null = !valid
	if !valid {
		return nil
	}

	c, ok := core.(ag.EdgeCore)
	if !ok {
		return fmt.Errorf("invalid edge core: %T", core)
	}

	e.meta.id = c.Id
	e.who = c.Start
	e.whom = c.End
	return nil
}

func (e *knows) SaveProperties(b []byte) error {
	var body knowsBody
	err := json.Unmarshal(b, &body)
	if err != nil {
		return err
	}

	switch body.Type {
	case "array":
		var ym [2]int
		err = json.Unmarshal(body.Since, &ym)
		if err != nil {
			return err
		}
		e.since.Year, e.since.Month = ym[0], ym[1]
	case "object":
		err := json.Unmarshal(body.Since, &e.since)
		if err != nil {
			return err
		}
	default:
		log.Panicf("unknown body type: %q", body.Type)
	}

	return nil
}

func (e *knows) Scan(src interface{}) error {
	return ag.ScanEntity(src, e)
}

func main() {
	ds := [][]byte{
		[]byte(`knows[4.1][3.1,3.2]{"type": "array", "since": [1970, 1]}`),
		[]byte(`knows[4.2][3.3,3.4]{"type": "object", "since": {"year": 2009, "month": 10}}`),
	}
	for _, d := range ds {
		var r knows
		err := r.Scan(d)
		if err != nil {
			log.Println(err)
		} else {
			fmt.Printf("%s\n", r)
		}
	}
}
Output:

func ScanPath

func ScanPath(src interface{}, saver PathSaver) error

ScanPath reads a path from src and stores the result by calling SavePath.

An error will be returned if the type of src is not []byte, or src is invalid.

Types

type BasicEdge

type BasicEdge struct {
	EdgeHeader
	Properties map[string]interface{}
}

BasicEdge can be used to scan the value from the database driver as a edge.

This is a reference implementation of an entity for edge using all the basic building blocks(Edge, EdgeCore, EdgeHeader, EntitySaver, PropertiesSaver, and ScanEntity.)

func (*BasicEdge) SaveProperties

func (e *BasicEdge) SaveProperties(b []byte) error

SaveProperties implements PropertiesSaver interface. It calls json.Unmarshal to unmarshal b and store the result in Properties.

func (*BasicEdge) Scan

func (e *BasicEdge) Scan(src interface{}) error

Scan implements the database/sql Scanner interface. It calls ScanEntity.

Example
var e ag.BasicEdge
err := db.QueryRow(`MATCH ()-[e]->() RETURN e LIMIT 1`).Scan(&e)
if err == nil && e.Valid {
	// Valid edge
} else {
	// An error occurred or the edge is NULL
}
Output:

func (BasicEdge) String

func (e BasicEdge) String() string

type BasicPath

type BasicPath struct {
	Valid    bool
	Vertices []BasicVertex
	Edges    []BasicEdge
}

BasicPath can be used to scan the value from the database driver as a path.

This is a reference implementation that uses PathSaver and ScanPath.

func (*BasicPath) SavePath

func (p *BasicPath) SavePath(valid bool, ds []interface{}) error

SavePath implements PathSaver interface.

func (*BasicPath) Scan

func (p *BasicPath) Scan(src interface{}) error

Scan implements the database/sql Scanner interface. It calls ScanPath.

Example
var p ag.BasicPath
err := db.QueryRow(`MATCH p=(:v)-[:e]->(:v)-[:e]->(:v) RETURN p LIMIT 1`).Scan(&p)
if err == nil && p.Valid {
	// Valid graphpath
} else {
	// An error occurred or the graphpath is NULL
}
Output:

func (BasicPath) String

func (p BasicPath) String() string

type BasicVertex

type BasicVertex struct {
	VertexHeader
	Properties map[string]interface{}
}

BasicVertex can be used to scan the value from the database driver as a vertex.

This is a reference implementation of an entity for vertex using all the basic building blocks(Vertex, VertexCore, VertexHeader, EntitySaver, PropertiesSaver, and ScanEntity.)

func (*BasicVertex) SaveProperties

func (v *BasicVertex) SaveProperties(b []byte) error

SaveProperties implements PropertiesSaver interface. It calls json.Unmarshal to unmarshal b and store the result in Properties.

func (*BasicVertex) Scan

func (v *BasicVertex) Scan(src interface{}) error

Scan implements the database/sql Scanner interface. It calls ScanEntity.

Example
var v ag.BasicVertex
err := db.QueryRow(`MATCH (n) RETURN n LIMIT 1`).Scan(&v)
if err == nil && v.Valid {
	// Valid vertex
} else {
	// An error occurred or the vertex is NULL
}
Output:

func (BasicVertex) String

func (v BasicVertex) String() string

type Edge

type Edge struct{}

Edge gives any struct an ability to read the value from the database driver as an edge if the struct has Edge as its embedded field.

type EdgeCore

type EdgeCore struct {
	Label string
	Id    GraphId
	Start GraphId
	End   GraphId
}

EdgeCore represents essential data to identify an edge.

type EdgeHeader

type EdgeHeader struct {
	Edge
	Valid    bool // Valid is true if the edge is not NULL
	EdgeCore      // EdgeCore is valid only if Valid is true
}

EdgeHeader may be used as an embedded field of any struct to change the struct to an entity for edge.

func (*EdgeHeader) SaveEntity

func (h *EdgeHeader) SaveEntity(valid bool, core interface{}) error

SaveEntity implements EntitySaver interface.

type Entity

type Entity interface {
	EntitySaver
	// contains filtered or unexported methods
}

Entity is an interface used by ScanEntity. Any struct that has Vertex or Edge as its embedded field and implements EntitySaver can be an entity for vertex or edge.

type EntitySaver

type EntitySaver interface {
	// SaveEntity assigns an entity from the database driver.
	//
	// valid is true if the entity is not NULL.
	//
	// core is VertexCore or EdgeCore that will be stored in the entity for
	// vertex or edge respectively. If valid is false, core will be nil.
	//
	// An error should be returned if the entity cannot be stored without
	// loss of information.
	SaveEntity(valid bool, core interface{}) error
}

EntitySaver is an interface used by ScanEntity.

type GraphId

type GraphId struct {
	// Valid is true if GraphId is not NULL
	Valid bool
	// contains filtered or unexported fields
}

GraphId is a unique ID for a vertex and an edge.

func NewGraphId

func NewGraphId(str string) (GraphId, error)

NewGraphId returns GraphId of str if str is between "1.1" and "65535.281474976710656". If str is "NULL", it returns GraphId whose Valid is false. Otherwise, it returns an error.

func (GraphId) Equal

func (gid GraphId) Equal(x GraphId) bool

Equal reports whether gid and x are the same GraphId.

func (*GraphId) Scan

func (gid *GraphId) Scan(src interface{}) error

Scan implements the database/sql Scanner interface.

Example
var gid ag.GraphId
err := db.QueryRow(`MATCH (n) RETURN id(n) LIMIT 1`).Scan(&gid)
if err == nil && gid.Valid {
	// Valid graphid
} else {
	// An error occurred or the graphid is NULL
}
Output:

func (GraphId) String

func (gid GraphId) String() string

func (GraphId) Value

func (gid GraphId) Value() (driver.Value, error)

Value implements the database/sql/driver Valuer interface.

Example
gid, _ := ag.NewGraphId("1.1")
db.QueryRow(`MATCH (n) WHERE id(n) = $1 RETURN n`, gid)
Output:

type NullArrayError

type NullArrayError struct{}

NullArrayError is returned by Scan if the type of dest for Array(dest) is array and the value from the database driver is NULL.

func (NullArrayError) Error

func (_ NullArrayError) Error() string

type PathSaver

type PathSaver interface {
	// SavePath assigns a path from the database driver.
	//
	// valid is true if the path is not NULL.
	//
	// ds is a series of connected vertices and edges. Each element of ds
	// can be stored in an entity for vertex or edge by calling ScanEntity.
	// If valid is false, ds will be nil.
	//
	// An error should be returned if the path cannot be stored without
	// loss of information.
	SavePath(valid bool, ds []interface{}) error
}

PathSaver is an interface used by ScanPath.

type PropertiesSaver

type PropertiesSaver interface {
	// By default, properties of an entity read by ScanEntity are stored in
	// the entity itself by calling json.Unmarshal over it. To modify this
	// default behavior, one may implement PropertiesSaver for the entity.
	//
	// The underlying array of b may be reused.
	//
	// An error should be returned if the properties cannot be stored
	// without loss of information.
	SaveProperties(b []byte) error
}

PropertiesSaver is an interface used by ScanEntity.

type Vertex

type Vertex struct{}

Vertex gives any struct an ability to read the value from the database driver as a vertex if the struct has Vertex as its embedded field.

type VertexCore

type VertexCore struct {
	Label string
	Id    GraphId
}

VertexCore represents essential data to identify a vertex.

type VertexHeader

type VertexHeader struct {
	Vertex
	Valid      bool // Valid is true if the vertex is not NULL
	VertexCore      // VertexCore is valid only if Valid is true
}

VertexHeader may be used as an embedded field of any struct to change the struct to an entity for vertex.

func (*VertexHeader) SaveEntity

func (h *VertexHeader) SaveEntity(valid bool, core interface{}) error

SaveEntity implements EntitySaver interface.

Jump to

Keyboard shortcuts

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