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
@@ -0,0 +1,94 @@
1
+ # Experiments with the GratefuldDeadConcterts database
2
+
3
+ First modify the database-entry (development) in /config/connect.yml to «GreatfulDeadConerts».
4
+ This should be present after the installation of the database
5
+ Then execute « ./bin/active-orient-console d »
6
+ ```
7
+ Present Classes (Hierarchy)
8
+ ---
9
+ - - E
10
+ - - followed_by
11
+ - sung_by
12
+ - written_by
13
+ - V
14
+
15
+ Active Classes -> ActiveOrient ClassName
16
+ ---------------------------------------------
17
+ V -> V
18
+ E -> E
19
+ followed_by -> FollowedBy
20
+ sung_by -> SungBy
21
+ written_by -> WrittenBy
22
+ ---------------------------------------------
23
+ ```
24
+
25
+ Lets start with simple queries
26
+
27
+ * Select all vertices (or object) in the database
28
+
29
+ ```ruby
30
+ V.all
31
+ ```
32
+
33
+ * Select the vertex with the id #9:8
34
+ ```ruby
35
+ V.autoload_object '#9:8'
36
+ ```
37
+
38
+ * Select all the artists
39
+
40
+ ```ruby
41
+ V.where type: 'artist'
42
+ ```
43
+
44
+ * Select all the songs that have been performed 10 times
45
+
46
+ Display songnames and authors
47
+
48
+
49
+ ```ruby
50
+ song_10 = V.where type: 'song', performances: 10
51
+ song_10.name
52
+ => ["TOMORROW IS FOREVER", "SHE BELONGS TO ME", "UNBROKEN CHAIN"]
53
+ song_10.out_written_by.in.name
54
+ => [["Dolly_Parton"], ["Bob_Dylan"], ["Petersen"]]
55
+ ```
56
+ * Select all the songs that have been performed more or less 10 times
57
+
58
+ ```ruby
59
+ V.where "type = 'song’ and performances > 10"
60
+ V.where "type = 'song’ and performances < 10"
61
+ ```
62
+ * Count all songs and artists
63
+
64
+ ```ruby
65
+ V.count where: { type: 'song' }
66
+ V.count where: { type: 'song', performances: 10 }
67
+
68
+ V.count where: { type: 'artist' }
69
+ ```
70
+
71
+
72
+ * Find all songs sung by the first artist
73
+
74
+ First get the artist
75
+ ```ruby
76
+ first_artist = OrientSupport::OrientQuery.new from: artist_vertex, where: { type: 'artist'} , limit: 1
77
+ first_artist.to_s => "select from V where type = 'artist' limit 1"
78
+ ```
79
+ Traverse through the database. List any song and author that is sung by this artist
80
+
81
+ ```ruby
82
+ songs = DB.execute{ "select expand(set(in('sung_by'))) from (#{first_artist.to_s}) " }
83
+ songs.name
84
+ ==> ["ROSA LEE MCFALL", "ROW JIMMY", "THAT WOULD BE SOMETHING", "BETTY AND DUPREE", "WHISKEY IN THE JAR", ...]
85
+
86
+ authors = DB.execute{ "select expand(set(in('sung_by').out('written_by'))) from (#{first_artist.to_s}) " }
87
+ authors.name
88
+ ==> ["Bob_Dylan", "Chuck_Berry", "Unknown", "Bernie_Casey_Pinkard", ...]
89
+
90
+ ```
91
+
92
+ go [Back](./README.md) to the introduction page
93
+
94
+
@@ -1,7 +1,7 @@
1
1
 
2
2
  module OrientDB
3
3
  UsingJava = RUBY_PLATFORM == 'java' ? true : false
4
- unless RUBY_PLATFORM == 'java'
4
+ unless UsingJava
5
5
  DocumentDatabase = nil
6
6
  DocumentDatabasePool = nil
7
7
  DocumentDatabasePooled = nil
@@ -26,12 +26,14 @@ module OrientDB
26
26
  # RecordSet = nil
27
27
  end
