iron_bank 2.2.0 → 3.0.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +0 -2
  3. data/.gitignore +0 -1
  4. data/.reek.yml +5 -15
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +9 -4
  7. data/.ruby-version +1 -0
  8. data/.travis.yml +4 -4
  9. data/Gemfile +1 -1
  10. data/Gemfile.lock +134 -0
  11. data/README.md +34 -14
  12. data/Rakefile +11 -16
  13. data/bin/console +8 -8
  14. data/iron_bank.gemspec +32 -34
  15. data/lib/generators/iron_bank/install/install_generator.rb +4 -4
  16. data/lib/generators/iron_bank/install/templates/iron_bank.rb +6 -6
  17. data/lib/iron_bank/action.rb +1 -1
  18. data/lib/iron_bank/actions/query_more.rb +1 -1
  19. data/lib/iron_bank/associations.rb +2 -2
  20. data/lib/iron_bank/authentication.rb +1 -1
  21. data/lib/iron_bank/authentications/cookie.rb +7 -7
  22. data/lib/iron_bank/authentications/token.rb +9 -9
  23. data/lib/iron_bank/cacheable.rb +1 -0
  24. data/lib/iron_bank/client.rb +6 -10
  25. data/lib/iron_bank/collection.rb +1 -0
  26. data/lib/iron_bank/configuration.rb +8 -19
  27. data/lib/iron_bank/csv.rb +2 -2
  28. data/lib/iron_bank/describe/field.rb +2 -2
  29. data/lib/iron_bank/describe/object.rb +5 -5
  30. data/lib/iron_bank/describe/related.rb +3 -3
  31. data/lib/iron_bank/describe/tenant.rb +2 -2
  32. data/lib/iron_bank/endpoint.rb +3 -3
  33. data/lib/iron_bank/error.rb +17 -17
  34. data/lib/iron_bank/local.rb +15 -7
  35. data/lib/iron_bank/local_records.rb +58 -20
  36. data/lib/iron_bank/logger.rb +3 -3
  37. data/lib/iron_bank/operation.rb +1 -1
  38. data/lib/iron_bank/query_builder.rb +4 -4
  39. data/lib/iron_bank/resource.rb +2 -7
  40. data/lib/iron_bank/resources/account.rb +6 -6
  41. data/lib/iron_bank/resources/export.rb +23 -0
  42. data/lib/iron_bank/resources/product_rate_plan.rb +2 -1
  43. data/lib/iron_bank/resources/product_rate_plan_charge_tier.rb +0 -44
  44. data/lib/iron_bank/resources/rate_plan_charge.rb +1 -1
  45. data/lib/iron_bank/resources/subscription.rb +4 -4
  46. data/lib/iron_bank/resources/usage.rb +1 -1
  47. data/lib/iron_bank/utils.rb +5 -5
  48. data/lib/iron_bank/version.rb +2 -2
  49. data/lib/iron_bank.rb +67 -75
  50. metadata +21 -52
  51. data/lib/iron_bank/instrumentation.rb +0 -14
  52. data/lib/iron_bank/open_tracing.rb +0 -18
  53. data/lib/iron_bank/resources/catalog_tiers/discount_amount.rb +0 -26
  54. data/lib/iron_bank/resources/catalog_tiers/discount_percentage.rb +0 -26
  55. data/lib/iron_bank/resources/catalog_tiers/price.rb +0 -26
@@ -5,8 +5,6 @@ module IronBank
5
5
  # Get a cookie to enable authenticated calls to Zuora through Session.
6
6
  #
7
7
  class Cookie
8
- include IronBank::OpenTracing
9
-
10
8
  TEN_MINUTES = 600
11
9
  ONE_HOUR = 3600
12
10
 
@@ -23,7 +21,7 @@ module IronBank
23
21
  end
24
22
 
25
23
  def header
26
- { 'Cookie' => use }
24
+ { "Cookie" => use }
27
25
  end
28
26
 
29
27
  private
@@ -38,7 +36,7 @@ module IronBank
38
36
 
