Class: DataMapper::Salesforce::Adapter

Inherits:
Adapters::AbstractAdapter
  • Object
show all
Includes:
SQL
Defined in:
lib/dm-salesforce/adapter.rb

Instance Method Summary collapse

Methods included from SQL

#comparison_operator, #comparison_statement, #conditions_statement, #equality_operator, #include_operator, #like_operator, #negate_operation, #order, #property_to_column_name, #quote_value, #storage_name

Constructor Details

#initialize(name, uri_or_options) ⇒ Adapter

Returns a new instance of Adapter.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/dm-salesforce/adapter.rb', line 5

def initialize(name, uri_or_options)
  super
  @resource_naming_convention = proc do |value|
    klass = Extlib::Inflection.constantize(value)
    if klass.respond_to?(:salesforce_class)
      klass.salesforce_class
    else
      value.split("::").last
    end
  end
  @field_naming_convention = proc do |property|
    connection.field_name_for(property.model.storage_name(name), property.name.to_s)
  end
end

Instance Method Details

#aggregate(query) ⇒ Object

www.salesforce.com/us/developer/docs/api90/Content/sforce_api_calls_soql.htm SOQL doesn’t support anything but count(), so we catch it here and interpret the result.



100
101
102
103
104
105
106
107
108
# File 'lib/dm-salesforce/adapter.rb', line 100

def aggregate(query)
  query.fields.each do |f|
    unless f.target == :all && f.operator == :count
      raise ArgumentError, %{Aggregate function #{f.operator} not supported in SOQL}
    end
  end

  [ execute_query(query).size ]
end

#connectionObject



20
21
22
# File 'lib/dm-salesforce/adapter.rb', line 20

def connection
  @connection ||= Connection.new(options["username"], options["password"], options["path"], options["apidir"])
end

#create(resources) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/dm-salesforce/adapter.rb', line 24

def create(resources)
  arr = resources.map do |resource|
    make_salesforce_obj(resource, resource.dirty_attributes)
  end

  result = connection.create(arr)
  result.each_with_index do |record, i|
    resource = resources[i]
    if id_field = resource.class.key.find {|p| p.serial?}
      normalized_value = normalize_id_value(resource.class, id_field, record.id)
      id_field.set!(resource, normalized_value)
    end
  end

  result.size

rescue Connection::SOAPError => e
  handle_server_outage(e)
end

#delete(collection) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'lib/dm-salesforce/adapter.rb', line 54

def delete(collection)
  query = collection.query
  keys  = collection.map { |r| r.key }.flatten.uniq

  connection.delete(keys).size

rescue Connection::SOAPError => e
  handle_server_outage(e)
end

#handle_server_outage(error) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/dm-salesforce/adapter.rb', line 64

def handle_server_outage(error)
  if error.server_unavailable?
    raise Connection::ServerUnavailable, "The salesforce server is currently unavailable"
  else
    raise error
  end
end

#read(query) ⇒ Object

Reading responses back from SELECTS:

In the typical case, response.size reflects the # of records returned.
In the aggregation case, response.size reflects the count.

Interpretation of this field requires knowledge of whether we are expecting an aggregate result, thus the response is processed differently depending on invocation.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/dm-salesforce/adapter.rb', line 79

def read(query)
  properties = query.fields
  repository = query.repository

  response = execute_query(query)
  return [] unless response.records

  rows = response.records.inject([]) do |results, record|
    results << properties.inject({}) do |result, property|
      meth = connection.field_name_for(property.model.storage_name(repository.name), property.field)
      result[property] = normalize_id_value(query.model, property, record.send(meth))
      result
    end
  end

  query.model.load(rows, query)
end

#update(attributes, collection) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/dm-salesforce/adapter.rb', line 44

def update(attributes, collection)
  query = collection.query
  arr   = collection.map { |obj| make_salesforce_obj(query, attributes) }

  connection.update(arr).size

rescue Connection::SOAPError => e
  handle_server_outage(e)
end