sugarcrm 0.9.12 → 0.9.13
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/README.rdoc +16 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/sugarcrm/attributes/attribute_methods.rb +1 -1
- data/lib/sugarcrm/attributes/attribute_validations.rb +29 -4
- data/lib/sugarcrm/base.rb +77 -18
- data/lib/sugarcrm/connection/request.rb +4 -0
- data/lib/sugarcrm/connection/response.rb +1 -0
- data/lib/sugarcrm/connection_pool.rb +1 -1
- data/lib/sugarcrm/finders/finder_methods.rb +59 -53
- data/lib/sugarcrm/session.rb +2 -6
- data/sugarcrm.gemspec +5 -6
- data/test/test_connection_pool.rb +3 -3
- data/test/test_finders.rb +183 -0
- data/test/test_sugarcrm.rb +73 -140
- metadata +34 -25
- data/sugarcrm.tmproj +0 -952
data/README.rdoc
CHANGED
@@ -38,7 +38,10 @@ A less clunky way to interact with SugarCRM via REST.
|
|
38
38
|
SugarCRM.modules
|
39
39
|
|
40
40
|
# Retrieve a User by user_name
|
41
|
-
SugarCRM::User.find_by_user_name("admin")
|
41
|
+
users = SugarCRM::User.find_by_user_name("admin")
|
42
|
+
|
43
|
+
# Return a User instance's SugarCRM URL (also works for any other module instance)
|
44
|
+
users.url
|
42
45
|
|
43
46
|
# Update a User's title
|
44
47
|
u = SugarCRM::User.find_by_first_name_and_last_name("Will", "Westin")
|
@@ -95,6 +98,9 @@ A less clunky way to interact with SugarCRM via REST.
|
|
95
98
|
a.contacts.delete(c)
|
96
99
|
a.save # or a.contacts.save
|
97
100
|
|
101
|
+
# Retrieve the number of accounts in CRM with 'Inc' in their name
|
102
|
+
SugarCRM::Account.count(:conditions => {:name => "LIKE '%Inc'"})
|
103
|
+
|
98
104
|
# Look up the Case with the smallest case number
|
99
105
|
SugarCRM::Case.first({
|
100
106
|
:order_by => 'case_number'
|
@@ -116,6 +122,12 @@ A less clunky way to interact with SugarCRM via REST.
|
|
116
122
|
SugarCRM::Account.all({
|
117
123
|
:conditions => { :name => "LIKE '%Fund%'" } # note that SQL operators must be uppercase
|
118
124
|
})
|
125
|
+
|
126
|
+
# Use block to iterate over results: print all account names
|
127
|
+
SugarCRM::Account.all{|a| puts a.name } # note: this method will be much quicker than SugarCRM::Account.all.each{|a| puts a.name }
|
128
|
+
# because records are passed to the block as they get fetched from SugarCRM (whereas `each`
|
129
|
+
# will fetch all records, and only then pass them to the block). This will make a major difference
|
130
|
+
# in resource use and execution time if you're dealing with many records.
|
119
131
|
|
120
132
|
# Look up the fields for a given module
|
121
133
|
SugarCRM::Module.find("Accounts").fields
|
@@ -149,7 +161,9 @@ Note: this gem requires Rails 3 as it depends on Active Support >= 3.
|
|
149
161
|
4. Run `rails g sugarcrm:config`
|
150
162
|
5. Edit the configuration file in `config/sugarcrm.yml` to match your environment
|
151
163
|
|
152
|
-
Example
|
164
|
+
Example apps:
|
165
|
+
* https://github.com/davidsulc/sugar_on_rails_basic
|
166
|
+
* https://github.com/davidsulc/dev_zone_basic_rails_app
|
153
167
|
|
154
168
|
== USING A CONFIGURATION FILE
|
155
169
|
|
data/Rakefile
CHANGED
@@ -18,7 +18,7 @@ Jeweler::Tasks.new do |gem|
|
|
18
18
|
gem.homepage = "http://github.com/chicks/sugarcrm"
|
19
19
|
gem.authors = ["Carl Hicks", "David Sulc"]
|
20
20
|
gem.executables = ['sugarcrm']
|
21
|
-
gem.files = FileList['./lib/**/*', './*'].exclude("*.lock").to_a
|
21
|
+
gem.files = FileList['./lib/**/*', './*'].exclude("*.lock", "*.tmproj").to_a
|
22
22
|
end
|
23
23
|
Jeweler::RubygemsDotOrgTasks.new
|
24
24
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.13
|
@@ -145,7 +145,7 @@ module SugarCRM; module AttributeMethods
|
|
145
145
|
# sets the id if it's a new record
|
146
146
|
def save_modified_attributes!
|
147
147
|
# Complain if we aren't valid
|
148
|
-
raise InvalidRecord, errors.
|
148
|
+
raise InvalidRecord, @errors.full_messages.join(", ") unless valid?
|
149
149
|
# Send the save request
|
150
150
|
response = self.class.session.connection.set_entry(self.class._module.name, serialize_modified_attributes)
|
151
151
|
# Complain if we don't get a parseable response back
|
@@ -1,11 +1,30 @@
|
|
1
1
|
module SugarCRM; module AttributeValidations
|
2
2
|
# Checks to see if we have all the neccessary attributes
|
3
3
|
def valid?
|
4
|
-
@errors =
|
4
|
+
@errors = ActiveSupport::HashWithIndifferentAccess.new
|
5
|
+
|
5
6
|
self.class._module.required_fields.each do |attribute|
|
6
7
|
valid_attribute?(attribute)
|
7
8
|
end
|
8
|
-
|
9
|
+
|
10
|
+
# for rails compatibility
|
11
|
+
def @errors.full_messages
|
12
|
+
# After removing attributes without errors, flatten the error hash, repeating the name of the attribute before each message:
|
13
|
+
# e.g. {'name' => ['cannot be blank', 'is too long'], 'website' => ['is not valid']}
|
14
|
+
# will become 'name cannot be blank, name is too long, website is not valid
|
15
|
+
self.inject([]){|memo, obj| memo.concat(obj[1].inject([]){|m, o| m << "#{obj[0].to_s.humanize} #{o}" })}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Rails needs each attribute to be present in the error hash (if the attribute has no error, it has [] as a value)
|
19
|
+
# Redefine the [] method for the errors hash to return [] instead of nil is the hash doesn't contain the key
|
20
|
+
class << @errors
|
21
|
+
alias :old_key_lookup :[]
|
22
|
+
def [](key)
|
23
|
+
old_key_lookup(key) || Array.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@errors.size == 0
|
9
28
|
end
|
10
29
|
|
11
30
|
protected
|
@@ -21,7 +40,7 @@ module SugarCRM; module AttributeValidations
|
|
21
40
|
validate_class_for(attribute, [Fixnum, Float])
|
22
41
|
else
|
23
42
|
if @attributes[attribute].blank?
|
24
|
-
|
43
|
+
add_error(attribute, "cannot be blank")
|
25
44
|
end
|
26
45
|
end
|
27
46
|
end
|
@@ -30,8 +49,14 @@ module SugarCRM; module AttributeValidations
|
|
30
49
|
# returns true if they match, otherwise adds an entry to the @errors collection, and returns false
|
31
50
|
def validate_class_for(attribute, class_array)
|
32
51
|
return true if class_array.include? @attributes[attribute].class
|
33
|
-
|
52
|
+
add_error(attribute, "must be a #{class_array.join(" or ")} object (not #{@attributes[attribute].class})")
|
34
53
|
false
|
35
54
|
end
|
36
55
|
|
56
|
+
# Add an error to the hash
|
57
|
+
def add_error(attribute, message)
|
58
|
+
@errors[attribute] ||= []
|
59
|
+
@errors[attribute] = @errors[attribute] << message unless @errors[attribute].include? message
|
60
|
+
@errors
|
61
|
+
end
|
37
62
|
end; end
|
data/lib/sugarcrm/base.rb
CHANGED
@@ -25,7 +25,7 @@ module SugarCRM; class Base
|
|
25
25
|
attr :errors, true
|
26
26
|
|
27
27
|
class << self # Class methods
|
28
|
-
def find(*args)
|
28
|
+
def find(*args, &block)
|
29
29
|
options = args.extract_options!
|
30
30
|
options = {:order_by => 'date_entered'}.merge(options)
|
31
31
|
validate_find_options(options)
|
@@ -35,39 +35,44 @@ module SugarCRM; class Base
|
|
35
35
|
find_initial(options)
|
36
36
|
when :last
|
37
37
|
begin
|
38
|
-
options[:order_by] = reverse_order_clause(options[:order_by])
|
38
|
+
options[:order_by] = reverse_order_clause(options[:order_by].to_s)
|
39
39
|
rescue Exception => e
|
40
40
|
raise
|
41
41
|
end
|
42
42
|
find_initial(options)
|
43
43
|
when :all
|
44
|
-
Array.wrap(find_every(options)).compact
|
44
|
+
Array.wrap(find_every(options, &block)).compact
|
45
45
|
else
|
46
|
-
find_from_ids(args, options)
|
46
|
+
find_from_ids(args, options, &block)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
# return the connection to the correct SugarCRM server (there can be several)
|
51
51
|
def connection
|
52
|
-
self.
|
52
|
+
self.session.connection
|
53
|
+
end
|
54
|
+
|
55
|
+
def count(options={})
|
56
|
+
query = query_from_options(options)
|
57
|
+
connection.get_entries_count(self._module.name, query, options)['result_count'].to_i
|
53
58
|
end
|
54
59
|
|
55
60
|
# A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
|
56
61
|
# same arguments to this method as you can to <tt>find(:first)</tt>.
|
57
|
-
def first(*args)
|
58
|
-
find(:first, *args)
|
62
|
+
def first(*args, &block)
|
63
|
+
find(:first, *args, &block)
|
59
64
|
end
|
60
65
|
|
61
66
|
# A convenience wrapper for <tt>find(:last, *args)</tt>. You can pass in all the
|
62
67
|
# same arguments to this method as you can to <tt>find(:last)</tt>.
|
63
|
-
def last(*args)
|
64
|
-
find(:last, *args)
|
68
|
+
def last(*args, &block)
|
69
|
+
find(:last, *args, &block)
|
65
70
|
end
|
66
71
|
|
67
72
|
# This is an alias for find(:all). You can pass in all the same arguments to this method as you can
|
68
73
|
# to find(:all)
|
69
|
-
def all(*args)
|
70
|
-
find(:all, *args)
|
74
|
+
def all(*args, &block)
|
75
|
+
find(:all, *args, &block)
|
71
76
|
end
|
72
77
|
|
73
78
|
# Creates an object (or multiple objects) and saves it to SugarCRM if validations pass.
|
@@ -102,11 +107,11 @@ module SugarCRM; class Base
|
|
102
107
|
object
|
103
108
|
end
|
104
109
|
end
|
105
|
-
|
106
110
|
end
|
107
111
|
|
108
112
|
# Creates an instance of a Module Class, i.e. Account, User, Contact, etc.
|
109
113
|
def initialize(attributes={}, &block)
|
114
|
+
@errors = {}
|
110
115
|
@modified_attributes = {}
|
111
116
|
merge_attributes(attributes.with_indifferent_access)
|
112
117
|
clear_association_cache
|
@@ -131,7 +136,7 @@ module SugarCRM; class Base
|
|
131
136
|
# Saves the current object, checks that required fields are present.
|
132
137
|
# returns true or false
|
133
138
|
def save
|
134
|
-
return false if !changed?
|
139
|
+
return false if !(new_record? || changed?)
|
135
140
|
return false if !valid?
|
136
141
|
begin
|
137
142
|
save!
|
@@ -156,6 +161,12 @@ module SugarCRM; class Base
|
|
156
161
|
params[:deleted]= {:name => "deleted", :value => "1"}
|
157
162
|
@attributes[:deleted] = (self.class.connection.set_entry(self.class._module.name, params).class == Hash)
|
158
163
|
end
|
164
|
+
alias :destroy :delete
|
165
|
+
|
166
|
+
# Returns if the record is persisted, i.e. it’s not a new record and it was not destroyed
|
167
|
+
def persisted?
|
168
|
+
!(new_record? || destroyed?)
|
169
|
+
end
|
159
170
|
|
160
171
|
# Reloads the record from SugarCRM
|
161
172
|
def reload!
|
@@ -178,16 +189,39 @@ module SugarCRM; class Base
|
|
178
189
|
end
|
179
190
|
alias :eql? :==
|
180
191
|
|
181
|
-
def update_attribute(name, value)
|
192
|
+
def update_attribute!(name, value)
|
182
193
|
self.send("#{name}=".to_sym, value)
|
183
|
-
self.save
|
194
|
+
self.save!
|
184
195
|
end
|
185
196
|
|
186
|
-
def
|
197
|
+
def update_attribute(name, value)
|
198
|
+
begin
|
199
|
+
update_attribute!(name, value)
|
200
|
+
rescue
|
201
|
+
return false
|
202
|
+
end
|
203
|
+
true
|
204
|
+
end
|
205
|
+
|
206
|
+
def update_attributes!(attributes)
|
187
207
|
attributes.each do |name, value|
|
188
208
|
self.send("#{name}=".to_sym, value)
|
189
209
|
end
|
190
|
-
self.save
|
210
|
+
self.save!
|
211
|
+
end
|
212
|
+
|
213
|
+
def update_attributes(attributes)
|
214
|
+
begin
|
215
|
+
update_attributes!(attributes)
|
216
|
+
rescue
|
217
|
+
return false
|
218
|
+
end
|
219
|
+
true
|
220
|
+
end
|
221
|
+
|
222
|
+
# Returns the URL (in string format) where the module instance is available in CRM
|
223
|
+
def url
|
224
|
+
"#{SugarCRM.session.config[:base_url]}/index.php?module=#{self.class._module}&action=DetailView&record=#{self.id}"
|
191
225
|
end
|
192
226
|
|
193
227
|
# Delegates to id in order to allow two records of the same type and id to work with something like:
|
@@ -197,7 +231,7 @@ module SugarCRM; class Base
|
|
197
231
|
end
|
198
232
|
|
199
233
|
def pretty_print(pp)
|
200
|
-
pp.text self.inspect, 0
|
234
|
+
pp.text self.inspect.to_s, 0
|
201
235
|
end
|
202
236
|
|
203
237
|
def attribute_methods_generated?
|
@@ -208,6 +242,31 @@ module SugarCRM; class Base
|
|
208
242
|
self.class.association_methods_generated
|
209
243
|
end
|
210
244
|
|
245
|
+
def to_key
|
246
|
+
new_record? ? nil : [ id ]
|
247
|
+
end
|
248
|
+
|
249
|
+
def to_param
|
250
|
+
id.to_s
|
251
|
+
end
|
252
|
+
|
253
|
+
def is_a?(klass)
|
254
|
+
superclasses.include? klass
|
255
|
+
end
|
256
|
+
alias :kind_of? :is_a?
|
257
|
+
alias :=== :is_a?
|
258
|
+
|
259
|
+
private
|
260
|
+
def superclasses
|
261
|
+
return @superclasses if @superclasses
|
262
|
+
@superclasses = [self.class]
|
263
|
+
current_class = self.class
|
264
|
+
while current_class.respond_to? :superclass
|
265
|
+
@superclasses << (current_class = current_class.superclass)
|
266
|
+
end
|
267
|
+
@superclasses
|
268
|
+
end
|
269
|
+
|
211
270
|
Base.class_eval do
|
212
271
|
extend FinderMethods::ClassMethods
|
213
272
|
include AttributeMethods
|
@@ -80,6 +80,7 @@ module SugarCRM; class Response
|
|
80
80
|
# Takes a hash like { "first_name" => {"name" => "first_name", "value" => "John"}}
|
81
81
|
# And flattens it into {"first_name" => "John"}
|
82
82
|
def flatten(list)
|
83
|
+
raise ArgumentError, list[0]['value'] if list[0] && list[0]['name'] == 'warning'
|
83
84
|
raise ArgumentError, 'method parameter must respond to #each_pair' unless list.respond_to? :each_pair
|
84
85
|
flat_list = {}
|
85
86
|
list.each_pair do |k,v|
|
@@ -11,7 +11,7 @@ module SugarCRM; class ConnectionPool
|
|
11
11
|
# The mutex used to synchronize pool access
|
12
12
|
@connection_mutex = Monitor.new
|
13
13
|
@queue = @connection_mutex.new_cond
|
14
|
-
@timeout = config_timeout ||
|
14
|
+
@timeout = config_timeout || 10
|
15
15
|
|
16
16
|
# default max pool size to 5
|
17
17
|
@size = config_pool_size || default_pool_size
|
@@ -8,7 +8,7 @@ module SugarCRM; module FinderMethods
|
|
8
8
|
result
|
9
9
|
end
|
10
10
|
|
11
|
-
def find_from_ids(ids, options)
|
11
|
+
def find_from_ids(ids, options, &block)
|
12
12
|
expects_array = ids.first.kind_of?(Array)
|
13
13
|
return ids.first if expects_array && ids.first.empty?
|
14
14
|
|
@@ -21,7 +21,7 @@ module SugarCRM; module FinderMethods
|
|
21
21
|
result = find_one(ids.first, options)
|
22
22
|
expects_array ? [ result ] : result
|
23
23
|
else
|
24
|
-
find_some(ids, options)
|
24
|
+
find_some(ids, options, &block)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -34,7 +34,7 @@ module SugarCRM; module FinderMethods
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def find_some(ids, options)
|
37
|
+
def find_some(ids, options, &block)
|
38
38
|
result = connection.get_entries(self._module.name, ids, {:fields => self._module.fields.keys})
|
39
39
|
|
40
40
|
# Determine expected size from limit and offset, not just ids.size.
|
@@ -51,67 +51,73 @@ module SugarCRM; module FinderMethods
|
|
51
51
|
end
|
52
52
|
|
53
53
|
if result.size == expected_size
|
54
|
+
if block_given?
|
55
|
+
result.each{|r|
|
56
|
+
yield r
|
57
|
+
}
|
58
|
+
end
|
54
59
|
result
|
55
60
|
else
|
56
61
|
raise RecordNotFound, "Couldn't find all #{name.pluralize} with IDs (#{ids_list})#{conditions} (found #{result.size} results, but was looking for #{expected_size})"
|
57
62
|
end
|
58
63
|
end
|
59
64
|
|
60
|
-
def find_every(options)
|
61
|
-
find_by_sql(options)
|
65
|
+
def find_every(options, &block)
|
66
|
+
find_by_sql(options, &block)
|
62
67
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
|
69
|
+
# the number of records we retrieve with each query
|
70
|
+
# it is kept small to avoid timeout issues
|
71
|
+
SLICE_SIZE = 5
|
72
|
+
SLICE_SIZE.freeze
|
73
|
+
# results accumulator stores the results we have fetched so far, recursively
|
74
|
+
def find_by_sql(options, results_accumulator=nil, &block)
|
75
|
+
# SugarCRM REST API has a bug where, when :limit and :offset options are passed simultaneously,
|
76
|
+
# :limit is considered to be the smallest of the two, and :offset is the larger
|
77
|
+
# In addition to allowing querying of large datasets while avoiding timeouts (by fetching results in small slices),
|
67
78
|
# this implementation fixes the :limit - :offset bug so that it behaves correctly
|
79
|
+
|
80
|
+
offset = options[:offset].to_i >= 1 ? options[:offset].to_i : nil
|
81
|
+
|
82
|
+
# if many results are requested (i.e. multiple result slices), we call this function recursively
|
83
|
+
# this array keeps track of which slice we are retrieving (by updating the :offset and :limit options)
|
68
84
|
local_options = {}
|
69
|
-
options.keys.each{|k|
|
70
|
-
local_options[k] = options[k]
|
71
|
-
}
|
72
|
-
local_options.delete(:offset) if local_options[:offset] == 0
|
73
|
-
|
74
|
-
# store the number of records wanted by user, as we'll overwrite :limit option to obtain several slices of records (to avoid timeout issues)
|
75
|
-
nb_to_fetch = local_options[:limit]
|
76
|
-
nb_to_fetch = nb_to_fetch.to_i if nb_to_fetch
|
77
|
-
offset_value = local_options[:offset] || 10 # arbitrary value, must be bigger than :limit used (see comment above)
|
78
|
-
offset_value = offset_value.to_i
|
79
|
-
offset_value.freeze
|
80
|
-
initial_limit = nb_to_fetch.nil? ? offset_value : [offset_value, nb_to_fetch].min # how many records should be fetched on first pass
|
81
85
|
# ensure results are ordered so :limit and :offset option behave in a deterministic fashion
|
82
|
-
local_options =
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
86
|
+
local_options[:order_by] = :id unless options[:order_by]
|
87
|
+
|
88
|
+
# we must ensure limit <= offset (due to bug mentioned above)
|
89
|
+
if offset
|
90
|
+
local_options[:limit] = [offset.to_i, SLICE_SIZE].min
|
91
|
+
local_options[:offset] = offset if offset
|
92
|
+
else
|
93
|
+
local_options[:limit] = options[:limit] ? [options[:limit].to_i, SLICE_SIZE].min : SLICE_SIZE
|
94
|
+
end
|
95
|
+
local_options[:limit] = [local_options[:limit], options[:limit]].min if options[:limit] # don't retrieve more records than required
|
96
|
+
local_options = options.merge(local_options)
|
97
|
+
|
98
|
+
query = query_from_options(local_options)
|
99
|
+
result_slice = connection.get_entry_list(self._module.name, query, local_options)
|
100
|
+
return results_accumulator unless result_slice
|
101
|
+
|
102
|
+
result_slice_array = Array.wrap(result_slice)
|
103
|
+
if block_given?
|
104
|
+
result_slice_array.each{|r| yield r }
|
105
|
+
else
|
106
|
+
results_accumulator = [] unless results_accumulator
|
107
|
+
results_accumulator = results_accumulator.concat(result_slice_array)
|
108
|
+
end
|
109
|
+
|
110
|
+
# adjust options to take into account records that were already retrieved
|
111
|
+
updated_options = {:offset => options[:offset].to_i + result_slice_array.size}
|
112
|
+
updated_options[:limit] = (options[:limit] ? options[:limit] - result_slice_array.size : nil)
|
113
|
+
updated_options = options.merge(updated_options)
|
114
|
+
|
115
|
+
# have we retrieved all the records?
|
116
|
+
if (updated_options[:limit] && updated_options[:limit] < 1) || local_options[:limit] > result_slice_array.size
|
117
|
+
return results_accumulator
|
118
|
+
else
|
119
|
+
find_by_sql(updated_options, results_accumulator, &block)
|
113
120
|
end
|
114
|
-
results
|
115
121
|
end
|
116
122
|
|
117
123
|
def query_from_options(options)
|
data/lib/sugarcrm/session.rb
CHANGED
@@ -16,7 +16,7 @@ module SugarCRM; class Session
|
|
16
16
|
|
17
17
|
setup_connection
|
18
18
|
register_namespace
|
19
|
-
|
19
|
+
connect(@config[:base_url], @config[:username], @config[:password], @config[:options])
|
20
20
|
end
|
21
21
|
|
22
22
|
# Creates a new session from the credentials present in a file
|
@@ -66,6 +66,7 @@ module SugarCRM; class Session
|
|
66
66
|
SugarCRM::Module.deregister_all(self)
|
67
67
|
@connection_pool = SugarCRM::ConnectionPool.new(self)
|
68
68
|
SugarCRM::Module.register_all(self)
|
69
|
+
SugarCRM.add_session(self)
|
69
70
|
load_extensions
|
70
71
|
true
|
71
72
|
end
|
@@ -195,11 +196,6 @@ module SugarCRM; class Session
|
|
195
196
|
def load_extensions
|
196
197
|
self.class.validate_path @extensions_path
|
197
198
|
Dir[File.join(@extensions_path, '**', '*.rb').to_s].each { |f| load(f) }
|
198
|
-
end
|
199
|
-
|
200
|
-
def connect_and_add_session
|
201
|
-
connect(@config[:base_url], @config[:username], @config[:password], @config[:options])
|
202
|
-
SugarCRM.add_session(self)
|
203
199
|
end
|
204
200
|
|
205
201
|
# Returns hash containing only keys/values relating to connection pool options. These are removed from parameter hash.
|
data/sugarcrm.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sugarcrm}
|
8
|
-
s.version = "0.9.
|
8
|
+
s.version = "0.9.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Carl Hicks", "David Sulc"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-04-06}
|
13
13
|
s.default_executable = %q{sugarcrm}
|
14
14
|
s.email = %q{carl.hicks@gmail.com}
|
15
15
|
s.executables = ["sugarcrm"]
|
@@ -78,12 +78,11 @@ Gem::Specification.new do |s|
|
|
78
78
|
"./lib/sugarcrm/module.rb",
|
79
79
|
"./lib/sugarcrm/module_methods.rb",
|
80
80
|
"./lib/sugarcrm/session.rb",
|
81
|
-
"./sugarcrm.gemspec"
|
82
|
-
"./sugarcrm.tmproj"
|
81
|
+
"./sugarcrm.gemspec"
|
83
82
|
]
|
84
83
|
s.homepage = %q{http://github.com/chicks/sugarcrm}
|
85
84
|
s.require_paths = ["lib"]
|
86
|
-
s.rubygems_version = %q{1.
|
85
|
+
s.rubygems_version = %q{1.6.2}
|
87
86
|
s.summary = %q{A less clunky way to interact with SugarCRM via REST.}
|
88
87
|
s.test_files = [
|
89
88
|
"test/connection/test_get_available_modules.rb",
|
@@ -106,6 +105,7 @@ Gem::Specification.new do |s|
|
|
106
105
|
"test/test_associations.rb",
|
107
106
|
"test/test_connection.rb",
|
108
107
|
"test/test_connection_pool.rb",
|
108
|
+
"test/test_finders.rb",
|
109
109
|
"test/test_module.rb",
|
110
110
|
"test/test_response.rb",
|
111
111
|
"test/test_session.rb",
|
@@ -113,7 +113,6 @@ Gem::Specification.new do |s|
|
|
113
113
|
]
|
114
114
|
|
115
115
|
if s.respond_to? :specification_version then
|
116
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
117
116
|
s.specification_version = 3
|
118
117
|
|
119
118
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
@@ -18,13 +18,13 @@ class TestConnectionPool < ActiveSupport::TestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
should "be able to specify its timeout" do
|
21
|
-
|
21
|
+
default_timeout = SugarCRM.session.connection_pool.timeout
|
22
22
|
|
23
23
|
config = SugarCRM.session.config
|
24
|
-
sess = SugarCRM::Session.new(config[:base_url], config[:username], config[:password], {:connection_pool => {:wait_timeout =>
|
24
|
+
sess = SugarCRM::Session.new(config[:base_url], config[:username], config[:password], {:connection_pool => {:wait_timeout => default_timeout+1}})
|
25
25
|
|
26
26
|
begin
|
27
|
-
assert_equal
|
27
|
+
assert_equal default_timeout+1, sess.connection_pool.timeout
|
28
28
|
ensure
|
29
29
|
sess.disconnect!
|
30
30
|
end
|