active-orient 0.5 → 0.6

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -2
  3. data/README.md +78 -35
  4. data/VERSION +1 -1
  5. data/active-orient.gemspec +4 -4
  6. data/bin/active-orient-console +8 -5
  7. data/config/boot.rb +2 -4
  8. data/config/config.yml +1 -1
  9. data/config/connect.yml +2 -2
  10. data/examples/time_graph.md +162 -0
  11. data/gratefuldeadconcerts.md +94 -0
  12. data/lib/active-orient.rb +4 -2
  13. data/lib/base.rb +53 -20
  14. data/lib/base_properties.rb +2 -3
  15. data/lib/class_utils.rb +3 -4
  16. data/lib/database_utils.rb +14 -5
  17. data/lib/init.rb +11 -1
  18. data/lib/model/edge.rb +12 -10
  19. data/lib/model/model.rb +17 -3
  20. data/lib/model/the_class.rb +60 -40
  21. data/lib/model/the_record.rb +63 -51
  22. data/lib/model/vertex.rb +114 -10
  23. data/lib/orient.rb +24 -33
  24. data/lib/orientdb_private.rb +31 -31
  25. data/lib/other.rb +55 -5
  26. data/lib/rest/change.rb +17 -4
  27. data/lib/rest/create.rb +38 -24
  28. data/lib/rest/delete.rb +3 -2
  29. data/lib/rest/operations.rb +37 -27
  30. data/lib/rest/read.rb +2 -2
  31. data/lib/rest/rest.rb +4 -3
  32. data/lib/support.rb +17 -16
  33. data/linkmap.md +75 -0
  34. data/namespace.md +111 -0
  35. data/rails.md +125 -0
  36. data/rails/activeorient.rb +53 -0
  37. data/{examples/time_graph/config → rails}/config.yml +3 -1
  38. data/{examples/time_graph/config → rails}/connect.yml +2 -2
  39. data/usecase_oo.md +3 -1
  40. metadata +21 -38
  41. data/examples/createTime.rb +0 -91
  42. data/examples/time_graph/Gemfile +0 -21
  43. data/examples/time_graph/Guardfile +0 -26
  44. data/examples/time_graph/README.md +0 -129
  45. data/examples/time_graph/bin/active-orient-console +0 -35
  46. data/examples/time_graph/config/boot.rb +0 -119
  47. data/examples/time_graph/config/init_db.rb +0 -59
  48. data/examples/time_graph/createTime.rb +0 -51
  49. data/examples/time_graph/lib/createTime.rb +0 -82
  50. data/examples/time_graph/model/day_of.rb +0 -3
  51. data/examples/time_graph/model/e.rb +0 -6
  52. data/examples/time_graph/model/edge.rb +0 -53
  53. data/examples/time_graph/model/monat.rb +0 -19
  54. data/examples/time_graph/model/stunde.rb +0 -16
  55. data/examples/time_graph/model/tag.rb +0 -29
  56. data/examples/time_graph/model/time_base.rb +0 -6
  57. data/examples/time_graph/model/time_of.rb +0 -4
  58. data/examples/time_graph/model/v.rb +0 -3
  59. data/examples/time_graph/model/vertex.rb +0 -32
  60. data/examples/time_graph/spec/lib/create_time_spec.rb +0 -50
  61. data/examples/time_graph/spec/rest_helper.rb +0 -37
  62. data/examples/time_graph/spec/spec_helper.rb +0 -46
  63. data/usecase.md +0 -104
@@ -45,10 +45,15 @@ ActiveOrient::Model-Object or an Array of Model-Objects as result.
45
45
  def query query
46
46
 
47
47
  sql_cmd = -> (command) {{ type: "cmd", language: "sql", command: command }}
48
- orientdb.execute do
48
+ result = orientdb.execute do
49
49
  sql_cmd[query.to_s]
50
50
  end
51
- end
51
+ if result.is_a? Array
52
+ OrientSupport::Array.new work_on: self, work_with: result
53
+ else
54
+ result
55
+ end # return value
56
+ end
52
57
 
53
58
  =begin
54
59
  queries the database starting with the current model-record.
@@ -97,7 +102,6 @@ Returns the result-set, ie. a Query-Object which contains links to the addressed
97
102
  def update_item_property method, array, item = nil, &ba # :nodoc:
98
103
  # begin
