arcadedb 0.3.3 → 0.5.0

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.
data/lib/model/vertex.rb CHANGED
@@ -13,45 +13,46 @@ module Arcade
13
13
  end
14
14
  ## ----------------------------------------- Class Methods------------------------------------ ##
15
15
  # #
16
+
16
17
  =begin
17
- Vertex.delete fires a "delete vertex" command to the database.
18
+ Creates a Vertex-Instance.
19
+ Similar to `Vertex#insert`.
18
20
 
19
- To remove all records use »all: true« as argument
21
+ Difference is the presence of a `created` property, a timestamp set to the time and date of creation.
22
+ =end
23
+
24
+ def self.create timestamp: true, **args
25
+ #t= timestamp ? ", created = Date(#{DateTime.now.to_i}) " : ""
26
+ t= timestamp ? ", created = sysdate() " : ""
27
+ # db.transmit { "create VERTEX #{database_name} set #{args.map{|x,y| [x,y.to_or].join("=")}.join(', ')+t}" } &.first.allocate_model(false)
28
+ Api.create_document db.database, database_name, session_id: db.session, **args
29
+ end
20
30
 
21
- To remove a specific rid, use rid: "#nn:mmm" as argument
22
31
 
23
- "where" parameter is optional
32
+ =begin
33
+ Vertex.delete fires a "delete vertex" command to the database.
34
+ To remove all records use »all: true« as argument
35
+ To remove a specific rid, use rid: "#nn:mmm" as argument
24
36
 
25
- ExtraNode.delete where: { item: 67 } == ExtraNode.delete item: 67
37
+ The "where" parameter is optional
26
38
 
39
+ Example:
40
+ ExtraNode.delete where: { item: 67 } == ExtraNode.delete item: 67
27
41
  =end
28
42
  def self.delete where: {} , **args
29
43
  if args[:all] == true
30
44
  where = {}
31
45
  elsif args[:rid].present?
32
- return db.execute { "delete vertex #{args[:rid]}" }.first["count"]
46
+ return db.transmit { "delete from #{args[:rid]}" }.first["count"]
33
47
  else
34
48
  where.merge!(args) if where.is_a?(Hash)
35
49
  return 0 if where.empty?
36
50
  end
37
51
  # query returns [{count => n }]
38
- db.execute { "delete vertex #{database_name} #{compose_where(where)}" } &.first[:count] rescue 0
52
+ # puts "delete from #{database_name} #{compose_where(where)}"
53
+ db.transmit { "delete from `#{database_name}` #{compose_where(where)}" } &.first[:count] rescue 0
39
54
  end
40
55
 
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
56
  ## get adjacent nodes based on a query on the actual model
56
57
 
57
58
 
@@ -59,34 +60,53 @@ module Arcade
59
60
 
60
61
  s = Query.new from: self
61
62
  s.nodes in_or_out, via: via, **args
62
- s.query.select_result
63
+ s.query &.select_result
63
64
  end
64
65
 
65
66
 
66
67
  # #
67
68
  ## --------------------------------- Instance Methods --------------------------------- ##
68
69
  #
69
- # We need expand as fallback if a vertex, which is stored as link is automatically loaded
70
+ # We need expand as fallback if a vertex, which is stored as link, is automatically loaded
70
71
  #
71
72
  def expand
72
73
  self
73
74
  end
74
- # Supports where: --> Strategie.first nodes where: {size: 10}
75
- # "select both()[ size = 10 ] from #113:8 "
75
+ # --------------------------------- Nodes ----------------------------------------------- #
76
+ # fetches adjacet nodes
77
+ # supported
78
+ # nodes in_or_out = :in, :out, :both, :inE, :outE
79
+ # depth = fetch the n'th node through travese
80
+ # via: = Arcade Database Type (the ruby class)
81
+ # where: = a condition
82
+ # inE, outE --> matches attributes on the edge
83
+ # in, out, both -> matches attributes on the adjacent vertex
84
+ # Example Strategie.first nodes where: {size: 10}
85
+ # "select both()[ size = 10 ] from #113:8 "
86
+ #
76
87
  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
88
+ if depth <= 1
89
+ s= query.nodes in_or_out, via: via, **args
90
+ execute ? s.query &.select_result : s
91
+ else
92
+ travese in_or_out, depth: depth, start_at: depth-1, via: via, execute: execute, where: args[:where]
93
+ end
84
94
  end
85
95
 
86
96
  # 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
97
+ def edges in_or_out = :both, depth= 1, via: nil , execute: true
98
+
99
+ v = in_or_out.to_s.delete_suffix 'E'
100
+ e = v + 'E'
101
+ edge_name = via.nil? ? "" : resolve_edge_name( via )
102
+ argument = "#{e}(#{edge_name})"
103
+ q= if depth > 1
104
+ repeated_argument = Array.new(depth -1 , "#{v}(#{edge_name})").join(".")
105
+ query.projection repeated_argument + "." + argument
106
+ else
107
+ query.projection argument
108
+ end
109
+ execute ? q.execute &.allocate_model : q
90
110
  end
91
111
 
92
112
 
@@ -120,17 +140,17 @@ module Arcade
120
140
 
121
141
  # get via-type-edges through in
122
142
  def inE count=1, via:nil
123
- nodes :inE, count, via: via
143
+ edges :in, count, via: via
124
144
  end
125
145
  #
126
146
  # get via-type-edges through out
127
147
  def outE count=1, via:nil
128
- nodes :outE, count, via: via
148
+ edges :out, count, via: via
129
149
  end
