active-orient 0.6 → 0.42
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/Gemfile +4 -10
- data/Guardfile +4 -12
- data/README.md +198 -261
- data/VERSION +1 -1
- data/active-orient-0.4.gem +0 -0
- data/active-orient-0.41.gem +0 -0
- data/active-orient.gemspec +5 -6
- data/config/boot.rb +0 -84
- data/config/connect.yml +4 -8
- data/examples/books.rb +39 -86
- data/examples/streets.rb +84 -85
- data/lib/active-orient.rb +9 -57
- data/lib/base.rb +145 -172
- data/lib/base_properties.rb +44 -40
- data/lib/model.rb +468 -0
- data/lib/orient.rb +60 -114
- data/lib/query.rb +73 -71
- data/lib/rest.rb +1059 -0
- data/lib/support.rb +319 -386
- data/test.rb +4 -0
- data/usecase.md +91 -0
- metadata +20 -65
- data/bin/active-orient-console +0 -38
- data/config/config.yml +0 -10
- data/create_project +0 -19
- data/examples/test_commands.rb +0 -92
- data/examples/test_commands_2.rb +0 -54
- data/examples/test_commands_3.rb +0 -48
- data/examples/test_commands_4.rb +0 -28
- data/examples/time_graph.md +0 -162
- data/gratefuldeadconcerts.md +0 -94
- data/lib/class_utils.rb +0 -300
- data/lib/database_utils.rb +0 -106
- data/lib/init.rb +0 -45
- data/lib/java-api.rb +0 -437
- data/lib/jdbc.rb +0 -211
- data/lib/model/edge.rb +0 -55
- data/lib/model/model.rb +0 -91
- data/lib/model/the_class.rb +0 -500
- data/lib/model/the_record.rb +0 -322
- data/lib/model/vertex.rb +0 -136
- data/lib/orientdb_private.rb +0 -48
- data/lib/other.rb +0 -330
- data/lib/rest/change.rb +0 -137
- data/lib/rest/create.rb +0 -488
- data/lib/rest/delete.rb +0 -134
- data/lib/rest/operations.rb +0 -160
- data/lib/rest/read.rb +0 -150
- data/lib/rest/rest.rb +0 -112
- data/lib/rest_disabled.rb +0 -24
- data/linkmap.md +0 -75
- data/namespace.md +0 -111
- data/old_lib_functions/two_general_class.rb +0 -139
- data/rails.md +0 -125
- data/rails/activeorient.rb +0 -53
- data/rails/config.yml +0 -10
- data/rails/connect.yml +0 -17
- data/usecase_oo.md +0 -61
data/lib/model/the_record.rb
DELETED
@@ -1,322 +0,0 @@
|
|
1
|
-
module ModelRecord
|
2
|
-
############### RECORD FUNCTIONS ###############
|
3
|
-
|
4
|
-
############# GET #############
|
5
|
-
|
6
|
-
def from_orient
|
7
|
-
self
|
8
|
-
end
|
9
|
-
|
10
|
-
# Returns just the name of the Class
|
11
|
-
|
12
|
-
def self.classname # :nodoc:
|
13
|
-
self.class.to_s.split(':')[-1]
|
14
|
-
end
|
15
|
-
|
16
|
-
#
|
17
|
-
# Obtain the RID of the Record (format: "00:00")
|
18
|
-
#
|
19
|
-
|
20
|
-
def rid
|
21
|
-
begin
|
22
|
-
"#{@metadata[:cluster]}:#{@metadata[:record]}"
|
23
|
-
rescue
|
24
|
-
"0:0"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
=begin
|
28
|
-
The extended representation of rid (format "#00:00" )
|
29
|
-
=end
|
30
|
-
def rrid
|
31
|
-
"#" + rid
|
32
|
-
end
|
33
|
-
alias to_orient rrid
|
34
|
-
|
35
|
-
def to_or
|
36
|
-
rrid
|
37
|
-
end
|
38
|
-
=begin
|
39
|
-
Query uses the current model-record as origin of the query
|
40
|
-
It sends the OrientSupport::OrientQuery directly to the database and returns a
|
41
|
-
ActiveOrient::Model-Object or an Array of Model-Objects as result.
|
42
|
-
|
43
|
-
=end
|
44
|
-
|
45
|
-
def query query
|
46
|
-
|
47
|
-
sql_cmd = -> (command) {{ type: "cmd", language: "sql", command: command }}
|
48
|
-
result = orientdb.execute do
|
49
|
-
sql_cmd[query.to_s]
|
50
|
-
end
|
51
|
-
if result.is_a? Array
|
52
|
-
OrientSupport::Array.new work_on: self, work_with: result
|
53
|
-
else
|
54
|
-
result
|
55
|
-
end # return value
|
56
|
-
end
|
57
|
-
|
58
|
-
=begin
|
59
|
-
queries the database starting with the current model-record.
|
60
|
-
|
61
|
-
Returns the result-set, ie. a Query-Object which contains links to the addressed records.
|
62
|
-
|
63
|
-
=end
|
64
|
-
def find attributes = {}
|
65
|
-
q = OrientSupport::OrientQuery.new from: self, where: attributes
|
66
|
-
query q
|
67
|
-
end
|
68
|
-
|
69
|
-
# Get the version of the object
|
70
|
-
def version # :nodoc:
|
71
|
-
if document.present?
|
72
|
-
document.version
|
73
|
-
else
|
74
|
-
@metadata[:version]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def version= version # :nodoc:
|
79
|
-
@metadata[:version] = version
|
80
|
-
end
|
81
|
-
|
82
|
-
def increment_version # :nodoc:
|
83
|
-
@metadata[:version] += 1
|
84
|
-
end
|
85
|
-
########### UPDATE PROPERTY ############
|
86
|
-
|
87
|
-
=begin
|
88
|
-
Convient method for populating embedded- or linkset-properties
|
89
|
-
In both cases an array/a collection is stored in the database.
|
90
|
-
Its called via
|
91
|
-
model.add_item_to_property(linkset- or embedded property, Object_to_be_linked_to\)
|
92
|
-
or
|
93
|
-
mode.add_items_to_property( linkset- or embedded property ) do
|
94
|
-
Array_of_Objects_to_be_linked_to
|
95
|
-
#(actually, the objects must inherent from ActiveOrient::Model, Numeric, String)
|
96
|
-
end
|
97
|
-
|
98
|
-
The method is aliased by "<<" i.e
|
99
|
-
model.array << new_item
|
100
|
-
=end
|
101
|
-
|
102
|
-
def update_item_property method, array, item = nil, &ba # :nodoc:
|
103
|
-
# begin
|
104
|
-
logger.progname = 'ActiveOrient::Model#UpdateItemToProperty'
|
105
|
-
self.attributes[array] = Array.new unless attributes[array].present?
|
106
|
-
|
107
|
-
items = if item.present?
|
108
|
-
item.is_a?(Array)? item : [item]
|
109
|
-
elsif block_given?
|
110
|
-
yield
|
111
|
-
end
|
112
|
-
db.manipulate_relation self, method, array, items
|
113
|
-
end
|
114
|
-
=begin
|
115
|
-
Add Items to a linked or embedded class
|
116
|
-
Parameter
|
117
|
-
|
118
|
-
array : the name of the property to work on
|
119
|
-
item : what to add (optional)
|
120
|
-
block: has to provide an array of elements to add to the property
|
121
|
-
|
122
|
-
example:
|
123
|
-
|
124
|
-
add_item_to_property :second_list do
|
125
|
-
(0 .. 9).map do | s |
|
126
|
-
SecondList.create label: s
|
127
|
-
end
|
128
|
-
end
|
129
|
-
adds 10 Elements to the property.
|
130
|
-
|
131
|
-
|
132
|
-
The method returns the model record itself. Thus nested initialisations are possible:
|
133
|
-
|
134
|
-
ORD.create_classes([:base, :first_list, :second_list ]){ "V" }
|
135
|
-
ORD.create_property :base, :first_list, type: :linklist, linkedClass: :first_list
|
136
|
-
ORD.create_property :base, :label, index: :unique
|
137
|
-
ORD.create_property :first_list, :second_list , type: :linklist, linkedClass: :second_list
|
138
|
-
ORD.create_vertex_class :log
|
139
|
-
(0 .. 9).each do | b |
|
140
|
-
base= Base.create label: b, first_list: []
|
141
|
-
base.add_item_to_property :first_list do
|
142
|
-
(0 .. 9).map do | f |
|
143
|
-
first = FirstList.create label: f, second_list: []
|
144
|
-
base.add_item_to_property :first_list , first
|
145
|
-
first.add_item_to_property :second_list do
|
146
|
-
(0 .. 9).map{| s | SecondList.create label: s }
|
147
|
-
end # add item second_list
|
148
|
-
end # 0..9 -> f
|
149
|
-
end # add item first_list
|
150
|
-
end # 0..9 -> b
|
151
|
-
|
152
|
-
|
153
|
-
Record#AddItemToProperty shines with its feature to specify records to insert in a block.
|
154
|
-
If only single Items are to insert, use
|
155
|
-
model_record.linklist << item
|
156
|
-
|
157
|
-
=end
|
158
|
-
|
159
|
-
def add_item_to_property array, *item
|
160
|
-
item = yield if block_given?
|
161
|
-
if attributes.keys.include? array.to_s
|
162
|
-
item.each{|x| self.attributes[array].push x.to_orient }
|
163
|
-
update
|
164
|
-
else
|
165
|
-
update array=> item
|
166
|
-
end
|
167
|
-
# rescue NoMethodError
|
168
|
-
#undefined method `<<' for nil:NilClass
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
|
173
|
-
def set_item_to_property array, *item
|
174
|
-
update array.to_s => item
|
175
|
-
end
|
176
|
-
|
177
|
-
def remove_position_from_property array, *pos
|
178
|
-
if attributes[array].is_a? Array
|
179
|
-
pos.each{|x| self.attributes[array].delete_at( x )}
|
180
|
-
update
|
181
|
-
end
|
182
|
-
end
|
183
|
-
def remove_item_from_property array, *item
|
184
|
-
if attributes[array].is_a? Array
|
185
|
-
item.each{|x| self.attributes[array].delete( x.to_orient )}
|
186
|
-
update
|
187
|
-
else
|
188
|
-
logger.error "Wrong attribute: #{attributes[array]}"
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
############# DELETE ###########
|
193
|
-
|
194
|
-
# Removes the Model-Instance from the database
|
195
|
-
# todo: overloaded in vertex and edge
|
196
|
-
|
197
|
-
def remove
|
198
|
-
orientdb.delete_record self
|
199
|
-
ActiveOrient::Base.remove_rid self ##if is_edge? # removes the obj from the rid_store
|
200
|
-
end
|
201
|
-
|
202
|
-
alias delete remove
|
203
|
-
|
204
|
-
########### UPDATE ############
|
205
|
-
|
206
|
-
=begin
|
207
|
-
Convient update of the dataset by calling sql-patch
|
208
|
-
|
209
|
-
Previously changed attributes are saved to the database.
|
210
|
-
With the optional :set argument ad-hoc attributes can be defined
|
211
|
-
obj = ActiveOrient::Model::Contracts.first
|
212
|
-
obj.name = 'new_name'
|
213
|
-
obj.update set: { yesterdays_event: 35 }
|
214
|
-
|
215
|
-
** note: The keyword »set« is optional
|
216
|
-
=end
|
217
|
-
|
218
|
-
def update set: {}, **args
|
219
|
-
logger.progname = 'ActiveOrient::Model#Update'
|
220
|
-
self.attributes.merge!(set) if set.present?
|
221
|
-
self.attributes.merge!(args) if args.present?
|
222
|
-
self.attributes['updated_at'] = DateTime.now
|
223
|
-
if rid.rid?
|
224
|
-
updated_dataset = db.update self, attributes, @metadata[:version]
|
225
|
-
# if the updated dataset changed, drop the changes made siently
|
226
|
-
if updated_dataset.is_a? ActiveOrient::Model
|
227
|
-
self.version = updated_dataset.version
|
228
|
-
updated_dataset # return_value
|
229
|
-
else
|
230
|
-
logger.error("Version Conflict: reloading database values")
|
231
|
-
reload!
|
232
|
-
end
|
233
|
-
else
|
234
|
-
save
|
235
|
-
end
|
236
|
-
|
237
|
-
end
|
238
|
-
|
239
|
-
# mocking active record, overrides the base-class-method
|
240
|
-
def update_attribute the_attribute, the_value
|
241
|
-
update set: {the_attribute => the_value }
|
242
|
-
super the_attribute, the_value
|
243
|
-
end
|
244
|
-
|
245
|
-
def update_attributes **args
|
246
|
-
update set: args
|
247
|
-
end
|
248
|
-
|
249
|
-
########## SAVE ############
|
250
|
-
|
251
|
-
=begin
|
252
|
-
Saves the record either
|
253
|
-
|
254
|
-
* by calling update or
|
255
|
-
* by creating the record
|
256
|
-
|
257
|
-
=end
|
258
|
-
def save
|
259
|
-
if rid.rid?
|
260
|
-
update
|
261
|
-
else
|
262
|
-
db_object= db.create_record self, attributes: attributes
|
263
|
-
@metadata[:cluster], @metadata[:record] = db_object.rid[0,db_object.rid.size].split(':').map( &:to_i)
|
264
|
-
reload! db_object
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
=begin
|
269
|
-
Overwrite the attributes with Database-Contents (or attributes provided by the updated_dataset.model-instance)
|
270
|
-
=end
|
271
|
-
|
272
|
-
def reload! updated_dataset = nil
|
273
|
-
updated_dataset = db.get_record(rid) if updated_dataset.nil?
|
274
|
-
@metadata[:version] = updated_dataset.version
|
275
|
-
self.attributes = updated_dataset.attributes
|
276
|
-
self # return_value (otherwise only the attributes would be returned)
|
277
|
-
end
|
278
|
-
|
279
|
-
########## CHECK PROPERTY ########
|
280
|
-
|
281
|
-
=begin
|
282
|
-
An Edge is defined
|
283
|
-
* when inherented from the superclass »E» (formal definition)
|
284
|
-
* if it has an in- and an out property
|
285
|
-
|
286
|
-
Actually we just check the second term as we trust the constuctor to work properly
|
287
|
-
=end
|
288
|
-
|
289
|
-
def is_edge?
|
290
|
-
attributes.keys.include?('in') && attributes.keys.include?('out')
|
291
|
-
end
|
292
|
-
|
293
|
-
=begin
|
294
|
-
How to handle other calls
|
295
|
-
|
296
|
-
* if attribute is specified, display it
|
297
|
-
* if attribute= is specify, assign to the known property or create a new one
|
298
|
-
|
299
|
-
=end
|
300
|
-
def method_missing *args
|
301
|
-
# if the first entry of the parameter-array is a known attribute
|
302
|
-
# proceed with the assignment
|
303
|
-
if args.size == 1
|
304
|
-
attributes.keys.include?( args.first.to_s ) ? attributes[args.first] : nil
|
305
|
-
elsif args[0][-1] == "="
|
306
|
-
if args.size == 2
|
307
|
-
if rid.rid?
|
308
|
-
update set:{ args[0][0..-2] => args.last }
|
309
|
-
else
|
310
|
-
self.attributes[ args[0][0..-2] ] = args.last
|
311
|
-
end
|
312
|
-
else
|
313
|
-
update set: {args[0][0..-2] => args[1 .. -1] } if rid.rid?
|
314
|
-
end
|
315
|
-
else
|
316
|
-
raise NameError
|
317
|
-
end
|
318
|
-
end
|
319
|
-
#end
|
320
|
-
|
321
|
-
|
322
|
-
end
|
data/lib/model/vertex.rb
DELETED
@@ -1,136 +0,0 @@
|
|
1
|
-
class V < ActiveOrient::Model
|
2
|
-
## link to the library-class
|
3
|
-
|
4
|
-
=begin
|
5
|
-
Vertex#delete fires a "delete edge" command to the database.
|
6
|
-
The where statement can be empty ( "" or {}"), then all vertices are removed
|
7
|
-
|
8
|
-
The rid-cache is reseted, too
|
9
|
-
=end
|
10
|
-
def self.delete where:
|
11
|
-
db.execute { "delete vertex #{ref_name} #{db.compose_where(where)}" }
|
12
|
-
reset_rid_store
|
13
|
-
end
|
14
|
-
|
15
|
-
def detect_inherent_edge kind, edge_name # :nodoc:
|
16
|
-
## returns a list of inherented classes
|
17
|
-
get_superclass = ->(e) do
|
18
|
-
n = ORD.get_db_superclass(e)
|
19
|
-
n =='E' ? e : e + ',' + get_superclass[n]
|
20
|
-
end
|
21
|
-
if edge_name.present?
|
22
|
-
e_name = edge_name.is_a?( Class) ? edge_name.ref_name : edge_name.to_s
|
23
|
-
the_edge = @metadata[:edges][kind].detect{|y| get_superclass[y].split(',').detect{|x| x == edge_name } }
|
24
|
-
|
25
|
-
candidate= attributes["#{kind.to_s}_#{the_edge}"]
|
26
|
-
candidate.present? ? candidate.map( &:from_orient ) : []
|
27
|
-
else
|
28
|
-
edges(kind).map &:from_orient
|
29
|
-
end
|
30
|
-
end
|
31
|
-
=begin
|
32
|
-
»in« and »out« provide the main access to edges.
|
33
|
-
|
34
|
-
If called without a parameter, all edges connected are displayed.
|
35
|
-
|
36
|
-
If called with a string, symbol or class, the edge-class is resolved and even inherented
|
37
|
-
edges are retrieved.
|
38
|
-
|
39
|
-
=end
|
40
|
-
|
41
|
-
def in edge_name= nil
|
42
|
-
detect_inherent_edge :in, edge_name
|
43
|
-
end
|
44
|
-
|
45
|
-
def out edge_name = nil
|
46
|
-
detect_inherent_edge :out, edge_name
|
47
|
-
end
|
48
|
-
=begin
|
49
|
-
retrieves connected edges
|
50
|
-
|
51
|
-
The basic ussage is to fetch all/ incomming/ outgoing edges
|
52
|
-
|
53
|
-
Model-Instance.edges :in # :out | :all
|
54
|
-
|
55
|
-
One can filter specific edges by providing parts of the edge-name
|
56
|
-
|
57
|
-
Model-Instance.edges 'in_sector'
|
58
|
-
Model-Instance.edges /sector/
|
59
|
-
|
60
|
-
returns an array of rid's
|
61
|
-
|
62
|
-
example:
|
63
|
-
|
64
|
-
Industry.first.attributes.keys
|
65
|
-
=> ["in_sector_classification", "k", "name", "created_at", "updated_at"] # edge--> in ...
|
66
|
-
|
67
|
-
Industry.first.edges :out
|
68
|
-
=> []
|
69
|
-
|
70
|
-
Industry.first.edges :in
|
71
|
-
=> ["#61:0", "#61:9", "#61:21", "#61:33", "#61:39", "#61:93", "#61:120", "#61:150", "#61:240", "#61:252", "#61:264", "#61:279", "#61:303", "#61:339" ...]
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
To fetch the associated records use the ActiveOrient::Model.autoload_object method
|
76
|
-
|
77
|
-
ActiveOrient::Model.autoload_object Industry.first.edges( :in).first
|
78
|
-
# or
|
79
|
-
Industry.autoload_object Industry.first.edges( /sector/ ).first
|
80
|
-
=> #<SectorClassification:0x00000002daad20 @metadata={"type"=>"d", "class"=>"sector_classification", "version"=>1, "fieldTypes"=>"out=x,in=x", "cluster"=>61, "record"=>0},(...)
|
81
|
-
|
82
|
-
=end
|
83
|
-
|
84
|
-
def edges kind=:all # :all, :in, :out
|
85
|
-
expression = case kind
|
86
|
-
when :all
|
87
|
-
/^in|^out/
|
88
|
-
when :in
|
89
|
-
/^in/
|
90
|
-
when :out
|
91
|
-
/^out/
|
92
|
-
when String
|
93
|
-
/#{kind}/
|
94
|
-
when Regexp
|
95
|
-
kind
|
96
|
-
else
|
97
|
-
return []
|
98
|
-
end
|
99
|
-
|
100
|
-
edges = attributes.keys.find_all{ |x| x =~ expression }
|
101
|
-
edges.map{|x| attributes[x]}.flatten
|
102
|
-
end
|
103
|
-
|
104
|
-
=begin
|
105
|
-
»in_edges« and »out_edges« are shortcuts to »edges :in« and »edges :out«
|
106
|
-
|
107
|
-
Its easy to expand the result:
|
108
|
-
tg.out( :ohlc).out.out_edges
|
109
|
-
=> [["#102:11032", "#121:0"]]
|
110
|
-
tg.out( :ohlc).out.out_edges.from_orient
|
111
|
-
=> [[#<TG::GRID_OF:0x00000002620e38
|
112
|
-
|
113
|
-
this displays the out-edges correctly
|
114
|
-
|
115
|
-
whereas
|
116
|
-
tg.out( :ohlc).out.edges( :out)
|
117
|
-
=> [["#101:11032", "#102:11032", "#94:10653", "#121:0"]]
|
118
|
-
|
119
|
-
returns all edges. The parameter (:out) is not recognized, because out is already a nested array.
|
120
|
-
|
121
|
-
this
|
122
|
-
tg.out( :ohlc).first.out.edges( :out)
|
123
|
-
is a walkaround, but using in_- and out_edges is more elegant.
|
124
|
-
=end
|
125
|
-
def in_edges
|
126
|
-
edges :in
|
127
|
-
end
|
128
|
-
def out_edges
|
129
|
-
edges :out
|
130
|
-
end
|
131
|
-
|
132
|
-
def remove
|
133
|
-
db.delete_vertex self
|
134
|
-
end
|
135
|
-
|
136
|
-
end
|