active-orient 0.6 → 0.42

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/Gemfile +4 -10
  4. data/Guardfile +4 -12
  5. data/README.md +198 -261
  6. data/VERSION +1 -1
  7. data/active-orient-0.4.gem +0 -0
  8. data/active-orient-0.41.gem +0 -0
  9. data/active-orient.gemspec +5 -6
  10. data/config/boot.rb +0 -84
  11. data/config/connect.yml +4 -8
  12. data/examples/books.rb +39 -86
  13. data/examples/streets.rb +84 -85
  14. data/lib/active-orient.rb +9 -57
  15. data/lib/base.rb +145 -172
  16. data/lib/base_properties.rb +44 -40
  17. data/lib/model.rb +468 -0
  18. data/lib/orient.rb +60 -114
  19. data/lib/query.rb +73 -71
  20. data/lib/rest.rb +1059 -0
  21. data/lib/support.rb +319 -386
  22. data/test.rb +4 -0
  23. data/usecase.md +91 -0
  24. metadata +20 -65
  25. data/bin/active-orient-console +0 -38
  26. data/config/config.yml +0 -10
  27. data/create_project +0 -19
  28. data/examples/test_commands.rb +0 -92
  29. data/examples/test_commands_2.rb +0 -54
  30. data/examples/test_commands_3.rb +0 -48
  31. data/examples/test_commands_4.rb +0 -28
  32. data/examples/time_graph.md +0 -162
  33. data/gratefuldeadconcerts.md +0 -94
  34. data/lib/class_utils.rb +0 -300
  35. data/lib/database_utils.rb +0 -106
  36. data/lib/init.rb +0 -45
  37. data/lib/java-api.rb +0 -437
  38. data/lib/jdbc.rb +0 -211
  39. data/lib/model/edge.rb +0 -55
  40. data/lib/model/model.rb +0 -91
  41. data/lib/model/the_class.rb +0 -500
  42. data/lib/model/the_record.rb +0 -322
  43. data/lib/model/vertex.rb +0 -136
  44. data/lib/orientdb_private.rb +0 -48
  45. data/lib/other.rb +0 -330
  46. data/lib/rest/change.rb +0 -137
  47. data/lib/rest/create.rb +0 -488
  48. data/lib/rest/delete.rb +0 -134
  49. data/lib/rest/operations.rb +0 -160
  50. data/lib/rest/read.rb +0 -150
  51. data/lib/rest/rest.rb +0 -112
  52. data/lib/rest_disabled.rb +0 -24
  53. data/linkmap.md +0 -75
  54. data/namespace.md +0 -111
  55. data/old_lib_functions/two_general_class.rb +0 -139
  56. data/rails.md +0 -125
  57. data/rails/activeorient.rb +0 -53
  58. data/rails/config.yml +0 -10
  59. data/rails/connect.yml +0 -17
  60. data/usecase_oo.md +0 -61
@@ -3,82 +3,85 @@ require 'active_support/concern'
3
3
  require 'active_support/hash_with_indifferent_access'
4
4
 
5
5
  module ActiveOrient
6
+
7
+ # Module adds prop Macro and
6
8
  module BaseProperties
7
9
  extend ActiveSupport::Concern
8
10
 
9
- # Default presentation of ActiveOrient::Model-Objects
11
+ ### Instance methods
10
12
 
13
+ # Default presentation
11
14
  def to_human
12
15
  "<#{self.class.to_s.demodulize}: " + content_attributes.map do |attr, value|
13
- v= case value
14
- when ActiveOrient::Model
15
- "< #{self.class.to_.demodulize} : #{value.rrid} >"
16
- else
17
- value.from_orient
18
- end
19
- "%s : %s" % [ attr, v] unless v.nil?
20
- end.compact.sort.join(', ') + ">".gsub('"' , ' ')
16
+ "#{attr}: #{value}" unless value.nil?
17
+ end.compact.sort.join(' ') + ">"
21
18
  end
