safrano 0.3.4 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/core_ext/Dir/iter.rb +18 -0
  3. data/lib/core_ext/Hash/transform.rb +21 -0
  4. data/lib/core_ext/Integer/edm.rb +13 -0
  5. data/lib/core_ext/REXML/Document/output.rb +16 -0
  6. data/lib/core_ext/String/convert.rb +25 -0
  7. data/lib/core_ext/String/edm.rb +13 -0
  8. data/lib/core_ext/dir.rb +3 -0
  9. data/lib/core_ext/hash.rb +3 -0
  10. data/lib/core_ext/integer.rb +3 -0
  11. data/lib/core_ext/rexml.rb +3 -0
  12. data/lib/core_ext/string.rb +5 -0
  13. data/lib/odata/attribute.rb +15 -10
  14. data/lib/odata/batch.rb +17 -15
  15. data/lib/odata/collection.rb +141 -500
  16. data/lib/odata/collection_filter.rb +44 -37
  17. data/lib/odata/collection_media.rb +193 -43
  18. data/lib/odata/collection_order.rb +50 -37
  19. data/lib/odata/common_logger.rb +39 -12
  20. data/lib/odata/complex_type.rb +152 -0
  21. data/lib/odata/edm/primitive_types.rb +184 -0
  22. data/lib/odata/entity.rb +201 -176
  23. data/lib/odata/error.rb +186 -33
  24. data/lib/odata/expand.rb +126 -0
  25. data/lib/odata/filter/base.rb +69 -0
  26. data/lib/odata/filter/error.rb +55 -6
  27. data/lib/odata/filter/parse.rb +38 -36
  28. data/lib/odata/filter/sequel.rb +121 -67
  29. data/lib/odata/filter/sequel_function_adapter.rb +148 -0
  30. data/lib/odata/filter/token.rb +15 -11
  31. data/lib/odata/filter/tree.rb +110 -60
  32. data/lib/odata/function_import.rb +166 -0
  33. data/lib/odata/model_ext.rb +618 -0
  34. data/lib/odata/navigation_attribute.rb +50 -32
  35. data/lib/odata/relations.rb +7 -7
  36. data/lib/odata/select.rb +54 -0
  37. data/lib/{safrano_core.rb → odata/transition.rb} +14 -60
  38. data/lib/odata/url_parameters.rb +128 -37
  39. data/lib/odata/walker.rb +19 -11
  40. data/lib/safrano.rb +18 -28
  41. data/lib/safrano/contract.rb +143 -0
  42. data/lib/safrano/core.rb +43 -0
  43. data/lib/safrano/core_ext.rb +13 -0
  44. data/lib/safrano/deprecation.rb +73 -0
  45. data/lib/{multipart.rb → safrano/multipart.rb} +37 -41
  46. data/lib/safrano/rack_app.rb +175 -0
  47. data/lib/{odata_rack_builder.rb → safrano/rack_builder.rb} +18 -2
  48. data/lib/{request.rb → safrano/request.rb} +102 -50
  49. data/lib/{response.rb → safrano/response.rb} +5 -4
  50. data/lib/safrano/sequel_join_by_paths.rb +5 -0
  51. data/lib/{service.rb → safrano/service.rb} +257 -188
  52. data/lib/safrano/version.rb +5 -0
  53. data/lib/sequel/plugins/join_by_paths.rb +17 -29
  54. metadata +53 -17
  55. data/lib/rack_app.rb +0 -174
  56. data/lib/sequel_join_by_paths.rb +0 -5
  57. data/lib/version.rb +0 -4
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Safrano
4
+ VERSION = '0.4.4'
5
+ end
@@ -1,31 +1,14 @@
1
- #!/usr/bin/env ruby
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
4
  require 'sequel'
5
5
 
6
- # some helpers
7
- class String
8
- # thanks https://stackoverflow.com/questions/1448670/ruby-stringto-class
9
- def constantize
10
- names = split('::')
11
- names.shift if names.empty? || names.first.empty?
12
-
13
- const = Object
14
- names.each do |name|
15
- const = if const.const_defined?(name)
16
- const.const_get(name)
17
- else
18
- const.const_missing(name)
19
- end
20
- end
21
- const
22
- end
23
- end
6
+ require 'safrano/core_ext'
24
7
 