28
28
  end # module OrientDB
29
+ require 'active_model'
30
+ #require 'active_model/serializers'
29
31
  require_relative "support.rb"
30
32
  require_relative "base.rb"
31
33
  require_relative "base_properties.rb"
32
34
  require_relative "orient.rb"
33
35
  #require_relative "query.rb"
34
- if RUBY_PLATFORM == 'java'
36
+ if OrientDB::UsingJava
35
37
  require_relative 'java-api.rb'
36
38
  end
37
39
  require_relative "orientdb_private.rb" # manage private functions
@@ -1,5 +1,5 @@
1
1
  module ActiveOrient
2
- require 'active_model'
2
+
3
3
 
4
4
  # Base class for tableless IB data Models, extends ActiveModel API
5
5
 
@@ -8,7 +8,7 @@ module ActiveOrient
8
8
  extend ActiveModel::Callbacks
9
9
  include ActiveModel::Validations
10
10
  include ActiveModel::Serialization
11
- include ActiveModel::Serializers::Xml
11
+ # include ActiveModel::Serializers::Xml
12
12
  include ActiveModel::Serializers::JSON
13
13
  include OrientDB
14
14
 
@@ -41,6 +41,10 @@ module ActiveOrient
41
41
  @@rid_store[rid]
42
42
  end
43
43
 
44
+ def self.reset_rid_store
45
+ @@rid_store = Hash.new
46
+ end
47
+
44
48
  def self.store_rid obj
45
49
  if obj.rid.present? && obj.rid.rid?
46
50
  # return the presence of a stored object as true by the block
@@ -104,16 +108,26 @@ The model instance fields are then set automatically from the opts Hash.
104
108
  end
105
109
 
106
110
  if @metadata[:fieldTypes ].present? && (@metadata[:fieldTypes] =~ /=g/)
111
+ @metadata[:edges] = { :in => [], :out => [] }
107
112
  edges = @metadata['fieldTypes'].split(',').find_all{|x| x=~/=g/}.map{|x| x.split('=').first}
113
+ # puts "Detected EDGES: #{edges.inspect}"
108
114
  edges.each do |edge|
109
115
  operator, *base_edge = edge.split('_')
110
116
  base_edge = base_edge.join('_')
111
- unless self.class.instance_methods.detect{|x| x == base_edge}
112
- ## define two methods: out_{Edge}/in_{Edge} -> edge.
113
- self.class.define_property base_edge, nil
114
- self.class.send :alias_method, base_edge.underscore, edge
115
- end
117
+ @metadata[:edges][operator.to_sym] << base_edge
116
118
  end
119
+ # unless self.class.instance_methods.detect{|x| x == base_edge}
120
+ # ## define two methods: out_{Edge}/in_{Edge} -> edge.
121
+ # self.class.define_property base_edge, nil
122
+ # allocate_edge_method = -> (edge) do
123
+ # unless (ee=db.get_db_superclass(edge)) == "E"
124
+ # allocate_edge_method[ee]
125
+ # self.class.send :alias_method, base_edge.underscore, edge
126
+ # ## define inherented classes, tooa
127
+ #
128
+
129
+ # end
130
+ # end
117
131
  end
118
132
  end
119
133
  self.attributes = attributes # set_attribute_defaults is now after_init callback
@@ -132,6 +146,19 @@ The model instance fields are then set automatically from the opts Hash.
132
146
  attrs.keys.each{|key| self.send("#{key}=", attrs[key])}
133
147
  end
134
148
 
149
+ def my_metadata key: nil, symbol: nil
150
+ if @metadata[:fieldTypes].present?
151
+ meta= Hash[ @metadata['fieldTypes'].split(',').map{|x| x.split '='} ]
152
+ if key.present?
153
+ meta[key.to_s]
154
+ elsif symbol.present?
155
+ meta.map{|x,y| x if y == symbol.to_s }.compact
156
+ else
157
+ meta
158
+ end
159
+ end
160
+ end
161
+
135
162
  =begin
