arcadedb 0.3.1 → 0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +57 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +25 -0
- data/Gemfile.lock +186 -0
- data/Guardfile +30 -0
- data/LICENSE +21 -0
- data/README.md +242 -0
- data/Rakefile +11 -0
- data/arcade.yml +23 -0
- data/arcadedb.gemspec +32 -0
- data/bin/+ +106 -0
- data/bin/console +126 -0
- data/examples/books.rb +139 -0
- data/examples/relation_1__1.rb +149 -0
- data/examples/relation_1__n.rb +56 -0
- data/examples/relation_n_n.rb +194 -0
- data/lib/arcade/api/operations.rb +257 -0
- data/lib/arcade/api/primitives.rb +98 -0
- data/lib/arcade/base.rb +454 -0
- data/lib/arcade/database.rb +367 -0
- data/lib/arcade/errors.rb +71 -0
- data/lib/arcade/logging.rb +38 -0
- data/lib/arcade/version.rb +3 -0
- data/lib/arcade.rb +36 -0
- data/lib/config.rb +72 -0
- data/lib/init.rb +50 -0
- data/lib/match.rb +216 -0
- data/lib/model/basicdocument.rb +7 -0
- data/lib/model/basicedge.rb +6 -0
- data/lib/model/basicvertex.rb +6 -0
- data/lib/model/document.rb +10 -0
- data/lib/model/edge.rb +47 -0
- data/lib/model/vertex.rb +238 -0
- data/lib/models.rb +6 -0
- data/lib/query.rb +384 -0
- data/lib/support/class.rb +13 -0
- data/lib/support/conversions.rb +295 -0
- data/lib/support/model.rb +87 -0
- data/lib/support/object.rb +20 -0
- data/lib/support/sql.rb +74 -0
- data/lib/support/string.rb +116 -0
- data/rails/arcade.rb +20 -0
- data/rails/config.yml +10 -0
- data/rails/connect.yml +17 -0
- data/rails.md +147 -0
- metadata +64 -5
data/lib/match.rb
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
#require 'active_support/inflector'
|
2
|
+
|
3
|
+
module Arcade
|
4
|
+
######################## MatchConnection ###############################
|
5
|
+
|
6
|
+
MatchAttributes = Struct.new(:edge, :direction, :as, :count, :where, :while, :max_depth , :depth_alias, :path_alias, :optional )
|
7
|
+
|
8
|
+
# where and while can be composed incremental
|
9
|
+
# direction, as, connect and edge cannot be changed after initialisation
|
10
|
+
class MatchConnection
|
11
|
+
include Support::Sql
|
12
|
+
|
13
|
+
def initialize edge= nil, direction: :both, as: nil, count: 1, **args
|
14
|
+
|
15
|
+
the_edge = edge.is_a?( Class ) ? edge.ref_name : edge.to_s unless edge.nil? || edge == E
|
16
|
+
@q = MatchAttributes.new the_edge , # class
|
17
|
+
direction, # may be :both, :in, :out
|
18
|
+
as, # a string
|
19
|
+
count, # a number
|
20
|
+
args[:where],
|
21
|
+
args[:while],
|
22
|
+
args[:max_depth],
|
23
|
+
args[:depth_alias], # not implemented
|
24
|
+
args[:path_alias], # not implemented
|
25
|
+
args[:optional] # not implemented
|
26
|
+
end
|
27
|
+
|
28
|
+
def direction= dir
|
29
|
+
@q[:direction] = dir
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def direction
|
34
|
+
fillup = @q[:edge].present? ? @q[:edge] : ''
|
35
|
+
case @q[:direction]
|
36
|
+
when :both
|
37
|
+
".both(#{fillup})"
|
38
|
+
when :in
|
39
|
+
".in(#{fillup})"
|
40
|
+
when :out
|
41
|
+
".out(#{fillup})"
|
42
|
+
when :both_vertex, :bothV
|
43
|
+
".bothV()"
|
44
|
+
when :out_vertex, :outV
|
45
|
+
".outV()"
|
46
|
+
when :in_vertex, :inV
|
47
|
+
".inV()"
|
48
|
+
when :both_edge, :bothE
|
49
|
+
".bothE(#{fillup})"
|
50
|
+
when :out_edge, :outE
|
51
|
+
".outE(#{fillup})"
|
52
|
+
when :in_edge, :outE
|
53
|
+
".inE(#{fillup})"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
def count c=nil
|
59
|
+
if c
|
60
|
+
@q[:count] = c
|
61
|
+
else
|
62
|
+
@q[:count]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def max_depth d=nil
|
67
|
+
if d.nil?
|
68
|
+
@q[:max_depth].present? ? "maxDepth: #{@q[:max_depth] }" : nil
|
69
|
+
else
|
70
|
+
@q[:max_depth] = d
|
71
|
+
end
|
72
|
+
end
|
73
|
+
def edge
|
74
|
+
@q[:edge]
|
75
|
+
end
|
76
|
+
|
77
|
+
def compose
|
78
|
+
where_statement =( where.nil? || where.size <5 ) ? nil : "where: ( #{ generate_sql_list( @q[:where] ) })"
|
79
|
+
while_statement =( while_s.nil? || while_s.size <5) ? nil : "while: ( #{ generate_sql_list( @q[:while] )})"
|
80
|
+
|
81
|
+
ministatement = "{"+ [ as, where_statement, while_statement, max_depth].compact.join(', ') + "}"
|
82
|
+
ministatement = "" if ministatement=="{}"
|
83
|
+
|
84
|
+
(1 .. count).map{|x| direction }.join("") + ministatement
|
85
|
+
|
86
|
+
end
|
87
|
+
alias :to_s :compose
|
88
|
+
|
89
|
+
end # class
|
90
|
+
|
91
|
+
|
92
|
+
######################## MatchStatement ################################
|
93
|
+
|
94
|
+
MatchSAttributes = Struct.new(:match_class, :as, :where )
|
95
|
+
class MatchStatement
|
96
|
+
include Support
|
97
|
+
def initialize match_class, as: 0, **args
|
98
|
+
reduce_class = ->(c){ c.is_a?(Class) ? c.ref_name : c.to_s }
|
99
|
+
|
100
|
+
@q = MatchSAttributes.new( reduce_class[match_class], # class
|
101
|
+
as.respond_to?(:zero?) && as.zero? ? reduce_class[match_class].pluralize : as ,
|
102
|
+
args[ :where ])
|
103
|
+
|
104
|
+
@query_stack = [ self ]
|
105
|
+
end
|
106
|
+
|
107
|
+
def match_alias
|
108
|
+
"as: #{@q[:as]}"
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
# used for the first compose-statement of a compose-query
|
114
|
+
def compose_simple
|
115
|
+
where_statement = where.is_a?(String) && where.size <3 ? nil : "where: ( #{ generate_sql_list( @q[:where] ) })"
|
116
|
+
'{'+ [ "class: #{@q[:match_class]}", as , where_statement].compact.join(', ') + '}'
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
def << connection
|
121
|
+
@query_stack << connection
|
122
|
+
self # return MatchStatement
|
123
|
+
end
|
124
|
+
#
|
125
|
+
def compile &b
|
126
|
+
"match " + @query_stack.map( &:to_s ).join + return_statement( &b )
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
# executes the standard-case.
|
131
|
+
# returns
|
132
|
+
# * as: :hash : an array of hashes
|
133
|
+
# * as: :array : an array of hash-values
|
134
|
+
# * as :flatten: a simple array of hash-values
|
135
|
+
#
|
136
|
+
# The optional block is used to customize the output.
|
137
|
+
# All previously defiend »as«-Statements are provided though the control variable.
|
138
|
+
#
|
139
|
+
# Background
|
140
|
+
# A match query "Match {class aaa, as: 'aa'} return aa "
|
141
|
+
#
|
142
|
+
# returns [ aa: { result of the query, a Vertex or a value-item }, aa: {}...}, ...] ]
|
143
|
+
# (The standard case)
|
144
|
+
#
|
145
|
+
# A match query "Match {class aaa, as: 'aa'} return aa.name "
|
146
|
+
# returns [ aa.name: { name }, aa.name: { name }., ...] ]
|
147
|
+
#
|
148
|
+
# Now, execute( as: :flatten){ "aa.name" } returns
|
149
|
+
# [name1, name2 ,. ...]
|
150
|
+
#
|
151
|
+
#
|
152
|
+
# Return statements (examples from https://orientdb.org/docs/3.0.x/sql/SQL-Match.html)
|
153
|
+
# "person.name as name, friendship.since as since, friend.name as friend"
|
154
|
+
#
|
155
|
+
# " person.name + \" is a friend of \" + friend.name as friends"
|
156
|
+
#
|
157
|
+
# "$matches"
|
158
|
+
# "$elements"
|
159
|
+
# "$paths"
|
160
|
+
# "$pathElements"
|
161
|
+
#
|
162
|
+
#
|
163
|
+
def execute as: :hash, &b
|
164
|
+
r = V.db.execute{ compile &b }
|
165
|
+
case as
|
166
|
+
when :hash
|
167
|
+
r
|
168
|
+
when :array
|
169
|
+
r.map{|y| y.values}
|
170
|
+
when :flatten
|
171
|
+
r.map{|y| y.values}.orient_flatten
|
172
|
+
else
|
173
|
+
raise ArgumentError, "Specify parameter «as:» with :hash, :array, :flatten"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
# def compose
|
177
|
+
#
|
178
|
+
# '{'+ [ "class: #{@q[:match_class]}",
|
179
|
+
# "as: #{@as}" , where, while_s,
|
180
|
+
# @maxdepth >0 ? "maxdepth: #{maxdepth}": nil ].compact.join(', ')+'}'
|
181
|
+
# end
|
182
|
+
|
183
|
+
alias :to_s :compose_simple
|
184
|
+
|
185
|
+
|
186
|
+
## return_statement
|
187
|
+
#
|
188
|
+
# summarizes defined as-statements ready to be included as last parameter
|
189
|
+
# in the match-statement-stack
|
190
|
+
#
|
191
|
+
# They can be modified through a block.
|
192
|
+
#
|
193
|
+
# i.e
|
194
|
+
#
|
195
|
+
# t= TestQuery.match( where: {a: 9, b: 's'}, as: nil ) << E.connect("<-", as: :test)
|
196
|
+
# t.return_statement{|y| "#{y.last}.name"}
|
197
|
+
#
|
198
|
+
# =>> " return test.name"
|
199
|
+
#
|
200
|
+
#return_statement is always called through compile
|
201
|
+
#
|
202
|
+
# t.compile{|y| "#{y.last}.name"}
|
203
|
+
|
204
|
+
private
|
205
|
+
def return_statement
|
206
|
+
resolve_as = ->{ @query_stack.map{|s| s.as.split(':').last unless s.as.nil? }.compact }
|
207
|
+
" return " + statement = if block_given?
|
208
|
+
a= yield resolve_as[]
|
209
|
+
a.is_a?(Array) ? a.join(', ') : a
|
210
|
+
else
|
211
|
+
resolve_as[].join(', ')
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end # class
|
215
|
+
|
216
|
+
end # module
|
data/lib/model/edge.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Arcade
|
2
|
+
class Edge < Base
|
3
|
+
# schema schema.strict # -- throws an error if specified keys are missing
|
4
|
+
attribute :in, Types::Rid
|
5
|
+
attribute :out, Types::Rid
|
6
|
+
|
7
|
+
def accepted_methods
|
8
|
+
super + [ :vertices, :in, :out, :inV, :outV ]
|
9
|
+
end
|
10
|
+
#
|
11
|
+
# Add Contrains to the edge
|
12
|
+
# CREATE INDEX Watched_out_in ON <edge type« (`@out`, `@in`) UNIQUE
|
13
|
+
#
|
14
|
+
def self.create from:, to:, **attr
|
15
|
+
db.create_edge database_name, from: from, to: to, **attr
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete
|
19
|
+
db.execute{ "delete edge #{ rid }" }.select_result
|
20
|
+
end
|
21
|
+
## gets the adjacent Vertex
|
22
|
+
def inV
|
23
|
+
query( projection: "inV()").query.select_result
|
24
|
+
end
|
25
|
+
def outV
|
26
|
+
query( projection: "outV()").query.select_result
|
27
|
+
end
|
28
|
+
def vertices in_or_out = nil
|
29
|
+
case in_or_out
|
30
|
+
when :in
|
31
|
+
inV
|
32
|
+
when :out
|
33
|
+
outV
|
34
|
+
else
|
35
|
+
[inV, outV]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
alias bothV vertices
|
40
|
+
|
41
|
+
|
42
|
+
def to_human
|
43
|
+
"<#{self.class.to_s.snake_case}[#{rid}] :.: #{ out }->#{invariant_attributes}->#{ attributes[:in] }>"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
data/lib/model/vertex.rb
ADDED
@@ -0,0 +1,238 @@
|
|
1
|
+
module Arcade
|
2
|
+
class Vertex < Base
|
3
|
+
|
4
|
+
# include Arcade::Support::Sql
|
5
|
+
include Arcade::Support::Model # instance methods
|
6
|
+
extend Arcade::Support::Model # class methods
|
7
|
+
|
8
|
+
attribute :in?, Types::Nominal::Any
|
9
|
+
attribute :out?, Types::Nominal::Any
|
10
|
+
# #
|
11
|
+
def accepted_methods
|
12
|
+
super + [ :in, :out, :both, :edges, :inE, :outE, :bothE, :assign]
|
13
|
+
end
|
14
|
+
## ----------------------------------------- Class Methods------------------------------------ ##
|
15
|
+
# #
|
16
|
+
=begin
|
17
|
+
Vertex.delete fires a "delete vertex" command to the database.
|
18
|
+
|
19
|
+
To remove all records use »all: true« as argument
|
20
|
+
|
21
|
+
To remove a specific rid, use rid: "#nn:mmm" as argument
|
22
|
+
|
23
|
+
"where" parameter is optional
|
24
|
+
|
25
|
+
ExtraNode.delete where: { item: 67 } == ExtraNode.delete item: 67
|
26
|
+
|
27
|
+
=end
|
28
|
+
def self.delete where: {} , **args
|
29
|
+
if args[:all] == true
|
30
|
+
where = {}
|
31
|
+
elsif args[:rid].present?
|
32
|
+
return db.execute { "delete vertex #{args[:rid]}" }.first["count"]
|
33
|
+
else
|
34
|
+
where.merge!(args) if where.is_a?(Hash)
|
35
|
+
return 0 if where.empty?
|
36
|
+
end
|
37
|
+
# query returns [{count => n }]
|
38
|
+
db.execute { "delete vertex #{database_name} #{compose_where(where)}" } &.first[:count] rescue 0
|
39
|
+
end
|
40
|
+
|
41
|
+
=begin
|
42
|
+
Creates a Vertex-Instance.
|
43
|
+
Similar to `Vertex#insert`.
|
44
|
+
|
45
|
+
Difference is the presence of a `created` property, a timestamp set to the time and date of creation.
|
46
|
+
=end
|
47
|
+
|
48
|
+
def self.create timestamp: true, **args
|
49
|
+
#t= timestamp ? ", created = Date(#{DateTime.now.to_i}) " : ""
|
50
|
+
t= timestamp ? ", created = sysdate() " : ""
|
51
|
+
db.execute { "create VERTEX #{database_name} set #{args.map{|x,y| [x,y.to_or].join("=")}.join(', ')+t}" } &.first.allocate_model(false)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
## get adjacent nodes based on a query on the actual model
|
56
|
+
|
57
|
+
|
58
|
+
def self.nodes in_or_out = :both, via: nil , **args
|
59
|
+
|
60
|
+
s = Query.new from: self
|
61
|
+
s.nodes in_or_out, via: via, **args
|
62
|
+
s.query &.select_result
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# #
|
67
|
+
## --------------------------------- Instance Methods --------------------------------- ##
|
68
|
+
#
|
69
|
+
# We need expand as fallback if a vertex, which is stored as link, is automatically loaded
|
70
|
+
#
|
71
|
+
def expand
|
72
|
+
self
|
73
|
+
end
|
74
|
+
# Supports where: --> Strategie.first nodes where: {size: 10}
|
75
|
+
# "select both()[ size = 10 ] from #113:8 "
|
76
|
+
def nodes in_or_out=:both, depth= 1, via: nil , execute: true, **args
|
77
|
+
s = Query.new from: rid
|
78
|
+
s.nodes in_or_out, via: via, **args
|
79
|
+
if execute
|
80
|
+
s.query &.select_result
|
81
|
+
else
|
82
|
+
s # just return the query
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Supports where: { where condition for edges }
|
87
|
+
def edges in_or_out = :both, depth= 1, via: nil , execute: true, **args
|
88
|
+
in_or_out = in_or_out.to_s + "E"
|
89
|
+
nodes in_or_out, depth, via: via , execute: execute, **args
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# get Vertices through in by edges of type via
|
94
|
+
def in count=0, via:nil
|
95
|
+
if count.zero?
|
96
|
+
@bufferedin ||= nodes :in, 1, via: via
|
97
|
+
else
|
98
|
+
nodes :in, count, via: via # not cached
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# get Vertices through out by edges of type via
|
103
|
+
def out count=0, via:nil
|
104
|
+
if count.zero?
|
105
|
+
@bufferedout ||= nodes :out, 1, via: via
|
106
|
+
else
|
107
|
+
nodes :out, count, via: via # not cached
|
108
|
+
end
|
109
|
+
end
|
110
|
+
#
|
111
|
+
# get all Vertices connected by edges of type via
|
112
|
+
def both count=0, via:nil
|
113
|
+
if count.zero?
|
114
|
+
@bufferedboth ||= nodes :both, 1, via: via
|
115
|
+
else
|
116
|
+
nodes :both, count, via: via # not cached
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
# get via-type-edges through in
|
122
|
+
def inE count=1, via:nil
|
123
|
+
nodes :inE, count, via: via
|
124
|
+
end
|
125
|
+
#
|
126
|
+
# get via-type-edges through out
|
127
|
+
def outE count=1, via:nil
|
128
|
+
nodes :outE, count, via: via
|
129
|
+
end
|
130
|
+
|
131
|
+
# get all via-type-edges
|
132
|
+
def bothE count=1, via:nil
|
133
|
+
nodes :bothE, count, via: via
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
# Returns a collection of all vertices passed during the traversal
|
138
|
+
#
|
139
|
+
# Includes the start_vertex (start_at =0 by default)
|
140
|
+
#
|
141
|
+
# If the vector should not include the start_vertex, call with `start_at: 1` and increase the depth by 1
|
142
|
+
#
|
143
|
+
# fires a query
|
144
|
+
#
|
145
|
+
# select from ( traverse outE('}#{via}').in from #{vertex} while $depth < #{depth} )
|
146
|
+
# where $depth >= #{start_at}
|
147
|
+
#
|
148
|
+
# If » execute: false « is specified, the traverse-statement is returned (as Arcade::Query object)
|
149
|
+
#
|
150
|
+
# Multiple Edges can be specifies in the via-parameter (use Array-notation)
|
151
|
+
# e.i.
|
152
|
+
# traverse( :in, via: [TG::DateOf, Arcade::HasOrder], depth: 4, start_at: 1 ).map(&:w).reverse
|
153
|
+
#
|
154
|
+
def traverse in_or_out = :out, via: nil, depth: 1, execute: true, start_at: 0, where: nil
|
155
|
+
|
156
|
+
the_query = query kind: 'traverse'
|
157
|
+
the_query.projection in_or_out.to_s + "(" + resolve_edge_name(*via) + ")"
|
158
|
+
the_query.where where if where.present?
|
159
|
+
the_query.while "$depth < #{depth} " unless depth <=0
|
160
|
+
outer_query = Query.new from: the_query, where: "$depth >= #{start_at}"
|
161
|
+
if execute
|
162
|
+
outer_query.execute.allocate_model
|
163
|
+
else
|
164
|
+
# the_query.from self # complete the query by assigning self
|
165
|
+
the_query # returns the Query -traverse object
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
=begin
|
170
|
+
Assigns another Vertex via an EdgeClass. If specified, puts attributes on the edge.
|
171
|
+
|
172
|
+
Returns the reloaded assigned vertex
|
173
|
+
|
174
|
+
Wrapper for
|
175
|
+
Edge.create in: self, out: a_vertex, some: attributes. on: the, edge: type }
|
176
|
+
|
177
|
+
returns the assigned vertex, thus enabling to chain vertices through
|
178
|
+
|
179
|
+
Vertex.assign() via: E , vertex: VertexClass.create()).assign( via: E, ... )
|
180
|
+
or
|
181
|
+
(1..100).each{|n| vertex = vertex.assign(via: E2, vertex: V2.create(item: n))}
|
182
|
+
=end
|
183
|
+
|
184
|
+
def assign vertex: , via: , **attributes
|
185
|
+
|
186
|
+
via.create from: self, to: vertex, **attributes
|
187
|
+
|
188
|
+
db.get vertex.rid # return the assigned vertex
|
189
|
+
rescue IndexError => e
|
190
|
+
db.logger.error "Edge not created, already present."
|
191
|
+
vertex # return the vertex (for chaining)
|
192
|
+
rescue ArgumentError => e
|
193
|
+
db.logger.error "ArgumentError: #{e.message}"
|
194
|
+
nil
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
def remove
|
199
|
+
db.execute{ "delete vertex #{rid}" }
|
200
|
+
end
|
201
|
+
=begin
|
202
|
+
Human readable representation of Vertices
|
203
|
+
|
204
|
+
Format: < Classname: Edges, Attributes >
|
205
|
+
=end
|
206
|
+
def to_human
|
207
|
+
|
208
|
+
in_and_out = -> { "{#{self.in.count}->}{->#{self.out.count }}, " }
|
209
|
+
|
210
|
+
#Default presentation of Arcade::Base::Model-Objects
|
211
|
+
|
212
|
+
"<#{self.class.to_s.snake_case}[#{rid}]:" +
|
213
|
+
in_and_out[] +
|
214
|
+
invariant_attributes.map do |attr, value|
|
215
|
+
v= case value
|
216
|
+
when Class
|
217
|
+
"< #{self.class.to_s.snake_case}: #{value.rid} >"
|
218
|
+
when Array
|
219
|
+
value.to_s
|
220
|
+
else
|
221
|
+
value.from_db
|
222
|
+
end
|
223
|
+
"%s: %s" % [ attr, v] unless v.nil?
|
224
|
+
end.compact.sort.join(', ') + ">".gsub('"' , ' ')
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
def refresh
|
229
|
+
# force reloading of edges and nodes
|
230
|
+
# edges are not cached (now)
|
231
|
+
@bufferedin, @bufferedout, @bufferedboth = nil
|
232
|
+
super
|
233
|
+
end
|
234
|
+
# expose class method to instances (as private)
|
235
|
+
# private define_method :resolve_edge_name, &method(:resolve_edge_name)
|
236
|
+
# private_class_method :resolve_edge_name
|
237
|
+
end
|
238
|
+
end
|
data/lib/models.rb
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
require_relative "../lib/model/document.rb"
|
2
|
+
require_relative "../lib/model/vertex.rb"
|
3
|
+
require_relative "../lib/model/edge.rb"
|
4
|
+
require_relative "../lib/model/basicvertex.rb"
|
5
|
+
require_relative "../lib/model/basicdocument.rb"
|
6
|
+
require_relative "../lib/model/basicedge.rb"
|