Class: Ashikawa::Core::Graph

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/ashikawa-core/graph.rb

Overview

Note:

All CRUD operations on related collections (edges and vertices) must be performed through their corresponding graph class. Not doing so will eventually lead to inconsistency and data corruption.

A certain graph in the database.

Constant Summary collapse

SPECIFIC_NEIGHBORS_AQL =

Prepared AQL statement for neighbors function on a specific edge collections

<<-AQL.gsub(/^[ \t]*/, '')
FOR n IN GRAPH_NEIGHBORS(@graph, { _key:@vertex_key }, {edgeCollectionRestriction: @edge_collection})
  RETURN n.vertex
AQL
ALL_NEIGHBORS_AQL =

Prepared AQL statement for neighbors function on ALL edge collections

<<-AQL.gsub(/^[ \t]*/, '')
FOR n IN GRAPH_NEIGHBORS(@graph, { _key:@vertex_key }, {})
  RETURN n.vertex
AQL

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(database, raw_graph) ⇒ Graph

Initialize a new graph instance

Parameters:

  • database (Database)

    A reference to the database this graph belongs to

  • raw_graph (Hash)

    The parsed JSON response from the database representing the graph


78
79
80
81
# File 'lib/ashikawa-core/graph.rb', line 78

def initialize(database, raw_graph)
  @database = database
  parse_raw_graph(raw_graph)
end

Instance Attribute Details

#databaseDatabase (readonly)

The database the Graph belongs to

Examples:

database = Ashikawa::Core::Database.new('http://localhost:8529')
raw_graph = {
  'name' => 'example_1',
  'edgeDefinitions' => [],
  'orphanCollections' => []
}
graph = Ashikawa::Core::Graph.new(database, raw_collection)
graph.database #=> #<Database: ...>

Returns:

  • (Database)

    The associated database


45
46
47
# File 'lib/ashikawa-core/graph.rb', line 45

def database
  @database
end

#edge_definitionsHash (readonly)

The edge definitions for this Graph

Returns:

  • (Hash)

    The edge definitons of this Graph as a simple data structure


72
73
74
# File 'lib/ashikawa-core/graph.rb', line 72

def edge_definitions
  @edge_definitions
end

#nameString (readonly)

The name of the graph

Examples:

database = Ashikawa::Core::Database.new('http://localhost:8529')
raw_graph = {
  'name' => 'example_1',
  'edgeDefinitions' => [],
  'orphanCollections' => []
}
graph = Ashikawa::Core::Graph.new(database, raw_collection)
graph.name #=> 'example_1

Returns:

  • (String)

    The name of the graph


60
61
62
# File 'lib/ashikawa-core/graph.rb', line 60

def name
  @name
end

#revisionString (readonly)

The revision of the Graph

Returns:

  • (String)

    The revision of the Graph


66
67
68
# File 'lib/ashikawa-core/graph.rb', line 66

def revision
  @revision
end

Instance Method Details

#add_edge_definition(collection_name, directions) ⇒ EdgeCollection

Adds an edge definition to this Graph

If the edge definition doesn't exist it will be created, else it will just return the edge collection.

Parameters:

  • collection_name (Symbol)

    The name of the resulting edge collection

  • directions (Hash)

    The specification between which vertices the edges should be created

  • [Array<Symbol>] (Hash)

    a customizable set of options

Returns:

See Also:

  • if you need to know the edge definition was already present

188
189
190
191
192
# File 'lib/ashikawa-core/graph.rb', line 188

def add_edge_definition(collection_name, directions)
  add_edge_definition!(collection_name, directions)
rescue Ashikawa::Core::EdgeCollectionAlreadyPresent
  edge_collection(collection_name)
end

#add_edge_definition!(collection_name, directions) ⇒ EdgeCollection

Adds an edge definition to this Graph

If the edge definition doesn't exist it will be created, else it will raise an error.

Parameters:

  • collection_name (Symbol)

    The name of the resulting edge collection

  • directions (Hash)

    The specification between which vertices the edges should be created

  • [Array<Symbol>] (Hash)

    a customizable set of options

Returns:

Raises:

  • Ashikawa::Core::EdgeCollectionAlreadyPresent if the edge definition is already defined

See Also:


205
206
207
208
209
210
211
212
213
214
215
# File 'lib/ashikawa-core/graph.rb', line 205

def add_edge_definition!(collection_name, directions)
  create_options = {
    collection: collection_name,
    from:       directions[:from],
    to:         directions[:to]
  }

  response = send_request("gharial/#@name/edge", post: create_options)
  parse_raw_graph(response['graph'])
  edge_collection(collection_name)
end

#add_vertex_collection(collection_name) ⇒ VertexCollection

Adds a vertex collection to this graph

If the collection does not yet exist it will be created. If it already exists it will just be added to the list of vertex collections.

Parameters:

  • collection_name (String)

    The name of the vertex collection

Returns:

See Also:


117
118
119
120
121
# File 'lib/ashikawa-core/graph.rb', line 117

