atomsphere 0.1.7 → 0.1.8
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/.gitignore +3 -0
- data/README.md +49 -22
- data/atomsphere.gemspec +1 -1
- data/lib/atomsphere.rb +2 -1
- data/lib/atomsphere/api/client.rb +18 -6
- data/lib/atomsphere/query.rb +55 -7
- data/lib/atomsphere/query/builder.rb +39 -0
- data/lib/atomsphere/query/builder/group.rb +26 -0
- data/lib/atomsphere/query/builder/property.rb +25 -0
- data/lib/atomsphere/query/expression.rb +13 -0
- data/lib/atomsphere/query/{grouping_expression.rb → expression/grouping_expression.rb} +29 -8
- data/lib/atomsphere/query/{simple_expression.rb → expression/simple_expression.rb} +16 -8
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e78f1312bd07e2b8624c0aae53b83463bf877134d6c9b3d0253f2256528e3441
|
4
|
+
data.tar.gz: 9f34dccf99636cb840a89f48fd256f92944ad55f5e6eec7e3c1d1ad200c0c9d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 571d407b997b509a116397fce8ee74d32819dab8890575cfa19b5eaff4c02c4a542fb41a3657fe1df0747a74934f429e5a0427d92ee8efba193dc2c31b01586a
|
7
|
+
data.tar.gz: 84f4c92a54014a100e2f33c4021167e085e1ca90291cb07c4d18896c5fe1423145b40013dbb4b303d07834c3b5d79c9277d2d2f34cb64f67f9ff78bb34da32d8
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Boomi Atomsphere API client for Ruby
|
2
2
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
4
|
+
[](https://badge.fury.io/rb/atomsphere)
|
5
|
+
[](https://www.rubydoc.info/gems/atomsphere)
|
6
|
+
|
3
7
|
Unofficial Ruby client for the Dell Boomi Atomsphere API. Implements the JSON flavour of Boomi's "RESTish" API.
|
4
8
|
|
5
9
|
## Status
|
@@ -40,35 +44,58 @@ Alternatively, environment variables may be used:
|
|
40
44
|
|
41
45
|
### Querying
|
42
46
|
|
47
|
+
Generate a query for all _"Processes"_ that start with _"Production"_ and
|
48
|
+
contain _"NetSuite"_ or _"Salesforce"_:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
query = Atomsphere.query('Process') do
|
52
|
+
group :and do
|
53
|
+
name.like 'Production%'
|
54
|
+
group :or do
|
55
|
+
name.like '%NetSuite%'
|
56
|
+
name.like '%Salesforce%'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Generate a query for all online Atoms:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
query = Atomsphere.query('Atom') do
|
66
|
+
status.equals 'ONLINE'
|
67
|
+
type.equals 'CLOUD'
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
Inspect the query filter:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
query.to_hash
|
75
|
+
query.to_json
|
76
|
+
```
|
77
|
+
|
78
|
+
Run the query:
|
79
|
+
|
43
80
|
```ruby
|
44
|
-
# create a new query
|
45
|
-
query = Atomsphere::Query.new
|
46
|
-
|
47
|
-
# specify the object type to query
|
48
|
-
query.object_type = 'Process'
|
49
|
-
|
50
|
-
# filter for query names starting with 'Netsuite'
|
51
|
-
query.filter = Atomsphere::Query::GroupingExpression.new(
|
52
|
-
operator: :and,
|
53
|
-
nested_expression: [
|
54
|
-
Atomsphere::Query::SimpleExpression.new(
|
55
|
-
operator: :equals,
|
56
|
-
property: :name,
|
57
|
-
argument: ['Netsuite%']
|
58
|
-
)
|
59
|
-
]
|
60
|
-
)
|
61
|
-
|
62
|
-
# run the query (fetches first page)
|
63
81
|
query.run
|
82
|
+
```
|
83
|
+
|
84
|
+
See results from all pages that have been fetched:
|
64
85
|
|
65
|
-
|
86
|
+
```ruby
|
66
87
|
query.results
|
88
|
+
```
|
89
|
+
|
90
|
+
Fetch the next page (returns `false` if `last_page?` is `true`):
|
67
91
|
|
68
|
-
|
92
|
+
```ruby
|
69
93
|
query.next_page
|
94
|
+
```
|
95
|
+
|
96
|
+
Iterate over `next_page` until `last_page?` is `true` and see all results:
|
70
97
|
|
71
|
-
|
98
|
+
```ruby
|
72
99
|
query.all_results
|
73
100
|
```
|
74
101
|
|
data/atomsphere.gemspec
CHANGED
data/lib/atomsphere.rb
CHANGED
@@ -96,12 +96,24 @@ module Atomsphere
|
|
96
96
|
'response code was nil'
|
97
97
|
) if response.code.nil?
|
98
98
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
99
|
+
if response.code >= 400
|
100
|
+
begin
|
101
|
+
json = JSON.parse(response.response.body)
|
102
|
+
if json['@type'].downcase.eql?('error')
|
103
|
+
message = json['message']
|
104
|
+
end
|
105
|
+
rescue JSON::ParserError
|
106
|
+
ensure
|
107
|
+
message ||= "API responded with error #{response.code}: #{response.message}"
|
108
|
+
end
|
109
|
+
|
110
|
+
raise ApiError.new(
|
111
|
+
request,
|
112
|
+
response,
|
113
|
+
e,
|
114
|
+
message
|
115
|
+
)
|
116
|
+
end
|
105
117
|
end
|
106
118
|
|
107
119
|
response
|
data/lib/atomsphere/query.rb
CHANGED
@@ -1,15 +1,40 @@
|
|
1
1
|
module Atomsphere
|
2
|
+
|
3
|
+
# @attr [String] object_type name of the object to query
|
4
|
+
# @attr [GroupingExpression] filter top level {GroupingExpression} for query
|
5
|
+
# @attr_reader [Integer] page the number of pages retrieved
|
6
|
+
# @attr_reader [Array<Api::Response>] result_pages array of api responses for each page retrieved
|
2
7
|
class Query
|
3
8
|
attr_accessor :object_type, :filter
|
4
9
|
attr_reader :query_token, :result_pages, :page
|
5
10
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
# accepts either a string of the name of the object to query, or a hash of options
|
12
|
+
# @param [String] params name of the object to query
|
13
|
+
# @param [Hash] params parameters to initialize query with
|
14
|
+
# @option params [String] :object_type name of the object to query
|
15
|
+
# @option params [GroupingExpression] :filter top level {GroupingExpression}
|
16
|
+
def initialize(params={})
|
17
|
+
case params
|
18
|
+
when String
|
19
|
+
params = {object_type: params}
|
20
|
+
end
|
21
|
+
|
22
|
+
params = {
|
23
|
+
object_type: nil,
|
24
|
+
page: 0,
|
25
|
+
result_pages: [],
|
26
|
+
filter: GroupingExpression.new
|
27
|
+
}.merge(Hash[params.select{|k,v| [:object_type, :filter].include? k}])
|
28
|
+
|
29
|
+
%w(object_type page result_pages filter).each do |v|
|
30
|
+
instance_variable_set :"@#{v}", params[v.to_sym]
|
31
|
+
end
|
32
|
+
|
33
|
+
self
|
11
34
|
end
|
12
35
|
|
36
|
+
# run all `validate_*!` private methods to ensure validity of query parameters
|
37
|
+
# @return [true, false]
|
13
38
|
def validate!
|
14
39
|
private_methods.select{ |m| m =~ /^validate_[a-z0-9_]+\!$/ }.each{ |v| send(v) }
|
15
40
|
filter.validate!
|
@@ -17,23 +42,33 @@ module Atomsphere
|
|
17
42
|
true
|
18
43
|
end
|
19
44
|
|
45
|
+
# @see #next_page
|
20
46
|
def run
|
21
47
|
next_page
|
22
48
|
end
|
23
|
-
|
49
|
+
|
50
|
+
# returns rows from {#result_pages} that have been retrieved
|
51
|
+
# @return [Array<Hash>] Array of returned rows as hashes
|
24
52
|
def results
|
25
53
|
result_pages.map(&:to_hash).map{ |h| h['result'] }.map(&:compact).flatten(1)
|
26
54
|
end
|
27
55
|
|
56
|
+
# runs {#next_page} to retrieve all {#result_pages} until {#last_page?} is `false`,
|
57
|
+
# and then returns all rows
|
58
|
+
# @return [Array<Hash>] Array of returned rows as hashes
|
28
59
|
def all_results
|
29
60
|
next_page until last_page?
|
30
61
|
results
|
31
62
|
end
|
32
63
|
|
64
|
+
# returns `true` when any pages have been retrieved the value of {#query_token} is `nil`
|
65
|
+
# @return [true, false]
|
33
66
|
def last_page?
|
34
67
|
!page.eql?(0) && query_token.nil?
|
35
68
|
end
|
36
69
|
|
70
|
+
# retrieve the next page for the query
|
71
|
+
# @return [Api::Response, false] returns the response, or `false` if {#last_page?} is `true`
|
37
72
|
def next_page
|
38
73
|
return false if last_page?
|
39
74
|
|
@@ -52,12 +87,19 @@ module Atomsphere
|
|
52
87
|
result_pages[page-1] = response
|
53
88
|
end
|
54
89
|
|
90
|
+
# validates all parameters with {#validate!} and returns a hash of the query
|
91
|
+
# that will be sent to the boomi api
|
92
|
+
# @see #to_json
|
93
|
+
# @return [Hash] hash representation of query that will be sent to the boomi api
|
55
94
|
def to_hash
|
56
95
|
validate!
|
57
96
|
|
58
97
|
{ QueryFilter: filter.to_hash }
|
59
98
|
end
|
60
99
|
|
100
|
+
# query json that will be sent to the boomi api
|
101
|
+
# @see #to_hash
|
102
|
+
# @return [String] JSON query string
|
61
103
|
def to_json
|
62
104
|
JSON.pretty_generate to_hash
|
63
105
|
end
|
@@ -73,10 +115,15 @@ module Atomsphere
|
|
73
115
|
end
|
74
116
|
end
|
75
117
|
|
118
|
+
# an instance of the API client
|
119
|
+
# @return [Api::Client]
|
76
120
|
def api_client
|
77
121
|
Api::Client.new
|
78
122
|
end
|
79
123
|
|
124
|
+
# if any pages have been retrieved, the value of `queryToken` from the
|
125
|
+
# last response
|
126
|
+
# @return [String, nil] value of `queryToken`, or `nil`
|
80
127
|
def query_token
|
81
128
|
if result_pages.last.nil? || !result_pages.last.to_hash.keys.include?('queryToken')
|
82
129
|
nil
|
@@ -86,5 +133,6 @@ module Atomsphere
|
|
86
133
|
end
|
87
134
|
end
|
88
135
|
|
89
|
-
|
136
|
+
require "#{ROOT}/query/builder"
|
137
|
+
require "#{ROOT}/query/expression"
|
90
138
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Atomsphere
|
2
|
+
class Query
|
3
|
+
class Builder
|
4
|
+
attr_reader :query
|
5
|
+
|
6
|
+
def initialize(object_type)
|
7
|
+
@query = object_type.nil? ? Query.new : Query.new(object_type)
|
8
|
+
end
|
9
|
+
|
10
|
+
def group operator, &block
|
11
|
+
new_group = GroupingExpression.new(operator)
|
12
|
+
Group.new(new_group).instance_eval(&block)
|
13
|
+
|
14
|
+
if @query.filter
|
15
|
+
@query.filter.nested_expression << new_group
|
16
|
+
else
|
17
|
+
@query.filter = new_group
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing m, *args, &block
|
22
|
+
@query.filter = GroupingExpression.new(:and) unless @query.filter
|
23
|
+
Group.new(@query.filter).instance_eval do
|
24
|
+
send(m, *args, &block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.query(object_type=nil, &block)
|
31
|
+
q = Query::Builder.new(object_type)
|
32
|
+
q.instance_eval(&block) if block_given?
|
33
|
+
|
34
|
+
q.query
|
35
|
+
end
|
36
|
+
|
37
|
+
require "#{ROOT}/query/builder/property"
|
38
|
+
require "#{ROOT}/query/builder/group"
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Atomsphere
|
2
|
+
class Query
|
3
|
+
class Builder
|
4
|
+
class Group
|
5
|
+
def initialize expression
|
6
|
+
@expression = expression
|
7
|
+
end
|
8
|
+
|
9
|
+
def group operator, &block
|
10
|
+
new_group = GroupingExpression.new(operator)
|
11
|
+
Group.new(new_group).instance_eval(&block)
|
12
|
+
@expression.nested_expression << new_group
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing m, *args, &block
|
16
|
+
__property(@expression, m)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def __property(expression, property)
|
21
|
+
Property.new(expression, property)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Atomsphere
|
2
|
+
class Query
|
3
|
+
class Builder
|
4
|
+
class Property
|
5
|
+
def initialize(expression, property)
|
6
|
+
@expression = expression
|
7
|
+
@property = property
|
8
|
+
end
|
9
|
+
|
10
|
+
def method_missing m, *args, &block
|
11
|
+
__operator(m, *args) if SimpleExpression::OPERATORS.keys.include? m
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def __operator(operator, args)
|
16
|
+
@expression.nested_expression << SimpleExpression.new(
|
17
|
+
property: @property,
|
18
|
+
operator: operator,
|
19
|
+
argument: args
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -2,12 +2,24 @@ require 'json'
|
|
2
2
|
|
3
3
|
module Atomsphere
|
4
4
|
class Query
|
5
|
-
|
5
|
+
|
6
|
+
# @see http://help.boomi.com/atomsphere/GUID-4CAE5616-76EB-4C58-B2E3-4173B65EA7EC.html
|
7
|
+
class GroupingExpression < Expression
|
6
8
|
attr_accessor :operator, :nested_expression
|
7
9
|
|
10
|
+
# allowed values for {#operator=}
|
8
11
|
OPERATORS = :and, :or
|
9
12
|
|
13
|
+
# @param [Hash] params
|
14
|
+
# @option params [:and, :or] :operator query operator
|
15
|
+
# @option params [Array<Expression>] :nested_expression one or more {Expression}s
|
10
16
|
def initialize(params={})
|
17
|
+
case params
|
18
|
+
when String
|
19
|
+
when Symbol
|
20
|
+
params = {operator: params}
|
21
|
+
end
|
22
|
+
|
11
23
|
params = {
|
12
24
|
operator: :and,
|
13
25
|
nested_expression: []
|
@@ -17,6 +29,16 @@ module Atomsphere
|
|
17
29
|
@nested_expression = params[:nested_expression]
|
18
30
|
end
|
19
31
|
|
32
|
+
def operator= arg
|
33
|
+
unless OPERATORS.include? arg.to_sym
|
34
|
+
raise ArgumentError, "operator must be one of: #{OPERATORS.join(', ')}"
|
35
|
+
end
|
36
|
+
|
37
|
+
instance_variable_set :@operator, arg.to_sym
|
38
|
+
end
|
39
|
+
|
40
|
+
# run all `validate_*!` private methods to ensure validity of expression parameters
|
41
|
+
# @return [true, false]
|
20
42
|
def validate!
|
21
43
|
private_methods.select{ |m| m =~ /^validate_[a-z0-9_]+\!$/ }.each{ |v| "#{v}"; send(v) }
|
22
44
|
@nested_expression.each(&:validate!)
|
@@ -24,6 +46,9 @@ module Atomsphere
|
|
24
46
|
true
|
25
47
|
end
|
26
48
|
|
49
|
+
# returns a hash of the expression that will be sent to the boomi api with {Query#to_hash}
|
50
|
+
# @see #to_json
|
51
|
+
# @return [Hash] hash representation of query that will be sent to the boomi api
|
27
52
|
def to_hash
|
28
53
|
{
|
29
54
|
expression: {
|
@@ -35,10 +60,6 @@ module Atomsphere
|
|
35
60
|
}
|
36
61
|
end
|
37
62
|
|
38
|
-
def to_json
|
39
|
-
JSON.pretty_generate to_hash
|
40
|
-
end
|
41
|
-
|
42
63
|
private
|
43
64
|
def validate_operators!
|
44
65
|
unless OPERATORS.include? @operator
|
@@ -49,13 +70,13 @@ module Atomsphere
|
|
49
70
|
def validate_expressions!
|
50
71
|
raise ArgumentError, "nested_expression must be an array" unless @nested_expression.is_a?(Array)
|
51
72
|
|
52
|
-
not_expressions = @nested_expression.map(&:class).reject do |k|
|
53
|
-
|
73
|
+
not_expressions = @nested_expression.map(&:class).map(&:ancestors).reject do |k|
|
74
|
+
k.include? Atomsphere::Query::Expression
|
54
75
|
end
|
55
76
|
|
56
77
|
if not_expressions.size > 0
|
57
78
|
raise ArgumentError,
|
58
|
-
"
|
79
|
+
"Expressions must be an object of a subclass of Atomsphere::Query::Expression"
|
59
80
|
end
|
60
81
|
end
|
61
82
|
|
@@ -2,9 +2,12 @@ require 'json'
|
|
2
2
|
|
3
3
|
module Atomsphere
|
4
4
|
class Query
|
5
|
-
|
5
|
+
|
6
|
+
# @see http://help.boomi.com/atomsphere/GUID-4CAE5616-76EB-4C58-B2E3-4173B65EA7EC.html
|
7
|
+
class SimpleExpression < Expression
|
6
8
|
attr_accessor :operator, :property, :argument
|
7
9
|
|
10
|
+
# allowed values for {#operator=}
|
8
11
|
OPERATORS = {
|
9
12
|
equals: 1,
|
10
13
|
like: 1,
|
@@ -19,6 +22,10 @@ module Atomsphere
|
|
19
22
|
less_than_or_equal: 1
|
20
23
|
}
|
21
24
|
|
25
|
+
# @param [Hash] params
|
26
|
+
# @option params [String] :property the property/field to query
|
27
|
+
# @option params [:equals,:like,:not_equals,:is_null,:is_not_null,:starts_with,:between,:greater_than,:less_than,:greater_than_or_equal,:less_than_or_equal] :operator query operator
|
28
|
+
# @option params [Array] :argument array containing the number of arguments specified in the {OPERATORS} constant, as arguments to the query {#operator}
|
22
29
|
def initialize(params={})
|
23
30
|
params = {
|
24
31
|
operator: :equals,
|
@@ -31,25 +38,26 @@ module Atomsphere
|
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
41
|
+
# run all `validate_*!` private methods to ensure validity of expression parameters
|
42
|
+
# @return [true, false]
|
34
43
|
def validate!
|
35
44
|
private_methods.select{ |m| m =~ /^validate_[a-z0-9_]+\!$/ }.each{ |v| send(v) }
|
36
45
|
true
|
37
46
|
end
|
38
47
|
|
48
|
+
# returns a hash of the expression that will be sent to the boomi api with {Query#to_hash}
|
49
|
+
# @see #to_json
|
50
|
+
# @return [Hash] hash representation of query that will be sent to the boomi api
|
39
51
|
def to_hash
|
40
52
|
{
|
41
53
|
expression: {
|
42
|
-
operator: operator.upcase,
|
43
|
-
property: property,
|
44
|
-
argument: [*argument]
|
54
|
+
operator: operator.to_s.upcase,
|
55
|
+
property: property.to_s,
|
56
|
+
argument: [*argument].map(&:to_s)
|
45
57
|
}
|
46
58
|
}
|
47
59
|
end
|
48
60
|
|
49
|
-
def to_json
|
50
|
-
to_hash.to_json
|
51
|
-
end
|
52
|
-
|
53
61
|
def operator= arg
|
54
62
|
unless OPERATORS.keys.include? arg.to_sym
|
55
63
|
raise ArgumentError, "operator must be one of: #{OPERATORS.keys.join(', ')}"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atomsphere
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Warren Guy
|
@@ -59,8 +59,12 @@ files:
|
|
59
59
|
- lib/atomsphere/api/response.rb
|
60
60
|
- lib/atomsphere/configuration.rb
|
61
61
|
- lib/atomsphere/query.rb
|
62
|
-
- lib/atomsphere/query/
|
63
|
-
- lib/atomsphere/query/
|
62
|
+
- lib/atomsphere/query/builder.rb
|
63
|
+
- lib/atomsphere/query/builder/group.rb
|
64
|
+
- lib/atomsphere/query/builder/property.rb
|
65
|
+
- lib/atomsphere/query/expression.rb
|
66
|
+
- lib/atomsphere/query/expression/grouping_expression.rb
|
67
|
+
- lib/atomsphere/query/expression/simple_expression.rb
|
64
68
|
homepage: https://github.com/warrenguy/atomsphere-ruby
|
65
69
|
licenses:
|
66
70
|
- MIT
|