39
37
  def fetch_cookie
40
38
  response = authenticate
41
- @cookie = response.headers['set-cookie']
39
+ @cookie = response.headers["set-cookie"]
42
40
  @zsession = fetch_zsession
43
41
  @expires_at = Time.now + ONE_HOUR
44
42
  end
@@ -49,14 +47,16 @@ module IronBank
49
47
  end
50
48
 
51
49
  def authenticate
52
- connection.post('v1/connections', {})
50
+ connection.post("v1/connections", {})
53
51
  end
54
52
 
55
53
  def connection
56
54
  @connection ||= Faraday.new(faraday_config) do |conn|
57
- conn.use :ddtrace, open_tracing_options if open_tracing_enabled?
55
+ IronBank.configuration.middlewares.each do |klass, options|
56
+ conn.use klass, options
57
+ end
58
+
58
59
  conn.request :url_encoded
59
- conn.response :logger, IronBank.logger
60
60
  conn.response :json
61
61
  conn.adapter Faraday.default_adapter
62
62
  end
@@ -5,8 +5,6 @@ module IronBank
5
5
  # Get a bearer token to enable authenticated calls to Zuora through OAuth.
6
6
  #
7
7
  class Token
8
- include IronBank::OpenTracing
9
-
10
8
  # Generic token error.
11
9
  #
12
10
  class Error < StandardError; end
@@ -31,7 +29,7 @@ module IronBank
31
29
  end
32
30
 
33
31
  def header
34
- { 'Authorization' => "Bearer #{use}" }
32
+ { "Authorization" => "Bearer #{use}" }
35
33
  end
36
34
 
37
35
  private
@@ -46,21 +44,23 @@ module IronBank
46
44
 
47
45
  def fetch_token
48
46
  response = authenticate || {}
49
- @access_token = response.fetch('access_token', nil)
50
- @expires_at = Time.now + response.fetch('expires_in', ONE_HOUR).to_i
47
+ @access_token = response.fetch("access_token", nil)
48
+ @expires_at = Time.now + response.fetch("expires_in", ONE_HOUR).to_i
51
49
  validate_access_token
52
50
  end
53
51
  alias refetch_token fetch_token
54
52
 
55
53
  def authenticate
56
- connection.post('/oauth/token', authentication_params).body
54
+ connection.post("/oauth/token", authentication_params).body
57
55
  end
58
56
 
59
57
  def connection
60
58
  @connection ||= Faraday.new(url: base_url) do |conn|
61
- conn.use :ddtrace, open_tracing_options if open_tracing_enabled?
59
+ IronBank.configuration.middlewares.each do |klass, options|
60
+ conn.use klass, options
61
+ end
62
+
62
63
  conn.request :url_encoded
63
- conn.response :logger, IronBank.logger
64
64
  conn.response :json
65
65
  conn.adapter Faraday.default_adapter
66
66
  end
@@ -70,7 +70,7 @@ module IronBank
70
70
  {
71
71
  client_id: client_id,
72
72
  client_secret: client_secret,
73
- grant_type: 'client_credentials'
73
+ grant_type: "client_credentials"
74
74
  }
75
75
  end
76
76
 
@@ -7,6 +7,7 @@ module IronBank
7
7
  def reload
8
8
  remove_instance_vars
9
9
  @remote = self.class.find(id, force: true).remote
10
+ self
10
11
  end
11
12
 
12
13
  private
@@ -5,9 +5,6 @@ module IronBank
5
5
  # authenticated request, reusing the same session cookie for future requests.
6
6
  #
7
7
  class Client
8
- include IronBank::Instrumentation
9
- include IronBank::OpenTracing
10
-
11
8
  # Generic client error.
12
9
  #
13
10
  class Error < StandardError; end
@@ -26,7 +23,7 @@ module IronBank
26
23
  end
27
24
  end
28
25
 
29
- def initialize(domain:, client_id:, client_secret:, auth_type: 'token')
26
+ def initialize(domain:, client_id:, client_secret:, auth_type: "token")
30
27
  @domain = domain