136
163
  ActiveModel-style read/write_attribute accessors
137
164
  Autoload mechanism and data conversion are defined in the method "from_orient" of each class
@@ -139,8 +166,12 @@ The model instance fields are then set automatically from the opts Hash.
139
166
 
140
167
  def [] key
141
168
  iv = attributes[key.to_sym]
142
- if @metadata[:fieldTypes].present? && @metadata[:fieldTypes].include?(key.to_s+"=t")
169
+ # puts my_metadata( key: key)
170
+ if my_metadata( key: key) == "t"
171
+ # puts "time detected"
143
172
  iv =~ /00:00:00/ ? Date.parse(iv) : DateTime.parse(iv)
173
+ elsif my_metadata( key: key) == "x"
174
+ iv = ActiveOrient::Model.autoload_object iv
144
175
  elsif iv.is_a? Array
145
176
  OrientSupport::Array.new( work_on: self, work_with: iv.from_orient){ key.to_sym }
146
177
  elsif iv.is_a? Hash
@@ -154,9 +185,11 @@ The model instance fields are then set automatically from the opts Hash.
154
185
  end
155
186
 
156
187
  def []= key, val
188
+ # puts "here I am: #{key}, #{val}"
157
189
  val = val.rid if val.is_a?( ActiveOrient::Model ) && val.rid.rid?
158
190
  attributes[key.to_sym] = case val
159
191
  when Array
192
+ # puts "I am an Array"
160
193
  if val.first.is_a?(Hash)
161
194
  v = val.map do |x|
162
195
  if x.is_a?(Hash)
@@ -194,20 +227,20 @@ The model instance fields are then set automatically from the opts Hash.
194
227
 
195
228
  # ActiveRecord::Base association API mocks
196
229
  #
197
- # def self.belongs_to model, *args
198
- # attr_accessor model
199
- # end
230
+ def self.belongs_to model, *args
231
+ attr_accessor model
232
+ end
200
233
  #
201
- # def self.has_one model, *args
202
- # attr_accessor model
203
- # end
234
+ def self.has_one model, *args
235
+ attr_accessor model
236
+ end
204
237
  #
205
- # def self.has_many models, *args
206
- # attr_accessor models
207
- # define_method(models) do
208
- # self.instance_variable_get("@#{models}") || self.instance_variable_set("@#{models}", [])
209
- # end
210
- # end
238
+ def self.has_many models, *args
239
+ attr_accessor models
240
+ define_method(models) do
241
+ self.instance_variable_get("@#{models}") || self.instance_variable_set("@#{models}", [])
242
+ end
243
+ end
211
244
  #
212
245
  # def self.find *args
213
246
  # []
@@ -54,8 +54,7 @@ module ActiveOrient
54
54
  # Default attributes support
55
55
 
56
56
  def default_attributes
57
- {:created_at => Time.now,
58
- :updated_at => Time.now}
57
+ {:created_at => DateTime.now }
59
58
  end
60
59
 
61
60
  def set_attribute_defaults # :nodoc:
@@ -138,7 +137,7 @@ module ActiveOrient
138
137
  end
139
138
 
140
139
  unless defined?(ActiveRecord::Base) && ancestors.include?(ActiveRecord::Base)
141
- prop :created_at, :updated_at
140
+ prop :created_at #, :updated_at
142
141
  end
143
142
 
144
143
  end # included
@@ -13,7 +13,7 @@ module ClassUtils
13
13
  name_or_class.ref_name
14
14
  # name_or_class.to_s.split('::').last
15
15
  else
16
- name_or_class.to_s #.to_s.camelcase # capitalize_first_letter
16
+ name_or_class.to_s.split(':').last #.to_s.camelcase # capitalize_first_letter
17
17
  end
18
18
  ## 16/5/31 : reintegrating functionality to check wether the classname is
19
19
  # present in the database or not
@@ -60,10 +60,10 @@ takes a classes-array as argument
60
60
  def allocate_classes_in_ruby classes # :nodoc:
61
61
  generate_ruby_object = ->( name, superclass, abstract ) do