25
8
  class PathNode < String
26
- attr_reader :table_name
27
9
  attr_accessor :model_class
28
10
  attr_accessor :path_str
11
+
29
12
  def initialize(str, start_model)
30
13
  super(str)
31
14
  @start_model = start_model
@@ -80,14 +63,14 @@ class QPath
80
63
  path_nodes = []
81
64
  start_node.path_str = path_str
82
65
  nodes = [start_node]
83
- nodes.concat @qpath.split('/').map { |nstr| @start_model.create_path_node(nstr) }
84
- if (ns = nodes.size) > 1
85
- nodes[0...-1].each_with_index do |node, i|
86
- nodes[i + 1].set_model_class_by_parent_model(node.model_class)
87
- path_nodes << nodes[i + 1]
88
- nodes[i + 1].path_str = path_nodes.join('/')
89
- @segments << [node, nodes[i + 1]]
90
- end
66
+ nodes.concat(@qpath.split('/').map { |nstr| @start_model.create_path_node(nstr) })
67
+ return unless nodes.size > 1
68
+
69
+ nodes[0...-1].each_with_index do |node, i|
70
+ nodes[i + 1].set_model_class_by_parent_model(node.model_class)
71
+ path_nodes << nodes[i + 1]
72
+ nodes[i + 1].path_str = path_nodes.join('/')
73
+ @segments << [node, nodes[i + 1]]
91
74
  end
92
75
  end
93
76
  end
@@ -96,13 +79,15 @@ class JoinByPathsHelper < Set
96
79
  attr_reader :result
97
80
  attr_reader :start_model
98
81
 
82
+ EMPTY_ARRAY = [].freeze
83
+
99
84
  def initialize(smodel)
100
85
  super()
101
86
  @start_model = smodel
102
87
  end
103
88
 
104
89
  def build_unique_join_segments
105
- return (@result = []) if empty?
90
+ return (@result = EMPTY_ARRAY) if empty?
106
91
 
107
92
  maxlen = map(&:size).max
108
93
  iset = nil
@@ -118,6 +103,7 @@ class JoinByPathsHelper < Set
118
103
  jseg.map do |seg|
119
104
  leftm = seg.first.model_class
120
105
  assoc = leftm.association_reflection(seg.last.to_sym)
106
+
121
107
  rightm = seg.last.model_class
122
108
  # cf. documentation in sequel/model/associations.rb
123
109
  case assoc[:type]
@@ -205,6 +191,7 @@ module Sequel
205
191
  module ClassMethods
206
192
  attr_reader :aliases_sym
207
193
  attr_reader :alias_cnt
194
+
208
195
  Plugins.inherited_instance_variables(self,
209
196
  :@aliases_sym => :dup,
210
197
  :@alias_cnt => :dup)
@@ -231,6 +218,7 @@ module Sequel
231
218
 
232
219
  module DatasetMethods
233
220
  attr_reader :join_helper
221
+
234
222
  def join_by_paths(*pathlist)
235
223
  model.join_by_paths_helper(*pathlist).dataset
236
224
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
- - D.M.
7
+ - oz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-22 00:00:00.000000000 Z
11
+ date: 2020-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.15'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rfc2047
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -94,13 +108,23 @@ dependencies:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0.51'
97
- description: Safrano is an OData server framework based on Ruby, Rack and Sequel.
98
- email: 'dev@aithscel.eu '
111
+ description: Safrano is an OData server library based on Ruby, Rack and Sequel.
112
+ email: dev@aithscel.eu
99
113
  executables: []
100
114
  extensions: []
101
115
  extra_rdoc_files: []
102
116
  files:
103
- - lib/multipart.rb
117
+ - lib/core_ext/Dir/iter.rb
118
+ - lib/core_ext/Hash/transform.rb
119
+ - lib/core_ext/Integer/edm.rb
120
+ - lib/core_ext/REXML/Document/output.rb
121
+ - lib/core_ext/String/convert.rb
122
+ - lib/core_ext/String/edm.rb
123
+ - lib/core_ext/dir.rb
124
+ - lib/core_ext/hash.rb
125
+ - lib/core_ext/integer.rb
126
+ - lib/core_ext/rexml.rb
127
+ - lib/core_ext/string.rb
104
128
  - lib/odata/attribute.rb