31
28
  @client_id = client_id
32
29
  @client_secret = client_secret
@@ -40,19 +37,18 @@ module IronBank
40
37
  def connection
41
38
  validate_domain
42
39
  reset_connection if auth.expired?
40
+ config = IronBank.configuration
43
41
 
44
42
  @connection ||= Faraday.new(faraday_config) do |conn|
43
+ config.middlewares.each { |klass, options| conn.use(klass, options) }
44
+
45
45
  conn.request :json
46
- conn.request :retry, IronBank.configuration.retry_options
46
+ conn.request :retry, config.retry_options
47
47
 
48
48
  conn.response :raise_error
49
49
  conn.response :renew_auth, auth
50
- conn.response :logger, IronBank.logger
51
50
  conn.response :json, content_type: /\bjson$/
52
51
 
53
- conn.use :ddtrace, open_tracing_options if open_tracing_enabled?
54
- conn.use instrumenter, instrumenter_options if instrumenter
55
-
56
52
  conn.adapter Faraday.default_adapter
57
53
  end
58
54
  end
@@ -103,7 +99,7 @@ module IronBank
103
99
  end
104
100
 
105
101
  def headers
106
- { 'Content-Type' => 'application/json' }.merge(auth.header)
102
+ { "Content-Type" => "application/json" }.merge(auth.header)
107
103
  end
108
104
 
109
105
  def reset_connection
@@ -10,6 +10,7 @@ module IronBank
10
10
  :[],
11
11
  :each,
12
12
  :length,
13
+ :map,
13
14
  :size
14
15
 
15
16
  def initialize(klass, conditions, records)
@@ -4,9 +4,8 @@ module IronBank
4
4
  # The Zuora configuration class.
5
5
  #
6
6
  class Configuration
7
- # Instrumentation
8
- attr_accessor :instrumenter
9
- attr_accessor :instrumenter_options
7
+ # middlewares
8
+ attr_accessor :middlewares
10
9
 
11
10
  # Logger
12
11
  attr_accessor :logger
@@ -26,15 +25,6 @@ module IronBank
26
25
  # Cache store instance, optionally used by certain resources.
27
26
  attr_accessor :cache
28
27
 
29
- # Open Tracing
30
- attr_accessor :open_tracing_enabled
31
-
32
- # Open Tracing service name
33
- attr_accessor :open_tracing_service_name
34
-
35
- # Faraday retry options
36
- attr_writer :retry_options
37
-
38
28
  # Directory where the XML describe files are located.
39
29
  attr_reader :schema_directory
40
30
 
@@ -42,12 +32,11 @@ module IronBank
42
32
  attr_reader :export_directory
43
33
 
44
34
  def initialize
45
- @schema_directory = './config/schema'
46
- @export_directory = './config/export'
47
- @logger = IronBank::Logger.new
48
- @auth_type = 'token'
49
- @open_tracing_enabled = false
50
- @open_tracing_service_name = 'ironbank'
35
+ @schema_directory = "./config/schema"
36
+ @export_directory = "./config/export"
37
+ @logger = IronBank::Logger.new
38
+ @auth_type = "token"
39
+ @middlewares = []
51
40
  end
52
41
 
53
42
  def schema_directory=(value)
@@ -68,7 +57,7 @@ module IronBank
68
57
  @export_directory = value
69
58
  return unless defined? IronBank::Product
70
59
 
71
- IronBank::LocalRecords::RESOURCES.each do |resource|
60
+ IronBank::LocalRecords::RESOURCE_QUERY_FIELDS.keys.each do |resource|
72
61
  IronBank::Resources.const_get(resource).reset_store
73
62
  end
74
63
  end
data/lib/iron_bank/csv.rb CHANGED
@@ -9,7 +9,7 @@ module IronBank
9
9
  encoding = field.encode(CSV::ConverterEncoding)
10
10
 
11
11
  # Match: [1, 10, 100], No match: [0.1, .1, 1., 0b10]