22
19
 
23
- # Comparison support
24
-
25
- def content_attributes # :nodoc:
20
+ # Comparison support
21
+ def content_attributes
26
22
  HashWithIndifferentAccess[attributes.reject do |(attr, _)|
27
- attr.to_s =~ /(_count)\z/ || [:created_at, :updated_at, :type, :id, :order_id, :contract_id].include?(attr.to_sym)
23
+ attr.to_s =~ /(_count)\z/ ||
24
+ [:created_at, :updated_at, :type,
25
+ :id, :order_id, :contract_id].include?(attr.to_sym)
28
26
  end]
29
27
  end
30
28
 
31
- # Update nil attributes from given Hash or model
32
-
33
- def update_missing attrs # :nodoc:
29
+ # Update nil attributes from given Hash or model
30
+ def update_missing attrs
34
31
  attrs = attrs.content_attributes unless attrs.kind_of?(Hash)
35
- attrs.each{|attr, val| send "#{attr}=", val if send(attr).blank?}
32
+
33
+ attrs.each { |attr, val| send "#{attr}=", val if send(attr).blank? }
36
34
  self # for chaining
37
35
  end
38
36
 
39
- # Default Model comparison
40
-
41
- def == other # :nodoc:
37
+ # Default Model comparison
38
+ def == other
42
39
  case other
43
40
  when String # Probably a link or a rid
44
- "##{rid}" == other || rid == other
41
+ link == other || rid == other
45
42
  when ActiveOrient::Model
46
- rid == other.rid
43
+ link == other.link
47
44
  else
48
- content_attributes.keys.inject(true){ |res, key|
49
- res && other.respond_to?(key) && (send(key) == other.send(key))
50
- }
45
+ content_attributes.keys.inject(true) { |res, key|
46
+ res && other.respond_to?(key) && (send(key) == other.send(key)) }
51
47
  end
52
48
  end
53
49
 
54
- # Default attributes support
50
+ ### Default attributes support
55
51
 
56
52
  def default_attributes
57
- {:created_at => DateTime.now }
53
+ {:created_at => Time.now,
54
+ :updated_at => Time.now,
55
+ }
58
56
  end
59
57
 
60
- def set_attribute_defaults # :nodoc:
58
+ def set_attribute_defaults
61
59
  default_attributes.each do |key, val|
62
60
  self.send("#{key}=", val) if self.send(key).nil?
61
+ # self.send("#{key}=", val) if self[key].nil? # Problems with association defaults
63
62
  end
64
63
  end
65
64
 
66
65
  included do
66
+
67
67
  after_initialize :set_attribute_defaults
68
68
 
69
- # Class macros
69
+ ### Class macros
70
70
 
71
- def self.prop *properties # :nodoc:
71
+ def self.prop *properties
72
72
  prop_hash = properties.last.is_a?(Hash) ? properties.pop : {}
73
+
73
74
  properties.each { |names| define_property names, nil }
74
75
  prop_hash.each { |names, type| define_property names, type }
75
76
  end
76
77
 
77
- def self.define_property names, body # :nodoc:
78
+ def self.define_property names, body
78
79
  aliases = [names].flatten
79
80
  name = aliases.shift
80
81
  instance_eval do
82
+
81
83
  define_property_methods name, body
84
+
82
85
  aliases.each do |ali|
83
86
  alias_method "#{ali}", name
84
87
  alias_method "#{ali}=", "#{name}="
@@ -86,7 +89,8 @@ module ActiveOrient
86
89
  end
87
90
  end
88
91
 
89
- def self.define_property_methods name, body={} # :nodoc:
92
+ def self.define_property_methods name, body={}
93
+ #p name, body
90
94
  case body
91
95
  when '' # default getter and setter
92
96
  define_property_methods name
@@ -98,24 +102,23 @@ module ActiveOrient
98
102
  :validate => body[2]
99
103
 
100
104
  when Hash # recursion base case