def add_vertex_collection(collection_name)
  add_vertex_collection!(collection_name)
rescue Ashikawa::Core::VertexCollectionAlreadyPresent
  vertex_collection(collection_name)
end

#add_vertex_collection!(collection_name) ⇒ VertexCollection

Adds a vertex collection to this graph

If the collection does not exist yet it will be created. Initially it will add it as an orphaned collection to the graph. If the collection is already present in the graph definition, either as an orphan or as part of an edge definition an error is raised.

Parameters:

  • collection_name (String)

    The name of the vertex collection

Returns:

Raises:

See Also:


133
134
135
136
137
# File 'lib/ashikawa-core/graph.rb', line 133

def add_vertex_collection!(collection_name)
  response = send_request("gharial/#@name/vertex", post: { collection: collection_name })
  parse_raw_graph(response['graph'])
  vertex_collection(collection_name)
end

#delete(options = {}) ⇒ Object


83
84
85
86
# File 'lib/ashikawa-core/graph.rb', line 83

def delete(options = {})
  drop_collections = options.fetch(:drop_collections) { false }
  send_request("gharial/#@name", delete: { dropCollections: drop_collections })
end

#edge_collection(collection_name) ⇒ EdgeCollection

Fetches an edge collection from the database

Parameters:

  • collection_name (String)

    The name of the desired edge

Returns:


221
222
223
224
# File 'lib/ashikawa-core/graph.rb', line 221

def edge_collection(collection_name)
  response = send_request("collection/#{collection_name}")
  EdgeCollection.new(database, response, self)
end

#edge_collection_namesArray

The list of names of the edge collections

Returns:

  • (Array)

    Names of all edge collections


173
174
175
# File 'lib/ashikawa-core/graph.rb', line 173

def edge_collection_names
  @edge_definitions.map { |edge_def| edge_def['collection'] }
end

#edge_collectionsEnumerator

Gets a list of edge collections

Due to the fact we need to fetch each of the collections by hand this will just return an enumerator which will lazily fetch the collections from the database.

Returns:

  • (Enumerator)

    An Enumerator referencing the edge collections


162
163
164
165
166
167
168
# File 'lib/ashikawa-core/graph.rb', line 162

def edge_collections
  Enumerator.new do |yielder|
    edge_collection_names.each do |collection_name|
      yielder.yield edge_collection(collection_name)
    end
  end
end

#has_vertex_collection?(collection_name) ⇒ Boolean

Checks if a collection is present in the list of vertices

Parameters:

  • collection_name (String)

    The name of the collection to query

Returns:

  • (Boolean)

    True if the collection is present, false otherwise


152
153
154
# File 'lib/ashikawa-core/graph.rb', line 152

def has_vertex_collection?(collection_name)
  vertex_collection_names.any? { |name| name == collection_name }
end

#neighbors(vertex, options = {}) ⇒ Cursor

Return a Cursor representing the neighbors for the given document and optional edge collections

Parameters:

  • vertex (Document)

    The start vertex

  • options (options) (defaults to: {})

    Additional options like restrictions on the edge collections

  • [Array<Symbol>] (Hash)

    a customizable set of options

Returns:

  • (Cursor)

    The cursor to the query result


232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/ashikawa-core/graph.rb', line 232

def neighbors(vertex, options = {})
  bind_vars = {
    graph: name,
    vertex_key: vertex.key
  }
  aql_string = ALL_NEIGHBORS_AQL

  if options.has_key?(:edges)
    aql_string = SPECIFIC_NEIGHBORS_AQL
    bind_vars[:edge_collection] = [options[:edges]].flatten
  end

  database.query.execute(aql_string, bind_vars: bind_vars)
end

#vertex_collection(collection_name) ⇒ VertexCollection

Fetches a vertex collection associated with graph from the database

Parameters:

  • collection_name (String)

    The name of the collection

Returns:


143
144
145
146
# File 'lib/ashikawa-core/graph.rb', line 143

def vertex_collection(collection_name)
  raw_collection = send_request("collection/#{collection_name}")
  VertexCollection.new(database, raw_collection, self)
end

#vertex_collection_namesArray

The list of names of the vertex collections

Returns:

  • (Array)

    Names of all vertex collections


105
106
107
# File 'lib/ashikawa-core/graph.rb', line 105

def vertex_collection_names
  @orphan_collections | @edge_definitions.map { |edge_def| edge_def.values_at('from', 'to') }.flatten
end

#vertex_collectionsEnumerator

Gets a list of vertex collections

Due to the fact we need to fetch each of the collections by hand this will just return an enumerator which will lazily fetch the collections from the database.

Returns:

  • (Enumerator)

    An Enumerator referencing the vertex collections


94
95
96
97
98
99
100
# File 'lib/ashikawa-core/graph.rb', line 94

def vertex_collections
  Enumerator.new do |yielder|
    vertex_collection_names.each do |collection_name|
      yielder.yield vertex_collection(collection_name)
    end
  end
end