12
- encoding =~ /^[+-]?\d+$/ ? encoding.to_i : field
12
+ /^[+-]?\d+$/.match?(encoding) ? encoding.to_i : field
13
13
  rescue # encoding or integer conversion
14
14
  field
15
15
  end
@@ -20,7 +20,7 @@ module IronBank
20
20
  encoding = field.encode(CSV::ConverterEncoding)
21
21
 
22
22
  # Match: [1.0, 1., 0.1, .1], No match: [1, 0b10]
23
- encoding =~ /^[+-]?(?:\d*\.|\.\d*)\d*$/ ? encoding.to_f : field
23
+ /^[+-]?(?:\d*\.|\.\d*)\d*$/.match?(encoding) ? encoding.to_f : field
24
24
  rescue # encoding or float conversion
25
25
  field
26
26
  end
@@ -33,7 +33,7 @@ module IronBank
33
33
 
34
34
  # Defined separately because the node name is not ruby-friendly
35
35
  def max_length
36
- doc.at_xpath('.//maxlength').text.to_i
36
+ doc.at_xpath(".//maxlength").text.to_i
37
37
  end
38
38
 
39
39
  TEXT_VALUES.each do |val|
@@ -46,7 +46,7 @@ module IronBank
46
46
  end
47
47
 
48
48
  BOOLEAN_VALUES.each do |val|
49
- define_method(:"#{val}?") { doc.at_xpath(".//#{val}").text == 'true' }
49
+ define_method(:"#{val}?") { doc.at_xpath(".//#{val}").text == "true" }
50
50
  end
51
51
 
52
52
  def inspect
@@ -31,22 +31,22 @@ module IronBank
31
31
  end
32
32
 
33
33
  def export
34
- File.open(file_path, 'w') { |file| file << doc.to_xml }
34
+ File.open(file_path, "w") { |file| file << doc.to_xml }
35
35
  end
36
36
 
37
37
  def name
38
- node = doc.at_xpath('.//object/name')
38
+ node = doc.at_xpath(".//object/name")
39
39
  raise InvalidXML unless node
40
40
 
41
41
  node.text
42
42
  end
43
43
 
44
44
  def label
45
- doc.at_xpath('.//object/label').text
45
+ doc.at_xpath(".//object/label").text
46
46
  end
47
47
 
48
48
  def fields
49
- @fields ||= doc.xpath('.//fields/field').map do |node|
49
+ @fields ||= doc.xpath(".//fields/field").map do |node|
50
50
  IronBank::Describe::Field.from_xml(node)
51
51
  end
52
52
  end
@@ -56,7 +56,7 @@ module IronBank
56
56
  end
57
57
 
58
58
  def related
59
- @related ||= doc.xpath('.//related-objects/object').map do |node|
59
+ @related ||= doc.xpath(".//related-objects/object").map do |node|
60
60
  IronBank::Describe::Related.from_xml(node)
61
61
  end
62
62
  end
@@ -13,15 +13,15 @@ module IronBank
13
13
  end
14
14
 
15
15
  def type
16
- @type ||= doc.attributes['href'].value.split('/').last
16
+ @type ||= doc.attributes["href"].value.split("/").last
17
17
  end
18
18
 
19
19
  def name
20
- doc.at_xpath('.//name').text
20
+ doc.at_xpath(".//name").text
21
21
  end
22
22
 
23
23
  def label
24
- doc.at_xpath('.//label').text
24
+ doc.at_xpath(".//label").text
25
25
  end
26
26
 
27
27
  def inspect
@@ -12,7 +12,7 @@ module IronBank
12
12
  end
13
13
 
14
14
  def self.from_connection(connection)
15
- xml = connection.get('v1/describe').body
15
+ xml = connection.get("v1/describe").body
16
16
  new(Nokogiri::XML(xml), connection)
17
17
  rescue TypeError
18
18
  # NOTE: Zuora returns HTTP 401 (unauthorized) roughly 1 out of 3 times
@@ -43,7 +43,7 @@ module IronBank
43
43
  end
44
44
 
45
45
  def object_names
