Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(golang driver): add some comments for use with GoDoc #1504

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 20 additions & 15 deletions drivers/golang/age/age.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func execCypher(cursorProvider CursorProvider, tx *sql.Tx, graphName string, col

cypherStmt := fmt.Sprintf(cypher, args...)

buf.WriteString("SELECT * from cypher(NULL,NULL) as (v0 agtype")
buf.WriteString("SELECT * from cypher(NULL,NULL) as (v0 agtype")

for i := 1; i < columnCount; i++ {
buf.WriteString(fmt.Sprintf(", v%d agtype", i))
Expand All @@ -85,25 +85,25 @@ func execCypher(cursorProvider CursorProvider, tx *sql.Tx, graphName string, col

stmt := buf.String()

// Pass in the graph name and cypher statement via parameters to prepare
// the cypher function call for session info.
// Pass in the graph name and cypher statement via parameters to prepare
// the cypher function call for session info.

prepare_stmt := "SELECT * FROM age_prepare_cypher($1, $2);"
_, perr := tx.Exec(prepare_stmt, graphName, cypherStmt)
if perr != nil {
fmt.Println(prepare_stmt + " " + graphName + " " + cypher)
return nil, perr
}
prepare_stmt := "SELECT * FROM age_prepare_cypher($1, $2);"
_, perr := tx.Exec(prepare_stmt, graphName, cypherStmt)
if perr != nil {
fmt.Println(prepare_stmt + " " + graphName + " " + cypher)
return nil, perr
}

if columnCount == 0 {
_, err := tx.Exec(stmt)
_, err := tx.Exec(stmt)
if err != nil {
fmt.Println(stmt)
return nil, err
}
return nil, nil
} else {
rows, err := tx.Query(stmt)
rows, err := tx.Query(stmt)
if err != nil {
fmt.Println(stmt)
return nil, err
Expand Down Expand Up @@ -148,7 +148,8 @@ type AgeTx struct {
tx *sql.Tx
}

/**
/*
*
@param dsn host=127.0.0.1 port=5432 dbname=postgres user=postgres password=agens sslmode=disable
*/
func ConnectAge(graphName string, dsn string) (*Age, error) {
Expand All @@ -171,6 +172,7 @@ func NewAge(graphName string, db *sql.DB) *Age {
return &Age{db: db, graphName: graphName}
}

// GetReady prepares the underlying database for use with AGE.
func (age *Age) GetReady() (bool, error) {
tx, err := age.db.Begin()
if err != nil {
Expand Down Expand Up @@ -215,6 +217,7 @@ func (a *Age) DB() *sql.DB {
return a.db
}

// Begin starts a transaction.
func (a *Age) Begin() (*AgeTx, error) {
ageTx := &AgeTx{age: a}
tx, err := a.db.Begin()
Expand Down Expand Up @@ -242,6 +245,7 @@ func (a *AgeTx) ExecCypherMap(columnCount int, cypher string, args ...interface{
return ExecCypherMap(a.tx, a.age.graphName, columnCount, cypher, args...)
}

// CypherCursor holds the result of a Cypher query.
type CypherCursor struct {
Cursor
columnCount int
Expand All @@ -257,8 +261,9 @@ func (c *CypherCursor) Next() bool {
return c.rows.Next()
}

// GetRow returns the next row of the result.
func (c *CypherCursor) GetRow() ([]Entity, error) {
var gstrs = make([]interface{}, c.columnCount)
gstrs := make([]interface{}, c.columnCount)
for i := 0; i < c.columnCount; i++ {
gstrs[i] = new(string)
}
Expand Down Expand Up @@ -286,7 +291,8 @@ func (c *CypherCursor) Close() error {
return c.rows.Close()
}

//
// CypherMapCursor holds the result of a Cypher query
// on a Cypher map.
type CypherMapCursor struct {
CypherCursor
mapper *AGMapper
Expand All @@ -304,7 +310,6 @@ func (c *CypherMapCursor) PutType(label string, tp reflect.Type) {

func (c *CypherMapCursor) GetRow() ([]interface{}, error) {
entities, err := c.CypherCursor.GetRow()

if err != nil {
return nil, fmt.Errorf("CypherMapCursor.GetRow:: %s", err)
}
Expand Down
16 changes: 11 additions & 5 deletions drivers/golang/age/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,23 @@ import (
"math/big"
"strconv"
"strings"

"github.com/antlr/antlr4/runtime/Go/antlr/v4"
"github.com/apache/age/drivers/golang/parser"
)

const MaxUint = ^uint(0)
const MaxInt = int(MaxUint >> 1)
const MinUint = 0
const MinInt = -MaxInt - 1
const (
MaxUint = ^uint(0)
MaxInt = int(MaxUint >> 1)
MinUint = 0
MinInt = -MaxInt - 1
)

type Unmarshaller interface {
unmarshal(text string) (Entity, error)
}

// AGUnmarshaler is a unmarshaler for AGE result data.
type AGUnmarshaler struct {
Unmarshaller
ageParser *parser.AgeParser
Expand All @@ -48,7 +52,8 @@ type AGUnmarshaler struct {
func NewAGUnmarshaler() *AGUnmarshaler {
vcache := make(map[int64]interface{})

m := &AGUnmarshaler{ageParser: parser.NewAgeParser(nil),
m := &AGUnmarshaler{
ageParser: parser.NewAgeParser(nil),
visitor: &UnmarshalVisitor{vcache: vcache},
errListener: NewAGErrorListener(),
vcache: vcache,
Expand Down Expand Up @@ -106,6 +111,7 @@ func (el *AGErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSym
func (el *AGErrorListener) getErrs() []antlr.RecognitionException {
return el.errList
}

func (el *AGErrorListener) clearErrs() {
el.errList = []antlr.RecognitionException{}
}
Expand Down
1 change: 1 addition & 0 deletions drivers/golang/age/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
)

// AgeError wraps the cause and message of an error.
type AgeError struct {
cause error
msg string
Expand Down
20 changes: 16 additions & 4 deletions drivers/golang/age/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,29 @@ import (
"fmt"
"reflect"
"strings"

"github.com/antlr/antlr4/runtime/Go/antlr/v4"
"github.com/apache/age/drivers/golang/parser"
)

// AGMapper is a mapper for AGE result data.
type AGMapper struct {
AGUnmarshaler
}

// NewAGMapper creates a new AGMapper instance.
// typeMap is a map of label to reflect.Type. If typeMap is nil, the mapper will use the default type map.
func NewAGMapper(typeMap map[string]reflect.Type) *AGMapper {
vcache := make(map[int64]interface{})
if typeMap == nil {
typeMap = make(map[string]reflect.Type)
}
m := AGUnmarshaler{ageParser: parser.NewAgeParser(nil),
visitor: &MapperVisitor{UnmarshalVisitor: UnmarshalVisitor{vcache: vcache},
typeMap: typeMap},
m := AGUnmarshaler{
ageParser: parser.NewAgeParser(nil),
visitor: &MapperVisitor{
UnmarshalVisitor: UnmarshalVisitor{vcache: vcache},
typeMap: typeMap,
},
errListener: NewAGErrorListener(),
vcache: vcache,
}
Expand All @@ -48,10 +55,12 @@ func NewAGMapper(typeMap map[string]reflect.Type) *AGMapper {
return agm
}

// PutType puts a type into the mapper.
func (m *AGMapper) PutType(label string, tp reflect.Type) {
m.visitor.(*MapperVisitor).PutType(label, tp)
}

// MapperVisitor is a visitor for AGE result data.
type MapperVisitor struct {
UnmarshalVisitor
typeMap map[string]reflect.Type
Expand All @@ -66,6 +75,7 @@ func (v *MapperVisitor) VisitAgeout(ctx *parser.AgeoutContext) interface{} {
return rtn
}

// VisitChildren visits every child of the parse tree starting from the root.
func (v *MapperVisitor) VisitChildren(node antlr.RuleNode) interface{} {
var rtn interface{}
for _, c := range node.GetChildren() {
Expand All @@ -75,6 +85,7 @@ func (v *MapperVisitor) VisitChildren(node antlr.RuleNode) interface{} {
return rtn
}

// Visit a parse tree produced by AgeParser query.
func (v *MapperVisitor) VisitPath(ctx *parser.PathContext) interface{} {
entities := []interface{}{}

Expand All @@ -101,6 +112,7 @@ func (v *MapperVisitor) VisitPath(ctx *parser.PathContext) interface{} {
return path
}

// Visit a parse tree produced by parsing a vertex.
func (v *MapperVisitor) VisitVertex(ctx *parser.VertexContext) interface{} {
propCtx := ctx.Properties()
props := propCtx.Accept(v).(map[string]interface{})
Expand Down Expand Up @@ -172,7 +184,7 @@ func mapStruct(tp reflect.Type, properties map[string]interface{}) (interface{},
if field.Type().ConvertibleTo(val.Type()) {
field.Set(val)
} else {
return nil, fmt.Errorf("Property[%s] value[%v] type is not convertable to %v", k, v, field.Type())
return nil, fmt.Errorf("Property[%s] value[%v] type is not convertible to %v", k, v, field.Type())
}
}
}
Expand Down
46 changes: 34 additions & 12 deletions drivers/golang/age/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,38 @@ const (
G_ARR
)

var _TpV = reflect.TypeOf(&Vertex{})
var _TpE = reflect.TypeOf(&Edge{})
var _TpP = reflect.TypeOf(&Path{})
var _TpMP = reflect.TypeOf(&MapPath{})
var _TpStr = reflect.TypeOf(string(""))
var _TpInt = reflect.TypeOf(int64(0))
var _TpIntBig = reflect.TypeOf(big.NewInt(0))
var _TpFloat = reflect.TypeOf(float64(0))
var _TpFloatBig = reflect.TypeOf(big.NewFloat(0))
var _TpBool = reflect.TypeOf(bool(false))
var _TpMap = reflect.TypeOf(map[string]interface{}{})
var _TpArr = reflect.TypeOf([]interface{}{})
var (
_TpV = reflect.TypeOf(&Vertex{})
_TpE = reflect.TypeOf(&Edge{})
_TpP = reflect.TypeOf(&Path{})
_TpMP = reflect.TypeOf(&MapPath{})
_TpStr = reflect.TypeOf(string(""))
_TpInt = reflect.TypeOf(int64(0))
_TpIntBig = reflect.TypeOf(big.NewInt(0))
_TpFloat = reflect.TypeOf(float64(0))
_TpFloatBig = reflect.TypeOf(big.NewFloat(0))
_TpBool = reflect.TypeOf(bool(false))
_TpMap = reflect.TypeOf(map[string]interface{}{})
_TpArr = reflect.TypeOf([]interface{}{})
)

// Entity object interface for parsed AGE result data : Vertex, Edge, Path and SimpleEntity
type Entity interface {
GType() GTYPE
String() string
}

// Check if the given value is Entity object.
// An entity is assigned a set of properties,
// each of which are uniquely identified in the set by the irrespective property keys.
// See https://age.apache.org/age-manual/master/intro/types.html#simple-entities for more details.
func IsEntity(v interface{}) bool {
_, ok := v.(Entity)
return ok
}

// SimpleEntity is a simple entity object that has a single value.
// It is used to represent a simple value such as string, integer, float, boolean, null, map and array.
type SimpleEntity struct {
Entity
typ GTYPE
Expand Down Expand Up @@ -186,6 +194,8 @@ type Vertex struct {
*LabeledEntity
}

// NewVertex creates a new Vertex object with the given id, label and properties.
// See https://age.apache.org/age-manual/master/intro/types.html#vertex for more details.
func NewVertex(id int64, label string, props map[string]interface{}) *Vertex {
return &Vertex{newLabeledEntity(id, label, props)}
}
Expand All @@ -194,16 +204,23 @@ func (v *Vertex) GType() GTYPE {
return G_VERTEX
}

// String returns a formatted string containing the vertex id, label and properties.
func (v *Vertex) String() string {
return fmt.Sprintf("V{id:%d, label:%s, props:%v}", v.id, v.label, v.props)
}

// An edge is an entity that encodes a directed connection between exactly two nodes,
// the source node and the target node. An outgoing edge is a directed relationship
// from the point of view of its source node. An incoming edge is a directed relationship
// from the point of view of its target node. An edge is assigned exactly one edge type.
type Edge struct {
*LabeledEntity
start_id int64
end_id int64
}

// NewEdge creates a new Edge object with the given id, label, start vertex id, end vertex id and properties.
// See https://age.apache.org/age-manual/master/intro/types.html#edge for more details.
func NewEdge(id int64, label string, start int64, end int64, props map[string]interface{}) *Edge {
return &Edge{LabeledEntity: newLabeledEntity(id, label, props), start_id: start, end_id: end}
}
Expand All @@ -220,11 +237,14 @@ func (e *Edge) EndId() int64 {
return e.end_id
}

// String returns a formatted string containing the edge id, label, start vertex id, end vertex id and properties.
func (e *Edge) String() string {
return fmt.Sprintf("E{id:%d, label:%s, start:%d, end:%d, props:%v}",
e.id, e.label, e.start_id, e.end_id, e.props)
}

// A path is a series of alternating vertices and edges.
// A path must start with a vertex, and have at least one edge.
type Path struct {
Entity
entities []Entity
Expand All @@ -242,13 +262,15 @@ func (e *Path) Size() int {
return len(e.entities)
}

// Get returns the entity at the specified position in the specified path.
func (e *Path) Get(index int) Entity {
if index < 0 && index >= len(e.entities) {
panic(fmt.Errorf("Entity index[%d] is out of range (%d) ", index, len(e.entities)))
}
return e.entities[index]
}

// GetAsVertex casts the entity at the specified position in the specified path to Vertex.
func (e *Path) GetAsVertex(index int) *Vertex {
v := e.Get(index)

Expand Down
Loading