salesforce_bulk 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,8 +2,12 @@
2
2
 
3
3
  ==Overview
4
4
 
5
- Salesforce bulk is a simple ruby gem for connecting to and using the Salesforce Bulk API (http://www.salesforce.com/us/developer/docs/api_asynch/index.htm). There are already some gems out there that provide connectivity to the Salesforce SOAP and Rest APIs, if your needs are simple, I recommend using those, specifically raygao's asf-rest-adapter (https://github.com/raygao/asf-rest-adapter).
5
+ Salesforce bulk is a simple ruby gem for connecting to and using the Salesforce Bulk API (http://www.salesforce.com/us/developer/docs/api_asynch/index.htm). There are already some gems out there that provide connectivity to the Salesforce SOAP and Rest APIs, if your needs are simple, I recommend using those, specifically raygao's asf-rest-adapter (https://github.com/raygao/asf-rest-adapter) or databasedotcom (https://rubygems.org/gems/databasedotcom).
6
6
 
7
+ ==Installation
8
+
9
+ sudo gem install salesforce_bulk
10
+
7
11
  ==How to use
8
12
 
9
13
  Using this gem is simple and straight forward.
@@ -28,7 +32,7 @@ Sample operations:
28
32
  puts "result is: #{result.inspect}"
29
33
 
30
34
  # Update
31
- updated_account = Hash["name" => "Test Account -- Updated", id => "a00A0001009zA2m"] # Nearly identical to an insert, but we need to pass the salesforce id.
35
+ updated_account = Hash["name" => "Test Account -- Updated", "id" => "a00A0001009zA2m"] # Nearly identical to an insert, but we need to pass the salesforce id.
32
36
  records_to_update = Array.new
33
37
  records_to_update.push(updated_account)
34
38
  salesforce.update("Account", records_to_update)
@@ -51,16 +55,21 @@ Sample operations:
51
55
 
52
56
  # Query
53
57
  res = salesforce.query("Account", "select id, name, createddate from Account limit 3") # We just need to pass the sobject name and the query string
58
+ puts res.records.inspect
54
59
 
55
- ==Installation
56
- sudo gem install salesforce_bulk
60
+ Result reporting:
57
61
 
58
- ==TODO
59
- This is a rough early version of the gem. Immediate plans include better error reporting as there currently is none.
62
+ new_account = Hash["type" => "Other"] # Missing required field "name."
63
+ records_to_insert = Array.new
64
+ records_to_insert.push(new_account) # You can add as many records as you want here, just keep in mind that Salesforce has governor limits.
65
+ result = salesforce.create("Account", records_to_insert)
66
+ puts result.success? # false
67
+ puts result.has_errors? # true
68
+ puts result.errors # An indexed hash detailing the errors
60
69
 
61
70
  == Copyright
62
71
 
63
- Copyright (c) 2011 Jorge Valdivia.
72
+ Copyright (c) 2012 Jorge Valdivia.
64
73
 
65
74
  ===end
66
75
 
@@ -19,16 +19,16 @@ module SalesforceBulk
19
19
  self.do_operation('upsert', sobject, records, external_field, wait)
20
20
  end
21
21
 
22
- def update(sobject, records)
23
- self.do_operation('update', sobject, records, nil)
22
+ def update(sobject, records, wait=false)
23
+ self.do_operation('update', sobject, records, nil, wait)
24
24
  end
25
25
 
26
- def create(sobject, records)
27
- self.do_operation('insert', sobject, records, nil)
26
+ def create(sobject, records, wait=false)
27
+ self.do_operation('insert', sobject, records, nil, wait)
28
28
  end
29
29
 
30
- def delete(sobject, records)
31
- self.do_operation('delete', sobject, records, nil)
30
+ def delete(sobject, records, wait=false)
31
+ self.do_operation('delete', sobject, records, nil, wait)
32
32
  end
33
33
 
34
34
  def query(sobject, query)
@@ -50,7 +50,6 @@ module SalesforceBulk
50
50
  if wait or operation == 'query'
51
51
  while true
52
52
  state = job.check_batch_status()
53
- #puts "\nstate is #{state}\n"
54
53
  if state != "Queued" && state != "InProgress"
55
54
  break
56
55
  end
@@ -59,12 +58,26 @@ module SalesforceBulk
59
58
 
60
59
  if state == 'Completed'
61
60
  job.get_batch_result()
61
+ job
62
62
  else
63
- return "There is an error in your job."
63
+ job.result.message = "There is an error in your job. The response returned a state of #{state}. Please check your query/parameters and try again."
64
+ job.result.success = false
65
+ return job
66
+
64
67
  end
65
68
  else
66
- return "The job has been closed."
69
+ return job
70
+ end
71
+
72
+ end
73
+
74
+ def parse_batch_result result
75
+ begin
76
+ CSV.parse(result, :headers => true)
77
+ rescue
78
+ result
67
79
  end
68
80
  end
81
+
69
82
  end # End class
70
83
  end # End module
@@ -40,7 +40,8 @@ module SalesforceBulk
40
40
  headers = Hash['Content-Type' => 'text/xml; charset=utf-8', 'SOAPAction' => 'login']
41
41
 
42
42
  response = post_xml(@@LOGIN_HOST, @@LOGIN_PATH, xml, headers)
43
- response_parsed = XmlSimple.xml_in(response)
43
+ # response_parsed = XmlSimple.xml_in(response)
44
+ response_parsed = parse_response response
44
45
 
45
46
  @session_id = response_parsed['Body'][0]['loginResponse'][0]['result'][0]['sessionId'][0]
46
47
  @server_url = response_parsed['Body'][0]['loginResponse'][0]['result'][0]['serverUrl'][0]
@@ -55,12 +56,9 @@ module SalesforceBulk
55
56
 
56
57
  if host != @@LOGIN_HOST # Not login, need to add session id to header
57
58
  headers['X-SFDC-Session'] = @session_id;
58
- #puts "session id is: #{@session_id} --- #{headers.inspect}\n"
59
59
  path = "#{@@PATH_PREFIX}#{path}"
60
60
  end
61
61
 
62
- #puts "#{host} -- #{path} -- #{headers.inspect}\n"
63
-
64
62
  https(host).post(path, xml, headers).body
65
63
  end
66
64
 
@@ -87,6 +85,28 @@ module SalesforceBulk
87
85
  @instance = $~.captures[0]
88
86
  end
89
87
 
88
+ def parse_response response
89
+ response_parsed = XmlSimple.xml_in(response)
90
+
91
+ if response.downcase.include?("faultstring") || response.downcase.include?("exceptionmessage")
92
+ begin
93
+
94
+ if response.downcase.include?("faultstring")
95
+ error_message = response_parsed["Body"][0]["Fault"][0]["faultstring"][0]
96
+ elsif response.downcase.include?("exceptionmessage")
97
+ error_message = response_parsed["exceptionMessage"][0]
98
+ end
99
+
100
+ rescue
101
+ raise "An unknown error has occured within the salesforce_bulk gem. This is most likely caused by bad request, but I am unable to parse the correct error message. Here is a dump of the response for your convenience. #{response}"
102
+ end
103
+
104
+ raise error_message
105
+ end
106
+
107
+ response_parsed
108
+ end
109
+
90
110
  end
91
111
 
92
112
  end
@@ -2,6 +2,8 @@ module SalesforceBulk
2
2
 
3
3
  class Job
4
4
 
5
+ attr :result
6
+
5
7
  def initialize(operation, sobject, records, external_field, connection)
6
8
 
7
9
  @@operation = operation
@@ -11,6 +13,9 @@ module SalesforceBulk
11
13
  @@connection = connection
12
14
  @@XML_HEADER = '<?xml version="1.0" encoding="utf-8" ?>'
13
15
 
16
+ # @result = {"errors" => [], "success" => nil, "records" => [], "raw" => nil, "message" => 'The job has been queued.'}
17
+ @result = JobResult.new
18
+
14
19
  end
15
20
 
16
21
  def create_job()
@@ -27,7 +32,7 @@ module SalesforceBulk
27
32
  headers = Hash['Content-Type' => 'application/xml; charset=utf-8']
28
33
 
29
34
  response = @@connection.post_xml(nil, path, xml, headers)
30
- response_parsed = XmlSimple.xml_in(response)
35
+ response_parsed = @@connection.parse_response response
31
36
 
32
37
  @@job_id = response_parsed['id'][0]
33
38
  end
@@ -110,16 +115,60 @@ module SalesforceBulk
110
115
  path = "job/#{@@job_id}/batch/#{@@batch_id}/result/#{result_id}"
111
116
  headers = Hash.new
112
117
  headers = Hash["Content-Type" => "text/xml; charset=UTF-8"]
113
- #puts "path is: #{path}\n"
114
118
 
115
119
  response = @@connection.get_request(nil, path, headers)
116
- #puts "\n\nres2: #{response.inspect}\n\n"
117
120
 
118
121
  end
119
122
 
123
+ parse_results response
124
+
120
125
  response = response.lines.to_a[1..-1].join
121
- csvRows = CSV.parse(response)
126
+ # csvRows = CSV.parse(response, :headers => true)
122
127
  end
123
128
 
129
+ def parse_results response
130
+ @result.success = true
131
+ @result.raw = response.lines.to_a[1..-1].join
132
+ csvRows = CSV.parse(response, :headers => true)
133
+
134
+ csvRows.each_with_index do |row, index|
135
+ if @@operation != "query"
136
+ row["Created"] = row["Created"] == "true" ? true : false
137
+ row["Success"] = row["Success"] == "true" ? true : false
138
+ end
139
+
140
+ @result.records.push row
141
+ if row["Success"] == false
142
+ @result.success = false
143
+ @result.errors.push({"#{index}" => row["Error"]}) if row["Error"]
144
+ end
145
+ end
146
+
147
+ @result.message = "The job has been closed."
148
+
149
+ end
150
+
151
+ end
152
+
153
+ class JobResult
154
+ attr_writer :errors, :success, :records, :raw, :message
155
+ attr_reader :errors, :success, :records, :raw, :message
156
+
157
+ def initialize
158
+ @errors = []
159
+ @success = nil
160
+ @records = []
161
+ @raw = nil
162
+ @message = 'The job has been queued.'
163
+ end
164
+
165
+ def success?
166
+ @success
167
+ end
168
+
169
+ def has_errors?
170
+ @errors.count > 0
171
+ end
124
172
  end
173
+
125
174
  end
@@ -1,3 +1,3 @@
1
1
  module SalesforceBulk
2
- VERSION = "0.1.0"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: salesforce_bulk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: