active-orient 0.6 → 0.42

Sign up to get free protection for your applications and to get access to all the features.
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