46
- @object_names ||= doc.xpath('.//object/name').map(&:text)
46
+ @object_names ||= doc.xpath(".//object/name").map(&:text)
47
47
  end
48
48
  end
49
49
  end
@@ -10,18 +10,18 @@ module IronBank
10
10
  SERVICES = /\Aservices(\d+)\.zuora\.com(:\d+)?\z/i.freeze
11
11
  APISANDBOX = /\Arest.apisandbox.zuora\.com\z/i.freeze
12
12
 
13
- def self.base_url(domain = '')
13
+ def self.base_url(domain = "")
14
14
  new(domain).base_url
15
15
  end
16
16
 
17
17
  def base_url
18
18
  case domain
19
19
  when PRODUCTION
20
- 'https://rest.zuora.com/'
20
+ "https://rest.zuora.com/"
21
21
  when SERVICES
22
22
  "https://#{domain}/".downcase
23
23
  when APISANDBOX
24
- 'https://rest.apisandbox.zuora.com/'
24
+ "https://rest.apisandbox.zuora.com/"
25
25
  end
26
26
  end
27
27
 
@@ -82,23 +82,23 @@ module IronBank
82
82
  class LockCompetitionError < TemporaryError; end
83
83
 
84
84
  CODE_CLASSES = {
85
- 'API_DISABLED' => ServerError,
86
- 'CANNOT_DELETE' => UnprocessableEntityError,
87
- 'DUPLICATE_VALUE' => ConflictError,
88
- 'INVALID_FIELD' => BadRequestError,
89
- 'INVALID_ID' => BadRequestError,
90
- 'INVALID_TYPE' => BadRequestError,
91
- 'INVALID_VALUE' => BadRequestError,
92
- 'LOCK_COMPETITION' => LockCompetitionError,
93
- 'MALFORMED_QUERY' => ClientError,
94
- 'MISSING_REQUIRED_VALUE' => ClientError,
95
- 'REQUEST_EXCEEDED_LIMIT' => TooManyRequestsError,
96
- 'REQUEST_EXCEEDED_RATE' => TooManyRequestsError,
97
- 'TEMPORARY_ERROR' => TemporaryError,
98
- 'TRANSACTION_FAILED' => InternalServerError,
99
- 'TRANSACTION_TERMINATED' => InternalServerError,
100
- 'TRANSACTION_TIMEOUT' => BadGatewayError,
101
- 'UNKNOWN_ERROR' => InternalServerError
85
+ "API_DISABLED" => ServerError,
86
+ "CANNOT_DELETE" => UnprocessableEntityError,
87
+ "DUPLICATE_VALUE" => ConflictError,
88
+ "INVALID_FIELD" => BadRequestError,
89
+ "INVALID_ID" => BadRequestError,
90
+ "INVALID_TYPE" => BadRequestError,
91
+ "INVALID_VALUE" => BadRequestError,
92
+ "LOCK_COMPETITION" => LockCompetitionError,
93
+ "MALFORMED_QUERY" => ClientError,
94
+ "MISSING_REQUIRED_VALUE" => ClientError,
95
+ "REQUEST_EXCEEDED_LIMIT" => TooManyRequestsError,
96
+ "REQUEST_EXCEEDED_RATE" => TooManyRequestsError,
97
+ "TEMPORARY_ERROR" => TemporaryError,
98
+ "TRANSACTION_FAILED" => InternalServerError,
99
+ "TRANSACTION_TERMINATED" => InternalServerError,
100
+ "TRANSACTION_TIMEOUT" => BadGatewayError,
101
+ "UNKNOWN_ERROR" => InternalServerError
102
102
  }.freeze
103
103
 
