active-orient 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/Gemfile +16 -0
- data/Guardfile +21 -0
- data/LICENSE +22 -0
- data/README.md +275 -0
- data/acitve-orient.gemspec +27 -0
- data/config/boot.rb +24 -0
- data/config/connect.yml +13 -0
- data/lib/base.rb +220 -0
- data/lib/base_properties.rb +147 -0
- data/lib/model.rb +441 -0
- data/lib/orient.rb +98 -0
- data/lib/query.rb +88 -0
- data/lib/rest.rb +942 -0
- data/lib/support.rb +315 -0
- data/test.rb +4 -0
- data/usecase.md +91 -0
- metadata +104 -0
data/lib/support.rb
ADDED
@@ -0,0 +1,315 @@
|
|
1
|
+
class String
|
2
|
+
def to_classname
|
3
|
+
if self[0] =='$'
|
4
|
+
self[1..-1]
|
5
|
+
else
|
6
|
+
self.camelize
|
7
|
+
end
|
8
|
+
end
|
9
|
+
def to_orient
|
10
|
+
self.gsub /%/, '(percent)'
|
11
|
+
|
12
|
+
end
|
13
|
+
def rid?
|
14
|
+
self =~ /\A[#]{,1}[0-9]{1,}:[0-9]{1,}\z/
|
15
|
+
end
|
16
|
+
def from_orient
|
17
|
+
if rid?
|
18
|
+
ActiveOrient::Model.autoload_object self
|
19
|
+
else
|
20
|
+
self
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
class NilClass
|
25
|
+
def to_orient
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
class Symbol
|
30
|
+
def to_orient
|
31
|
+
self.to_s.to_orient
|
32
|
+
end
|
33
|
+
def from_orient
|
34
|
+
self
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Numeric
|
39
|
+
def from_orient
|
40
|
+
self
|
41
|
+
end
|
42
|
+
def to_orient
|
43
|
+
self
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Time
|
48
|
+
def from_orient
|
49
|
+
self
|
50
|
+
end
|
51
|
+
def to_orient
|
52
|
+
self
|
53
|
+
end
|
54
|
+
end
|
55
|
+
class Date
|
56
|
+
def from_orient
|
57
|
+
self
|
58
|
+
end
|
59
|
+
def to_orient
|
60
|
+
self
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class TrueClass
|
65
|
+
def from_orient
|
66
|
+
self
|
67
|
+
end
|
68
|
+
def to_orient
|
69
|
+
self
|
70
|
+
end
|
71
|
+
end
|
72
|
+
class FalseClass
|
73
|
+
def from_orient
|
74
|
+
self
|
75
|
+
end
|
76
|
+
def to_orient
|
77
|
+
self
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Array
|
82
|
+
def to_orient
|
83
|
+
map &:to_orient
|
84
|
+
end
|
85
|
+
def from_orient
|
86
|
+
map &:from_orient
|
87
|
+
end
|
88
|
+
end
|
89
|
+
class Hash #WithIndifferentAccess
|
90
|
+
def from_orient
|
91
|
+
substitute_hash = HashWithIndifferentAccess.new
|
92
|
+
keys.each{ |k| puts self[k].inspect }
|
93
|
+
keys.each{| k | substitute_hash[k] = self[k].from_orient }
|
94
|
+
substitute_hash
|
95
|
+
|
96
|
+
end
|
97
|
+
def to_orient
|
98
|
+
substitute_hash = Hash.new
|
99
|
+
keys.each{| k | substitute_hash[k] = self[k].to_orient }
|
100
|
+
substitute_hash
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
def nested_under_indifferent_access
|
105
|
+
HashWithIndifferentAccess.new self
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
module OrientSupport
|
111
|
+
|
112
|
+
module Support
|
113
|
+
=begin
|
114
|
+
supports
|
115
|
+
|
116
|
+
where: 'string'
|
117
|
+
where: { property: 'value', property: value, ... }
|
118
|
+
where: ['string, { property: value, ... }, ... ]
|
119
|
+
|
120
|
+
|
121
|
+
Used by update and select
|
122
|
+
=end
|
123
|
+
|
124
|
+
def compose_where *arg
|
125
|
+
arg=arg.flatten
|
126
|
+
return "" if arg.blank? || arg.size == 1 && arg.first.blank?
|
127
|
+
"where " + arg.map do |issue|
|
128
|
+
case issue
|
129
|
+
when String
|
130
|
+
issue
|
131
|
+
when Hash
|
132
|
+
generate_sql_list issue
|
133
|
+
end
|
134
|
+
end.join( ' and ' )
|
135
|
+
end
|
136
|
+
def generate_sql_list attributes={}
|
137
|
+
attributes.map do | key, value |
|
138
|
+
case value
|
139
|
+
when Numeric
|
140
|
+
key.to_s << " = " << value.to_s
|
141
|
+
else # String, Symbol, Date, Time, Trueclass, Falseclass ...
|
142
|
+
key.to_s << ' = ' << "\'#{ value }\'"
|
143
|
+
end
|
144
|
+
end.join( ' and ' )
|
145
|
+
end
|
146
|
+
end # module
|
147
|
+
|
148
|
+
|
149
|
+
class OrientQuery
|
150
|
+
|
151
|
+
include Support
|
152
|
+
|
153
|
+
def initialize **args
|
154
|
+
@projection = []
|
155
|
+
@misc= []
|
156
|
+
args.each do | k,v|
|
157
|
+
self.send k, v
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def method_missing method, *arg, &b
|
162
|
+
@misc << method.to_s << " " << arg.map(&:to_s).join(' ')
|
163
|
+
end
|
164
|
+
|
165
|
+
def misc
|
166
|
+
@misc.join(' ') unless @misc.empty?
|
167
|
+
end
|
168
|
+
|
169
|
+
def subquery
|
170
|
+
nil
|
171
|
+
end
|
172
|
+
|
173
|
+
def compose
|
174
|
+
[ "select", projection, from, where , subquery, misc, order , group_by, unwind, skip ].compact.join(' ')
|
175
|
+
end
|
176
|
+
=begin
|
177
|
+
from can either be a Databaseclass to operate on or a Subquery providing data to query further
|
178
|
+
=end
|
179
|
+
def from arg=nil
|
180
|
+
if arg.present?
|
181
|
+
@database = case arg
|
182
|
+
when Class
|
183
|
+
arg.new.classname
|
184
|
+
when ActiveOrient::Model
|
185
|
+
classname
|
186
|
+
when String
|
187
|
+
arg
|
188
|
+
when Symbol
|
189
|
+
arg
|
190
|
+
when OrientQuery
|
191
|
+
nil # don't set @database
|
192
|
+
end
|
193
|
+
@from = arg
|
194
|
+
else # read from
|
195
|
+
"from " << if @from.is_a?( OrientQuery )
|
196
|
+
"( #{@from.compose} )"
|
197
|
+
else
|
198
|
+
@database.to_s
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
def database_class= arg
|
203
|
+
@database = arg if @database.present?
|
204
|
+
if @from.is_a? OrientQuery
|
205
|
+
@from.database_class= arg
|
206
|
+
end
|
207
|
+
end
|
208
|
+
def database_class
|
209
|
+
if @database.present?
|
210
|
+
@database
|
211
|
+
elsif @from.is_a? OrientQuery
|
212
|
+
@from.database_class
|
213
|
+
else
|
214
|
+
nil
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
=begin
|
220
|
+
Call where without a parameter to request the saved where-string
|
221
|
+
|
222
|
+
to create the where-part of the query a string, a hash or an Array is supported
|
223
|
+
|
224
|
+
where: "r > 9" --> where r > 9
|
225
|
+
where: {a: 9, b: 's'} --> where a = 9 and b = 's'
|
226
|
+
where:[{ a: 2} , 'b > 3',{ c: 'ufz' }] --> where a = 2 and b > 3 and c = 'ufz'
|
227
|
+
=end
|
228
|
+
def where *arg
|
229
|
+
@where= compose_where(*arg) unless arg.empty?
|
230
|
+
@where # return_value
|
231
|
+
end
|
232
|
+
|
233
|
+
def let *arg
|
234
|
+
# SELECT FROM Profile
|
235
|
+
# LET $city = address.city
|
236
|
+
# WHERE $city.name like '%Saint%"' AND
|
237
|
+
# ( $city.country.name = 'Italy' OR $city.country.name = 'France' )
|
238
|
+
puts "OrientSupport::OrientQuery@let is not implementated"
|
239
|
+
end
|
240
|
+
def distinct d=nil
|
241
|
+
if d.present?
|
242
|
+
@projection << case d
|
243
|
+
when String
|
244
|
+
"distinct( #{d} )"
|
245
|
+
when Array
|
246
|
+
"distinct( #{d.first} ) as #{d.last}"
|
247
|
+
when Hash
|
248
|
+
"distinct( #{d.first.first} ) as #{d.first.last}"
|
249
|
+
else
|
250
|
+
""
|
251
|
+
end
|
252
|
+
end
|
253
|
+
@projection.join(' ,') #return_value
|
254
|
+
end
|
255
|
+
def projection s=nil
|
256
|
+
if s.present?
|
257
|
+
|
258
|
+
@projection << case s
|
259
|
+
when Hash
|
260
|
+
s.map{ |x,y| "#{x} as #{y}"}.join( ', ')
|
261
|
+
when Array
|
262
|
+
s.join(', ')
|
263
|
+
else
|
264
|
+
s
|
265
|
+
end
|
266
|
+
|
267
|
+
end
|
268
|
+
@projection.join(', ')
|
269
|
+
end
|
270
|
+
|
271
|
+
# def where= w
|
272
|
+
|
273
|
+
# end
|
274
|
+
# select_string = ("select " + select_string + distinct_string + ' from ' + class_name(o_class) ).squeeze(' ')
|
275
|
+
# where_string = compose_where( where )
|
276
|
+
def group_by g=nil
|
277
|
+
@group = "group_by #{g.to_s}" if g.present?
|
278
|
+
# only a string is allowed
|
279
|
+
@group # return_value
|
280
|
+
end
|
281
|
+
def unwind u=nil
|
282
|
+
@unwind = "unwind #{u.to_s}" if u.present?
|
283
|
+
# only a string is allowed
|
284
|
+
@unwind # return_value
|
285
|
+
end
|
286
|
+
|
287
|
+
def skip n=nil
|
288
|
+
@skip= n if n.present?
|
289
|
+
"skip #{n}" if @skip.present?
|
290
|
+
end
|
291
|
+
|
292
|
+
def order o=nil
|
293
|
+
@order_string = "order by " << case o
|
294
|
+
when Hash
|
295
|
+
o.map{ |x,y| "#{x} #{y}" }.join( " " )
|
296
|
+
when Array
|
297
|
+
o.map{ |x| "#{x} asc"}.join( " " )
|
298
|
+
else
|
299
|
+
o.to_s
|
300
|
+
end if o.present?
|
301
|
+
@order_string
|
302
|
+
end
|
303
|
+
# misc_string = if skip > 0 && limit > 0
|
304
|
+
# " skip: #{skip} "
|
305
|
+
# else
|
306
|
+
# ""
|
307
|
+
# end
|
308
|
+
# #
|
309
|
+
#
|
310
|
+
# def compose
|
311
|
+
#
|
312
|
+
# end
|
313
|
+
|
314
|
+
end
|
315
|
+
end # module
|
data/test.rb
ADDED
data/usecase.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
## Usecase
|
2
|
+
Below some typical features are summarized by example
|
3
|
+
|
4
|
+
Start a irb-session and initialize ActiveOrient
|
5
|
+
```ruby
|
6
|
+
topo@gamma:~/new_hctw$ irb
|
7
|
+
2.2.1 :001 > require './config/boot'
|
8
|
+
Using development-environment
|
9
|
+
-------------------- initialize -------------------- => true
|
10
|
+
2.2.1 :002 > ActiveOrient::Model.orientdb = ror = ActiveOrient::OrientDB.new
|
11
|
+
=> #<ActiveOrient::OrientDB:0x000000046f1a90 @res=#<RestClient::Resource:0x000000046c0af8 @url="http://localhost:2480", @block=nil, @options={:user=>"hctw", :password=>"**"}>, @database="hc_database", @classes=[]>
|
12
|
+
```
|
13
|
+
#### Object Mapping
|
14
|
+
Lets create a class, put some content in it and perform basic oo-steps.
|
15
|
+
|
16
|
+
Attributes(Properties) do not have to be formaly declared. However it is nessessary to introduce them properly. This is done with the »attributes«-Argument during the initialisation step or via
|
17
|
+
»update«
|
18
|
+
|
19
|
+
``` ruby
|
20
|
+
A = r.create_class 'my_a_class'
|
21
|
+
=> ActiveOrient::Model::Myaclass
|
22
|
+
a = A.new_document attributes: { test: 45}
|
23
|
+
a.update set: { a_array: aa= [ 1,4,'r', :r ] ,
|
24
|
+
a_hash: { :a => 'b', b: 2 } }
|
25
|
+
a.to_human
|
26
|
+
=> <Myaclass: a_array: [1, 4, "r", :r] a_hash: {:a=>"b", :b=>2} test: 45>
|
27
|
+
|
28
|
+
```
|
29
|
+
Then the attibutes/properties can be handled as normal ruby objects ie.
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
a.a_array << "a new element"
|
33
|
+
a.a_hash[ :a_new_element ] = "value of the new element"
|
34
|
+
a.test += 3
|
35
|
+
a.test = 567
|
36
|
+
a.update
|
37
|
+
```
|
38
|
+
Objects are synchronized with the database with »update«. To revert changes, a »reload!« method is available.
|
39
|
+
|
40
|
+
#### Contracts-Example
|
41
|
+
Assume a Database, which is defined as
|
42
|
+
```
|
43
|
+
create class Industries
|
44
|
+
create class Categories
|
45
|
+
create class SubCategories
|
46
|
+
create class OpenInterest ABSTRACT
|
47
|
+
create class Stocks extends Contracts
|
48
|
+
create class Futures extends Contracts
|
49
|
+
create class Options extends Contracts
|
50
|
+
create class Forexes extends Contracts
|
51
|
+
create property Industries.categories linkset
|
52
|
+
create property Categories.subcategories linkset
|
53
|
+
create property Categories.industry link
|
54
|
+
create property SubCategories.category link
|
55
|
+
create property SubCategories.contracts linkset
|
56
|
+
|
57
|
+
create property Contracts.subcategory link
|
58
|
+
create property Contracts.details link
|
59
|
+
create property OpenInterest.contracts linkset
|
60
|
+
|
61
|
+
```
|
62
|
+
This defines some conventional relations:
|
63
|
+
|
64
|
+
OpenInterest -> Contracts <- Subcategory <- Category <- Industry
|
65
|
+
|
66
|
+
with some oo-Behavior
|
67
|
+
```ruby
|
68
|
+
2.2.1 :003 > ror.class_hierachie base_class: 'Contracts'
|
69
|
+
=> ["Forexes", "Futures", "Options", "Stocks"]
|
70
|
+
```
|
71
|
+
|
72
|
+
then the following ORM-behavior is implemented:
|
73
|
+
```ruby
|
74
|
+
topo@gamma:~/new_hctw$ irb
|
75
|
+
2.2.1 :001 > require './config/boot'
|
76
|
+
Using development-environment
|
77
|
+
-------------------- initialize -------------------- => true
|
78
|
+
2.2.1 :002 > ActiveOrient::Model.orientdb = ror = ActiveOrient::OrientDB.new
|
79
|
+
=> #<ActiveOrient::OrientDB:0x000000046f1a90 @res=#<RestClient::Resource:0x000000046c0af8 @url="http://localhost:2480", @block=nil, @options={:user=>"hctw", :password=>"**"}>, @database="hc_database", @classes=[]>
|
80
|
+
2.2.1 :003 > OpenInterest = ror.open_class 'Openinterest'
|
81
|
+
=> ActiveOrient::Model::Openinterest
|
82
|
+
2.2.1 :004 > first_open_interest = OpenInterest.first
|
83
|
+
=> #<ActiveOrient::Model::Openinterest:0x0000000443ede8 @metadata={"type"=>"d", "class"=>"Openinterest", "version"=>5, "fieldTypes"=>"fetch_date=t,contracts=z", "cluster"=>13, "record"=>0}, @attributes={"fetch_date"=>"2015-06-02 00:00:00", "contracts"=>["#21:36", "#21:35", "#21:34", "#21:33", "#21:32", "#21:31", "#21:30", "#21:29", "#21:28", "#21:27", "#21:26", "#21:25", "#21:24", "#21:23", "#21:22", "#21:21", "#21:51", "#21:49", "#21:50", "#21:47", "#21:48", "#21:45", "#21:46", "#21:43", "#21:44", "#21:41", "#21:42", "#21:39", "#21:40", "#21:37", "#21:38", "#21:4", "#21:3", "#21:0", "#21:17", "#21:18", "#21:19", "#21:20", "#21:13", "#21:14", "#21:15", "#21:16", "#21:9", "#21:10", "#21:11", "#21:12", "#21:5", "#21:6", "#21:7", "#21:8"], "created_at"=>2015-07-01 15:27:41 +0200, "updated_at"=>2015-07-01 15:27:41 +0200}>
|
84
|
+
2.2.1 :005 > first_open_interest.contracts.first.subcategory.category.industry
|
85
|
+
=> #<ActiveOrient::Model::Industries:0x00000004af88f0 @metadata={"type"=>"d", "class"=>"Industries", "version"=>8, "fieldTypes"=>"categories=n", "cluster"=>17, "record"=>1}, @attributes={"categories"=>["#15:13", "#15:4", "#15:1"], "name"=>"Basic Materials", "created_at"=>2015-07-01 15:27:58 +0200, "updated_at"=>2015-07-01 15:27:58 +0200}>
|
86
|
+
|
87
|
+
2.2.1 :006 > first_open_interest.contracts.first.subcategory.category.industry.name
|
88
|
+
=> "Basic Materials"
|
89
|
+
```
|
90
|
+
|
91
|
+
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active-orient
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.2'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- " Hartmut Bischoff"
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Persistent ORM for OrientDB, based on ActiveModel
|
56
|
+
email:
|
57
|
+
- topofocus@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".rspec"
|
64
|
+
- Gemfile
|
65
|
+
- Guardfile
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- acitve-orient.gemspec
|
69
|
+
- config/boot.rb
|
70
|
+
- config/connect.yml
|
71
|
+
- lib/base.rb
|
72
|
+
- lib/base_properties.rb
|
73
|
+
- lib/model.rb
|
74
|
+
- lib/orient.rb
|
75
|
+
- lib/query.rb
|
76
|
+
- lib/rest.rb
|
77
|
+
- lib/support.rb
|
78
|
+
- test.rb
|
79
|
+
- usecase.md
|
80
|
+
homepage: https://github.com/topofocus/active-orient
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 2.2.0
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.4.6
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Pure ruby client for OrientDB based on ActiveModel
|
104
|
+
test_files: []
|