101
- # puts "NAME: "+name.to_S
102
- # puts "BODY::"+body.inspect
103
105
  getter = case # Define getter
104
106
  when body[:get].respond_to?(:call)
105
107
  body[:get]
106
108
  when body[:get]
107
- proc{self[name].send "to_#{body[:get]}"}
109
+ proc { self[name].send "to_#{body[:get]}" }
108
110
  else
109
- proc{self[name]}
111
+ proc { self[name] }
110
112
  end
111
113
  define_method name, &getter if getter
114
+
112
115
  setter = case # Define setter
113
116
  when body[:set].respond_to?(:call)
114
117
  body[:set]
115
118
  when body[:set]
116
- proc{|value| self[name] = value.send "to_#{body[:set]}"}
119
+ proc { |value| self[name] = value.send "to_#{body[:set]}" }
117
120
  else
118
- proc{|value| self[name] = value} # p name, value;
121
+ proc { |value| self[name] = value } # p name, value;
119
122
  end
120
123
  define_method "#{name}=", &setter if setter
121
124
 
@@ -129,15 +132,16 @@ module ActiveOrient
129
132
  end
130
133
  end
131
134
 
132
- # todo define self[:name] accessors for :virtual and :flag properties
135
+ # TODO define self[:name] accessors for :virtual and :flag properties
133
136
 
134
137
  else # setter given
135
138
  define_property_methods name, :set => body, :get => body
136
139
  end
137
140
  end
138
141
 
142
+ # Timestamps in lightweight models
139
143
  unless defined?(ActiveRecord::Base) && ancestors.include?(ActiveRecord::Base)
140
- prop :created_at #, :updated_at
144
+ prop :created_at, :updated_at
141
145
  end
142
146
 
143
147
  end # included
