active-orient 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []