You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.4 KiB
239 lines
7.4 KiB
//
|
|
// DISCLAIMER
|
|
//
|
|
// Copyright 2017 ArangoDB GmbH, Cologne, Germany
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
//
|
|
// Author Ewout Prangsma
|
|
//
|
|
|
|
package driver
|
|
|
|
import (
|
|
"context"
|
|
"path"
|
|
)
|
|
|
|
type graphDefinition struct {
|
|
Name string `json:"name"`
|
|
IsSmart bool `json:"isSmart"`
|
|
IsSatellite bool `json:"isSatellite"`
|
|
IsDisjoint bool `json:"isDisjoint,omitempty"`
|
|
|
|
EdgeDefinitions []EdgeDefinition `json:"edgeDefinitions,omitempty"`
|
|
|
|
NumberOfShards int `json:"numberOfShards,omitempty"`
|
|
OrphanCollections []string `json:"orphanCollections,omitempty"`
|
|
|
|
// Deprecated: use 'WriteConcern' instead.
|
|
MinReplicationFactor int `json:"minReplicationFactor,omitempty"`
|
|
WriteConcern int `json:"writeConcern,omitempty"`
|
|
|
|
// ReplicationFactor is the number of replication factor that is used for every collection within this graph.
|
|
// Cannot be modified later.
|
|
ReplicationFactor graphReplicationFactor `json:"replicationFactor,omitempty"`
|
|
|
|
// This field must be set to the attribute that will be used for sharding or smart graphs.
|
|
// All vertices are required to have this attribute set. Edges derive the attribute from their connected vertices.
|
|
// This requires ArangoDB Enterprise Edition.
|
|
SmartGraphAttribute string `json:"smartGraphAttribute,omitempty"`
|
|
|
|
Initial *string `json:"initial,omitempty"`
|
|
InitialCid int `json:"initialCid,omitempty"`
|
|
ID string `json:"_id"`
|
|
Key DocumentID `json:"_key"`
|
|
Rev string `json:"_rev"`
|
|
}
|
|
|
|
type getGraphResponse struct {
|
|
Graph graphDefinition `json:"graph"`
|
|
ArangoError
|
|
}
|
|
|
|
// EdgeCollection opens a connection to an existing edge-collection within the graph.
|
|
// If no edge-collection with given name exists, an NotFoundError is returned.
|
|
func (g *graph) EdgeCollection(ctx context.Context, name string) (Collection, VertexConstraints, error) {
|
|
req, err := g.conn.NewRequest("GET", g.relPath())
|
|
if err != nil {
|
|
return nil, VertexConstraints{}, WithStack(err)
|
|
}
|
|
resp, err := g.conn.Do(ctx, req)
|
|
if err != nil {
|
|
return nil, VertexConstraints{}, WithStack(err)
|
|
}
|
|
if err := resp.CheckStatus(200); err != nil {
|
|
return nil, VertexConstraints{}, WithStack(err)
|
|
}
|
|
var data getGraphResponse
|
|
if err := resp.ParseBody("", &data); err != nil {
|
|
return nil, VertexConstraints{}, WithStack(err)
|
|
}
|
|
for _, n := range data.Graph.EdgeDefinitions {
|
|
if n.Collection == name {
|
|
ec, err := newEdgeCollection(name, g)
|
|
if err != nil {
|
|
return nil, VertexConstraints{}, WithStack(err)
|
|
}
|
|
constraints := VertexConstraints{
|
|
From: n.From,
|
|
To: n.To,
|
|
}
|
|
return ec, constraints, nil
|
|
}
|
|
}
|
|
return nil, VertexConstraints{}, WithStack(newArangoError(404, 0, "not found"))
|
|
}
|
|
|
|
// EdgeCollectionExists returns true if an edge-collection with given name exists within the graph.
|
|
func (g *graph) EdgeCollectionExists(ctx context.Context, name string) (bool, error) {
|
|
req, err := g.conn.NewRequest("GET", g.relPath())
|
|
if err != nil {
|
|
return false, WithStack(err)
|
|
}
|
|
resp, err := g.conn.Do(ctx, req)
|
|
if err != nil {
|
|
return false, WithStack(err)
|
|
}
|
|
if err := resp.CheckStatus(200); err != nil {
|
|
return false, WithStack(err)
|
|
}
|
|
var data getGraphResponse
|
|
if err := resp.ParseBody("", &data); err != nil {
|
|
return false, WithStack(err)
|
|
}
|
|
for _, n := range data.Graph.EdgeDefinitions {
|
|
if n.Collection == name {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
// EdgeCollections returns all edge collections of this graph
|
|
func (g *graph) EdgeCollections(ctx context.Context) ([]Collection, []VertexConstraints, error) {
|
|
req, err := g.conn.NewRequest("GET", g.relPath())
|
|
if err != nil {
|
|
return nil, nil, WithStack(err)
|
|
}
|
|
resp, err := g.conn.Do(ctx, req)
|
|
if err != nil {
|
|
return nil, nil, WithStack(err)
|
|
}
|
|
if err := resp.CheckStatus(200); err != nil {
|
|
return nil, nil, WithStack(err)
|
|
}
|
|
var data getGraphResponse
|
|
if err := resp.ParseBody("", &data); err != nil {
|
|
return nil, nil, WithStack(err)
|
|
}
|
|
result := make([]Collection, 0, len(data.Graph.EdgeDefinitions))
|
|
constraints := make([]VertexConstraints, 0, len(data.Graph.EdgeDefinitions))
|
|
for _, n := range data.Graph.EdgeDefinitions {
|
|
ec, err := newEdgeCollection(n.Collection, g)
|
|
if err != nil {
|
|
return nil, nil, WithStack(err)
|
|
}
|
|
result = append(result, ec)
|
|
constraints = append(constraints, VertexConstraints{
|
|
From: n.From,
|
|
To: n.To,
|
|
})
|
|
}
|
|
return result, constraints, nil
|
|
}
|
|
|
|
// collection: The name of the edge collection to be used.
|
|
// from: contains the names of one or more vertex collections that can contain source vertices.
|
|
// to: contains the names of one or more edge collections that can contain target vertices.
|
|
func (g *graph) CreateEdgeCollection(ctx context.Context, collection string, constraints VertexConstraints) (Collection, error) {
|
|
req, err := g.conn.NewRequest("POST", path.Join(g.relPath(), "edge"))
|
|
if err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
input := EdgeDefinition{
|
|
Collection: collection,
|
|
From: constraints.From,
|
|
To: constraints.To,
|
|
}
|
|
if _, err := req.SetBody(input); err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
resp, err := g.conn.Do(ctx, req)
|
|
if err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
if err := resp.CheckStatus(201, 202); err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
ec, err := newEdgeCollection(collection, g)
|
|
if err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
return ec, nil
|
|
}
|
|
|
|
// CreateEdgeCollectionWithOptions creates an edge collection in the graph with additional options
|
|
func (g *graph) CreateEdgeCollectionWithOptions(ctx context.Context, collection string, constraints VertexConstraints, options CreateEdgeCollectionOptions) (Collection, error) {
|
|
req, err := g.conn.NewRequest("POST", path.Join(g.relPath(), "edge"))
|
|
if err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
input := EdgeDefinition{
|
|
Collection: collection,
|
|
From: constraints.From,
|
|
To: constraints.To,
|
|
Options: options,
|
|
}
|
|
if _, err := req.SetBody(input); err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
resp, err := g.conn.Do(ctx, req)
|
|
if err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
if err := resp.CheckStatus(201, 202); err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
ec, err := newEdgeCollection(collection, g)
|
|
if err != nil {
|
|
return nil, WithStack(err)
|
|
}
|
|
return ec, nil
|
|
}
|
|
|
|
// SetVertexConstraints modifies the vertex constraints of an existing edge collection in the graph.
|
|
func (g *graph) SetVertexConstraints(ctx context.Context, collection string, constraints VertexConstraints) error {
|
|
req, err := g.conn.NewRequest("PUT", path.Join(g.relPath(), "edge", collection))
|
|
if err != nil {
|
|
return WithStack(err)
|
|
}
|
|
input := EdgeDefinition{
|
|
Collection: collection,
|
|
From: constraints.From,
|
|
To: constraints.To,
|
|
}
|
|
if _, err := req.SetBody(input); err != nil {
|
|
return WithStack(err)
|
|
}
|
|
resp, err := g.conn.Do(ctx, req)
|
|
if err != nil {
|
|
return WithStack(err)
|
|
}
|
|
if err := resp.CheckStatus(201, 202); err != nil {
|
|
return WithStack(err)
|
|
}
|
|
return nil
|
|
}
|
|
|