activesalesforce 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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