99
104
  logger.progname = 'ActiveOrient::Model#UpdateItemToProperty'
100
- #self.attributes[array] = OrientSupport::Array.new(self) unless attributes[array].present?
101
105
  self.attributes[array] = Array.new unless attributes[array].present?
102
106
 
103
107
  items = if item.present?
@@ -106,10 +110,6 @@ Returns the result-set, ie. a Query-Object which contains links to the addressed
106
110
  yield
107
111
  end
108
112
  db.manipulate_relation self, method, array, items
109
- #rescue RestClient::InternalServerError => e
110
- # logger.error{"Duplicate found in #{array}"}
111
- # logger.error{e.inspect}
112
- # end
113
113
  end
114
114
  =begin
115
115
  Add Items to a linked or embedded class
@@ -156,36 +156,42 @@ If only single Items are to insert, use
156
156
 
157
157
  =end
158
158
 
159
- def add_item_to_property array, item = nil, &b
160
- items = block_given? ? yield : nil
161
- update_item_property "ADD", array, item, &b
162
- self # return_value
159
+ def add_item_to_property array, *item
160
+ item = yield if block_given?
161
+ if attributes.keys.include? array.to_s
162
+ item.each{|x| self.attributes[array].push x.to_orient }
163
+ update
164
+ else
165
+ update array=> item
166
+ end
167
+ # rescue NoMethodError
168
+ #undefined method `<<' for nil:NilClass
169
+
163
170
  end
164
- # alias add_items_to_property add_item_to_property
165
- ## historical aliases
166
- # alias update_linkset add_item_to_property
167
- # alias update_embedded add_item_to_property
168
171
 
169
- def set_item_to_property array, item = nil, &b
170
- update_item_property "SET", array, item, &b
172
+
173
+ def set_item_to_property array, *item
174
+ update array.to_s => item
171
175
  end
172
176
 
173
- def remove_item_from_property array, item = nil, &b
174
- update_item_property "REMOVE", array, item, &b
175
- if block_given?
176
- items = yield
177
- items.each{|x| self.attributes[array].delete(x)}
178
- elsif item.present?
179
- a = attributes
180
- a.delete item
181
- self.attributes[array].delete(item)
177
+ def remove_position_from_property array, *pos
178
+ if attributes[array].is_a? Array
179
+ pos.each{|x| self.attributes[array].delete_at( x )}
180
+ update
181
+ end
182
+ end
183
+ def remove_item_from_property array, *item
184
+ if attributes[array].is_a? Array
185
+ item.each{|x| self.attributes[array].delete( x.to_orient )}
186
+ update
187
+ else
188
+ logger.error "Wrong attribute: #{attributes[array]}"
182
189
  end
183
- self # return_value
184
190
  end
185
191
 
186
192
  ############# DELETE ###########
187
193
 
188
- # Removes the Model-Instance from the databasea
194
+ # Removes the Model-Instance from the database
189
195
  # todo: overloaded in vertex and edge
190
196
 
191
197
  def remove
@@ -193,8 +199,6 @@ def remove
193
199
  ActiveOrient::Base.remove_rid self ##if is_edge? # removes the obj from the rid_store
194
200
  end
195
201
 
196
- ## delete works for any model-class
197
- ## it calls delete_record and does not check for dependencies
198
202
  alias delete remove
199
203
 
200
204
  ########### UPDATE ############
@@ -207,23 +211,41 @@ alias delete remove
207
211
  obj = ActiveOrient::Model::Contracts.first
208
212
  obj.name = 'new_name'
209
213
  obj.update set: { yesterdays_event: 35 }
214
+
215
+ ** note: The keyword »set« is optional
210
216
  =end
211
217
 
212
- def update set: {}
218
+ def update set: {}, **args
213
219
  logger.progname = 'ActiveOrient::Model#Update'
214
220
  self.attributes.merge!(set) if set.present?
215
- self.attributes['updated_at'] = Time.new
216
- updated_dataset = db.update self, attributes, @metadata[:version]
217
- # if the updated dataset changed, drop the changes made siently
218
- if updated_dataset.is_a? ActiveOrient::Model
219
- self.version = updated_dataset.version
220
- updated_dataset # return_value
221
+ self.attributes.merge!(args) if args.present?
222
+ self.attributes['updated_at'] = DateTime.now
223
+ if rid.rid?
224
+ updated_dataset = db.update self, attributes, @metadata[:version]
225
+ # if the updated dataset changed, drop the changes made siently
226
+ if updated_dataset.is_a? ActiveOrient::Model
227
+ self.version = updated_dataset.version
228
+ updated_dataset # return_value
229
+ else
230
+ logger.error("Version Conflict: reloading database values")
231
+ reload!
232
+ end
221
233
  else