130
150
 
131
151
  # get all via-type-edges
132
152
  def bothE count=1, via:nil
133
- nodes :bothE, count, via: via
153
+ edges :both, count, via: via
134
154
  end
135
155
 
136
156
 
@@ -158,34 +178,33 @@ module Arcade
158
178
  the_query.where where if where.present?
159
179
  the_query.while "$depth < #{depth} " unless depth <=0
160
180
  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
181
+ execute ? outer_query.execute.allocate_model : the_query # return only the traverse part
167
182
  end
168
183
 
169
184
  =begin
170
185
  Assigns another Vertex via an EdgeClass. If specified, puts attributes on the edge.
171
186
 
187
+ `Vertex.assign via: Edge to: Vertex`
188
+
172
189
  Returns the reloaded assigned vertex
173
190
 
174
191
  Wrapper for
175
- Edge.create in: self, out: a_vertex, some: attributes. on: the, edge: type }
192
+ Edge.create from: self, to: a_vertex, some: attributes. on: the, edge: type }
176
193
 
177
194
  returns the assigned vertex, thus enabling to chain vertices through
178
195
 
179
- Vertex.assign() via: E , vertex: VertexClass.create()).assign( via: E, ... )
196
+ Vertex.assign() via: E , to: VertexClass.create()).assign( via: E, ... )
180
197
  or
181
198
  (1..100).each{|n| vertex = vertex.assign(via: E2, vertex: V2.create(item: n))}
182
199
  =end
183
200
 
184
- def assign vertex: , via: , **attributes
201
+ def assign vertex: nil , via: Arcade::Edge , **attributes
202
+ vertex = attributes[:to] if attributes.has_key? :to
203
+ raise "vertex not provided" if vertex.nil?
185
204
 
186
205
  via.create from: self, to: vertex, **attributes
187
206
 
188
- db.get vertex.rid # return the assigned vertex
207
+ db.get vertex.rid unless vertex.is_a? Array # return the assigned vertex
189
208
  rescue IndexError => e
190
209
  db.logger.error "Edge not created, already present."
191
210
  vertex # return the vertex (for chaining)
@@ -205,12 +224,12 @@ Format: < Classname: Edges, Attributes >
205
224
  =end
206
225
  def to_human
207
226
 
208
- in_and_out = -> { "{#{self.in.count}->}{->#{self.out.count }}, " }
227
+ in_and_out = "{#{inE.count}->}{->#{outE.count }}, "
209
228
 
210
229
  #Default presentation of Arcade::Base::Model-Objects
211
230
 
212
- "<#{self.class.to_s.snake_case}[#{rid}]: " +
213
- in_and_out[] +
231
+ "<#{self.class.to_s.snake_case}[#{rid}]:" +
232
+ in_and_out +
214
233
  invariant_attributes.map do |attr, value|
215
234
  v= case value
216
235
  when Class
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arcadedb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hartmut Bischoff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-23 00:00:00.000000000 Z
11
+ date: 2023-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: typhoeus
56
+ name: httpx
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: dry-configurable
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Provides access to ArcadeDB from ruby
112
126
  email: topofocus@gmail.com
113
127
  executables: []
@@ -130,17 +144,27 @@ files:
130
144
  - examples/relation_1__1.rb
131
145
  - examples/relation_1__n.rb
132
146
  - examples/relation_n_n.rb
147
+ - iruby/.ipynb_checkpoints/01-start-and-end-of-datarows-checkpoint.ipynb
148
+ - iruby/01-start-and-end-of-datarows.ipynb
149
+ - iruby/db-console.rb
133
150
  - lib/arcade.rb
134
151
  - lib/arcade/api/operations.rb
135
- - lib/arcade/api/version.rb
152
+ - lib/arcade/api/primitives.rb
136
153
  - lib/arcade/base.rb
154
+ - lib/arcade/config.rb
137
155
  - lib/arcade/database.rb
138
156
  - lib/arcade/errors.rb
157
+ - lib/arcade/init.rb
139
158
  - lib/arcade/logging.rb
159
+ - lib/arcade/match.rb
160
+ - lib/arcade/query.rb
161
+ - lib/arcade/support/class.rb
162
+ - lib/arcade/support/conversions.rb
163
+ - lib/arcade/support/model.rb
164
+ - lib/arcade/support/object.rb
165
+ - lib/arcade/support/sql.rb
166
+ - lib/arcade/support/string.rb
140
167
  - lib/arcade/version.rb
141
- - lib/config.rb
142
- - lib/init.rb
143
- - lib/match.rb
144
168
  - lib/model/basicdocument.rb
145
169
  - lib/model/basicedge.rb
146
170
  - lib/model/basicvertex.rb
@@ -148,13 +172,6 @@ files:
148
172
  - lib/model/edge.rb
149
173
  - lib/model/vertex.rb
150
174
  - lib/models.rb
151
- - lib/query.rb
152
- - lib/support/class.rb
153
- - lib/support/conversions.rb
154
- - lib/support/model.rb
155
- - lib/support/object.rb
156
- - lib/support/sql.rb
157
- - lib/support/string.rb
158
175
  - rails.md
159
176
  - rails/arcade.rb
160
177
  - rails/config.yml
@@ -1,5 +0,0 @@
1
- module Arcade
2
- module Api
3
- VERSION = 0.1
4
- end
5
- end
data/lib/match.rb DELETED
@@ -1,216 +0,0 @@
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
File without changes
File without changes
File without changes
File without changes
File without changes