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.
@@ -21,7 +21,7 @@
21
21
  SOFTWARE.
22
22
  =end
23
23
 
24
- require 'salesforce_connection_adapter'
24
+ require 'asf_adapter'
25
25
 
26
26
  module ActionView
27
27
  module Helpers
@@ -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
- COLUMN_NAME_REGEX = /@C_(\w+)/
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 = "'NULL'"
155
- when TrueClass then quoted_value = "'TRUE'"
156
- when FalseClass then quoted_value = "'FALSE'"
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
- "@V_#{quoted_value}"
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 =~ COLUMN_NAME_REGEX
213
- column = columns[$~[1]]
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 = extract_columns(sql)
277
+ names = sql.match(/\((.+)\) VALUES/i)[1].scan(/\w+/i)
281
278
 
282
279
  # Extract arrays of values
283
- values = extract_values(sql)
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
- names = extract_columns(sql)
308
- values = extract_values(sql)
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 = @V_'(\w+)'/i)[1]
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 ids
329
- ids = extract_values(sql)
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
@@ -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.2
7
- date: 2006-02-06 00:00:00 -05:00
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/salesforce_connection_adapter.rb
34
+ - lib/asf_adapter.rb
35
+ - lib/relationship_definition.rb
35
36
  - test/unit
36
37
  - test/unit/account_test.rb
37
38
  - README