nne_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +19 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +92 -0
  5. data/Rakefile +2 -0
  6. data/lib/nne_client/fetch.rb +22 -0
  7. data/lib/nne_client/query.rb +35 -0
  8. data/lib/nne_client/question.rb +36 -0
  9. data/lib/nne_client/record_types/finance.rb +43 -0
  10. data/lib/nne_client/record_types/ownership.rb +25 -0
  11. data/lib/nne_client/record_types/subsidiary.rb +25 -0
  12. data/lib/nne_client/record_types/trade.rb +21 -0
  13. data/lib/nne_client/request.rb +56 -0
  14. data/lib/nne_client/result.rb +171 -0
  15. data/lib/nne_client/result_attributes.rb +37 -0
  16. data/lib/nne_client/result_set.rb +43 -0
  17. data/lib/nne_client/search.rb +15 -0
  18. data/lib/nne_client/version.rb +3 -0
  19. data/lib/nne_client.rb +43 -0
  20. data/nne_client.gemspec +24 -0
  21. data/spec/finance_spec.rb +79 -0
  22. data/spec/ownership_spec.rb +34 -0
  23. data/spec/result_spec.rb +284 -0
  24. data/spec/search_spec.rb +78 -0
  25. data/spec/spec_helper.rb +29 -0
  26. data/spec/subsidiary_spec.rb +36 -0
  27. data/spec/trade_spec.rb +21 -0
  28. data/spec/vcr_cassettes/result_additional_names_single.yml +706 -0
  29. data/spec/vcr_cassettes/result_extended_info.yml +705 -0
  30. data/spec/vcr_cassettes/result_extended_info_with_access_key.yml +705 -0
  31. data/spec/vcr_cassettes/result_fetching_basic_attributes.yml +705 -0
  32. data/spec/vcr_cassettes/result_fetching_ext_attributes_email_hash.yml +1407 -0
  33. data/spec/vcr_cassettes/result_fetching_missing_company.yml +706 -0
  34. data/spec/vcr_cassettes/result_multiple_finances.yml +1408 -0
  35. data/spec/vcr_cassettes/result_multiple_ownerships.yml +1409 -0
  36. data/spec/vcr_cassettes/result_multiple_trades.yml +1407 -0
  37. data/spec/vcr_cassettes/result_names.yml +705 -0
  38. data/spec/vcr_cassettes/result_names_empty.yml +706 -0
  39. data/spec/vcr_cassettes/result_no_finance.yml +1408 -0
  40. data/spec/vcr_cassettes/result_no_ownerships.yml +706 -0
  41. data/spec/vcr_cassettes/result_no_subsidiaries.yml +1409 -0
  42. data/spec/vcr_cassettes/result_single_finance.yml +1409 -0
  43. data/spec/vcr_cassettes/result_single_ownership.yml +1408 -0
  44. data/spec/vcr_cassettes/result_single_subsidiary.yml +1408 -0
  45. data/spec/vcr_cassettes/result_trades.yml +705 -0
  46. data/spec/vcr_cassettes/search_for_noise.yml +706 -0
  47. data/spec/vcr_cassettes/search_lokale.yml +705 -0
  48. data/spec/vcr_cassettes/search_lokale_100.yml +705 -0
  49. data/spec/vcr_cassettes/search_lokalebasen.yml +706 -0
  50. data/spec/vcr_cassettes/search_lokalebasen_with_access_key.yml +706 -0
  51. metadata +234 -0
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rvmrc
19
+ .rspec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nne_client.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jacob Atzen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # NNEClient
2
+
3
+ Client library for interacting with the "Navne & Numre Erhverv" SOAP API.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'nne_client'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install nne_client
18
+
19
+ ## Warning
20
+
21
+ NNEClient only works with the Net/HTTP and will force HTTPI to use this.
22
+
23
+ ## Usage
24
+
25
+ If you need to provide an access key configure NNE Client with:
26
+
27
+ NNEClient.configure do |config|
28
+ config.access_key = 'some key'
29
+ end
30
+
31
+ Searching for a company:
32
+
33
+ result_set = NNEClient.search(:name => 'Lokalebasen')
34
+ result_set.first.official_name
35
+ => "Lokalebasen.dk A/S"
36
+
37
+ So far the following keys can be used for searching:
38
+
39
+ :houseNo (string)
40
+ :name (string)
41
+ :nameStartsWith (boolean)
42
+ :street (string)
43
+ :zipCode (number)
44
+ :tdcId (number)
45
+
46
+ Each entry in the result\_set has the following methods available for accessing
47
+ information about the company:
48
+
49
+ ad_protection
50
+ cvr_no
51
+ district
52
+ email
53
+ founded_year
54
+ homepage
55
+ number_of_employees
56
+ official_name
57
+ p_no
58
+ phone
59
+ status_text
60
+ street
61
+ tdf_name
62
+ zip_code
63
+
64
+ Additionally further information can be fetched through the methods:
65
+
66
+ additional_names
67
+ trades
68
+ associates
69
+ ownerships
70
+ subsidiaries
71
+ finances
72
+
73
+ ## Configuration
74
+
75
+ NNEClient is based on Savon and HTTPI. You may use these libraries to control
76
+ logging. For example:
77
+
78
+ HTTPI.log = false
79
+
80
+ Savon.configure do |config|
81
+ config.log = false # disable logging
82
+ config.log_level = :info # changing the log level
83
+ config.logger = Rails.logger # using the Rails logger
84
+ end
85
+
86
+ ## Contributing
87
+
88
+ 1. Fork it
89
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
90
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
91
+ 4. Push to the branch (`git push origin my-new-feature`)
92
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ module NNEClient
2
+ # @!visibility private
3
+ class Fetch
4
+ def initialize(tdc_id, command)
5
+ @tdc_id = tdc_id
6
+ @command = command
7
+ end
8
+
9
+ def result_set
10
+ Request.execute(@command) do |xml|
11
+ tag(xml, :int_1, @tdc_id, :int)
12
+ tag(xml, :int_2, 0, :int)
13
+ tag(xml, :String_3, nil, :string)
14
+ tag(xml, :String_4, NNEClient.config.access_key, :string)
15
+ end
16
+ end
17
+
18
+ def tag(xml, attribute, value, type)
19
+ xml.tag!(attribute, value, 'xsi:type' => "xsd:#{type}")
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,35 @@
1
+ module NNEClient
2
+ # @!visibility private
3
+ class Query
4
+ def initialize(query_hash, xml)
5
+ @query_hash = query_hash
6
+ @xml = xml
7
+ end
8
+
9
+ def render
10
+ Question.new(@query_hash, @xml).render
11
+ tag(:int_2, hits_per_page, :int)
12
+ tag(:int_3, wanted_page_number, :int)
13
+ tag(:int_4, include_ad_protected, :int)
14
+ tag(:String_5, NNEClient.config.access_key, :string)
15
+ end
16
+
17
+ private
18
+
19
+ def include_ad_protected
20
+ @query_hash[:include_ad_protected] ? 1 : 0
21
+ end
22
+
23
+ def hits_per_page
24
+ @query_hash[:hits_per_page] || 10
25
+ end
26
+
27
+ def wanted_page_number
28
+ @query_hash[:wanted_page_number] || 1
29
+ end
30
+
31
+ def tag(attribute, value, type)
32
+ @xml.tag!(attribute, value, 'xsi:type' => "xsd:#{type}")
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ module NNEClient
2
+ # @!visibility private
3
+ class Question
4
+ def initialize(query_hash, xml)
5
+ @query_hash = query_hash
6
+ @xml = xml
7
+ end
8
+
9
+ def render
10
+ @xml.Question_1(question_attributes) do
11
+ query(:houseNo, :string)
12
+ query(:name, :string)
13
+ query(:nameStartsWith, :boolean)
14
+ query(:street, :string)
15
+ query(:zipCode, :int)
16
+ query(:tdcId, :int)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def query(attribute, type)
23
+ if @query_hash[attribute]
24
+ @xml.tag!(attribute, @query_hash[attribute], 'xsi:type' => "xsd:#{type}")
25
+ end
26
+ end
27
+
28
+ def question_attributes
29
+ {
30
+ 'xmlns:nne' => "http://com.stibo.net/nne/3.1/Types/NNE",
31
+ 'xsi:type' => "nne:Question"
32
+ }
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ module NNEClient
2
+ class Finance
3
+ extend NNEClient::ResultAttributes
4
+
5
+ def initialize(finance_hash)
6
+ @hash = finance_hash
7
+ end
8
+
9
+ attributes :accounting_date,
10
+ :assets,
11
+ :available_funds,
12
+ :available_funds_ratio,
13
+ :balance,
14
+ :capacity_ratio,
15
+ :contribution_ratio,
16
+ :credit_rating,
17
+ :current_assets,
18
+ :depreciations,
19
+ :fixed_assets,
20
+ :fixed_cost,
21
+ :gross_profit,
22
+ :income_before_income_tax,
23
+ :link_pdf,
24
+ :long_termed_liability,
25
+ :lots_and_sites,
26
+ :net_outcome,
27
+ :number_of_employees,
28
+ :placings,
29
+ :profit,
30
+ :profit_for_the_year,
31
+ :profit_ratio,
32
+ :published_date,
33
+ :return_on_assets,
34
+ :share_holders_funds_of_interest,
35
+ :shareholders_funds,
36
+ :short_termed_liability,
37
+ :solvency_ratio,
38
+ :stock,
39
+ :trade_debitors,
40
+ :turnover,
41
+ :year
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ module NNEClient
2
+ class Ownership
3
+ extend NNEClient::ResultAttributes
4
+
5
+ attributes :name, :country
6
+
7
+ def initialize(ownership_hash)
8
+ @hash = ownership_hash
9
+ end
10
+
11
+ def share
12
+ @hash[:share].strip
13
+ end
14
+
15
+ def ==(other)
16
+ share == other.share &&
17
+ name == other.name &&
18
+ country == other.country
19
+ end
20
+
21
+ def company
22
+ Result.new(:tdc_id => @hash[:tdc_id])
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module NNEClient
2
+ class Subsidiary
3
+ extend NNEClient::ResultAttributes
4
+
5
+ attributes :name, :country
6
+
7
+ def initialize(subsidiary_hash)
8
+ @hash = subsidiary_hash
9
+ end
10
+
11
+ def ==(other)
12
+ share == other.share &&
13
+ name == other.name &&
14
+ country == other.country
15
+ end
16
+
17
+ def share
18
+ @hash[:share].strip
19
+ end
20
+
21
+ def company
22
+ Result.new(:tdc_id => @hash[:tdc_id])
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ module NNEClient
2
+ class Trade
3
+ attr_reader :trade_code, :trade
4
+
5
+ def initialize(trade_hash)
6
+ @primary = trade_hash[:primary]
7
+ @trade_code = trade_hash[:trade_code]
8
+ @trade = trade_hash[:trade]
9
+ end
10
+
11
+ def primary?
12
+ @primary
13
+ end
14
+
15
+ def ==(other)
16
+ primary? == other.primary? &&
17
+ trade_code == other.trade_code &&
18
+ trade == other.trade
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,56 @@
1
+ module NNEClient
2
+ # @!visibility private
3
+ class Request
4
+ class << self
5
+ def execute(command, &block)
6
+ new(command).result_set(&block)
7
+ end
8
+ end
9
+
10
+ def initialize(command)
11
+ @command = command
12
+ end
13
+
14
+ def result_set(&block)
15
+ retries = 3
16
+ begin
17
+ ResultSet.new(perform_request(&block))
18
+ rescue Net::HTTPRequestTimeOut => e
19
+ retries -= 1
20
+ retry if retries > 0
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def perform_request(&block)
27
+ client.request('wsdl', @command, request_attributes) do
28
+ if false
29
+ # Savon 0.9.5 does not support this
30
+ soap.body do |xml|
31
+ yield xml
32
+ end
33
+ else
34
+ # So create a builder manually
35
+ str = StringIO.new
36
+ builder = Builder::XmlMarkup.new(:target => str)
37
+ yield builder
38
+ str.rewind
39
+ soap.body = str.read
40
+ end
41
+ end
42
+ end
43
+
44
+ def request_attributes
45
+ { "env:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/" }
46
+ end
47
+
48
+ def wsdl_url
49
+ 'http://service.nnerhverv.dk/nne-ws/3.1/NNE?WSDL'
50
+ end
51
+
52
+ def client
53
+ @client ||= Savon::Client.new(wsdl_url)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,171 @@
1
+ module NNEClient
2
+
3
+ # The Result is used to represent a single result from a result set. It can
4
+ # be seen roughly as an NNE CompanyBasic object. It provides transparent
5
+ # loading of attributes from the NNE Company object. It also provides methods
6
+ # for navigating the API further.
7
+ #
8
+ # The Result can be instantiated with either a full result hash from an API
9
+ # query or with just a tdc_id in which case the attributes will be lazy loaded
10
+ # from the API.
11
+ class Result
12
+ class << self
13
+ # Basic attributes are attributes returned by NNE on the
14
+ # CompanyBasic object
15
+ #
16
+ # @!visibility private
17
+ def basic_attributes(*attrs)
18
+ attrs.each do |attr|
19
+ define_method(attr) { basic_attribute(attr) }
20
+ end
21
+ end
22
+
23
+ # Extended attributes are attributes returned by NNE on the
24
+ # Company object
25
+ #
26
+ # @!visibility private
27
+ def extended_attributes(*attrs)
28
+ attrs.each do |attr|
29
+ define_method(attr) { extended_attributes[attr] }
30
+ end
31
+ end
32
+ end
33
+
34
+ # @!visibility private
35
+ attr_reader :tdc_id
36
+
37
+ # @!visibility private
38
+ def initialize(result_hash)
39
+ @basic_attributes = result_hash
40
+ @tdc_id = result_hash[:tdc_id]
41
+ end
42
+
43
+ # @!attribute [r] cvr_no
44
+ # @!attribute [r] p_no
45
+ # @!attribute [r] district
46
+ # @!attribute [r] phone
47
+ # @!attribute [r] street
48
+ # @!attribute [r] zip_code
49
+ # @!attribute [r] official_name
50
+ # @!attribute [r] ad_protection
51
+ basic_attributes :cvr_no, :p_no, :district, :phone, :street, :zip_code,
52
+ :official_name, :ad_protection
53
+
54
+ # @!attribute [r] email
55
+ # @!attribute [r] homepage
56
+ # @!attribute [r] founded_year
57
+ # @!attribute [r] number_of_employees
58
+ # @!attribute [r] tdf_name
59
+ # @!attribute [r] status_text
60
+ extended_attributes :email, :homepage, :founded_year,
61
+ :number_of_employees, :tdf_name, :status_text
62
+
63
+ # List of additional_names
64
+ def additional_names
65
+ result = Fetch.new(tdc_id, 'fetchCompanyAdditionalNames').result_set.to_hash
66
+ Array(result[:array_ofstring][:item])
67
+ end
68
+
69
+ # List of trades
70
+ def trades
71
+ trades = Fetch.new(tdc_id, 'fetchCompanyTrade').result_set.to_hash[:trade]
72
+ if trades.kind_of?(Hash)
73
+ [Trade.new(trades)]
74
+ else
75
+ trades.map{|trade| Trade.new(trade) }
76
+ end
77
+ end
78
+
79
+ # List of associates
80
+ def associates
81
+ subsidiaries = fetch_associates
82
+ if subsidiaries.kind_of?(Hash)
83
+ [Subsidiary.new(subsidiaries)]
84
+ else
85
+ subsidiaries.map{|subsidiary| Subsidiary.new(subsidiary) }
86
+ end
87
+ end
88
+
89
+ # List of ownerships
90
+ def ownerships
91
+ ownerships = fetch_ownerships
92
+ if ownerships.kind_of?(Hash)
93
+ [Ownership.new(ownerships)]
94
+ else
95
+ ownerships.map{|ownership| Ownership.new(ownership) }
96
+ end
97
+ end
98
+
99
+ # List of subsidiaries
100
+ def subsidiaries
101
+ subsidiaries = fetch_subsidiaries
102
+ if subsidiaries.kind_of?(Hash)
103
+ [Subsidiary.new(subsidiaries)]
104
+ else
105
+ subsidiaries.map{|subsidiary| Subsidiary.new(subsidiary) }
106
+ end
107
+ end
108
+
109
+ # List of finance records
110
+ def finances
111
+ finances = fetch_finances
112
+ if finances.kind_of?(Hash)
113
+ [Finance.new(finances)]
114
+ else
115
+ finances.map{|finance| Finance.new(finance) }
116
+ end
117
+ end
118
+
119
+ def ==(other)
120
+ other.tdc_id == tdc_id
121
+ end
122
+
123
+ def hash
124
+ tdc_id.hash
125
+ end
126
+
127
+ def eql?(other)
128
+ hash == other.hash
129
+ end
130
+
131
+ private
132
+
133
+ def fetch_associates
134
+ Fetch.new(tdc_id, 'fetchCompanyAssociates').result_set.to_hash[:subsidiary] || []
135
+ end
136
+
137
+ def fetch_finances
138
+ Fetch.new(tdc_id, 'fetchCompanyFinance').result_set.to_hash[:finance] || []
139
+ end
140
+
141
+ def fetch_subsidiaries
142
+ Fetch.new(tdc_id, 'fetchCompanySubsidiaries').result_set.to_hash[:subsidiary] || []
143
+ end
144
+
145
+ def fetch_ownerships
146
+ Fetch.new(tdc_id, 'fetchCompanyOwnership').result_set.to_hash[:ownership] || []
147
+ end
148
+
149
+ def basic_attribute(attribute)
150
+ unless @basic_attributes.has_key?(attribute)
151
+ unless @basic_result
152
+ @basic_result = Search.new(:tdcId => tdc_id).result_set.first or
153
+ raise NNEClient::CompanyMissing
154
+ end
155
+ @basic_attributes[attribute] = @basic_result.send(attribute)
156
+ end
157
+ return nil if @basic_attributes[attribute].kind_of?(Hash)
158
+ @basic_attributes[attribute]
159
+ end
160
+
161
+ def extended_attributes
162
+ @extended_attributes ||= fetch_extended_attributes.reject{ |k,v|
163
+ v.kind_of?(Hash)
164
+ }
165
+ end
166
+
167
+ def fetch_extended_attributes
168
+ Fetch.new(tdc_id, 'fetchCompany').result_set.to_hash[:company]
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,37 @@
1
+ module NNEClient
2
+
3
+ # ResultAttributes provides an attributes class method. When calling attributes
4
+ # with a list of keys from the @hash instance variable a method are defined for
5
+ # each key returning the value from the @hash. As such it requires a @hash
6
+ # instance variable on the class that extends the module. Additionally it
7
+ # ignores any value in the @hash that is itself a Hash. This is due to the way
8
+ # the NNE SOAP API works together with Savon.
9
+ #
10
+ # Example:
11
+ #
12
+ # class Foo
13
+ # extends NNEClient::ResultAttributes
14
+ # def initialize
15
+ # @hash = { :foo => 1, :bar => { :a => 2 }}
16
+ # attributes :foo, :bar
17
+ # end
18
+ # end
19
+ #
20
+ # Foo.new.foo
21
+ # => 1
22
+ # Foo.new.bar
23
+ # => nil
24
+ #
25
+ # @!visibility private
26
+ module ResultAttributes
27
+
28
+ # Create a method for each key listed in attrs
29
+ def attributes(*attrs)
30
+ attrs.each do |attribute|
31
+ define_method(attribute) do
32
+ @hash[attribute] unless @hash[attribute].kind_of?(Hash)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ module NNEClient
2
+ # A ResultSet holds the results returned by the SOAP API. The ResultSet includes Enumerable
3
+ # so it is possible to use all the regular enumerable methods to iterate over it.
4
+ class ResultSet
5
+ include Enumerable
6
+
7
+ def initialize(result)
8
+ @result = result
9
+ end
10
+
11
+ # Yield each result in turn
12
+ def each
13
+ company_basic.each do |cb|
14
+ yield Result.new(cb)
15
+ end
16
+ end
17
+
18
+ # The to_hash method is used by other parts of the library and can't be
19
+ # made private for now.
20
+ # @!visibility private
21
+ def to_hash
22
+ @result.to_hash
23
+ end
24
+
25
+ def total
26
+ window[:total].to_i
27
+ end
28
+
29
+ private
30
+
31
+ def window
32
+ to_hash[:window]
33
+ end
34
+
35
+ def company_basic
36
+ if to_hash[:company_basic].kind_of?(Hash)
37
+ [to_hash[:company_basic]]
38
+ else
39
+ to_hash[:company_basic] || []
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,15 @@
1
+ module NNEClient
2
+ # @!visibility private
3
+ class Search
4
+
5
+ def initialize(query)
6
+ @query = query
7
+ end
8
+
9
+ def result_set
10
+ Request.execute('search') do |xml|
11
+ Query.new(@query, xml).render
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module NNEClient
2
+ VERSION = "0.0.1"
3
+ end