active-orient 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,4 @@
1
+ $:.unshift File.expand_path('.')
2
+ require 'config/boot'
3
+
4
+
@@ -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: []