@@ -0,0 +1,468 @@
1
+ class String
2
+ def to_or
3
+ "'#{self}'"
4
+ end
5
+ end
6
+
7
+ class Numeric
8
+ def to_or
9
+ "#{self.to_s}"
10
+ end
11
+ end
12
+ module ActiveOrient
13
+
14
+ #require 'base'
15
+ #require 'base_properties'
16
+
17
+ class Model < ActiveOrient::Base
18
+ include BaseProperties
19
+
20
+ mattr_accessor :orientdb
21
+ mattr_accessor :logger
22
+ =begin
23
+ orientdb_class is used to instantiate a ActiveOrient:Model:{class} by providing its name
24
+ todo: implement object-inherence
25
+ =end
26
+ def self.orientdb_class name:
27
+ klass = Class.new( self )
28
+ name = name.to_s.camelize
29
+ if self.send :const_defined?, name
30
+ retrieved_class = self.send :const_get, name
31
+ else
32
+ new_class = self.send :const_set , name , klass
33
+ new_class.orientdb = orientdb
34
+ new_class # return_value
35
+ end
36
+ rescue NameError => e
37
+ logger.error "Model:: Class name cannot be initialized"
38
+ puts "klass: #{klass.inspect}"
39
+ puts "name : #{name.inspect}"
40
+ puts e.inspect
41
+ end
42
+
43
+ =begin
44
+ ActiveOrient::Model.autoload_object "#00:00"
45
+ either retrieves the object from the rid_store or loads it from the DB
46
+
47
+ the rid_store is updated!
48
+
49
+ to_do: fetch for version in the db and load the object if a change is detected
50
+ =end
51
+ def self.autoload_object link
52
+ # puts "autoload_object #{link}"
53
+ link_cluster_and_record = link[1,link.size].split(':').map &:to_i
54
+ @@rid_store[link_cluster_and_record].presence || orientdb.get_document( link )
55
+ end
56
+
57
+
58
+ def self.superClass
59
+ orientdb.get_classes( 'name', 'superClass').detect{|x| x["name"].downcase == new.class.to_s.downcase.split(':')[-1].to_s
60
+ }['superClass']
61
+ end
62
+
63
+ def to_orient
64
+ link
65
+ end
66
+ def from_orient
67
+ self
68
+ end
69
+ =begin
70
+ Returns just the name of the Class
71
+ =end
72
+ def classname
73
+ self.class.to_s.split(':')[-1]
74
+ end
75
+
76
+ =begin
77
+ If a Rest::Model-Object is included in a HashWidhtIndifferentAccess-Object, only the link is stored
78
+ =end
79
+ def nested_under_indifferent_access # :nodoc:
80
+ link
81
+ end
82
+
83
+ # hard-coded orientdb-columns
84
+ # prop :cluster, :version, :record, :fieldtypes
85
+
86
+ # def default_attributes
87
+ # super.merge cluster: 0
88
+ # super.merge version: 0
89
+ # super.merge record: 0
90
+ # end
91
+ def riid # :nodoc:
92
+ [ @metadata[ :cluster ] , @metadata[ :record ] ]
93
+ end
94
+ =begin
95
+ rid is used in the where-part of sql-queries
96
+ =end
97
+ def rid
98
+ "#{@metadata[ :cluster ]}:#{@metadata[ :record ]}"
99
+ rescue
100
+ "0:0"
101
+ end
102
+ =begin
103
+ link is used in any sql-commands
104
+ eg . update #link set ...
105
+ =end
106
+ def link
107
+ "##{rid}"
108
+ end
109
+
110
+
111
+ # def method_missing method, *args, &b
112
+ # property= orientdb.get_class_properties( classname )['properties'].detect{|x| x.has_value? method.to_s }
113
+ # puts "method_missing::property"
114
+ # puts property.inspect
115
+ # if property.present?
116
+ # if property['type'] == 'LINKSET'
117
+ # attributes[method] = OrientSupport::Array.new( self )
118
+ # else
119
+ # attributes[method] = ''
120
+ # end
121
+ # else
122
+ # raise NoMethodError
123
+ # end
124
+ # end
125
+ =begin
126
+ Queries the database and fetches the count of datasets
127
+
128
+ Any parameter that qualifies a database-query is suppoerted
129
+ (see method get_documents)
130
+ =end
131
+ def self.count **args
132
+ orientdb.count_documents from: self , **args
133
+ end
134
+ =begin
135
+ Creates a new Instance of the Class with the applied attributes
136
+ and returns the freshly instantiated Object
137
+ =end
138
+
139
+ def self.create properties = {}
140
+ orientdb.create_or_update_document self, set: properties
141
+ end
142
+
143
+ def self.update_or_create set: {}, where:{} ,**args, &b
144
+ orientdb.update_or_create_documents self , set: set, where: where , **args , &b
145
+
146
+ end
147
+
148
+ # historic method
149
+ def self.new_document attributes: {} # :nodoc:
150
+ orientdb.create_or_update_document self, set: attributes
151
+ end
152
+ =begin
153
+ Create a Property in the Schema of the Class
154
+ :call-seq:
155
+ self.create_property( field (required) , type: 'string', linked_class: nil, index: nil) do
156
+ index
157
+ end
158
+ =end
159
+
160
+ def self.get_properties
161
+ object = orientdb.get_class_properties self
162
+ {:properties => object['properties'] , :indexes => object['indexes'] }
163
+ end
164
+
165
+ def self.create_property field, **keyword_arguments, &b
166
+ orientdb.create_property self, field, **keyword_arguments, &b
167
+ end
168
+
169
+ def self.create_properties argument_hash, &b
170
+ orientdb.create_properties self, argument_hash, &b
171
+ end
172
+
173
+ def self.create_link name, class_name
174
+ orientdb.create_property self, name, type: 'link', linked_class: class_name
175
+ end
176
+ def self.create_linkset name, class_name
177
+ orientdb.create_property self, name, type: 'linkset', linked_class: class_name
178
+ end
179
+ =begin
180
+ Only if the Class inherents from »E«
181
+ Instantiate a new Edge betwen two Vertices
182
+
183
+ Parameter: unique: (true) In case of an existing Edge just update its Properties.
184
+ The parameters »from« and »to« can take a list of model-records. Then subsequent edges are created.
185
+ :call-seq:
186
+ self.create_edge from: , to: , unique: false, attributes:{}
187
+ =end
188
+ def self.create_edge **keyword_arguments
189
+ o=orientdb.nexus_edge self, **keyword_arguments
190
+ [:from,:to].each{|y| keyword_arguments[y].is_a?(Array) ? keyword_arguments[y].each( &:reload! ): keyword_arguments[y].reload! }
191
+ o # return_value
192
+ end
193
+ =begin
194
+ QueryDatabase sends the Query, direct to the database.
195
+ The result is not nessessary a Object of self.
196
+ However, if the query does not return an array of Active::Model-Objects, then the entries become self
197
+ =end
198
+ def self.query_database query, set_from: true
199
+ query.from self if set_from && query.is_a?( OrientSupport::OrientQuery ) && query.from.nil?
200
+ sql_cmd = -> (command) { { type: "cmd", language: "sql", command: command } }
201
+ orientdb.execute( self.to_s.split(':')[-1] ) do
202
+ [ sql_cmd[ query.to_s ] ]
203
+ end
204
+ end
205
+ def query q
206
+ a= ActiveOrient::Query.new
207
+ a.queries << q
208
+ a.execute_queries
209
+ end
210
+ =begin
211
+ Parameter projection:
212
+
213
+ »select« is a method of enumeration, we use »projection:« to specify anything between »select« and »from«
214
+ in the query-string.
215
+
216
+ projection: a_string --> inserts the sting as it appears
217
+ an OrientSupport::OrientQuery-Object --> performs a sub-query and uses the result for further querying though the given parameters.
218
+
219
+ [ a, b, c ] --> "a , b , c " ( inserts a comma-separated list )
220
+
221
+ { a: b, "sum(x) "=> f } --> "a as b, sum(x) as f" (renames properties and uses functions )
222
+ Parameter distinct:
223
+
224
+ Performs a Query like » select distinct( property ) [ as property ] from ...«
225
+
226
+ distinct: :property --> the result is mapped to the property »distinct«.
227
+
228
+ [ :property ] --> the result replaces the property
229
+
230
+ { property: :some_name} --> the result is mapped to ModelInstance.some_name
231
+
232
+ Parameter Order
233
+
234
+ Sorts the result-set.
235
+
236
+ If new properties are introduced via select:, distinct: etc
237
+
238
+ Sorting takes place on these properties
239
+
240
+ order: :property
241
+ { property: asc, property: desc }
242
+ [property, property, .. ] ( orderdirection is 'asc' )
243
+
244
+
245
+ Further supported Parameter:
246
+ group_by
247
+ skip
248
+ limit
249
+ unwind
250
+
251
+ see orientdb- documentation (https://orientdb.com/docs/last/SQL-Query.html)
252
+
253
+ Parameter query:
254
+ Instead of providing the parameter, the OrientSupport::OrientQuery can build and
255
+ tested before the method-call. The OrientQuery-Object can be provided with the query-parameter
256
+ i.e.
257
+ q= OrientSupport::OrientQuery.new
258
+ TestModel = r.open_class 'test_model'
259
+ q.from TestModel
260
+ q.where { name: 'Thomas' }
261
+
262
+ count= TestModel.count query:q
263
+ q.limit 10
264
+ 0.step(count,10) do |x|
265
+ q.skip = x
266
+ puts TestModel.get_documents( query: q ).map{|x| x.adress }.join('\t')
267
+ end
268
+ prints a Table with 10 columns.
269
+ =end
270
+
271
+ def self.get_documents **args
272
+ orientdb.get_documents( from: self, **args ){ self }
273
+
274
+ end
275
+ =begin
276
+ Performs a query on the Class and returns an Array of ActiveOrient:Model-Records.
277
+
278
+ Example:
279
+ Log = r.open_class 'Log'
280
+ Log.where priority: 'high'
281
+ --> submited database-request: query/hc_database/sql/select from Log where priority = 'high'/-1
282
+ => [ #<ActiveOrient::Model::Log:0x0000000480f7d8 @metadata={ ... }, ... ]
283
+
284
+
285
+ =end
286
+ def self.where attributes = {}
287
+ q = OrientSupport::OrientQuery.new where: attributes
288
+ query_database q
289
+ end
290
+ =begin
291
+
292
+ removes the Model-Instance from the database
293
+
294
+ returns true (successfully deleted) or false ( obj not deleted)
295
+ =end
296
+ def delete
297
+
298
+ r= if is_edge?
299
+ # returns the count of deleted edges
300
+ orientdb.delete_edge rid
301
+ else
302
+ orientdb.delete_document rid
303
+ end
304
+ ActiveOrient::Base.remove_riid self if r # removes the obj from the rid_store
305
+ r # true or false
306
+ end
307
+ =begin
308
+ An Edge is defined
309
+ * when inherented from the superclass »E» (formal definition)
310
+ * if it has an in- and an out property
311
+
312
+ Actually we just check the second term as we trust the constuctor to work properly
313
+ =end
314
+ def is_edge?
315
+ attributes.keys.include?( 'in') && attributes.keys.include?('out')
316
+ end
317
+ # get enables loading of datasets if a link is followed
318
+ # model_class.all.first.link.get
319
+ def self.get rid
320
+ orientdb.get_document rid
321
+ end
322
+ def self.all
323
+ orientdb.get_documents from: self
324
+ end
325
+ def self.first where: {}
326
+ orientdb.get_documents( from: self, where: where, limit: 1).pop
327
+ end
328
+
329
+ def self.last where: {}
330
+ # debug:: orientdb.get_documents( self, order: { "@rid" => 'desc' }, limit: 1 ){ |x| puts x }.pop
331
+ orientdb.get_documents( from: self, where: where, order: { "@rid" => 'desc' }, limit: 1 ).pop
332
+ end
333
+ =begin
334
+ Convient update of the dataset by calling sql-patch
335
+ The attributes are saved to the database.
336
+ With the optional :set argument ad-hoc attributes can be defined
337
+ obj = ActiveOrient::Model::Contracts.first
338
+ obj.name = 'new_name'
339
+ obj.update set: { yesterdays_event: 35 }
340
+ =end
341
+ def update set: {}
342
+ attributes.merge!( set ) if set.present?
343
+ result= orientdb.patch_document(rid) do
344
+ attributes.merge( { '@version' => @metadata[ :version ], '@class' => @metadata[ :class ] } )
345
+ end
346
+ # returns a new instance of ActiveOrient::Model
347
+ reload! ActiveOrient::Model.orientdb_class(name: classname).new( JSON.parse( result ))
348
+ # instantiate object, update rid_store and reassign to self
349
+
350
+ end
351
+ =begin
352
+ Overwrite the attributes with Database-Contents (or attributes provided by the updated_dataset.model-instance)
353
+ =end
354
+ def reload! updated_dataset=nil
355
+ updated_dataset = orientdb.get_document( link) if updated_dataset.nil?
356
+ @metadata[:version]= updated_dataset.version
357
+ attributes = updated_dataset.attributes
358
+ self # return_value (otherwise only the attributes would be returned)
359
+ end
360
+
361
+ def remove_item_from_property array, item=nil
362
+ logger.progname = 'ActiveOrient::Model#RemoveItemFromProperty'
363
+ execute_array = Array.new
364
+ return unless attributes.has_key? array
365
+ remove_execute_array = -> (it) do
366
+ case it
367
+ when ActiveOrient::Model
368
+ execute_array << {type: "cmd", language: "sql", command: "update #{link} remove #{array} = #{it.link}"}
369
+ when String
370
+ execute_array << {type: "cmd", language: "sql", command: "update #{link} remove #{array} = '#{it}'"}
371
+ when Numeric
372
+ execute_array << {type: "cmd", language: "sql", command: "update #{link} remove #{array} = #{it}"}
373
+ else
374
+ logger.error { "Only Basic Formats supported . Cannot Serialize #{it.class} this way" }
375
+ logger.error { "Try to load the array from the DB, modify it and update the hole record" }
376
+ end
377
+ end
378
+
379
+ if block_given?
380
+ items = yield
381
+ items.each{|x| remove_execute_array[x]; self.attributes[array].delete( x ) }
382
+ elsif item.present?
383
+ remove_execute_array[item]
384
+ a= attributes; a.delete item
385
+ self.attributes[array].delete( item )
386
+ end
387
+ orientdb.execute do
388
+ execute_array
389
+ end
390
+ reload!
391
+
392
+ rescue RestClient::InternalServerError => e
393
+ logger.error " Could not remove item in #{array} "
394
+ logger.error e.inspect
395
+ end
396
+
397
+ =begin
398
+ Convient method for populating embedded- or linkset-properties
399
+
400
+ In both cases an array/ a collection is stored in the database.
401
+
402
+ its called via
403
+ model.add_item_to_property( linkset- or embedded property, Object_to_be_linked_to )
404
+ or
405
+ mode.add_items_to_property( linkset- or embedded property ) do
406
+ Array_of_Objects_to_be_linked_to
407
+ (actually, the objects must inherent from ActiveOrient::Model, Numeric, String)
408
+ end
409
+
410
+ to_do: use "<<" to add the item to the property
411
+ =end
412
+ def add_item_to_property array, item=nil
413
+ logger.progname = 'ActiveOrient::Model#AddItem2Property'
414
+ execute_array = Array.new
415
+ self.attributes[array] = Array.new unless attributes[array].present?
416
+ add_2_execute_array = -> (it) do
417
+ case it
418
+ when ActiveOrient::Model
419
+ execute_array << {type: "cmd", language: "sql", command: "update #{link} add #{array} = #{it.link}"}
420
+ when String
421
+ execute_array << {type: "cmd", language: "sql", command: "update #{link} add #{array} = '#{it}'"}
422
+ when Numeric
423
+ execute_array << {type: "cmd", language: "sql", command: "update #{link} add #{array} = #{it}"}
424
+ else
425
+ logger.error { "Only Basic Formats supported . Cannot Serialize #{it.class} this way" }
426
+ logger.error { "Try to load the array from the DB, modify it and update the hole record" }
427
+ end
428
+ end
429
+
430
+ if block_given?
431
+ items = yield
432
+ items.each{|x| add_2_execute_array[x]; self.attributes[array] << x }
433
+ elsif item.present?
434
+ add_2_execute_array[item]
435
+ self.attributes[array] << item
436
+ end
437
+ orientdb.execute do
438
+ execute_array
439
+ end
440
+ reload!
441
+
442
+ rescue RestClient::InternalServerError => e
443
+ logger.error " Duplicate found in #{array} "
444
+ logger.error e.inspect
445
+ end
446
+
447
+ alias add_items_to_property add_item_to_property
448
+ ## historical aliases
449
+ alias update_linkset add_item_to_property
450
+ alias update_embedded add_item_to_property
451
+ =begin
452
+ Convient method for updating a linkset-property
453
+ its called via
454
+ model.update_linkset( linkset-property, Object_to_be_linked_to )
455
+ or
456
+ mode.update_linkset( linkset-property ) do
457
+ Array_of_Objects_to_be_linked_to
458
+ end
459
+ =end
460
+
461
+ #private
462
+ def version
463
+ @metadata[ :version ]
464
+ end
465
+
466
+ end # class
467
+
468
+ end # module