62
62
  begin
63
- # if the class is prefined, use specs from get_classes
63
+ # if the class is predefined, use specs from get_classes
64
64
  or_def = get_classes('name', 'superClass', 'abstract' ).detect{|x| x['name']== name.to_s }
65
65
  superclass, abstract = or_def.reject{|k,v| k=='name'}.values unless or_def.nil?
66
- # print "GENERATE_RUBY_CLASS: #{name} / #{superclass} \n"
66
+ #print "GENERATE_RUBY_CLASS: #{name} / #{superclass} \n"
67
67
  m= ActiveOrient::Model.orientdb_class name: name, superclass: superclass
68
68
  m.abstract = abstract
69
69
  m.ref_name = name.to_s
@@ -109,7 +109,6 @@ def allocate_classes_in_ruby classes # :nodoc:
109
109
  when String, Symbol
110
110
  generate_ruby_object[classes,superclass, abstract]
111
111
  end
112
- # consts.unshift superclass_object if superclass_object.present? rescue [ superclass_object, consts ]
113
112
  consts
114
113
  end
115
114
  =begin
@@ -27,9 +27,9 @@ if abstract: true is given, only basic classes (Abstact-Classes) are returend
27
27
  =end
28
28
 
29
29
  def class_hierarchy base_class: '', system_classes: nil
30
- @all_classes = get_classes('name', 'superClass') #if requery || @all_classes.blank?
30
+ @actual_class_hash = get_classes('name', 'superClass') #if requery || @all_classes.blank?
31
31
  def fv s # :nodoc:
32
- @all_classes.find_all{|x| x['superClass']== s}.map{|v| v['name']}
32
+ @actual_class_hash.find_all{|x| x['superClass']== s}.map{|v| v['name']}
33
33
  end
34
34
 
35
35
  def fx v # :nodoc:
@@ -78,20 +78,29 @@ Service-Method for Model#OrientdbClass
78
78
  def get_db_superclass name
79
79
  @actual_class_hash = get_classes( 'name', 'superClass') if @actual_class_hash.nil?
80
80
  z= @actual_class_hash.find{|x,y| x['name'] == name.to_s }
81
- z['superclass'] unless z.nil?
81
+ z['superClass'] unless z.nil?
82
82
 
83
83
  end
84
84
 
85
85
  =begin
86
86
  preallocate classes reads any class from the @classes-Array and allocates adequat Ruby-Objects
87
87
  =end
88
- def preallocate_classes
88
+ def preallocate_classes from_model_dir= nil
89
89
  # first fetch all non-system-classes
90
90
  # io = class_hierarchy
91
91
  # allocate them and call require_model_file on each model
92
92
  # if something goes wrong, allocate_classes_in_ruby returns nil, thus compact prevents
93
93
  # from calling NilClass.require_model_file
94
- allocate_classes_in_ruby(class_hierarchy).flatten.compact.each &:require_model_file
94
+ all_classes = allocate_classes_in_ruby(class_hierarchy).flatten.compact
95
+ classes_with_model_files = all_classes.map do |x|
96
+ success = x.require_model_file(from_model_dir)
97
+ if ActiveOrient::Model.keep_models_without_file.nil? && success.nil? && ![E,V].include?(x)
98
+ logger.info{ "Database-Class #{x.name} is not asseccible, model file is missing "}
99
+ x.delete_class :only_ruby_space
100
+ end
101
+ success # return_value
102
+ end
103
+
95
104
  end
96
105
 
97
106
  end # module
@@ -3,11 +3,21 @@ module ActiveOrient
3
3
 
4
4
  =begin
5
5
  Parameters: yml: hash from config.yml , namespace: Class to use as Namespace
6
+ A custom Constant can be provided via Block
6
7
 
8
+ i.e.
9
+ configyml = YAML.load_file (...) # with an entry "namespace:"
10
+ ActiveOrient.define_namespace yml: configyml
11
+ #or
12
+ ActiveOrient.define_namespace namespace: :self | :object | :active_orient
13
+ #or
14
+ ActiveOrient.define_namespace { IB }
7
15
  =end