222
- logger.error("Version Conflict: reloading database values")
223
- reload!
234
+ save
224
235
  end
225
236
 
226
237
  end
238
+
239
+ # mocking active record, overrides the base-class-method
240
+ def update_attribute the_attribute, the_value
241
+ update set: {the_attribute => the_value }
242
+ super the_attribute, the_value
243
+ end
244
+
245
+ def update_attributes **args
246
+ update set: args
247
+ end
248
+
227
249
  ########## SAVE ############
228
250
 
229
251
  =begin
@@ -237,7 +259,7 @@ def save
237
259
  if rid.rid?
238
260
  update
239
261
  else
240
- db_object= DB.create_record self, attributes: attributes
262
+ db_object= db.create_record self, attributes: attributes
241
263
  @metadata[:cluster], @metadata[:record] = db_object.rid[0,db_object.rid.size].split(':').map( &:to_i)
242
264
  reload! db_object
243
265
  end
@@ -250,7 +272,7 @@ end
250
272
  def reload! updated_dataset = nil
251
273
  updated_dataset = db.get_record(rid) if updated_dataset.nil?
252
274
  @metadata[:version] = updated_dataset.version
253
- attributes = updated_dataset.attributes
275
+ self.attributes = updated_dataset.attributes
254
276
  self # return_value (otherwise only the attributes would be returned)
255
277
  end
256
278
 
@@ -294,16 +316,6 @@ How to handle other calls
294
316
  raise NameError
295
317
  end
296
318
  end
297
- # rescue NameError => e
298
- # logger.progname = 'ActiveOrient::Model#MethodMissing'
299
- # if args.size == 1
300
- # logger.error{"Unknown Attribute: #{args.first} "}
301
- # else
302
- # logger.error{"Unknown Method: #{args.map{|x| x.to_s}.join(" / ")} "}
303
- # end
304
- # puts "Method Missing: Args: #{args.inspect}"
305
- # print e.backtrace.join("\n")
306
- # raise
307
319
  #end
308
320
 
309
321
 
@@ -1,16 +1,85 @@
1
1
  class V < ActiveOrient::Model
2
2
  ## link to the library-class
3
- # create
4
- # seems not to be nessesary as its identically to the universal create
5
-
6
3
 