104
104
  CODE_MATCHER = /(#{CODE_CLASSES.keys.join('|')})/.freeze
@@ -33,25 +33,33 @@ module IronBank
33
33
 
34
34
  private
35
35
 
36
+ # NOTE: Handle associations within the CSV export. E.g., when reading the
37
+ # `ProductRatePlan.csv` file, we have `ProductRatePlan.Id` and
38
+ # `Product.Id` fields. We want to end up with `id` and `product_id`
39
+ # respectively.
40
+ def underscore_header
41
+ lambda do |header|
42
+ parts = header.split(".")
43
+ header = parts.first.casecmp?(object_name) ? parts.last : parts.join
44
+
45
+ IronBank::Utils.underscore(header).to_sym
46
+ end
47
+ end
48
+
36
49
  def store
37
50
  @store ||= File.exist?(file_path) ? load_records : {}
38
51
  end
39
52
 
40
53
  def load_records
41
54
  CSV.foreach(file_path, csv_options).with_object({}) do |row, store|
42
- # NOTE: when we move away from Ruby 2.2.x and 2.3.x we can uncomment
43
- # this line, delete the other one, since `Hash#compact` is available in
44
- # 2.4.x and we can remove two smells from `.reek` while we are at it
45
- #
46
- # store[row[:id]] = new(row.to_h.compact)
47
- store[row[:id]] = new(row.to_h.reject { |_, value| value.nil? })
55
+ store[row[:id]] = new(row.to_h.compact)
48
56
  end
49
57
  end
50
58
 
51
59
  def csv_options
52
60
  {
53
61
  headers: true,
54
- header_converters: [->(h) { IronBank::Utils.underscore(h).to_sym }],
62
+ header_converters: [underscore_header],
55
63
  converters: csv_converters
56
64
  }
57
65
  end
@@ -6,12 +6,12 @@ module IronBank
6
6
  class LocalRecords
7
7
  private_class_method :new
8
8
 
9
- RESOURCES = %w[
10
- Product
11
- ProductRatePlan
12
- ProductRatePlanCharge
13
- ProductRatePlanChargeTier
14
- ].freeze
9
+ RESOURCE_QUERY_FIELDS = {
10
+ "Product" => ["*"],
11
+ "ProductRatePlan" => ["*", "Product.Id"],
12
+ "ProductRatePlanCharge" => ["*", "ProductRatePlan.Id"],
13
+ "ProductRatePlanChargeTier" => ["*", "ProductRatePlanCharge.Id"]
14
+ }.freeze
15
15
 
16
16
  def self.directory
17
17
  IronBank.configuration.export_directory
@@ -19,39 +19,77 @@ module IronBank
19
19
 
20
20
  def self.export
21
21
  FileUtils.mkdir_p(directory) unless Dir.exist?(directory)
22
- RESOURCES.each { |resource| new(resource).export }
22
+ RESOURCE_QUERY_FIELDS.keys.each { |resource| new(resource).save_file }
23
23
  end
24
24
 
25
- def export
26
- CSV.open(file_path, 'w') do |csv|
27
- # first row = CSV headers
28
- write_headers(csv)
29
- write_records(csv)
25
+ def save_file
26
+ until completed? || max_query?
27
+ IronBank.logger.info(export_query_info)
28
+ sleep backoff_time
30
29
  end
30
+
31
+ File.open(file_path, "w") { |file| file.write(export.content) }
31
32
  end
32
33
 
33
34
  private
34
35
 
35
- attr_reader :resource
36
+ BACKOFF = {
37
+ max: 3,
38
+ interval: 0.5,
39
+ randomness: 0.5,
40
+ factor: 4
41
+ }.freeze
42
+ private_constant :BACKOFF
43
+
44
+ attr_reader :resource, :query_attempts
36
45
 
37
46
  def initialize(resource)
38
- @resource = resource
47
+ @resource = resource
48
+ @query_attempts = 0
39
49
  end
40
50
 
41
- def klass
42
- IronBank::Resources.const_get(resource)
51
+ def export
52
+ @export ||= IronBank::Export.create(
53
+ "select #{RESOURCE_QUERY_FIELDS[resource].join(', ')} from #{resource}"
54
+ )
43
55
  end
44
56
 
45
57
  def file_path
46
58
  File.expand_path("#{resource}.csv", self.class.directory)
47
59
  end
48
60
 
49
- def write_headers(csv)
50
- csv << klass.fields
61
+ def export_query_info
62
+ "Waiting for export #{export.id} to complete " \
63
+ "(attempt #{query_attempts} of #{BACKOFF[:max]})"
64
+ end
65
+
66
+ def completed?
67
+ return false unless (status = export.reload.status)
68
+
69
+ case status
70
+ when "Pending", "Processing" then false
71
+ when "Completed" then true
72
+ else raise_export_error
73
+ end
74
+ end
75
+
76
+ def raise_export_error
77
+ raise IronBank::Error, "Export #{export.id} has status #{export.status}"
51
78
  end
52
79
 
53
- def write_records(csv)
54
- klass.find_each { |record| csv << record.to_csv_row }
80
+ def max_query?
81
+ @query_attempts += 1
82
+ return false unless @query_attempts > BACKOFF[:max]
83
+
84
+ raise IronBank::Error, "Export query attempts exceeded"
85
+ end
86
+
87
+ def backoff_time
88
+ interval = BACKOFF[:interval]
89
+ current_interval = interval * (BACKOFF[:factor]**query_attempts)
90
+ random_interval = rand * BACKOFF[:randomness].to_f * interval
91
+
92
+ current_interval + random_interval
55
93
  end
56
94
  end
57
95
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'singleton'
4
- require 'logger'
3
+ require "singleton"
4
+ require "logger"
5
5
 
6
6
  module IronBank
7
7
  # Default logger for IronBank events
@@ -9,7 +9,7 @@ module IronBank
9
9
  class Logger
10
10
  extend Forwardable
11
11
 
12
- PROGNAME = 'iron_bank'
12
+ PROGNAME = "iron_bank"
13
13
  LEVEL = ::Logger::DEBUG
14
14
 
15
15
  def_delegators :@logger, :debug, :info, :warn, :error, :fatal
@@ -27,7 +27,7 @@ module IronBank
27
27
  end
28
28
 
29
29
  def name
30
- self.class.name.split('::').last
30
+ self.class.name.split("::").last
31
31
  end
32
32
  end
33
33
  end
@@ -26,7 +26,7 @@ module IronBank
26
26
  end
27
27
 
28
28
  def query_fields
29
- fields.join(',')
29
+ fields.join(",")
30
30
  end
31
31
 
32
32
  def query_conditions
@@ -41,7 +41,7 @@ module IronBank
41
41
  def range_query_builder(field, value)
42
42
  value.each.with_object([]) do |option, range_query|
43
43
  range_query << "#{field}='#{option}'"
44
- end.join(' OR ')
44
+ end.join(" OR ")
45
45
  end
46
46
 
47
47
  def hash_query_conditions
@@ -49,7 +49,7 @@ module IronBank
49
49
  # TODO: sanitize the value
50
50
  field = IronBank::Utils.camelize(field)
51
51
  filters << current_filter(field, value)
52
- end.join(' AND ')
52
+ end.join(" AND ")
53
53
  end
54
54
 
55
55
  def current_filter(field, value)
@@ -66,7 +66,7 @@ module IronBank
66
66
  return if conditions.count <= 1
67
67
  return unless conditions.values.any? { |value| value.is_a?(Array) }
68
68
 
69
- raise 'Filter ranges must be used in isolation.'
69
+ raise "Filter ranges must be used in isolation."
70
70
  end
71
71
  end
72
72
  end
@@ -10,7 +10,7 @@ module IronBank
10
10
  extend IronBank::Queryable
11
11
 
12
12
  def self.object_name
13
- name.split('::').last
13
+ name.split("::").last
14
14
  end
15
15
 
16
16
  def self.with_local_records
@@ -52,12 +52,7 @@ module IronBank
52
52
  def reload
53
53
  remove_instance_vars
54
54
  @remote = self.class.find(id).remote
55
- end
56
-
57
- def to_csv_row
58
- self.class.fields.each.with_object([]) do |field, row|
59
- row << remote[IronBank::Utils.underscore(field).to_sym]
60
- end
55
+ self
61
56
  end
62
57
 
63
58
  def remove_instance_vars