105
129
  - lib/odata/batch.rb
106
130
  - lib/odata/collection.rb
@@ -108,27 +132,40 @@ files:
108
132
  - lib/odata/collection_media.rb
109
133
  - lib/odata/collection_order.rb
110
134
  - lib/odata/common_logger.rb
135
+ - lib/odata/complex_type.rb
136
+ - lib/odata/edm/primitive_types.rb
111
137
  - lib/odata/entity.rb
112
138
  - lib/odata/error.rb
139
+ - lib/odata/expand.rb
140
+ - lib/odata/filter/base.rb
113
141
  - lib/odata/filter/error.rb
114
142
  - lib/odata/filter/parse.rb
115
143
  - lib/odata/filter/sequel.rb
144
+ - lib/odata/filter/sequel_function_adapter.rb
116
145
  - lib/odata/filter/token.rb
117
146
  - lib/odata/filter/tree.rb
147
+ - lib/odata/function_import.rb
148
+ - lib/odata/model_ext.rb
118
149
  - lib/odata/navigation_attribute.rb
119
150
  - lib/odata/relations.rb
151
+ - lib/odata/select.rb
152
+ - lib/odata/transition.rb
120
153
  - lib/odata/url_parameters.rb
121
154
  - lib/odata/walker.rb
122
- - lib/odata_rack_builder.rb
123
- - lib/rack_app.rb
124
- - lib/request.rb
125
- - lib/response.rb
126
155
  - lib/safrano.rb
127
- - lib/safrano_core.rb
156
+ - lib/safrano/contract.rb
157
+ - lib/safrano/core.rb
158
+ - lib/safrano/core_ext.rb
159
+ - lib/safrano/deprecation.rb
160
+ - lib/safrano/multipart.rb
161
+ - lib/safrano/rack_app.rb
162
+ - lib/safrano/rack_builder.rb
163
+ - lib/safrano/request.rb
164
+ - lib/safrano/response.rb
165
+ - lib/safrano/sequel_join_by_paths.rb
166
+ - lib/safrano/service.rb
167
+ - lib/safrano/version.rb
128
168
  - lib/sequel/plugins/join_by_paths.rb
129
- - lib/sequel_join_by_paths.rb
130
- - lib/service.rb
131
- - lib/version.rb
132
169
  homepage: https://gitlab.com/dm0da/safrano
133
170
  licenses:
134
171
  - MIT
@@ -152,9 +189,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
189
  - !ruby/object:Gem::Version
153
190
  version: '0'
154
191
  requirements: []
155
- rubyforge_project:
156
- rubygems_version: 2.7.6.2
192
+ rubygems_version: 3.1.4
157
193
  signing_key:
158
194
  specification_version: 4
159
- summary: Safrano is a Ruby OData provider based on Sequel and Rack
195
+ summary: Safrano is a Ruby OData server library based on Sequel and Rack
160
196
  test_files: []
