databasedotcom 1.0.1
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/MIT-LICENSE +20 -0
- data/README.rdoc +154 -0
- data/lib/databasedotcom.rb +7 -0
- data/lib/databasedotcom/chatter.rb +11 -0
- data/lib/databasedotcom/chatter/comment.rb +10 -0
- data/lib/databasedotcom/chatter/conversation.rb +100 -0
- data/lib/databasedotcom/chatter/feed.rb +64 -0
- data/lib/databasedotcom/chatter/feed_item.rb +40 -0
- data/lib/databasedotcom/chatter/feeds.rb +5 -0
- data/lib/databasedotcom/chatter/filter_feed.rb +14 -0
- data/lib/databasedotcom/chatter/group.rb +45 -0
- data/lib/databasedotcom/chatter/group_membership.rb +9 -0
- data/lib/databasedotcom/chatter/like.rb +9 -0
- data/lib/databasedotcom/chatter/message.rb +29 -0
- data/lib/databasedotcom/chatter/photo_methods.rb +55 -0
- data/lib/databasedotcom/chatter/record.rb +122 -0
- data/lib/databasedotcom/chatter/subscription.rb +9 -0
- data/lib/databasedotcom/chatter/user.rb +153 -0
- data/lib/databasedotcom/client.rb +421 -0
- data/lib/databasedotcom/collection.rb +37 -0
- data/lib/databasedotcom/core_extensions.rb +3 -0
- data/lib/databasedotcom/core_extensions/class_extensions.rb +41 -0
- data/lib/databasedotcom/core_extensions/hash_extensions.rb +8 -0
- data/lib/databasedotcom/core_extensions/string_extensions.rb +8 -0
- data/lib/databasedotcom/sales_force_error.rb +26 -0
- data/lib/databasedotcom/sobject.rb +2 -0
- data/lib/databasedotcom/sobject/sobject.rb +291 -0
- data/lib/databasedotcom/version.rb +3 -0
- metadata +138 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
module Databasedotcom
|
2
|
+
# A collection of Sobject or Record objects that holds a single page of results, and understands how to
|
3
|
+
# retrieve the next page, if any. Inherits from Array, thus, behaves as an Enumerable.
|
4
|
+
|
5
|
+
class Collection < Array
|
6
|
+
attr_reader :total_size, :next_page_url, :previous_page_url, :current_page_url, :client
|
7
|
+
|
8
|
+
# Creates a paginatable collection. You should never need to call this.
|
9
|
+
def initialize(client, total_size, next_page_url=nil, previous_page_url=nil, current_page_url=nil) #:nodoc:
|
10
|
+
@client = client
|
11
|
+
@total_size = total_size
|
12
|
+
@next_page_url = next_page_url
|
13
|
+
@previous_page_url = previous_page_url
|
14
|
+
@current_page_url = current_page_url
|
15
|
+
end
|
16
|
+
|
17
|
+
# Does this collection have a next page?
|
18
|
+
def next_page?
|
19
|
+
!!self.next_page_url
|
20
|
+
end
|
21
|
+
|
22
|
+
# Retrieve the next page of this collection. Returns the new collection, which is an empty collection if no next page exists
|
23
|
+
def next_page
|
24
|
+
self.next_page? ? @client.next_page(@next_page_url) : Databasedotcom::Collection.new(self.client, 0)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Does this collection have a previous page?
|
28
|
+
def previous_page?
|
29
|
+
!!self.previous_page_url
|
30
|
+
end
|
31
|
+
|
32
|
+
# Retrieve the previous page of this collection. Returns the new collection, which is an empty collection if no previous page exists
|
33
|
+
def previous_page
|
34
|
+
self.previous_page? ? @client.previous_page(@previous_page_url) : Databasedotcom::Collection.new(self.client, 0)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# This extends Class to be able to use +cattr_accessor+ if active_support is not being used.
|
2
|
+
class Class
|
3
|
+
unless respond_to?(:cattr_reader)
|
4
|
+
def cattr_reader(sym)
|
5
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
6
|
+
unless defined? @@#{sym}
|
7
|
+
@@#{sym} = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.#{sym}
|
11
|
+
@@#{sym}
|
12
|
+
end
|
13
|
+
|
14
|
+
def #{sym}
|
15
|
+
@@#{sym}
|
16
|
+
end
|
17
|
+
EOS
|
18
|
+
end
|
19
|
+
|
20
|
+
def cattr_writer(sym)
|
21
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
22
|
+
unless defined? @@#{sym}
|
23
|
+
@@#{sym} = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.#{sym}=(obj)
|
27
|
+
@@#{sym} = obj
|
28
|
+
end
|
29
|
+
|
30
|
+
def #{sym}=(obj)
|
31
|
+
@@#{sym} = obj
|
32
|
+
end
|
33
|
+
EOS
|
34
|
+
end
|
35
|
+
|
36
|
+
def cattr_accessor(*syms, &blk)
|
37
|
+
cattr_reader(*syms)
|
38
|
+
cattr_writer(*syms, &blk)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Databasedotcom
|
2
|
+
# An exception raised when any non successful request is made to Force.com.
|
3
|
+
class SalesForceError < StandardError
|
4
|
+
# the Net::HTTPResponse from the API call
|
5
|
+
attr_accessor :response
|
6
|
+
# the +errorCode+ from the server response body
|
7
|
+
attr_accessor :error_code
|
8
|
+
|
9
|
+
def initialize(response)
|
10
|
+
self.response = response
|
11
|
+
parsed_body = JSON.parse(response.body) rescue nil
|
12
|
+
if parsed_body
|
13
|
+
if parsed_body.is_a?(Array)
|
14
|
+
message = parsed_body[0]["message"]
|
15
|
+
self.error_code = parsed_body[0]["errorCode"]
|
16
|
+
else
|
17
|
+
message = parsed_body["error_description"]
|
18
|
+
self.error_code = parsed_body["error"]
|
19
|
+
end
|
20
|
+
else
|
21
|
+
message = response.body
|
22
|
+
end
|
23
|
+
super(message)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,291 @@
|
|
1
|
+
module Databasedotcom
|
2
|
+
module Sobject
|
3
|
+
# Parent class of dynamically created sobject types. Interacts with Force.com through a Client object that is passed in during materialization.
|
4
|
+
class Sobject
|
5
|
+
cattr_accessor :client
|
6
|
+
extend ActiveModel::Naming if defined?(ActiveModel::Naming)
|
7
|
+
|
8
|
+
# Returns a new Sobject. The default values for all attributes are set based on its description.
|
9
|
+
def initialize(attrs = {})
|
10
|
+
super
|
11
|
+
self.class.description["fields"].each do |field|
|
12
|
+
self.send("#{field["name"]}=", field["defaultValueFormula"])
|
13
|
+
end
|
14
|
+
self.attributes=(attrs)
|
15
|
+
end
|
16
|
+
|
17
|
+
def attributes=(attrs)
|
18
|
+
attrs.each do |key, value|
|
19
|
+
self.send("#{key}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns true if the object has been persisted in the Force.com database.
|
24
|
+
def persisted?
|
25
|
+
!self.Id.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns true if this record has not been persisted in the Force.com database.
|
29
|
+
def new_record?
|
30
|
+
!self.persisted?
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns self.
|
34
|
+
def to_model
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns a unique object id for self.
|
39
|
+
def to_key
|
40
|
+
[object_id]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the Force.com Id for this instance.
|
44
|
+
def to_param
|
45
|
+
self.Id
|
46
|
+
end
|
47
|
+
|
48
|
+
# Updates the corresponding record on Force.com by setting the attribute +attr_name+ to +attr_value+.
|
49
|
+
#
|
50
|
+
# client.materialize("Car")
|
51
|
+
# c = Car.new
|
52
|
+
# c.update_attribute("Color", "Blue")
|
53
|
+
def update_attribute(attr_name, attr_value)
|
54
|
+
update_attributes(attr_name => attr_value)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Updates the corresponding record on Force.com with the attributes specified by the +new_attrs+ hash.
|
58
|
+
#
|
59
|
+
# client.materialize("Car")
|
60
|
+
# c = Car.new
|
61
|
+
# c.update_attributes {"Color" => "Blue", "Year" => "2012"}
|
62
|
+
def update_attributes(new_attrs)
|
63
|
+
if self.client.update(self.class, self.Id, new_attrs)
|
64
|
+
new_attrs = new_attrs.is_a?(Hash) ? new_attrs : JSON.parse(new_attrs)
|
65
|
+
new_attrs.each do |attr, value|
|
66
|
+
self.send("#{attr}=", value)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
# Updates the corresponding record on Force.com with the attributes of self.
|
73
|
+
#
|
74
|
+
# client.materialize("Car")
|
75
|
+
# c = Car.find_by_Color("Yellow")
|
76
|
+
# c.Color = "Green"
|
77
|
+
# c.save
|
78
|
+
def save
|
79
|
+
attr_hash = {}
|
80
|
+
self.class.description["fields"].select { |f| f["updateable"] }.collect { |f| f["name"] }.each { |attr| attr_hash[attr] = self.send(attr) }
|
81
|
+
|
82
|
+
if self.Id.nil?
|
83
|
+
self.client.create(self.class, attr_hash)
|
84
|
+
else
|
85
|
+
self.client.update(self.class, self.Id, attr_hash)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Deletes the corresponding record from the Force.com database. Returns self.
|
90
|
+
#
|
91
|
+
# client.materialize("Car")
|
92
|
+
# c = Car.find_by_Color("Yellow")
|
93
|
+
# c.delete
|
94
|
+
def delete
|
95
|
+
if self.client.delete(self.class, self.Id)
|
96
|
+
self
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Reloads the record from the Force.com database. Returns the reloaded record.
|
101
|
+
#
|
102
|
+
# client.materialize("Car")
|
103
|
+
# c = Car.find_by_Color("Yellow")
|
104
|
+
# c.reload
|
105
|
+
def reload
|
106
|
+
self.class.find(self.Id)
|
107
|
+
end
|
108
|
+
|
109
|
+
def [](attr_name)
|
110
|
+
self.send(attr_name) rescue nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def []=(attr_name, value)
|
114
|
+
raise ArgumentError.new("No attribute named #{attr_name}") unless self.class.attributes.include?(attr_name)
|
115
|
+
self.send("#{attr_name}=", value)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Returns an Array of attribute names that this Sobject has.
|
119
|
+
#
|
120
|
+
# client.materialize("Car")
|
121
|
+
# Car.attributes #=> ["Id", "Name", "Color", "Year"]
|
122
|
+
def self.attributes
|
123
|
+
self.description["fields"].collect { |f| f["name"] }
|
124
|
+
end
|
125
|
+
|
126
|
+
# Materializes the dynamically created Sobject class by adding all attribute accessors for each field as described in the description of the object on Force.com
|
127
|
+
def self.materialize(sobject_name)
|
128
|
+
self.cattr_accessor :description
|
129
|
+
self.cattr_accessor :type_map
|
130
|
+
self.cattr_accessor :sobject_name
|
131
|
+
|
132
|
+
self.sobject_name = sobject_name
|
133
|
+
self.description = self.client.describe_sobject(self.sobject_name)
|
134
|
+
self.type_map = {}
|
135
|
+
self.description["fields"].each do |field|
|
136
|
+
name = field["name"]
|
137
|
+
attr_accessor name.to_sym
|
138
|
+
self.type_map[name] = {:type => field["type"], :label => field["label"], :picklist_values => field["picklistValues"], :updateable? => field["updateable"]}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns the Force.com type of the attribute +attr_name+. Raises ArgumentError if attribute does not exist.
|
143
|
+
#
|
144
|
+
# client.materialize("Car")
|
145
|
+
# Car.field_type("Color") #=> "string"
|
146
|
+
def self.field_type(attr_name)
|
147
|
+
self.type_map_attr(attr_name, :type)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Returns the label for the attribute +attr_name+. Raises ArgumentError if attribute does not exist.
|
151
|
+
def self.label_for(attr_name)
|
152
|
+
self.type_map_attr(attr_name, :label)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns the possible picklist options for the attribute +attr_name+. If +attr_name+ is not of type picklist or multipicklist, [] is returned. Raises ArgumentError if attribute does not exist.
|
156
|
+
def self.picklist_values(attr_name)
|
157
|
+
self.type_map_attr(attr_name, :picklist_values)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Returns true if the attribute +attr_name+ can be updated. Raises ArgumentError if attribute does not exist.
|
161
|
+
def self.updateable?(attr_name)
|
162
|
+
self.type_map_attr(attr_name, :updateable?)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Delegates to Client.find with arguments +record_id+ and self
|
166
|
+
#
|
167
|
+
# client.materialize("Car")
|
168
|
+
# Car.find("rid") #=> #<Car @Id="rid", ...>
|
169
|
+
def self.find(record_id)
|
170
|
+
self.client.find(self, record_id)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Returns all records of type self as instances.
|
174
|
+
#
|
175
|
+
# client.materialize("Car")
|
176
|
+
# Car.all #=> [#<Car @Id="1", ...>, #<Car @Id="2", ...>, #<Car @Id="3", ...>, ...]
|
177
|
+
def self.all
|
178
|
+
self.client.query("SELECT #{self.field_list} FROM #{self.sobject_name}")
|
179
|
+
end
|
180
|
+
|
181
|
+
# Returns a collection of instances of self that match the conditional +where_expr+, which is the WHERE part of a SOQL query.
|
182
|
+
#
|
183
|
+
# client.materialize("Car")
|
184
|
+
# Car.query("Color = 'Blue'") #=> [#<Car @Id="1", @Color="Blue", ...>, #<Car @Id="5", @Color="Blue", ...>, ...]
|
185
|
+
def self.query(where_expr)
|
186
|
+
self.client.query("SELECT #{self.field_list} FROM #{self.sobject_name} WHERE #{where_expr}")
|
187
|
+
end
|
188
|
+
|
189
|
+
# Delegates to Client.search
|
190
|
+
def self.search(sosl_expr)
|
191
|
+
self.client.search(sosl_expr)
|
192
|
+
end
|
193
|
+
|
194
|
+
# Find the first record. If the +where_expr+ argument is present, it must be the WHERE part of a SOQL query
|
195
|
+
def self.first(where_expr=nil)
|
196
|
+
where = where_expr ? "WHERE #{where_expr} " : ""
|
197
|
+
self.client.query("SELECT #{self.field_list} FROM #{self.sobject_name} #{where}ORDER BY Id ASC LIMIT 1").first
|
198
|
+
end
|
199
|
+
|
200
|
+
# Find the last record. If the +where_expr+ argument is present, it must be the WHERE part of a SOQL query
|
201
|
+
def self.last(where_expr=nil)
|
202
|
+
where = where_expr ? "WHERE #{where_expr} " : ""
|
203
|
+
self.client.query("SELECT #{self.field_list} FROM #{self.sobject_name} #{where}ORDER BY Id DESC LIMIT 1").first
|
204
|
+
end
|
205
|
+
|
206
|
+
#Delegates to Client.upsert with arguments self, +field+, +values+, and +attrs+
|
207
|
+
def self.upsert(field, value, attrs)
|
208
|
+
self.client.upsert(self.sobject_name, field, value, attrs)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Delegates to Client.delete with arguments +record_id+ and self
|
212
|
+
def self.delete(record_id)
|
213
|
+
self.client.delete(self.sobject_name, record_id)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Sobject objects support dynamic finders similar to ActiveRecord.
|
217
|
+
#
|
218
|
+
# client.materialize("Car")
|
219
|
+
# Car.find_by_Color("Blue")
|
220
|
+
# Car.find_all_by_Year("2011")
|
221
|
+
# Car.find_by_Color_and_Year("Blue", "2011")
|
222
|
+
# Car.find_or_create_by_Year("2011")
|
223
|
+
# Car.find_or_initialize_by_Name("Foo")
|
224
|
+
def self.method_missing(method_name, *args, &block)
|
225
|
+
if method_name.to_s =~ /^find_(or_create_|or_initialize_)?by_(.+)$/ || method_name.to_s =~ /^find_(all_)by_(.+)$/
|
226
|
+
named_attrs = $2.split('_and_')
|
227
|
+
attrs_and_values_for_find = []
|
228
|
+
hash_args = args.length == 1 && args[0].is_a?(Hash)
|
229
|
+
attrs_and_values_for_write = hash_args ? args[0] : {}
|
230
|
+
|
231
|
+
named_attrs.each_with_index do |attr, index|
|
232
|
+
value = hash_args ? args[0][attr] : args[index]
|
233
|
+
attrs_and_values_for_find << "#{attr} = '#{value}'"
|
234
|
+
attrs_and_values_for_write[attr] = value unless hash_args
|
235
|
+
end
|
236
|
+
|
237
|
+
limit_clause = method_name.to_s.include?('_all_by_') ? "" : " LIMIT 1"
|
238
|
+
|
239
|
+
results = self.client.query("SELECT #{self.field_list} FROM #{self.sobject_name} WHERE #{attrs_and_values_for_find.join(' AND ')}#{limit_clause}")
|
240
|
+
results = limit_clause == "" ? results : results.first rescue nil
|
241
|
+
|
242
|
+
if results.nil?
|
243
|
+
if method_name.to_s =~ /^find_or_create_by_(.+)$/
|
244
|
+
results = self.client.create(self, attrs_and_values_for_write)
|
245
|
+
elsif method_name.to_s =~ /^find_or_initialize_by_(.+)$/
|
246
|
+
results = self.new
|
247
|
+
attrs_and_values_for_write.each { |attr, val| results.send("#{attr}=", val) }
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
results
|
252
|
+
else
|
253
|
+
super
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Delegates to Client.create with arguments +object_attributes+ and self
|
258
|
+
def self.create(object_attributes)
|
259
|
+
self.client.create(self, object_attributes)
|
260
|
+
end
|
261
|
+
|
262
|
+
# Coerce values submitted from a Rails form to the values expected by the database
|
263
|
+
# returns a new hash with updated values
|
264
|
+
def self.coerce_params(params)
|
265
|
+
params.each do |attr, value|
|
266
|
+
case self.field_type(attr)
|
267
|
+
when "boolean"
|
268
|
+
params[attr] = value.is_a?(String) ? value.to_i != 0 : value
|
269
|
+
when "currency", "percent", "double"
|
270
|
+
params[attr] = value.to_f
|
271
|
+
when "date"
|
272
|
+
params[attr] = Date.parse(value) rescue Date.today
|
273
|
+
when "datetime"
|
274
|
+
params[attr] = DateTime.parse(value) rescue DateTime.now
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
private
|
280
|
+
|
281
|
+
def self.field_list
|
282
|
+
self.description['fields'].collect { |f| f['name'] }.join(',')
|
283
|
+
end
|
284
|
+
|
285
|
+
def self.type_map_attr(attr_name, key)
|
286
|
+
raise ArgumentError.new("No attribute named #{attr_name}") unless self.type_map.has_key?(attr_name)
|
287
|
+
self.type_map[attr_name][key]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: databasedotcom
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Glenn Gillen, Danny Burkes & Richard Zhao
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-08-23 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: multipart-post
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.1.3
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - "="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 2.5.0
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: webmock
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rake
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - "="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.8.6
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: ruby-debug19
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
description: A ruby wrapper for the Force.com REST API
|
72
|
+
email:
|
73
|
+
- me@glenngillen.com
|
74
|
+
executables: []
|
75
|
+
|
76
|
+
extensions: []
|
77
|
+
|
78
|
+
extra_rdoc_files: []
|
79
|
+
|
80
|
+
files:
|
81
|
+
- README.rdoc
|
82
|
+
- MIT-LICENSE
|
83
|
+
- lib/databasedotcom/chatter/comment.rb
|
84
|
+
- lib/databasedotcom/chatter/conversation.rb
|
85
|
+
- lib/databasedotcom/chatter/feed.rb
|
86
|
+
- lib/databasedotcom/chatter/feed_item.rb
|
87
|
+
- lib/databasedotcom/chatter/feeds.rb
|
88
|
+
- lib/databasedotcom/chatter/filter_feed.rb
|
89
|
+
- lib/databasedotcom/chatter/group.rb
|
90
|
+
- lib/databasedotcom/chatter/group_membership.rb
|
91
|
+
- lib/databasedotcom/chatter/like.rb
|
92
|
+
- lib/databasedotcom/chatter/message.rb
|
93
|
+
- lib/databasedotcom/chatter/photo_methods.rb
|
94
|
+
- lib/databasedotcom/chatter/record.rb
|
95
|
+
- lib/databasedotcom/chatter/subscription.rb
|
96
|
+
- lib/databasedotcom/chatter/user.rb
|
97
|
+
- lib/databasedotcom/chatter.rb
|
98
|
+
- lib/databasedotcom/client.rb
|
99
|
+
- lib/databasedotcom/collection.rb
|
100
|
+
- lib/databasedotcom/core_extensions/class_extensions.rb
|
101
|
+
- lib/databasedotcom/core_extensions/hash_extensions.rb
|
102
|
+
- lib/databasedotcom/core_extensions/string_extensions.rb
|
103
|
+
- lib/databasedotcom/core_extensions.rb
|
104
|
+
- lib/databasedotcom/sales_force_error.rb
|
105
|
+
- lib/databasedotcom/sobject/sobject.rb
|
106
|
+
- lib/databasedotcom/sobject.rb
|
107
|
+
- lib/databasedotcom/version.rb
|
108
|
+
- lib/databasedotcom.rb
|
109
|
+
has_rdoc: true
|
110
|
+
homepage: ""
|
111
|
+
licenses: []
|
112
|
+
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: "0"
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: "0"
|
130
|
+
requirements: []
|
131
|
+
|
132
|
+
rubyforge_project: databasedotcom
|
133
|
+
rubygems_version: 1.6.0
|
134
|
+
signing_key:
|
135
|
+
specification_version: 3
|
136
|
+
summary: A ruby wrapper for the Force.com REST API
|
137
|
+
test_files: []
|
138
|
+
|