7
- # to do
4
+ =begin
5
+ Vertex#delete fires a "delete edge" command to the database.
6
+ The where statement can be empty ( "" or {}"), then all vertices are removed
7
+
8
+ The rid-cache is reseted, too
9
+ =end
10
+ def self.delete where:
11
+ db.execute { "delete vertex #{ref_name} #{db.compose_where(where)}" }
12
+ reset_rid_store
13
+ end
14
+
15
+ def detect_inherent_edge kind, edge_name # :nodoc:
16
+ ## returns a list of inherented classes
17
+ get_superclass = ->(e) do
18
+ n = ORD.get_db_superclass(e)
19
+ n =='E' ? e : e + ',' + get_superclass[n]
20
+ end
21
+ if edge_name.present?
22
+ e_name = edge_name.is_a?( Class) ? edge_name.ref_name : edge_name.to_s
23
+ the_edge = @metadata[:edges][kind].detect{|y| get_superclass[y].split(',').detect{|x| x == edge_name } }
24
+
25
+ candidate= attributes["#{kind.to_s}_#{the_edge}"]
26
+ candidate.present? ? candidate.map( &:from_orient ) : []
27
+ else
28
+ edges(kind).map &:from_orient
29
+ end
30
+ end
31
+ =begin
32
+ »in« and »out« provide the main access to edges.
33
+
34
+ If called without a parameter, all edges connected are displayed.
35
+
36
+ If called with a string, symbol or class, the edge-class is resolved and even inherented
37
+ edges are retrieved.
38
+
39
+ =end
40
+
41
+ def in edge_name= nil
42
+ detect_inherent_edge :in, edge_name
43
+ end
44
+
45
+ def out edge_name = nil
46
+ detect_inherent_edge :out, edge_name
47
+ end
48
+ =begin
49
+ retrieves connected edges
50
+
51
+ The basic ussage is to fetch all/ incomming/ outgoing edges
52
+
53
+ Model-Instance.edges :in # :out | :all
54
+
55
+ One can filter specific edges by providing parts of the edge-name
56
+
57
+ Model-Instance.edges 'in_sector'
58
+ Model-Instance.edges /sector/
59
+
60
+ returns an array of rid's
8
61
 
9
- # def delete
10
- # delete an edge (as class method)
11
- # and
12
- # def remove
13
- # delete an edge (as instance method)
62
+ example:
63
+
64
+ Industry.first.attributes.keys
65
+ => ["in_sector_classification", "k", "name", "created_at", "updated_at"] # edge--> in ...
66
+
67
+ Industry.first.edges :out
68
+ => []
69
+
70
+ Industry.first.edges :in
71
+ => ["#61:0", "#61:9", "#61:21", "#61:33", "#61:39", "#61:93", "#61:120", "#61:150", "#61:240", "#61:252", "#61:264", "#61:279", "#61:303", "#61:339" ...]
72
+
73
+
74
+
75
+ To fetch the associated records use the ActiveOrient::Model.autoload_object method
76
+
77
+ ActiveOrient::Model.autoload_object Industry.first.edges( :in).first
78
+ # or
79
+ Industry.autoload_object Industry.first.edges( /sector/ ).first
80
+ => #<SectorClassification:0x00000002daad20 @metadata={"type"=>"d", "class"=>"sector_classification", "version"=>1, "fieldTypes"=>"out=x,in=x", "cluster"=>61, "record"=>0},(...)
81
+
82
+ =end
14
83
 
15
84
  def edges kind=:all # :all, :in, :out
16
85
  expression = case kind
@@ -20,11 +89,46 @@ class V < ActiveOrient::Model
20
89
  /^in/
21
90
  when :out
22
91
  /^out/
23
- end
92
+ when String
93
+ /#{kind}/
94
+ when Regexp
95
+ kind
96
+ else
97
+ return []
98
+ end
99
+
24
100
  edges = attributes.keys.find_all{ |x| x =~ expression }
25
101
  edges.map{|x| attributes[x]}.flatten
26
102
  end
27
103
 
104
+ =begin
105
+ »in_edges« and »out_edges« are shortcuts to »edges :in« and »edges :out«
106
+
107
+ Its easy to expand the result:
108
+ tg.out( :ohlc).out.out_edges
109
+ => [["#102:11032", "#121:0"]]
110
+ tg.out( :ohlc).out.out_edges.from_orient
111
+ => [[#<TG::GRID_OF:0x00000002620e38
112
+
113
+ this displays the out-edges correctly
114
+
115
+ whereas
116
+ tg.out( :ohlc).out.edges( :out)
117
+ => [["#101:11032", "#102:11032", "#94:10653", "#121:0"]]
118
+
119
+ returns all edges. The parameter (:out) is not recognized, because out is already a nested array.
120
+
121
+ this
122
+ tg.out( :ohlc).first.out.edges( :out)
123
+ is a walkaround, but using in_- and out_edges is more elegant.
124
+ =end
125
+ def in_edges
126
+ edges :in
127
+ end
128
+ def out_edges
129
+ edges :out
130
+ end
131
+
28
132
  def remove
29
133
  db.delete_vertex self
30
134
  end
@@ -35,11 +35,8 @@ Append the argument to the Array, changes the Array itself.
35
35
 
36
36
  The change is transmitted to the database immediately
37
37
  =end
38
- def << arg
39
- # print "\n <<---> #{@name}, #{arg} <--- \n"
40
- if @name.present?
41
- @orient.add_item_to_property(@name, arg)
42
- end
38
+ def << *arg
39
+ @orient.add_item_to_property(@name, *arg) if @name.present?
43
40
  super
44
41
  end
45
42
 
@@ -54,33 +51,32 @@ The change is transmitted to the database immediately
54
51
  @orient.update set: {@name => self} if @name.present?
55
52
  end
56
53
 
57
- def [] *arg
58
- super
59
- end
60
-
61
- def delete_at *pos
62
- if @name.present?
63
- delete self[*pos]
64
- else
65
- super
66
- end
54
+ # def [] *arg
55
+ # #puts "ARG #{arg}"
56
+ # super
57
+ # end
58
+ #
59
+ =begin
60
+ Remove_at performs Array#delete_at
61
+ =end
62
+ def remove_at *pos
63
+ @orient.remove_position_from_property(@name,*pos) if @name.present?
67
64
  end
68
65
 
69
- def delete_if
70
- if @name.present?
71
- delete *self.map{|y| y if yield(y)}.compact # if the block returns true then delete the item
72
- else
73
- super
74
- end
75
- end
66
+ #
67
+ # alias :del_org :delete
68
+ =begin
69
+ Remove performs Array#delete
76
70
 
77
- def delete *item
78
- @orient.remove_item_from_property(@name){item} if @name.present?
71
+ If the Array-element is a link, this is removed, the linked table is untouched
72
+ =end
73
+ def remove *item
74
+ @orient.remove_item_from_property(@name,*item) if @name.present?
79
75
  end
80
-
76
+ ###
81
77
  ## just works with Hashes as parameters
82
78
  def where *item
83
- where_string = item.map{|m| where_string = compose_where m}.join(' and ')
79
+ where_string = item.map{|m| where_string = compose_where( m ) }.join(' and ')
84
80
  subquery= OrientSupport::OrientQuery.new from: @orient, projection: "expand( #{@name})"
85
81
  q= OrientSupport::OrientQuery.new from: subquery, where: item
86
82
  # query = "SELECT FROM ( SELECT EXPAND( #{@name} ) FROM #{@orient.classname}) #{where_string} "
@@ -93,12 +89,11 @@ The change is transmitted to the database immediately
93
89
  end
94
90
 
95
91
  def method_missing *args
96
- begin
97
- map{|x| x.send args.first}
92
+
93
+ map{|x| x.send *args }
98
94
  rescue NoMethodError => e
99
95
  logger.progname = "OrientSupport::Array#MethodMissing"
100
96
  logger.error{"Undefined method: #{e.message}"}
101
- end
102
97
  end
103
98
 
104
99
  end #Class
@@ -150,10 +145,6 @@ The change is transmitted to the database immediately
150
145
 
151
146
  end
152
147
 
153
- # def <<
154
-
155
-
156
- # def to_orient
157
148
  # self
158
149
  # end
159
150
 
@@ -13,36 +13,36 @@ module OrientDbPrivate
13
13
  end
14
14
  end
15
15
 
16
- # def property_uri this_classname
17
- # if block_given?
18
- # "property/#{@database}/#{this_classname}/" << yield
19
- # else
20
- # "property/#{@database}/#{this_classname}"
21
- # end
22
- # end
23
- #
24
- # def self.simple_uri *names
25
- # names.each do |name|
26
- # m_name = ("#{name.to_s}_uri").to_sym
27
- # define_method(m_name) do |&b|
28
- # if b
29
- # "#{name.to_s}/#{@database}/#{b.call}"
30
- # else
31
- # "#{name.to_s}/#{@database}"
32
- # end # branch
33
- # end
34
- # end
35
- # end
36
- #
37
- # def self.sql_uri *names
38
- # names.each do |name|
39
- # define_method(("#{name.to_s}_sql_uri").to_sym) do
40
- # "#{name.to_s}/#{@database}/sql/"
41
- # end
42
- # end
43
- # end
44
- #
45
- # simple_uri :database, :document, :class, :batch, :function
46
- # sql_uri :command, :query
16
+ def property_uri this_classname
17
+ if block_given?
18
+ "property/#{@database}/#{this_classname}/" << yield
19
+ else
20
+ "property/#{@database}/#{this_classname}"
21
+ end
22
+ end
23
+
24
+ def self.simple_uri *names
25
+ names.each do |name|
26
+ m_name = ("#{name.to_s}_uri").to_sym
27
+ define_method(m_name) do |&b|
28
+ if b
29
+ "#{name.to_s}/#{@database}/#{b.call}"
30
+ else
31
+ "#{name.to_s}/#{@database}"
32
+ end # branch
33
+ end
34
+ end
35
+ end
36
+
37
+ def self.sql_uri *names
38
+ names.each do |name|
39
+ define_method(("#{name.to_s}_sql_uri").to_sym) do
40
+ "#{name.to_s}/#{@database}/sql/"
41
+ end
42
+ end
43
+ end
44
+
45
+ simple_uri :database, :document, :class, :batch, :function
46
+ sql_uri :command, :query
47
47
 
48
48
  end