active-orient 0.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -2
- data/README.md +78 -35
- data/VERSION +1 -1
- data/active-orient.gemspec +4 -4
- data/bin/active-orient-console +8 -5
- data/config/boot.rb +2 -4
- data/config/config.yml +1 -1
- data/config/connect.yml +2 -2
- data/examples/time_graph.md +162 -0
- data/gratefuldeadconcerts.md +94 -0
- data/lib/active-orient.rb +4 -2
- data/lib/base.rb +53 -20
- data/lib/base_properties.rb +2 -3
- data/lib/class_utils.rb +3 -4
- data/lib/database_utils.rb +14 -5
- data/lib/init.rb +11 -1
- data/lib/model/edge.rb +12 -10
- data/lib/model/model.rb +17 -3
- data/lib/model/the_class.rb +60 -40
- data/lib/model/the_record.rb +63 -51
- data/lib/model/vertex.rb +114 -10
- data/lib/orient.rb +24 -33
- data/lib/orientdb_private.rb +31 -31
- data/lib/other.rb +55 -5
- data/lib/rest/change.rb +17 -4
- data/lib/rest/create.rb +38 -24
- data/lib/rest/delete.rb +3 -2
- data/lib/rest/operations.rb +37 -27
- data/lib/rest/read.rb +2 -2
- data/lib/rest/rest.rb +4 -3
- data/lib/support.rb +17 -16
- data/linkmap.md +75 -0
- data/namespace.md +111 -0
- data/rails.md +125 -0
- data/rails/activeorient.rb +53 -0
- data/{examples/time_graph/config → rails}/config.yml +3 -1
- data/{examples/time_graph/config → rails}/connect.yml +2 -2
- data/usecase_oo.md +3 -1
- metadata +21 -38
- data/examples/createTime.rb +0 -91
- data/examples/time_graph/Gemfile +0 -21
- data/examples/time_graph/Guardfile +0 -26
- data/examples/time_graph/README.md +0 -129
- data/examples/time_graph/bin/active-orient-console +0 -35
- data/examples/time_graph/config/boot.rb +0 -119
- data/examples/time_graph/config/init_db.rb +0 -59
- data/examples/time_graph/createTime.rb +0 -51
- data/examples/time_graph/lib/createTime.rb +0 -82
- data/examples/time_graph/model/day_of.rb +0 -3
- data/examples/time_graph/model/e.rb +0 -6
- data/examples/time_graph/model/edge.rb +0 -53
- data/examples/time_graph/model/monat.rb +0 -19
- data/examples/time_graph/model/stunde.rb +0 -16
- data/examples/time_graph/model/tag.rb +0 -29
- data/examples/time_graph/model/time_base.rb +0 -6
- data/examples/time_graph/model/time_of.rb +0 -4
- data/examples/time_graph/model/v.rb +0 -3
- data/examples/time_graph/model/vertex.rb +0 -32
- data/examples/time_graph/spec/lib/create_time_spec.rb +0 -50
- data/examples/time_graph/spec/rest_helper.rb +0 -37
- data/examples/time_graph/spec/spec_helper.rb +0 -46
- 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
|
+
|
data/lib/active-orient.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
module OrientDB
|
3
3
|
UsingJava = RUBY_PLATFORM == 'java' ? true : false
|
4
|
-
unless
|
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
|
36
|
+
if OrientDB::UsingJava
|
35
37
|
require_relative 'java-api.rb'
|
36
38
|
end
|
37
39
|
require_relative "orientdb_private.rb" # manage private functions
|
data/lib/base.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module ActiveOrient
|
2
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
198
|
-
|
199
|
-
|
230
|
+
def self.belongs_to model, *args
|
231
|
+
attr_accessor model
|
232
|
+
end
|
200
233
|
#
|
201
|
-
|
202
|
-
|
203
|
-
|
234
|
+
def self.has_one model, *args
|
235
|
+
attr_accessor model
|
236
|
+
end
|
204
237
|
#
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
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
|
# []
|
data/lib/base_properties.rb
CHANGED
@@ -54,8 +54,7 @@ module ActiveOrient
|
|
54
54
|
# Default attributes support
|
55
55
|
|
56
56
|
def default_attributes
|
57
|
-
{:created_at =>
|
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
|
140
|
+
prop :created_at #, :updated_at
|
142
141
|
end
|
143
142
|
|
144
143
|
end # included
|
data/lib/class_utils.rb
CHANGED
@@ -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
|
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
|
-
#
|
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
|
data/lib/database_utils.rb
CHANGED
@@ -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
|
-
@
|
30
|
+
@actual_class_hash = get_classes('name', 'superClass') #if requery || @all_classes.blank?
|
31
31
|
def fv s # :nodoc:
|
32
|
-
@
|
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['
|
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
|
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
|
data/lib/init.rb
CHANGED
@@ -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
|
data/lib/model/edge.rb
CHANGED
@@ -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 "#{
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
data/lib/model/model.rb
CHANGED
@@ -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
|
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.
|
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
|
data/lib/model/the_class.rb
CHANGED
@@ -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
|
-
|
48
|
+
self.allocated_classes = HashWithIndifferentAccess.new( V: V, E: E) unless allocated_classes.present?
|
49
49
|
|
50
|
-
update_my_array = ->(s) {
|
51
|
-
|
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
|
-
|
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
|
-
|
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
|
73
|
-
retrieved_class =
|
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 =
|
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
|
-
|
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 =
|
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 #{
|
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
|
326
|
-
|
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
|