reso_transport 1.5.4 → 1.5.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d8d276bf6165281a38be1f3eecda4f50c530bb7a2a2d40b2f8382ae44211bf9
4
- data.tar.gz: 2ecab6485d270956e91e5e3278fd46a9c1cd65a8960914dfccf86fa530d4c561
3
+ metadata.gz: 49e97dc43976dfe814ab0bdc7ce7aea16ae5f03e00c94d10d60de3319cb4d388
4
+ data.tar.gz: f15dd31a948a33dbd8008447be68828ba953114214b7633ff8a4628afa2bdfeb
5
5
  SHA512:
6
- metadata.gz: 55b29a0d927e87fa2aef9736bed074b72dfdce04d866ec6b4f1b9f1e4a237d4d7ef44199e19956b45bdf879954f5575e055049adb3b550f80eb10ec2ad42ca10
7
- data.tar.gz: 91366382060311726be58cf26c1439aad63e6fcfb96f1b6044465fdc630bc499d8ef0edcd6c1443d4ce06b0acc881009977584faed9b2bc6ebe3efbcc121bcb4
6
+ metadata.gz: 375f0962243d54dd27b80da550281fbc1a3b2e9a92affc6cb3a00e94104f5be0fddf6b3e1e5e636fc77a557d2a21438427867af8a66b1b18ae4a897c1027d5f1
7
+ data.tar.gz: 272dedeb65d29749ff3abeacb955c900a9e7e7dcf2449b53ab1bf9c6f7b996e84b78773f635868e603cc86eb34812a7e3b88f7e981ae41ce671055ddc9fd02a2
data/.gitignore CHANGED
@@ -13,5 +13,7 @@
13
13
  /log/**
14
14
  /test/vcr_cassettes/**
15
15
  md_cache/**
16
+ ds_cache/**
16
17
  .byebug_history
17
18
  secrets.yml
19
+ /.history/
data/.gitpod.yml ADDED
@@ -0,0 +1,2 @@
1
+ tasks:
2
+ - init: bundle install
data/.rubocop.yml ADDED
@@ -0,0 +1,33 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+
4
+ Layout/FirstHashElementIndentation:
5
+ Enabled: false
6
+
7
+ Layout/MultilineMethodCallIndentation:
8
+ Enabled: false
9
+
10
+ Metrics/AbcSize:
11
+ Max: 20
12
+
13
+ Metrics/BlockLength:
14
+ Exclude:
15
+ - test/**/*
16
+
17
+ Metrics/ClassLength:
18
+ Max: 150
19
+
20
+ Metrics/MethodLength:
21
+ Max: 15
22
+
23
+ Metrics/ModuleLength:
24
+ Max: 150
25
+
26
+ Style/ColonMethodCall:
27
+ Enabled: false
28
+
29
+ Style/Documentation:
30
+ Enabled: false
31
+
32
+ Style/FrozenStringLiteralComment:
33
+ Enabled: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reso_transport (1.5.2)
4
+ reso_transport (1.5.5)
5
5
  faraday (~> 1.0.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/wrstudios/reso_transport)