8
- def define_namespace yml: {}, namespace: nil
16
+ def self.define_namespace yml: {}, namespace: nil
9
17
  ActiveOrient::Model.namespace = if namespace.present?
10
18
  namespace
19
+ elsif block_given?
20
+ yield
11
21
  else
12
22
  n= yml[:namespace].presence || :self
13
23
  case n
@@ -14,7 +14,7 @@ Creates individual indices for child-classes if applied to the class itself.
14
14
  def uniq_index
15
15
  create_property :in, type: :link, linked_class: :V
16
16
  create_property :out, type: :link, linked_class: :V
17
- create_index "#{self.name}_idx", on: [ :in, :out ]
17
+ create_index "#{ref_name}_idx", on: [ :in, :out ]
18
18
  end
19
19
  =begin
20
20
  Instantiate a new Edge between two Vertices
@@ -29,20 +29,22 @@ Creates individual indices for child-classes if applied to the class itself.
29
29
  def create **keyword_arguments
30
30
  new_edge = db.create_edge self, **keyword_arguments
31
31
  new_edge = new_edge.pop if new_edge.is_a?( Array) && new_edge.size == 1
32
+ # to.reload! if to.is_a? ActiveOrient::Model
33
+ # from.reload! if from.is_a? ActiveOrient::Model
32
34
  # vertices must be reloaded
33
35
 
34
36
  new_edge # returns the created edge (or an array of created edges
35
37
  end
36
38
 