@@ -1,174 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rack'
4
- require_relative 'odata/walker.rb'
5
- require_relative 'request.rb'
6
- require_relative 'response.rb'
7
-
8
- module OData
9
- # handle GET PUT etc
10
- module MethodHandlers
11
- def odata_options
12
- # cf. stackoverflow.com/questions/22924678/sinatra-delete-response-headers
13
-
14
- x = if @walker.status == :end
15
- headers.delete('Content-Type')
16
- @response.headers.delete('Content-Type')
17
- [200, {}, '']
18
- else
19
- odata_error
20
- end
21
- @response.headers['Content-Type'] = ''
22
- x
23
- end
24
-
25
- def odata_error
26
- return @walker.error.odata_get(@request) unless @walker.error.nil?
27
-
28
- # this is too critical; raise a real Exception
29
- raise 'Walker construction failed with a unknown Error '
30
- end
31
-
32
- def odata_delete
33
- if @walker.status == :end
34
- @walker.end_context.odata_delete(@request)
35
- else
36
- odata_error
37
- end
38
- end
39
-
40
- def odata_put
41
- if @walker.status == :end
42
- @walker.end_context.odata_put(@request)
43
- else
44
- odata_error
45
- end
46
- end
47
-
48
- def odata_patch
49
- if @walker.status == :end
50
- @walker.end_context.odata_patch(@request)
51
- else
52
- odata_error
53
- end
54
- end
55
-
56
- def odata_get
57
- if @walker.status == :end
58
- @walker.end_context.odata_get(@request)
59
- else
60
- odata_error
61
- end
62
- end
63
-
64
- def odata_post
65
- if @walker.status == :end
66
- @walker.end_context.odata_post(@request)
67
- else
68
- odata_error
69
- end
70
- end
71
-
72
- def odata_head
73
- [200, {}, ['']]
74
- end
75
- end
76
-
77
- # the main Rack server app. Source: the Rack docu/examples and partly
78
- # inspired from Sinatra
79
- class ServerApp
80
- METHODS_REGEXP = Regexp.new('HEAD|OPTIONS|GET|POST|PATCH|MERGE|PUT|DELETE')
81
- include MethodHandlers
82
- def before
83
- headers 'Cache-Control' => 'no-cache'
84
- headers 'Expires' => '-1'
85
- headers 'Pragma' => 'no-cache'
86
-
87
- @request.service_base = self.class.get_service_base
88
-
89
- neg_error = @request.negotiate_service_version
90
-
91
- raise RuntimeError if neg_error
92
-
93
- return false unless @request.service
94
-
95
- headers 'DataServiceVersion' => @request.service.data_service_version
96
- end
97
-
98
- # dispatch for all methods requiring parsing of the path
99
- # with walker (ie. allmost all excepted HEAD)
100
- def dispatch_with_walker
101
- @walker = @request.create_odata_walker
102
- case @request.request_method
103
- when 'GET'
104
- odata_get
105
- when 'POST'
106
- odata_post
107
- when 'DELETE'
108
- odata_delete
109
- when 'OPTIONS'
110
- odata_options
111
- when 'PUT'
112
- odata_put
113
- when 'PATCH', 'MERGE'
114
- odata_patch
115
- else
116
- raise Error
117
- end
118
- end
119
-
120
- def dispatch
121
- req_ret = if @request.request_method !~ METHODS_REGEXP
122
- [404, {}, ['Did you get lost?']]
123
- elsif @request.request_method == 'HEAD'
124
- odata_head
125
- else
126
- dispatch_with_walker
127
- end
128
- @response.status, rsph, @response.body = req_ret
129
- headers rsph
130
- end
131
-
132
- def call(env)
133
- @request = OData::Request.new(env)
134
- @response = OData::Response.new
135
-
136
- before
137
-
138
- dispatch
139
-
140
- @response.finish
141
- end
142
-
143
- # Set multiple response headers with Hash.
144
- def headers(hash = nil)
145
- @response.headers.merge! hash if hash
146
- @response.headers
147
- end
148
-
149
- def self.enable_batch
150
- @service_base.enable_batch
151
- end
152
-
153
- def self.path_prefix(path_pr)
154
- @service_base.path_prefix path_pr
155
- end
156
-
157
- def self.get_service_base
158
- @service_base
159
- end
160
-
161
- def self.set_servicebase(sbase)
162
- @service_base = sbase
163
- @service_base.enable_v1_service
164
- @service_base.enable_v2_service
165
- end
166
-
167
- def self.publish_service(&block)
168
- sbase = OData::ServiceBase.new
169
- sbase.instance_eval(&block) if block_given?
170
- sbase.finalize_publishing
171
- set_servicebase(sbase)
172
- end
173
- end
174
- end
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative './sequel/plugins/join_by_paths.rb'
4
-
5
- Sequel::Model.plugin Sequel::Plugins::JoinByPaths
@@ -1,4 +0,0 @@
1
-
2
- module Safrano
3
- VERSION = '0.3.4'
4
- end