2
+ [![Gem Version](https://badge.fury.io/rb/reso_transport.svg)](https://badge.fury.io/rb/reso_transport)
3
+
1
4
  # ResoTransport
2
5
 
3
6
  A Ruby gem for connecting to and interacting with RESO WebAPI services. Learn more about what that is by checking out the [RESO WebAPI](https://www.reso.org/reso-web-api/) Documentation.
@@ -51,7 +54,7 @@ Or you can set a logger for each specific instance of a client which can be usef
51
54
 
52
55
  ### Getting Connected
53
56
 
54
- There are 2 strategies for authentication.
57
+ There are 2 strategies for authentication.
55
58
 
56
59
  **Bearer Token**
57
60
 
@@ -60,7 +63,8 @@ It's simple to use a static access token if your token never expires:
60
63
  ```ruby
61
64
  @client = ResoTransport::Client.new({
62
65
  md_file: METADATA_CACHE,
63
- endpoint: ENDPOINT_URL
66
+ endpoint: ENDPOINT_URL,
67
+ use_replication_endpoint: false # this is the default and can be ommitted
64
68
  authentication: {
65
69
  access_token: TOKEN,
66
70
  token_type: "Bearer" # this is the default and can be ommitted
@@ -89,7 +93,13 @@ If the connection requires requesting a new token periodically, it's easy to pro
89
93
 
90
94
  This will pre-fetch a token from the provided endpoint when the current token is either non-existent or has expired.
91
95
 
96
+ The `use_replication_endpoint` flag will append `/replication` to all resource queries if set to `true`. This is required by some data sources to query resources beyond 10,000 records.
92
97
 
98
+ When using this feature, you can retrieve the next link by accessing `next_link` after gettings results:
99
+ ```
100
+ results = @client.resources["Property"].query.results
101
+ next_link = @client.resources["Property"].query.next_link
102
+ ```
93
103
 
94
104
  ### Caching Metadata
95
105
 
@@ -108,9 +118,9 @@ If you don't have access to the file system, like on Heroku, or you just don't w
108
118
 
109
119
  ```ruby
110
120
  class MyCacheStore < ResoTransport::MetadataCache
111
-
121
+
112
122
  def read
113
- # read `name` from somewhere
123
+ # read `name` from somewhere
114
124
  end
115
125
 
116
126
  def write(data)
@@ -158,12 +168,25 @@ Once you have a successful connection you can explore what resources are availab
158
168
  #=> {"Property"=>#<ResoTransport::Resource entity_set="Property", schema="ODataService">, "Office"=>#<ResoTransport::Resource entity_set="Office", schema="ODataService">, "Member"=>#<ResoTransport::Resource entity_set="Member", schema="ODataService">}
159
169
 
160
170
  @client.resources["Property"]
161
- #=> #<ResoTransport::Resource entity_set="Property", schema="ODataService">
171
+ #=> #<ResoTransport::Resource entity_set="Property", schema="ODataService">
162
172
 
163
173
  @client.resources["Property"].query.limit(1).results
164
174
  #=> Results Array
165
175
  ```
166
176
 
177
+ If the resource contains localizations you can access those as well.
178
+
179
+ ```ruby
180
+ @client.resources["Property"].localizations
181
+ #=> {"CommercialSale"=>{"Name"=>"CommercialSale", "ResourcePath"=>"/Property?Class=CommercialSale", "Description"=>"Contains data for Commercial searches.", "DateTimeStamp"=>"2021-05-03T18:13:20.643-07:00"}, "Residential"=>{"Name"=>"Residential", "ResourcePath"=>"/Property?Class=Residential", "Description"=>"Contains data for Residential searches.", "DateTimeStamp"=>"2021-05-03T18:13:20.643-07:00"}}
182
+ ```
183
+
184
+ If a resource contains localizations you must select one by name, before querying, like so:
185
+
186
+ ```ruby
187
+ @client.resources["Property"].localization('Residential').query.limit(1).results
188
+ ```
189
+
167
190
  #### Querying
168
191
 
169
192
  ResoTransport provides powerful querying capabilities:
@@ -196,7 +219,7 @@ To see what child records can be expanded look at `expandable`:
196
219
 
197
220
  ```ruby
198
221
  @resource.expandable
199
- #=> [#<struct ResoTransport::Property name="Media", data_type="Collection(RESO.Media)", attrs={"Name"=>"Media", "Type"=>"Collection(RESO.Media)"}, multi=true, enum=nil, complex_type=nil, entity_type=#<struct ResoTransport::EntityType name="Media", base_type=nil, primary_key="MediaKey", schema="CoreLogic.DataStandard.RESO.DD">> ...]
222
+ #=> [#<struct ResoTransport::Property name="Media", data_type="Collection(RESO.Media)", attrs={"Name"=>"Media", "Type"=>"Collection(RESO.Media)"}, multi=true, enum=nil, complex_type=nil, entity_type=#<struct ResoTransport::EntityType name="Media", base_type=nil, primary_key="MediaKey", schema="CoreLogic.DataStandard.RESO.DD">> ...]
200
223
  ```
201
224
 
202
225
  Use `expand` to expand child records with the top level results.
@@ -210,7 +233,7 @@ You have several options to expand multiple child record sets. Each of these wil
210
233
 
211
234
  ```ruby
212
235
  @resource.query.expand("Media", "Office").limit(10).results
213
-
236
+
214
237
  @resource.query.expand(["Media", "Office"]).limit(10).results
215
238
 
216
239
  @resource.query.expand("Media").expand("Office").limit(10).results
@@ -257,9 +280,22 @@ When querying for an enumeration value, you can provide either the system name,
257
280
 
258
281
  ```ruby
259
282
  @resource.query.eq(StandardStatus: "Active Under Contract").limit(1).compile_params
260
- #=> {"$top"=>1, "$filter"=>"StandardStatus eq 'ActiveUnderContract'"}
283
+ #=> {"$top"=>1, "$filter"=>"StandardStatus eq 'ActiveUnderContract'"}
261
284
  ```
262
285
 
286
+ ### Troubleshooting
287
+
288
+ In the event there are connection issues, the following errors are raised:
289
+
290
+ * `ResoTransport::NoResponse` - The server did not respond to the request
291
+ * `ResoTransport::RequestError` - The server responded with a status code outside the 200 range
292
+ * `ResoTransport::ResponseError` - The server responded with errors in the body
293
+ * `ResoTransport::AccessDenied` - Check your authentication details
294
+ * `ResoTransport::LocalizationRequired` - Provide one of the required localizations through the `localization` method
295
+ * `ResoTransport::EncodeError` - No match was found for one or more of the properties
296
+
297
+ The Faraday Request hash is attached to the error for `NoResponse`, `RequestError`, `ResponseError`, and `AccessDenied`. A Faraday Response is attached on `RequestError`, `ResponseError`, and `AccessDenied`.
298
+
263
299
  ## Development
264
300
 
265
301
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "reso_transport"
3
+ require 'bundler/setup'
4
+ require 'reso_transport'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -12,19 +12,19 @@ require "reso_transport"
12
12
  #
13
13
 
14
14
  ResoTransport.configure do |c|
15
- c.logger = Logger.new("log/console.log")
15
+ c.logger = Logger.new('log/console.log')
16
16
  end
17
17
 
18
-
19
- require "irb"
18
+ require 'irb'
20
19
  require 'yaml'
21
20
  require 'byebug'
22
21
 
23
- SECRETS = YAML.load_file("secrets.yml")
22
+ SECRETS = YAML.load_file('secrets.yml')
24
23
 
25
- @trestle = ResoTransport::Client.new(SECRETS[:trestle].merge(logger: Logger.new($stdout)))
26
- #@bridge = ResoTransport::Client.new(SECRETS[:bridge].merge(logger: Logger.new($stdout)))
27
- # @spark = ResoTransport::Client.new(SECRETS[:spark])
28
- #@crmls = ResoTransport::Client.new(SECRETS[:crmls])
24
+ SECRETS.each do |name, data|
25
+ data[:logger] = Logger.new($stdout)
26
+ client = ResoTransport::Client.new(data)
27
+ instance_variable_set("@#{name}", client)
28
+ end
29
29
 
30
30
  IRB.start(__FILE__)
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
@@ -1,48 +1,71 @@
1
1
  module ResoTransport
2
2
  module Authentication
3
3
  class FetchTokenAuth < AuthStrategy
4
- attr_reader :connection, :endpoint, :client_id, :client_secret, :grant_type, :scope
5
-
4
+ attr_reader :endpoint,
5
+ :client_id,
6
+ :client_secret,
7
+ :grant_type,
8
+ :scope,
9
+ :username,
10
+ :password
11
+
6
12
  def initialize(options)
7
- @grant_type = options.fetch(:grant_type, "client_credentials")
8
- @scope = options.fetch(:scope, "api")
13
+ super()
14
+
15
+ @grant_type = options.fetch(:grant_type, 'client_credentials')
16
+ @scope = options.fetch(:scope, 'api')
9
17
  @client_id = options.fetch(:client_id)
10
18
  @client_secret = options.fetch(:client_secret)
11
19
  @endpoint = options.fetch(:endpoint)
20
+ @username = options.fetch(:username, nil)
21
+ @password = options.fetch(:password, nil)
22
+ @request = nil
23
+ end
12
24
 
13
- @connection = Faraday.new(@endpoint) do |faraday|
25
+ def connection
26
+ @connection ||= Faraday.new(@endpoint) do |faraday|
14
27
  faraday.request :url_encoded
15
28
  faraday.response :logger, ResoTransport.configuration.logger if ResoTransport.configuration.logger
16
29
  faraday.adapter Faraday.default_adapter
17
- faraday.basic_auth @client_id, @client_secret
30
+ faraday.basic_auth client_id, client_secret
18
31
  end
19
32
  end
20
33
 
21
34
  def authenticate
22
- response = connection.post nil, auth_params
35
+ response = connection.post(nil, auth_params { |req| @request = req })
23
36
  json = JSON.parse response.body
24
37
 
25
- unless response.success?
26
- message = "#{response.reason_phrase}: #{json['error'] || response.body}"
27
- raise ResoTransport::AccessDenied, response: response, message: message
28
- end
38
+ raise AccessDenied.new(request, response, 'token') unless response.success?
29
39
 
30
40
  Access.new({
31
41
  access_token: json.fetch('access_token'),
32
42
  expires_in: json.fetch('expires_in', 1 << (1.size * 8 - 2) - 1),
33
- token_type: json.fetch('token_type', "Bearer")
43
+ token_type: json.fetch('token_type', 'Bearer')
34
44
  })
35
45
  end
36
46
 
47
+ def request
48
+ return @request.to_h if @request.respond_to? :to_h
49
+
50
+ {}
51
+ end
52
+
37
53
  private
38
54
 
39
55
  def auth_params
40
- {
41
- client_id: client_id,
56
+ params = {
57
+ client_id: client_id,
42
58
  client_secret: client_secret,
43
- grant_type: grant_type,
44
- scope: scope
59
+ grant_type: grant_type,
60
+ scope: scope
45
61
  }
62
+
63
+ if grant_type == 'password'
64
+ params[:username] = username
65
+ params[:password] = password
66
+ end
67
+
68
+ params
46
69
  end
47
70
  end
48
71
  end
@@ -18,10 +18,11 @@ module ResoTransport
18
18
  authorize_request(request_env)
19
19
 
20
20
  @app.call(request_env).on_complete do |response_env|
21
- raise_if_unauthorized(response_env)
21
+ raise_if_unauthorized(request_env, response_env)
22
22
  end
23
23
  rescue ResoTransport::AccessDenied
24
- raise if retries == 0
24
+ raise if retries.zero?
25
+
25
26
  @auth.reset
26
27
  retries -= 1
27
28
  retry
@@ -38,8 +39,8 @@ module ResoTransport
38
39
  )
39
40
  end
40
41
 
41
- def raise_if_unauthorized(response_env)
42
- raise ResoTransport::AccessDenied if response_env[:status] == 401
42
+ def raise_if_unauthorized(request_env, response_env)
43
+ raise ResoTransport::AccessDenied.new(request_env.to_h, response_env) if response_env[:status] == 401
43
44
  end
44
45
  end
45
46
  end
@@ -0,0 +1,64 @@
1
+ module ResoTransport
2
+ class BaseMetadata
3
+ MIME_TYPES = {
4
+ xml: 'application/xml',
5
+ json: 'application/json'
6
+ }.freeze
7
+
8
+ attr_reader :client
9
+
10
+ def initialize(client)
11
+ @client = client
12
+ @prefix = nil
13
+ @classname = nil
14
+ end
15
+
16
+ def prefix
17
+ raise 'prefix not set' unless @prefix
18
+
19
+ @prefix
20
+ end
21
+
22
+ def classname
23
+ raise 'classname not set' unless @classname
24
+
25
+ @classname
26
+ end
27
+
28
+ def parser
29
+ @parser ||= Object::const_get("#{classname}Parser").new.parse(data)
30
+ end
31
+
32
+ def data
33
+ if cache_file
34
+ cache.read || cache.write(raw)
35
+ else
36
+ raw
37
+ end
38
+ end
39
+
40
+ def cache
41
+ @cache ||= client.send("#{prefix}_cache").new(cache_file)
42
+ end
43
+
44
+ def cache_file
45
+ @cache_file ||= client.send "#{prefix}_file"
46
+ end
47
+
48
+ def raw
49
+ return response.body if response.success?
50
+
51
+ raise RequestError.new(request, response, classname)
52
+ end
53
+
54
+ def response
55
+ raise 'Must implement response method'
56
+ end
57
+
58
+ def request
59
+ return @request.to_h if @request.respond_to? :to_h
60
+
61
+ {}
62
+ end
63
+ end
64
+ end
@@ -1,35 +1,52 @@
1
1
  module ResoTransport
2
2
  class Client
3
- attr_reader :connection, :uid, :vendor, :endpoint, :auth, :md_file, :md_cache
4
-
3
+ attr_reader :connection, :uid, :vendor, :endpoint, :authentication, :md_file, :md_cache, :ds_file, :ds_cache,
4
+ :use_replication_endpoint
5
+
5
6
  def initialize(options)
6
- @endpoint = options.fetch(:endpoint)
7
- @md_file = options.fetch(:md_file, nil)
8
- @authentication = ensure_valid_auth_strategy(options.fetch(:authentication))
9
- @vendor = options.fetch(:vendor, {})
10
- @faraday_options = options.fetch(:faraday_options, {})
11
- @logger = options.fetch(:logger, nil)
12
- @md_cache = options.fetch(:md_cache, ResoTransport::MetadataCache)
13
-
14
- @connection = Faraday.new(@endpoint, @faraday_options) do |faraday|
7
+ @use_replication_endpoint = options.fetch(:use_replication_endpoint, false)
8
+ @endpoint = options.fetch(:endpoint)
9
+ @md_file = options.fetch(:md_file, nil)
10
+ @ds_file = options.fetch(:ds_file, nil)
11
+ @authentication = ensure_valid_auth_strategy(options.fetch(:authentication))
12
+ @vendor = options.fetch(:vendor, {})
13
+ @faraday_options = options.fetch(:faraday_options, {})
14
+ @logger = options.fetch(:logger, nil)
15
+ @md_cache = options.fetch(:md_cache, ResoTransport::MetadataCache)
16
+ @ds_cache = options.fetch(:ds_cache, ResoTransport::MetadataCache)
17
+ @connection = establish_connection
18
+ end
19
+
20
+ def establish_connection
21
+ Faraday.new(@endpoint, @faraday_options) do |faraday|
15
22
  faraday.request :url_encoded
16
23
  faraday.response :logger, @logger || ResoTransport.configuration.logger
17
- #yield faraday if block_given?
18
24
  faraday.use Authentication::Middleware, @authentication
19
- faraday.adapter Faraday.default_adapter #unless faraday.builder.send(:adapter_set?)
25
+ faraday.adapter Faraday.default_adapter # unless faraday.builder.send(:adapter_set?)
20
26
  end
21
27
  end
22
28
 
23
29
  def resources
24
- @resources ||= metadata.entity_sets.map {|es| {es.name => Resource.new(self, es)} }.reduce(:merge!)
30
+ @resources ||= metadata.entity_sets.map { |es| { es.name => resource_for(es) } }.reduce(:merge!)
31
+ end
32
+
33
+ def resource_for(entity_set)
34
+ localizations = {}
35
+ localizations = datasystem.localizations_for(entity_set.entity_type) if metadata.datasystem?
36
+
37
+ Resource.new(self, entity_set, localizations)
25
38
  end
26
39
 
27
40
  def metadata
28
41
  @metadata ||= Metadata.new(self)
29
42
  end
30
43
 
44
+ def datasystem
45
+ @datasystem ||= Datasystem.new(self)
46
+ end
47
+
31
48
  def to_s
32
- %(#<ResoTransport::Client endpoint="#{endpoint}", md_file="#{md_file}">)
49
+ %(#<ResoTransport::Client endpoint="#{endpoint}", md_file="#{md_file}", ds_file="#{ds_file}">)
33
50
  end
34
51
 
35
52
  def inspect
@@ -41,7 +58,7 @@ module ResoTransport
41
58
  def ensure_valid_auth_strategy(options)
42
59
  case options
43
60
  when Hash
44
- if options.has_key?(:endpoint)
61
+ if options.key?(:endpoint)
45
62
  Authentication::FetchTokenAuth.new(options)
46
63
  else
47
64
  Authentication::StaticTokenAuth.new(options)
@@ -50,6 +67,5 @@ module ResoTransport
50
67
  raise ArgumentError, "#{options.inspect} invalid: cannot determine strategy"
51
68
  end
52
69
  end
53
-
54
70
  end
55
71
  end
@@ -0,0 +1,25 @@
1
+ require_relative 'base_metadata'
2
+
3
+ module ResoTransport
4
+ class Datasystem < BaseMetadata
5
+ def initialize(client)
6
+ super client
7
+ @prefix = 'ds'
8
+ @classname = self.class.name
9
+ end
10
+
11
+ def localizations_for(resource_name)
12
+ localizations = parser.resources.dig(resource_name, 'Localizations') || []
13
+ localizations.map { |l| [l['Name'], l] }.to_h
14
+ end
15
+
16
+ def response
17
+ @response ||= client.connection.get('DataSystem') do |req|
18
+ req.headers['Accept'] = 'application/json'
19
+ @request = req
20
+ end
21
+ rescue Faraday::ConnectionFailed
22
+ raise NoResponse.new(request, nil, 'DataSystem')
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ module ResoTransport
2
+ class DatasystemParser
3
+ def parse(doc)
4
+ begin
5
+ data = doc.is_a?(File) ? doc.read : doc
6
+ @json = JSON.parse data
7
+ rescue JSON::ParserError => e
8
+ @json = {}
9
+ puts e.message
10
+ end
11
+ self
12
+ end
13
+
14
+ # value ->
15
+ # Resources ->
16
+ # Name ->
17
+ # ResourcePath ->
18
+ # Localizations ->
19
+ # Name ->
20
+ # ResourcePath ->
21
+
22
+ def resources
23
+ @resources ||= @json['value'].map { |v| v['Resources'] }.flatten.compact.map { |r| [r['Name'], r] }.to_h
24
+ end
25
+ end
26
+ end
@@ -1,11 +1,9 @@
1
1
  module ResoTransport
2
2
  EntitySet = Struct.new(:name, :schema, :entity_type) do
3
-
4
3
  def self.from_stream(args)
5
- schema, entity_type = ResoTransport.split_schema_and_class_name(args["EntityType"])
4
+ schema, entity_type = ResoTransport.split_schema_and_class_name(args['EntityType'])
6
5
 
7
- new(args["Name"], schema, entity_type)
6
+ new(args['Name'], schema, entity_type)
8
7
  end
9
-
10
8
  end
11
9
  end
@@ -1,30 +1,29 @@
1
1
  module ResoTransport
2
2
  EntityType = Struct.new(:name, :base_type, :primary_key, :schema) do
3
-
4
3
  def self.from_stream(args)
5
- new(args["Name"], args["BaseType"])
4
+ new(args['Name'], args['BaseType'])
6
5
  end
7
6
 
8
7
  def parse(record)
9
- record.each_pair do |k,v|
8
+ record.each_pair do |k, v|
10
9
  next if v.nil?
11
- if property = (property_map[k] || navigation_property_map[k])
12
- record[k] = property.parse(v)
13
- end
10
+
11
+ property = property_map[k] || navigation_property_map[k]
12
+ record[k] = property.parse(v) if property
14
13
  end
15
14
  end
16
15
 
17
16
  def parse_value(record)
18
- record.each_pair do |k,v|
17
+ record.each_pair do |k, v|
19
18
  next if v.nil?
20
- if property = (property_map[k] || navigation_property_map[k])
21
- record[k] = property.parse(v)
22
- end
19
+
20
+ property = property_map[k] || navigation_property_map[k]
21
+ record[k] = property.parse(v) if property
23
22
  end
24
23
  end
25
24
 
26
25
  def property_map
27
- @property_map ||= properties.inject({}) {|hsh, p| hsh[p.name] = p; hsh }
26
+ @property_map ||= properties.each_with_object({}) { |p, hsh| hsh[p.name] = p; }
28
27
  end
29
28
 
30
29
  def properties
@@ -32,7 +31,7 @@ module ResoTransport
32
31
  end
33
32
 
34
33
  def navigation_property_map
35
- @navigation_property_map ||= navigation_properties.inject({}) {|hsh, p| hsh[p.name] = p; hsh }
34
+ @navigation_property_map ||= navigation_properties.each_with_object({}) { |p, hsh| hsh[p.name] = p; }
36
35
  end
37
36
 
38
37
  def navigation_properties
@@ -42,6 +41,5 @@ module ResoTransport
42
41
  def enumerations
43
42
  @enumerations ||= []
44
43
  end
45
-
46
44
  end
47
45
  end