37
- # to do
38
- # def delete
39
- # delete an edge (as class method)
40
- # and
41
- # def remove
42
- # delete an edge (as instance method)
43
- #
44
- def delete where: attributes
45
- puts "work in progress"
39
+ =begin
40
+ Edge#delete fires a "delete edge" command to the database.
41
+ The where statement can be empty ( "" or {}"), then all edges are removed
42
+
43
+ The rid-cache is reseted, too
44
+ =end
45
+ def delete where:
46
+ db.execute { "delete edge #{ref_name} #{db.compose_where(where)}" }
47
+ reset_rid_store
46
48
  end
47
49
 
48
50
  # remove works on record-level
@@ -47,10 +47,22 @@ Note: This function is not in ModelClass since it needs to use @@rid_store
47
47
  =begin
48
48
  Deletes the database class and removes the ruby-class
49
49
  =end
50
- def self.delete_class
51
- orientdb.delete_class self
50
+ def self.delete_class what= :all
51
+ orientdb.delete_class( self ) if what == :all # remove the database-class
52
52
  ## namespace is defined in config/boot
53
- namespace.send(:remove_const, naming_convention.to_sym)
53
+ ns = namespace.to_s == 'Object' ? "" : namespace.to_s
54
+ ns_found = -> ( a_class ) do
55
+ to_compare = a_class.to_s.split(':')
56
+ if ns == "" && to_compare.size == 1
57
+ true
58
+ elsif to_compare.first == ns
59
+ true
60
+ else
61
+ false
62
+ end
63
+ end
64
+ self.allocated_classes.delete_if{|x,y| x == self.ref_name && ns_found[y]} if allocated_classes.is_a?(Hash)
65
+ namespace.send(:remove_const, naming_convention.to_sym) if namespace.send( :const_defined?, naming_convention)
54
66
  end
55
67
 
56
68
  # provides an unique accessor on the Class
@@ -62,6 +74,8 @@ Deletes the database class and removes the ruby-class
62
74
  # mattr_accessor :logger ... already inherented from ::Base
63
75
  mattr_accessor :namespace # Namespace in which Model records are initialized, a constant ( defined in config.yml )
64
76
  mattr_accessor :model_dir # path to model-files
77
+ mattr_accessor :keep_models_without_file
78
+ mattr_accessor :allocated_classes
65
79
 
66
80
  # mattr_accessor :ref_name
67
81
  # Used to read the metadata
@@ -45,20 +45,36 @@ To overwrite use
45
45
  def orientdb_class name:, superclass: nil # :nodoc: # public method: autoload_class
46
46
  logger.progname = "ModelClass#OrientDBClass"
47
47
  # @s-class is a cash for actual String -> Class relations
48
- @s_class = HashWithIndifferentAccess.new( V: V, E: E) unless @s_class.present?
48
+ self.allocated_classes = HashWithIndifferentAccess.new( V: V, E: E) unless allocated_classes.present?
49
49
 
50
- update_my_array = ->(s) { @s_class[s.ref_name] = s unless @s_class[s.ref_name].present? }
51
- get_class = ->(n) { @s_class[n] }
50
+ #update_my_array = ->(s) { self.allocated_classes[s.ref_name] = s unless allocated_classes[s.ref_name].present? }
51
+ update_my_array = ->(s) do
52
+ if allocated_classes[s.ref_name].present?
53
+ # puts "found ref_name: #{allocated_classes[s.ref_name]}"
54
+ else
55
+ self.allocated_classes[s.ref_name] = s
56
+ end
57
+
58
+ end
59
+ get_class = ->(n) { allocated_classes[n] }
60
+ extract_namespace = -> (n) do
61
+ if get_class[n].present?
62
+ separated_class_parts = get_class[n].to_s.split(':')
63
+ separated_class_parts.size >1 ? separated_class_parts.first.constantize : namespace
64
+ else
65
+ namespace
66
+ end
67
+ end
52
68
 
53
69
 
54
70
  ref_name = name.to_s
55
71
  klass = if superclass.present? # superclass is parameter, use if class, otherwise transfer to class
56
72
  s= if superclass.is_a? Class
57
- namespace.send( :const_get, superclass.to_s )
73
+ extract_namespace[name].send( :const_get, superclass.to_s )
58
74
  else
59
75
  superclass = orientdb.get_db_superclass( ref_name ) if superclass == :find_ME
60
76
  if superclass.present?
61
- namespace.send( :const_get, get_class[superclass].to_s )
77
+ extract_namespace[name].send( :const_get, get_class[superclass].to_s )
62
78
  else
63
79
  self
64
80
  end
@@ -68,12 +84,13 @@ To overwrite use
68
84
  Class.new(self)
69
85
  end
70
86
  # namespace is defined in config/boot
87
+ this_namespace = extract_namespace[ref_name]
71
88
  name = klass.naming_convention ref_name #
72
- if namespace.send :const_defined?, name
73
- retrieved_class = namespace.send :const_get, name
89
+ if this_namespace.send :const_defined?, name
90
+ retrieved_class = this_namespace.send :const_get, name
74
91
  else
75
92
 
76
- new_class = namespace.send :const_set, name, klass
93
+ new_class = this_namespace.send :const_set, name, klass
77
94
  new_class.ref_name = ref_name
78
95
  update_my_array[new_class]
79
96
  # logger.debug{"created:: Class #{new_class} < #{new_class.superclass} "}
@@ -112,23 +129,27 @@ class does not reestablish the connection to the required model file.
112
129
 
113
130
  Actual only a flat directory is supported. However -the Parameter model has the format: [ superclass, class ]. Its possible to extend the method adress a model-tree.
114
131
  =end
115
- def require_model_file
132
+ def require_model_file dir=nil
116
133
  logger.progname = 'ModelClass#RequireModelFile'
117
- if File.exists?( ActiveOrient::Model.model_dir )
134
+ dir = dir.presence || ActiveOrient::Model.model_dir
135
+ if File.exists?( dir )
118
136
  model= model.flatten.last if model.is_a?( Array )
119
- filename = ActiveOrient::Model.model_dir + "/" + self.to_s.underscore + '.rb'
120
- puts "REQUIRE_MODEL_FILE: #{self.to_s} <-- #{self.superclass}"
137
+ filename = dir + "/" + self.to_s.underscore + '.rb'
121
138
  if File.exists?(filename )
122
139
  if load filename
123
140
  logger.info{ "#{filename} sucessfully loaded" }
141
+ self #return_value
124
142
  else
125
143
  logger.error{ "#{filename} load error" }
144
+ nil #return_value
126
145
  end
127
146
  else
128
147
  logger.info{ "model-file not present: #{filename}" }
148
+ nil #return_value
129
149
  end
130
150
  else
131
- logger.info{ "Directory #{ ActiveOrient::Model.model_dir } not present " }
151
+ logger.info{ "Directory #{ dir } not present " }
152
+ nil #return_value
132
153
  end
133
154
  rescue TypeError => e
134
155
  puts "TypeError: #{e.message}"
@@ -180,9 +201,28 @@ otherwise update it. It returns the freshly instantiated Objects
180
201
  end
181
202
 
182
203
  alias update_or_create_documents update_or_create_records
183
- alias create_or_update_document upsert
184
- alias update_or_create upsert
185
204
 
205
+ =begin
206
+ Sets a value to certain attributes, overwrites existing entries, creates new attributes if nessesary
207
+
208
+ IB::Account.update_all connected: false
209
+ IB::Account.update_all where: "account containsText 'F'", set:{ connected: false }
210
+
211
+ **note: By calling UpdateAll, all records of the Class previously stored in the rid-cache are removed from the cache. Thus autoload gets the updated records.
212
+ =end
213
+
214
+ def update_all where: {} , set: {}, **arg
215
+ if where.empty?
216
+ set.merge! arg
217
+ end
218
+ db.update_records self, set: set, where: where
219
+
220
+ end
221
+ #
222
+ # removes a property from the collection (where given) or the entire class
223
+ def remove attribute, where:{}
224
+ db.update_records self, remove: attribute, where: where
225
+ end
186
226
 
187
227
  =begin
188
228
  Create a Property in the Schema of the Class
@@ -319,11 +359,11 @@ otherwise update it. It returns the freshly instantiated Objects
319
359
 
320
360
  def custom_where search_string
321
361
  q = OrientSupport::OrientQuery.new from: self, where: search_string
322
- puts q.compose
362
+ #puts q.compose
323
363
  query_database q
324
364
  end
325
- def where **attributes
326
- ##puts "ATTRIBUTES: "+attributes.inspect
365
+ def where *attributes
366
+ ## puts "ATTRIBUTES: "+attributes.inspect
327
367
  q = OrientSupport::OrientQuery.new from: self, where: attributes
328
368
  query_database q
329
369
  end
@@ -373,20 +413,6 @@ By using subsequent »connect« and »statement« method-calls even complex Matc
373
413
  end
374
414
 
375
415
 
376
- # Get the superclass of the class
377
-
378
- def superClass
379
- { superclass => superclass.ref_name }
380
- # logger.progname = 'ActiveOrient::Model#Superclass'
381
- # r = orientdb.get_classes('name', 'superClass').detect{|x|
382
- # x["name"].downcase == new.class.to_s.downcase.split(':')[-1].to_s
383
- # }['superClass']
384
- # if r.empty?
385
- # logger.info{"#{self} does not have any superclass. Probably it is a Document"}
386
- # end
387
- # return r
388
- end
389
-
390
416
  =begin
391
417
  QueryDatabase sends the Query, direct to the database.
392
418
  The result is not nessessary an Object of self.
@@ -424,14 +450,6 @@ By using subsequent »connect« and »statement« method-calls even complex Matc
424
450
  alias delete_documents delete_records
425
451
 
426
452
 
427
- ########### UPDATE #############
428
-
429
- # Update records of a class
430
-
431
- def update_records set:, where:
432
- db.update_records self, set: set, where: where
433
- end
434
- alias update_documents update_records
435
453
 
436
454
  ##################### EXPERIMENT #################
437
455
 
@@ -477,4 +495,6 @@ By using subsequent »connect« and »statement« method-calls even complex Matc
477
495
  orientdb.alter_property self, property: property, attribute: attribute, alteration: alteration
478
496
  end
479
497
 
498
+
499
+
480
500
  end