bodhi-slam 0.3.4 → 0.4.0
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.
- checksums.yaml +4 -4
- data/lib/bodhi-slam.rb +2 -0
- data/lib/bodhi-slam/queries.rb +209 -0
- data/lib/bodhi-slam/resource.rb +83 -27
- data/lib/bodhi-slam/types.rb +1 -1
- data/lib/bodhi-slam/validators/multi.rb +5 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6df30b96a6aec463e6caa1ccbd279e47d27a57a2
|
4
|
+
data.tar.gz: 6852921c1be4570e84dab5869713af2f2f95bd81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a04d8bf2df4d929e2d533283610f9d93eef65479383250d93c91e4cd22a27ae2b1ed14fdbe3c476b1576561acd85b84bd19e0d9479c18c7a88a2e66ff892d6c
|
7
|
+
data.tar.gz: 1df3159b31651ba636903099ac5f7ac5c1dd85bca80866c7de94be3ba1be5ac52c7e34e387ecd1a1cd591a770f44f8b714d7356e6eeee081edc30395720e79eb
|
data/lib/bodhi-slam.rb
CHANGED
@@ -4,6 +4,7 @@ require "json"
|
|
4
4
|
require "time"
|
5
5
|
require "SecureRandom"
|
6
6
|
require 'regexp-examples'
|
7
|
+
require 'active_model'
|
7
8
|
|
8
9
|
require 'bodhi-slam/validations'
|
9
10
|
require 'bodhi-slam/errors'
|
@@ -16,6 +17,7 @@ require 'bodhi-slam/resource'
|
|
16
17
|
require 'bodhi-slam/types'
|
17
18
|
require 'bodhi-slam/users'
|
18
19
|
require 'bodhi-slam/profiles'
|
20
|
+
require 'bodhi-slam/queries'
|
19
21
|
|
20
22
|
class BodhiSlam
|
21
23
|
# Defines a context to interact with the Bodhi API
|
@@ -0,0 +1,209 @@
|
|
1
|
+
module Bodhi
|
2
|
+
class Query
|
3
|
+
attr_reader :klass, :url, :context, :criteria, :fields, :paging, :sorting
|
4
|
+
|
5
|
+
def initialize(klass)
|
6
|
+
@klass = Object.const_get(klass.to_s)
|
7
|
+
@criteria = []
|
8
|
+
@fields = []
|
9
|
+
@paging = {}
|
10
|
+
@sorting = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def clear!
|
14
|
+
@context = nil
|
15
|
+
@criteria.clear
|
16
|
+
@fields.clear
|
17
|
+
@paging.clear
|
18
|
+
@sorting.clear
|
19
|
+
end
|
20
|
+
|
21
|
+
def url
|
22
|
+
unless context.nil?
|
23
|
+
query = "/#{context.namespace}/resources/#{klass}?"
|
24
|
+
else
|
25
|
+
query = "/resources/#{klass}?"
|
26
|
+
end
|
27
|
+
params = []
|
28
|
+
|
29
|
+
unless criteria.empty?
|
30
|
+
if criteria.size > 1
|
31
|
+
where_string = "{$and:[#{criteria.join(',')}]}"
|
32
|
+
else
|
33
|
+
where_string = criteria.join
|
34
|
+
end
|
35
|
+
|
36
|
+
params << "where=#{where_string}"
|
37
|
+
end
|
38
|
+
|
39
|
+
unless fields.empty?
|
40
|
+
params << "fields=#{fields.join(',')}"
|
41
|
+
end
|
42
|
+
|
43
|
+
unless paging.empty?
|
44
|
+
paging_params = []
|
45
|
+
|
46
|
+
if paging[:page]
|
47
|
+
paging_params << "page:#{paging[:page]}"
|
48
|
+
end
|
49
|
+
|
50
|
+
if paging[:limit]
|
51
|
+
paging_params << "limit:#{paging[:limit]}"
|
52
|
+
end
|
53
|
+
|
54
|
+
params << "paging=#{paging_params.join(',')}"
|
55
|
+
end
|
56
|
+
|
57
|
+
unless sorting.empty?
|
58
|
+
sort_params = []
|
59
|
+
|
60
|
+
if sorting[:field]
|
61
|
+
sort_params << sorting[:field]
|
62
|
+
end
|
63
|
+
|
64
|
+
if sorting[:order]
|
65
|
+
sort_params << sorting[:order]
|
66
|
+
end
|
67
|
+
|
68
|
+
params << "sort=#{sort_params.join(':')}"
|
69
|
+
end
|
70
|
+
|
71
|
+
query << params.join('&')
|
72
|
+
query.gsub(/\s+/, "")
|
73
|
+
end
|
74
|
+
|
75
|
+
def all
|
76
|
+
if context.nil?
|
77
|
+
raise ArgumentError.new("a Bodhi::Context is required to query the API")
|
78
|
+
end
|
79
|
+
|
80
|
+
if context.invalid?
|
81
|
+
raise Bodhi::ContextErrors.new(context.errors.messages), context.errors.to_a.to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
result = context.connection.get do |request|
|
85
|
+
request.url self.url
|
86
|
+
request.headers[context.credentials_header] = context.credentials
|
87
|
+
end
|
88
|
+
|
89
|
+
if result.status != 200
|
90
|
+
raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
|
91
|
+
end
|
92
|
+
|
93
|
+
resources = JSON.parse(result.body)
|
94
|
+
resources.map{ |attributes| klass.factory.build(context, attributes) }
|
95
|
+
end
|
96
|
+
|
97
|
+
def first
|
98
|
+
if context.nil?
|
99
|
+
raise ArgumentError.new("a Bodhi::Context is required to query the API")
|
100
|
+
end
|
101
|
+
|
102
|
+
if context.invalid?
|
103
|
+
raise Bodhi::ContextErrors.new(context.errors.messages), context.errors.to_a.to_s
|
104
|
+
end
|
105
|
+
|
106
|
+
result = context.connection.get do |request|
|
107
|
+
request.url self.url
|
108
|
+
request.headers[context.credentials_header] = context.credentials
|
109
|
+
end
|
110
|
+
|
111
|
+
if result.status != 200
|
112
|
+
raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
|
113
|
+
end
|
114
|
+
|
115
|
+
resources = JSON.parse(result.body)
|
116
|
+
resources.map{ |attributes| klass.factory.build(context, attributes) }.first
|
117
|
+
end
|
118
|
+
|
119
|
+
def last
|
120
|
+
if context.nil?
|
121
|
+
raise ArgumentError.new("a Bodhi::Context is required to query the API")
|
122
|
+
end
|
123
|
+
|
124
|
+
if context.invalid?
|
125
|
+
raise Bodhi::ContextErrors.new(context.errors.messages), context.errors.to_a.to_s
|
126
|
+
end
|
127
|
+
|
128
|
+
result = context.connection.get do |request|
|
129
|
+
request.url self.url
|
130
|
+
request.headers[context.credentials_header] = context.credentials
|
131
|
+
end
|
132
|
+
|
133
|
+
if result.status != 200
|
134
|
+
raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
|
135
|
+
end
|
136
|
+
|
137
|
+
resources = JSON.parse(result.body)
|
138
|
+
resources.map{ |attributes| klass.factory.build(context, attributes) }.last
|
139
|
+
end
|
140
|
+
|
141
|
+
def from(context)
|
142
|
+
unless context.is_a? Bodhi::Context
|
143
|
+
raise ArgumentError.new("Expected Bodhi::Context but received #{context.class}")
|
144
|
+
end
|
145
|
+
|
146
|
+
@context = context
|
147
|
+
self
|
148
|
+
end
|
149
|
+
|
150
|
+
def where(query)
|
151
|
+
unless query.is_a? String
|
152
|
+
raise ArgumentError.new("Expected String but received #{query.class}")
|
153
|
+
end
|
154
|
+
|
155
|
+
@criteria << query
|
156
|
+
@criteria.uniq!
|
157
|
+
self
|
158
|
+
end
|
159
|
+
alias :and :where
|
160
|
+
|
161
|
+
def select(field_names)
|
162
|
+
unless field_names.is_a? String
|
163
|
+
raise ArgumentError.new("Expected String but received #{field_names.class}")
|
164
|
+
end
|
165
|
+
|
166
|
+
fields_array = field_names.split(',')
|
167
|
+
@fields << fields_array
|
168
|
+
@fields.flatten!
|
169
|
+
@fields.uniq!
|
170
|
+
self
|
171
|
+
end
|
172
|
+
|
173
|
+
def limit(number)
|
174
|
+
unless number.is_a? Integer
|
175
|
+
raise ArgumentError.new("Expected Integer but received #{number.class}")
|
176
|
+
end
|
177
|
+
|
178
|
+
unless number <= 100
|
179
|
+
raise ArgumentError.new("Expected limit to be less than or equal to 100 but received #{number}")
|
180
|
+
end
|
181
|
+
|
182
|
+
@paging[:limit] = number
|
183
|
+
self
|
184
|
+
end
|
185
|
+
|
186
|
+
def page(number)
|
187
|
+
unless number.is_a? Integer
|
188
|
+
raise ArgumentError.new("Expected Integer but received #{number.class}")
|
189
|
+
end
|
190
|
+
|
191
|
+
@paging[:page] = number
|
192
|
+
self
|
193
|
+
end
|
194
|
+
|
195
|
+
def sort(field, order=nil)
|
196
|
+
unless field.is_a? String
|
197
|
+
raise ArgumentError.new("Expected String but received #{field.class}")
|
198
|
+
end
|
199
|
+
|
200
|
+
unless order.nil?
|
201
|
+
@sorting[:order] = order
|
202
|
+
end
|
203
|
+
|
204
|
+
@sorting[:field] = field
|
205
|
+
self
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|
data/lib/bodhi-slam/resource.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Bodhi
|
2
2
|
module Resource
|
3
|
+
|
3
4
|
SYSTEM_ATTRIBUTES = [:sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
|
4
5
|
:sys_namespace, :sys_created_by, :sys_type_version, :sys_id, :sys_embeddedType]
|
5
6
|
SUPPORT_ATTRIBUTES = [:bodhi_context, :errors]
|
@@ -62,8 +63,9 @@ module Bodhi
|
|
62
63
|
raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
|
63
64
|
end
|
64
65
|
|
65
|
-
|
66
|
-
|
66
|
+
record = Object.const_get(name).new(JSON.parse(result.body))
|
67
|
+
record.bodhi_context = context
|
68
|
+
record
|
67
69
|
end
|
68
70
|
|
69
71
|
# Returns all records of the given resource from the Bodhi Cloud.
|
@@ -92,7 +94,7 @@ module Bodhi
|
|
92
94
|
records << JSON.parse(result.body)
|
93
95
|
end while records.size == 100
|
94
96
|
|
95
|
-
records.flatten.collect{ |record|
|
97
|
+
records.flatten.collect{ |record| Object.const_get(name).new(record) }
|
96
98
|
end
|
97
99
|
|
98
100
|
# Aggregates the given resource based on the supplied +pipeline+
|
@@ -120,30 +122,15 @@ module Bodhi
|
|
120
122
|
JSON.parse(result.body)
|
121
123
|
end
|
122
124
|
|
123
|
-
# Returns
|
125
|
+
# Returns a Bodhi::Query object for quering the given Resource
|
124
126
|
#
|
125
127
|
# context = Bodhi::Context.new
|
126
|
-
# Resource.where(
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
unless query.is_a? String
|
133
|
-
raise ArgumentError.new("Expected 'query' to be a String. 'query' #=> #{query.class}")
|
134
|
-
end
|
135
|
-
|
136
|
-
result = context.connection.get do |request|
|
137
|
-
request.url "/#{context.namespace}/resources/#{name}?where=#{query}"
|
138
|
-
request.headers[context.credentials_header] = context.credentials
|
139
|
-
end
|
140
|
-
|
141
|
-
if result.status != 200
|
142
|
-
raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
|
143
|
-
end
|
144
|
-
|
145
|
-
resources = JSON.parse(result.body)
|
146
|
-
resources.map{ |attributes| factory.build(context, attributes) }
|
128
|
+
# Resource.where("{property: 'value'}").from(context).all
|
129
|
+
# Resource.where("{conditions}").and("{more conditions}").limit(10).from(context).all
|
130
|
+
def where(query)
|
131
|
+
query_obj = Bodhi::Query.new(name)
|
132
|
+
query_obj.where(query)
|
133
|
+
query_obj
|
147
134
|
end
|
148
135
|
|
149
136
|
# Deletes all records from a resource in the given +context+
|
@@ -167,6 +154,9 @@ module Bodhi
|
|
167
154
|
end
|
168
155
|
|
169
156
|
module InstanceMethods
|
157
|
+
def id; @sys_id; end
|
158
|
+
def persisted?; !@sys_id.nil?; end
|
159
|
+
|
170
160
|
# Returns a Hash of the Objects form attributes
|
171
161
|
#
|
172
162
|
# s = SomeResource.build({foo:"test", bar:12345})
|
@@ -181,7 +171,22 @@ module Bodhi
|
|
181
171
|
end
|
182
172
|
attributes
|
183
173
|
end
|
184
|
-
|
174
|
+
|
175
|
+
# Updates the resource with the given attributes Hash
|
176
|
+
#
|
177
|
+
# s = SomeResource.factory.build(foo:"test", bar:12345)
|
178
|
+
# s.attributes # => { foo: "test", bar: 12345 }
|
179
|
+
# s.update_attributes(foo:"12345", bar:10)
|
180
|
+
# s.attributes # => { foo: "12345", bar: 10 }
|
181
|
+
def update_attributes(params)
|
182
|
+
self.instance_variables.each do |variable|
|
183
|
+
attribute_name = variable.to_s.delete('@').to_sym
|
184
|
+
unless SYSTEM_ATTRIBUTES.include?(attribute_name) || SUPPORT_ATTRIBUTES.include?(attribute_name)
|
185
|
+
send("#{attribute_name}=", params[attribute_name])
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
185
190
|
# Returns all the Objects attributes as JSON.
|
186
191
|
# It converts any nested Objects to JSON if they respond to +to_json+
|
187
192
|
#
|
@@ -192,6 +197,34 @@ module Bodhi
|
|
192
197
|
attributes.to_json
|
193
198
|
end
|
194
199
|
|
200
|
+
# Saves the resource to the Bodhi Cloud. Returns true if record was saved
|
201
|
+
#
|
202
|
+
# obj = Resource.new
|
203
|
+
# obj.save # => true
|
204
|
+
# obj.persisted? # => true
|
205
|
+
def save
|
206
|
+
if self.invalid?
|
207
|
+
return false
|
208
|
+
end
|
209
|
+
|
210
|
+
result = bodhi_context.connection.post do |request|
|
211
|
+
request.url "/#{bodhi_context.namespace}/resources/#{self.class}"
|
212
|
+
request.headers['Content-Type'] = 'application/json'
|
213
|
+
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
214
|
+
request.body = attributes.to_json
|
215
|
+
end
|
216
|
+
|
217
|
+
if result.status != 201
|
218
|
+
raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
|
219
|
+
end
|
220
|
+
|
221
|
+
if result.headers['location']
|
222
|
+
@sys_id = result.headers['location'].match(/(?<id>[a-zA-Z0-9]{24})/)[:id]
|
223
|
+
end
|
224
|
+
|
225
|
+
true
|
226
|
+
end
|
227
|
+
|
195
228
|
# Saves the resource to the Bodhi Cloud. Raises ArgumentError if record could not be saved.
|
196
229
|
#
|
197
230
|
# obj = Resouce.new
|
@@ -224,6 +257,29 @@ module Bodhi
|
|
224
257
|
raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
|
225
258
|
end
|
226
259
|
end
|
260
|
+
alias :destroy :delete!
|
261
|
+
|
262
|
+
def update!(params)
|
263
|
+
update_attributes(params)
|
264
|
+
|
265
|
+
if invalid?
|
266
|
+
return false
|
267
|
+
end
|
268
|
+
|
269
|
+
result = bodhi_context.connection.put do |request|
|
270
|
+
request.url "/#{bodhi_context.namespace}/resources/#{self.class}/#{sys_id}"
|
271
|
+
request.headers['Content-Type'] = 'application/json'
|
272
|
+
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
273
|
+
request.body = params.to_json
|
274
|
+
end
|
275
|
+
|
276
|
+
if result.status != 204
|
277
|
+
raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
|
278
|
+
end
|
279
|
+
|
280
|
+
true
|
281
|
+
end
|
282
|
+
alias :update :update!
|
227
283
|
|
228
284
|
def patch!(params)
|
229
285
|
result = bodhi_context.connection.patch do |request|
|
@@ -241,7 +297,7 @@ module Bodhi
|
|
241
297
|
|
242
298
|
def self.included(base)
|
243
299
|
base.extend(ClassMethods)
|
244
|
-
base.include(InstanceMethods, Bodhi::Validations)
|
300
|
+
base.include(InstanceMethods, Bodhi::Validations, ActiveModel::Model)
|
245
301
|
base.instance_variable_set(:@factory, Bodhi::Factory.new(base))
|
246
302
|
end
|
247
303
|
end
|
data/lib/bodhi-slam/types.rb
CHANGED
@@ -176,7 +176,7 @@ module Bodhi
|
|
176
176
|
})
|
177
177
|
|
178
178
|
type.properties.each_pair do |attr_name, attr_properties|
|
179
|
-
attr_properties.delete_if{ |key, value| ["system", "trim", "unique", "default", "isCurrentUser"].include?(key) }
|
179
|
+
attr_properties.delete_if{ |key, value| ["system", "trim", "unique", "default", "isCurrentUser", "toLower"].include?(key) }
|
180
180
|
klass.validates(attr_name.to_sym, attr_properties)
|
181
181
|
klass.factory.add_generator(attr_name.to_sym, attr_properties)
|
182
182
|
end
|
@@ -4,7 +4,11 @@ module Bodhi
|
|
4
4
|
def initialize(value); end
|
5
5
|
|
6
6
|
def validate(record, attribute, value)
|
7
|
-
|
7
|
+
if value.nil?
|
8
|
+
#do nothing
|
9
|
+
else
|
10
|
+
record.errors.add(attribute, "must be an array") unless value.is_a? Array
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
def to_options
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bodhi-slam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- willdavis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-http-persistent
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activemodel
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.2'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -138,6 +152,7 @@ files:
|
|
138
152
|
- lib/bodhi-slam/errors/context.rb
|
139
153
|
- lib/bodhi-slam/factory.rb
|
140
154
|
- lib/bodhi-slam/profiles.rb
|
155
|
+
- lib/bodhi-slam/queries.rb
|
141
156
|
- lib/bodhi-slam/resource.rb
|
142
157
|
- lib/bodhi-slam/types.rb
|
143
158
|
- lib/bodhi-slam/users.rb
|