active-orient 0.5 → 0.6

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