activesalesforce 0.2.2 → 0.2.3
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.
data/lib/activesalesforce.rb
CHANGED
@@ -28,6 +28,7 @@ require 'thread'
|
|
28
28
|
|
29
29
|
require File.dirname(__FILE__) + '/rforce'
|
30
30
|
require File.dirname(__FILE__) + '/column_definition'
|
31
|
+
require File.dirname(__FILE__) + '/relationship_definition'
|
31
32
|
|
32
33
|
class ResultArray < Array
|
33
34
|
attr_reader :actual_size
|
@@ -120,8 +121,7 @@ module ActiveRecord
|
|
120
121
|
end
|
121
122
|
end
|
122
123
|
|
123
|
-
|
124
|
-
COLUMN_VALUE_REGEX = /@V_'(([^']|\\')*)'/
|
124
|
+
COLUMN_VALUE_REGEX = /@V_'(([^']|\\')*)'/m
|
125
125
|
|
126
126
|
include StringHelper
|
127
127
|
|
@@ -151,21 +151,16 @@ module ActiveRecord
|
|
151
151
|
|
152
152
|
def quote(value, column = nil)
|
153
153
|
case value
|
154
|
-
when NilClass then quoted_value = "
|
155
|
-
when TrueClass then quoted_value = "
|
156
|
-
when FalseClass then quoted_value = "
|
154
|
+
when NilClass then quoted_value = "NULL"
|
155
|
+
when TrueClass then quoted_value = "TRUE"
|
156
|
+
when FalseClass then quoted_value = "FALSE"
|
157
157
|
else quoted_value = super(value, column)
|
158
158
|
end
|
159
159
|
|
160
|
-
|
160
|
+
quoted_value
|
161
161
|
end
|
162
162
|
|
163
163
|
|
164
|
-
def quote_column_name(name) #:nodoc:
|
165
|
-
# Mark the column name to make it easier to find later
|
166
|
-
"@C_#{name}"
|
167
|
-
end
|
168
|
-
|
169
164
|
# CONNECTION MANAGEMENT ====================================
|
170
165
|
|
171
166
|
def active?
|
@@ -198,7 +193,7 @@ module ActiveRecord
|
|
198
193
|
|
199
194
|
# Always (unless COUNT*)'ing) select all columns (required for the AR attributes mechanism to work correctly
|
200
195
|
soql = sql.sub(/SELECT .+ FROM/i, "SELECT #{column_names.join(', ')} FROM") unless selectCountMatch
|
201
|
-
|
196
|
+
|
202
197
|
soql.sub!(/ FROM \w+/i, " FROM #{entity_def.api_name}")
|
203
198
|
|
204
199
|
# Look for a LIMIT clause
|
@@ -209,8 +204,10 @@ module ActiveRecord
|
|
209
204
|
|
210
205
|
# Fixup column references to use api names
|
211
206
|
columns = columns_map(table_name)
|
212
|
-
while soql =~
|
213
|
-
|
207
|
+
while soql =~ /\w+\.(\w+)/i
|
208
|
+
column_name = $~[1]
|
209
|
+
|
210
|
+
column = columns[column_name]
|
214
211
|
soql = $~.pre_match + column.api_name + $~.post_match
|
215
212
|
end
|
216
213
|
|
@@ -277,10 +274,12 @@ module ActiveRecord
|
|
277
274
|
columns = columns_map(table_name)
|
278
275
|
|
279
276
|
# Extract array of column names
|
280
|
-
names =
|
277
|
+
names = sql.match(/\((.+)\) VALUES/i)[1].scan(/\w+/i)
|
281
278
|
|
282
279
|
# Extract arrays of values
|
283
|
-
values =
|
280
|
+
values = sql.match(/VALUES\s*\((.+)\)/i)[1]
|
281
|
+
values = values.scan(/(((NULL))|'(([^']|\\')*)'),*/mi)
|
282
|
+
values.map! { |v| v[3] }
|
284
283
|
|
285
284
|
fields = {}
|
286
285
|
names.each_with_index do | name, n |
|
@@ -291,7 +290,7 @@ module ActiveRecord
|
|
291
290
|
end
|
292
291
|
|
293
292
|
sobject = create_sobject(entity_name, nil, fields)
|
294
|
-
|
293
|
+
|
295
294
|
check_result(get_result(@connection.create(:sObjects => sobject), :create))[0][:id]
|
296
295
|
end
|
297
296
|
|
@@ -304,8 +303,11 @@ module ActiveRecord
|
|
304
303
|
entity_name = entity_name_from_table(table_name)
|
305
304
|
columns = columns_map(table_name)
|
306
305
|
|
307
|
-
|
308
|
-
|
306
|
+
match = sql.match(/SET\s+(.+)\s+WHERE/mi)[1]
|
307
|
+
names = match.scan(/(\w+)\s+=/).flatten
|
308
|
+
|
309
|
+
values = match.scan(/=\s+(((NULL))|'(([^']|\\')*)'),*/mi)
|
310
|
+
values.map! { |v| v[3] }
|
309
311
|
|
310
312
|
fields = {}
|
311
313
|
names.each_with_index do | name, n |
|
@@ -314,7 +316,7 @@ module ActiveRecord
|
|
314
316
|
fields[column.api_name] = value if not column.readonly and value != "NULL"
|
315
317
|
end
|
316
318
|
|
317
|
-
id = sql.match(/WHERE id =
|
319
|
+
id = sql.match(/WHERE id = '(\w+)'/i)[1]
|
318
320
|
|
319
321
|
sobject = create_sobject(entity_name, id, fields)
|
320
322
|
|
@@ -325,12 +327,22 @@ module ActiveRecord
|
|
325
327
|
def delete(sql, name = nil)
|
326
328
|
log(sql, name)
|
327
329
|
|
328
|
-
# Extract the
|
329
|
-
|
330
|
+
# Extract the id
|
331
|
+
match = sql.match(/WHERE\s+id\s*=\s*'(\w+)'/mi)
|
332
|
+
|
333
|
+
if match
|
334
|
+
ids = [ match[1] ]
|
335
|
+
else
|
336
|
+
# Check for the form id IN ('x', 'y')
|
337
|
+
match = sql.match(/WHERE\s+id\s+IN\s*\((.+)\)/mi)[1]
|
338
|
+
ids = match.scan(/\w+/)
|
339
|
+
end
|
330
340
|
|
331
341
|
ids_element = []
|
332
342
|
ids.each { |id| ids_element << :ids << id }
|
333
343
|
|
344
|
+
pp ids_element
|
345
|
+
|
334
346
|
check_result(get_result(@connection.delete(ids_element), :delete))
|
335
347
|
end
|
336
348
|
|
@@ -380,15 +392,10 @@ module ActiveRecord
|
|
380
392
|
end
|
381
393
|
|
382
394
|
if metadata.childRelationships
|
383
|
-
metadata.childRelationships.each do |relationship|
|
384
|
-
|
385
|
-
# DCHASMAN TO Figure out the weird and wacky world of relationship metadata
|
386
|
-
if (relationship[:childSObject].casecmp(entity_name) == 0) # or (relationship[:cascadeDelete] == "true")
|
395
|
+
metadata.childRelationships.each do |relationship|
|
396
|
+
if relationship[:cascadeDelete] == "true"
|
387
397
|
r = SalesforceRelationship.new(relationship)
|
388
398
|
cached_relationships << r
|
389
|
-
else
|
390
|
-
#puts " Skipping relationship"
|
391
|
-
#pp relationship
|
392
399
|
end
|
393
400
|
end
|
394
401
|
end
|
@@ -414,7 +421,7 @@ module ActiveRecord
|
|
414
421
|
# Create relationships for any reference field
|
415
422
|
entity_def.relationships.each do |relationship|
|
416
423
|
referenceName = relationship.name
|
417
|
-
unless self.respond_to? referenceName.to_sym or relationship.reference_to == "Profile"
|
424
|
+
unless self.respond_to? referenceName.to_sym or relationship.reference_to == "Profile"
|
418
425
|
reference_to = relationship.reference_to
|
419
426
|
|
420
427
|
begin
|
@@ -422,6 +429,9 @@ module ActiveRecord
|
|
422
429
|
rescue NameError => e
|
423
430
|
# Automatically create a least a stub for the referenced entity
|
424
431
|
referenced_klass = klass.class_eval("::#{reference_to} = Class.new(ActiveRecord::Base)")
|
432
|
+
referenced_klass.connection = klass.connection
|
433
|
+
#configure_active_record(get_entity_def(reference_to))
|
434
|
+
|
425
435
|
puts "Created ActiveRecord stub for the referenced entity '#{reference_to}'"
|
426
436
|
end
|
427
437
|
|
@@ -484,16 +494,6 @@ module ActiveRecord
|
|
484
494
|
columns(table_name).map { |column| column.api_name }
|
485
495
|
end
|
486
496
|
|
487
|
-
|
488
|
-
def extract_columns(sql)
|
489
|
-
sql.scan(COLUMN_NAME_REGEX).flatten
|
490
|
-
end
|
491
|
-
|
492
|
-
|
493
|
-
def extract_values(sql)
|
494
|
-
sql.scan(COLUMN_VALUE_REGEX).map { |v| v[0] }
|
495
|
-
end
|
496
|
-
|
497
497
|
end
|
498
498
|
|
499
499
|
end
|
data/lib/column_definition.rb
CHANGED
@@ -38,10 +38,11 @@ module ActiveRecord
|
|
38
38
|
class SalesforceColumn < Column
|
39
39
|
include StringHelper
|
40
40
|
|
41
|
-
attr_reader :api_name, :label, :readonly, :reference_to
|
41
|
+
attr_reader :api_name, :custom, :label, :readonly, :reference_to
|
42
42
|
|
43
43
|
def initialize(field)
|
44
44
|
@api_name = field[:name]
|
45
|
+
@custom = field[:custom] == "true"
|
45
46
|
@name = column_nameize(@api_name)
|
46
47
|
@type = get_type(field[:type])
|
47
48
|
@limit = field[:length]
|
@@ -56,6 +57,8 @@ module ActiveRecord
|
|
56
57
|
@reference_to = field[:referenceTo]
|
57
58
|
@one_to_many = false
|
58
59
|
@cascade_delete = false
|
60
|
+
|
61
|
+
@name.chop!.chop! << "id__c" if @custom
|
59
62
|
end
|
60
63
|
end
|
61
64
|
|
@@ -90,37 +93,5 @@ module ActiveRecord
|
|
90
93
|
|
91
94
|
end
|
92
95
|
|
93
|
-
class SalesforceRelationship
|
94
|
-
include StringHelper
|
95
|
-
|
96
|
-
attr_reader :name, :api_name, :foreign_key, :label, :reference_to, :one_to_many, :cascade_delete
|
97
|
-
|
98
|
-
def initialize(source)
|
99
|
-
if source[:childSObject]
|
100
|
-
relationship = source
|
101
|
-
|
102
|
-
@api_name = relationship[:relationshipName] ? relationship[:relationshipName] : relationship[:field].chop.chop
|
103
|
-
@one_to_many = relationship[:relationshipName] != nil
|
104
|
-
@cascade_delete = relationship[:cascadeDelete] == "true"
|
105
|
-
@reference_to = relationship[:childSObject]
|
106
|
-
@label = @name
|
107
|
-
@foreign_key = column_nameize(relationship[:field])
|
108
|
-
else
|
109
|
-
field = source
|
110
|
-
|
111
|
-
@api_name = field[:name].chop.chop
|
112
|
-
@label = field[:label]
|
113
|
-
@readonly = (field[:updateable] != "true" or field[:createable] != "true")
|
114
|
-
@reference_to = field[:referenceTo]
|
115
|
-
@one_to_many = false
|
116
|
-
@cascade_delete = false
|
117
|
-
@foreign_key = column_nameize(field[:name])
|
118
|
-
end
|
119
|
-
|
120
|
-
@name = column_nameize(@api_name)
|
121
|
-
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
96
|
end
|
126
97
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
=begin
|
2
|
+
ActiveSalesforce
|
3
|
+
Copyright (c) 2006 Doug Chasman
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'rubygems'
|
25
|
+
require_gem 'rails', ">= 1.0.0"
|
26
|
+
|
27
|
+
require 'pp'
|
28
|
+
|
29
|
+
|
30
|
+
module ActiveRecord
|
31
|
+
module StringHelper
|
32
|
+
def column_nameize(s)
|
33
|
+
s.underscore
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module ConnectionAdapters
|
38
|
+
|
39
|
+
class SalesforceRelationship
|
40
|
+
include StringHelper
|
41
|
+
|
42
|
+
attr_reader :name, :api_name, :custom, :foreign_key, :label, :reference_to, :one_to_many
|
43
|
+
|
44
|
+
def initialize(source)
|
45
|
+
if source[:childSObject]
|
46
|
+
relationship = source
|
47
|
+
|
48
|
+
@api_name = relationship[:relationshipName] ? relationship[:relationshipName] : relationship[:field].chop.chop
|
49
|
+
@one_to_many = relationship[:relationshipName] != nil
|
50
|
+
@reference_to = relationship[:childSObject]
|
51
|
+
@label = @name
|
52
|
+
@foreign_key = column_nameize(relationship[:field])
|
53
|
+
@custom = false
|
54
|
+
else
|
55
|
+
field = source
|
56
|
+
|
57
|
+
@api_name = field[:name]
|
58
|
+
@custom = field[:custom] == "true"
|
59
|
+
|
60
|
+
@api_name = @api_name.chop.chop unless @custom
|
61
|
+
|
62
|
+
@label = field[:label]
|
63
|
+
@readonly = (field[:updateable] != "true" or field[:createable] != "true")
|
64
|
+
@reference_to = field[:referenceTo]
|
65
|
+
@one_to_many = false
|
66
|
+
#@foreign_key = column_nameize(field[:name])
|
67
|
+
@foreign_key = field[:name]
|
68
|
+
end
|
69
|
+
|
70
|
+
@name = column_nameize(@api_name)
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: activesalesforce
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.2.
|
7
|
-
date: 2006-02-
|
6
|
+
version: 0.2.3
|
7
|
+
date: 2006-02-15 00:00:00 -05:00
|
8
8
|
summary: ActiveSalesforce is an extension to the Rails Framework that allows for the dynamic creation and management of ActiveRecord objects through the use of Salesforce meta-data and uses a Salesforce.com organization as the backing store.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -31,7 +31,8 @@ files:
|
|
31
31
|
- lib/column_definition.rb
|
32
32
|
- lib/activesalesforce.rb
|
33
33
|
- lib/rforce.rb
|
34
|
-
- lib/
|
34
|
+
- lib/asf_adapter.rb
|
35
|
+
- lib/relationship_definition.rb
|
35
36
|
- test/unit
|
36
37
|
- test/unit/account_test.rb
|
37
38
|
- README
|