rhosync 2.1.16 → 2.1.17.beta1
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/CHANGELOG +8 -0
- data/Rakefile +0 -1
- data/lib/rhosync.rb +1 -1
- data/lib/rhosync/api/fast_delete.rb +8 -0
- data/lib/rhosync/api/fast_insert.rb +8 -0
- data/lib/rhosync/api/fast_update.rb +8 -0
- data/lib/rhosync/app.rb +0 -3
- data/lib/rhosync/bulk_data/bulk_data.rb +5 -1
- data/lib/rhosync/client_sync.rb +15 -0
- data/lib/rhosync/jobs/bulk_data_job.rb +22 -2
- data/lib/rhosync/server.rb +20 -11
- data/lib/rhosync/source_sync.rb +31 -1
- data/lib/rhosync/stats/middleware.rb +13 -8
- data/lib/rhosync/version.rb +1 -1
- data/spec/api/api_helper.rb +2 -0
- data/spec/api/fast_delete_spec.rb +27 -0
- data/spec/api/fast_insert_spec.rb +28 -0
- data/spec/api/fast_update_spec.rb +51 -0
- data/spec/api/stats_spec.rb +2 -0
- data/spec/client_sync_spec.rb +40 -11
- data/spec/jobs/bulk_data_job_spec.rb +14 -5
- data/spec/perf/bulk_data_perf_spec.rb +1 -0
- data/spec/ping/apple_spec.rb +14 -8
- data/spec/server/server_spec.rb +2 -8
- data/spec/source_sync_spec.rb +20 -8
- data/spec/spec_helper.rb +22 -0
- data/spec/stats/middleware_spec.rb +11 -1
- metadata +54 -60
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 2.1.17 (not yet released)
|
2
|
+
* Refactor server middleware. Remove explicit rack dependency. Fix broken rspec examples.
|
3
|
+
* Fixing error with recursive loading of application.rb in ruby-1.8.7 and ree
|
4
|
+
* #28330213 - Implementing fast_insert/update/delete API
|
5
|
+
* #27612327 - Bulk Sync Not Returning Errors from Zendesk ticket #2336
|
6
|
+
* #28219647 - Schema Change Error from Zendesk ticket #2353
|
7
|
+
* #28328057 - Feature Request: Adding a Bulk Data Job after_perform hook from Zendesk ticket #2367
|
8
|
+
|
1
9
|
## 2.1.16
|
2
10
|
* revert rack support for v. 1.4.1 and lock to v. 1.3.6 due to problems with Heroku deployment (Rack 1.4.1 produces 502 error)
|
3
11
|
|
data/Rakefile
CHANGED
@@ -66,7 +66,6 @@ begin
|
|
66
66
|
gemspec.files = FileList["[A-Z]*", "{bench,bin,generators,lib,spec,tasks}/**/*"]
|
67
67
|
|
68
68
|
# TODO: Due to https://www.pivotaltracker.com/story/show/3417862, we can't use JSON 1.4.3
|
69
|
-
gemspec.add_dependency "rack", "~> 1.3.6"
|
70
69
|
gemspec.add_dependency "sinatra", "~> 1.3.1"
|
71
70
|
gemspec.add_dependency "json", "~>1.4.2"
|
72
71
|
gemspec.add_dependency "sqlite3-ruby", "~>1.2.5"
|
data/lib/rhosync.rb
CHANGED
@@ -137,7 +137,7 @@ module Rhosync
|
|
137
137
|
if secret == '<changeme>'
|
138
138
|
log "*"*60+"\n\n"
|
139
139
|
log "WARNING: Change the session secret in config.ru from <changeme> to something secure."
|
140
|
-
log " i.e. running `rake secret` in
|
140
|
+
log " i.e. running `rake rhosync:secret` in your rhosync app directory will generate a secret you could use.\n\n"
|
141
141
|
log "*"*60
|
142
142
|
end
|
143
143
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Server.api :fast_delete do |params,user|
|
2
|
+
source = Source.load(params[:source_id],{:app_id=>APP_NAME,:user_id=>params[:user_id]})
|
3
|
+
source_sync = SourceSync.new(source)
|
4
|
+
timeout = params[:timeout] || 10
|
5
|
+
raise_on_expire = params[:raise_on_expire] || false
|
6
|
+
source_sync.fast_delete(params[:data], timeout,raise_on_expire)
|
7
|
+
'done'
|
8
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Server.api :fast_insert do |params,user|
|
2
|
+
source = Source.load(params[:source_id],{:app_id=>APP_NAME,:user_id=>params[:user_id]})
|
3
|
+
source_sync = SourceSync.new(source)
|
4
|
+
timeout = params[:timeout] || 10
|
5
|
+
raise_on_expire = params[:raise_on_expire] || false
|
6
|
+
source_sync.fast_insert(params[:data], timeout,raise_on_expire)
|
7
|
+
'done'
|
8
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Server.api :fast_update do |params,user|
|
2
|
+
source = Source.load(params[:source_id],{:app_id=>APP_NAME,:user_id=>params[:user_id]})
|
3
|
+
source_sync = SourceSync.new(source)
|
4
|
+
timeout = params[:timeout] || 10
|
5
|
+
raise_on_expire = params[:raise_on_expire] || false
|
6
|
+
source_sync.fast_update(params[:delete_data], params[:data],timeout,raise_on_expire)
|
7
|
+
'done'
|
8
|
+
end
|
data/lib/rhosync/app.rb
CHANGED
data/lib/rhosync/client_sync.rb
CHANGED
@@ -256,6 +256,21 @@ module Rhosync
|
|
256
256
|
|
257
257
|
if data and data.completed? and data.dbfiles_exist?
|
258
258
|
client.update_clientdoc(sources)
|
259
|
+
sources.each do |src|
|
260
|
+
s = Source.load(src, {:user_id => client.user_id, :app_id => client.app_id})
|
261
|
+
errordoc = s.docname(:errors)
|
262
|
+
errors = {}
|
263
|
+
Store.lock(errordoc) do
|
264
|
+
errors = Store.get_data(errordoc)
|
265
|
+
end
|
266
|
+
unless errors.empty?
|
267
|
+
# FIXME: :result => :bulk_sync_error, :errors => "#{errors}"
|
268
|
+
log "Bulk sync errors are found in #{src}: #{errors}"
|
269
|
+
# Delete all related bulk files
|
270
|
+
data.delete_files
|
271
|
+
return {:result => :url, :url => ''}
|
272
|
+
end
|
273
|
+
end
|
259
274
|
{:result => :url, :url => data.url}
|
260
275
|
elsif data
|
261
276
|
{:result => :wait}
|
@@ -21,8 +21,8 @@ module Rhosync
|
|
21
21
|
create_hsql_data_file(bulk_data,ts) if Rhosync.blackberry_bulk_sync
|
22
22
|
lap_timer('create_hsql_data_file',timer)
|
23
23
|
log "finished bulk data process"
|
24
|
-
bulk_data.state = :completed
|
25
|
-
bulk_data.refresh_time = Time.now.to_i + Rhosync.bulk_sync_poll_interval
|
24
|
+
#bulk_data.state = :completed
|
25
|
+
#bulk_data.refresh_time = Time.now.to_i + Rhosync.bulk_sync_poll_interval
|
26
26
|
else
|
27
27
|
raise Exception.new("No bulk data found for #{params["data_name"]}")
|
28
28
|
end
|
@@ -33,6 +33,26 @@ module Rhosync
|
|
33
33
|
raise e
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
def self.after_perform_x(*args)
|
38
|
+
log "BulkDataJob.after_perform_x hook called ..."
|
39
|
+
params = args[0] # 1st parameter is bulk data
|
40
|
+
begin
|
41
|
+
bulk_data = BulkData.load(params["data_name"]) if BulkData.is_exist?(params["data_name"])
|
42
|
+
if bulk_data
|
43
|
+
bulk_data.state = :completed
|
44
|
+
bulk_data.refresh_time = Time.now.to_i + Rhosync.bulk_sync_poll_interval
|
45
|
+
log "BulkDataJob.after_perform_x hook set data state to complete."
|
46
|
+
else
|
47
|
+
raise Exception.new("No bulk data found for #{params["data_name"]}")
|
48
|
+
end
|
49
|
+
rescue Exception => e
|
50
|
+
bulk_data.delete if bulk_data
|
51
|
+
log "Bulk data after_perform_x raised: #{e.message}"
|
52
|
+
log e.backtrace.join("\n")
|
53
|
+
raise e
|
54
|
+
end
|
55
|
+
end
|
36
56
|
|
37
57
|
def self.import_data_to_object_values(db,source)
|
38
58
|
data = source.get_data(:md)
|
data/lib/rhosync/server.rb
CHANGED
@@ -28,13 +28,28 @@ module Rhosync
|
|
28
28
|
set :stats, false
|
29
29
|
|
30
30
|
# default secret
|
31
|
-
|
31
|
+
@secret = '<changeme>'
|
32
32
|
|
33
33
|
# Setup route and mimetype for bulk data downloads
|
34
34
|
# TODO: Figure out why "mime :data, 'application/octet-stream'" doesn't work
|
35
35
|
Rack::Mime::MIME_TYPES['.data'] = 'application/octet-stream'
|
36
36
|
|
37
37
|
include Rhosync
|
38
|
+
|
39
|
+
# Set rhosync middleware
|
40
|
+
set :use_middleware, Proc.new {
|
41
|
+
return false if @middleware_configured # Middleware might be configured only once!
|
42
|
+
|
43
|
+
use Rhosync::BodyContentTypeParser
|
44
|
+
use Rhosync::Stats::Middleware
|
45
|
+
Rhosync::Server.set :secret, @secret unless settings.respond_to?(:secret)
|
46
|
+
use Rack::Session::Cookie,
|
47
|
+
:key => 'rhosync_session',
|
48
|
+
:expire_after => 31536000,
|
49
|
+
:secret => Rhosync::Server.secret
|
50
|
+
|
51
|
+
@middleware_configured ||= true
|
52
|
+
}
|
38
53
|
|
39
54
|
helpers do
|
40
55
|
def request_action
|
@@ -145,19 +160,13 @@ module Rhosync
|
|
145
160
|
|
146
161
|
# hook into new so we can enable middleware
|
147
162
|
def self.new
|
148
|
-
use Rhosync::BodyContentTypeParser
|
149
163
|
if settings.respond_to?(:stats) and settings.send(:stats) == true
|
150
|
-
|
151
|
-
Rhosync.stats = true
|
164
|
+
Rhosync.stats = true
|
152
165
|
else
|
153
|
-
|
154
|
-
|
166
|
+
Rhosync::Server.disable :stats
|
167
|
+
Rhosync.stats = false
|
155
168
|
end
|
156
|
-
|
157
|
-
use Rack::Session::Cookie,
|
158
|
-
:key => 'rhosync_session',
|
159
|
-
:expire_after => 31536000,
|
160
|
-
:secret => Rhosync::Server.secret
|
169
|
+
settings.use_middleware
|
161
170
|
super
|
162
171
|
end
|
163
172
|
|
data/lib/rhosync/source_sync.rb
CHANGED
@@ -81,6 +81,29 @@ module Rhosync
|
|
81
81
|
@source.app_id,@source.user_id,client_id,params)
|
82
82
|
end
|
83
83
|
|
84
|
+
def fast_insert(new_objs, timeout=10,raise_on_expire=false)
|
85
|
+
@source.lock(:md,timeout,raise_on_expire) do |s|
|
86
|
+
diff_count = new_objs.size
|
87
|
+
@source.put_data(:md, new_objs, true)
|
88
|
+
@source.update_count(:md_size,diff_count)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def fast_update(orig_hash, new_hash, timeout=10,raise_on_expire=false)
|
93
|
+
@source.lock(:md,timeout,raise_on_expire) do |s|
|
94
|
+
@source.delete_data(:md, orig_hash)
|
95
|
+
@source.put_data(:md, new_hash, true)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def fast_delete(delete_objs, timeout=10,raise_on_expire=false)
|
100
|
+
@source.lock(:md,timeout,raise_on_expire) do |s|
|
101
|
+
diff_count = -delete_objs.size
|
102
|
+
@source.delete_data(:md, delete_objs)
|
103
|
+
@source.update_count(:md_size,diff_count)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
84
107
|
def push_objects(objects,timeout=10,raise_on_expire=false,rebuild_md=true)
|
85
108
|
@source.lock(:md,timeout,raise_on_expire) do |s|
|
86
109
|
diff_count = 0
|
@@ -259,7 +282,14 @@ module Rhosync
|
|
259
282
|
data = @adapter.send(method)
|
260
283
|
if data
|
261
284
|
@source.put_value(method,data)
|
262
|
-
|
285
|
+
if method == :schema
|
286
|
+
parsed = JSON.parse(data)
|
287
|
+
schema_version = parsed['version']
|
288
|
+
raise "Mandatory version key is not defined in source adapter schema method" if schema_version.nil?
|
289
|
+
@source.put_value("#{method}_sha1",Digest::SHA1.hexdigest(schema_version))
|
290
|
+
else
|
291
|
+
@source.put_value("#{method}_sha1",Digest::SHA1.hexdigest(data))
|
292
|
+
end
|
263
293
|
end
|
264
294
|
end
|
265
295
|
end
|
@@ -6,14 +6,19 @@ module Rhosync
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def call(env)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
if Rhosync.stats || Rhosync::Server.stats
|
10
|
+
start = Time.now.to_f
|
11
|
+
status, headers, body = @app.call(env)
|
12
|
+
finish = Time.now.to_f
|
13
|
+
metric = "http:#{env['REQUEST_METHOD']}:#{env['PATH_INFO']}"
|
14
|
+
source_name = env['rack.request.query_hash']["source_name"] if env['rack.request.query_hash']
|
15
|
+
metric << ":#{source_name}" if source_name
|
16
|
+
Record.save_average(metric,finish - start)
|
17
|
+
[status, headers, body]
|
18
|
+
else
|
19
|
+
status, headers, body = @app.call(env)
|
20
|
+
[status, headers, body]
|
21
|
+
end
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
data/lib/rhosync/version.rb
CHANGED
data/spec/api/api_helper.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'api_helper')
|
2
|
+
|
3
|
+
describe "RhoconnectApiFastDelete" do
|
4
|
+
it_should_behave_like "ApiHelper"
|
5
|
+
|
6
|
+
it "should delete an object from rhosync's :md" do
|
7
|
+
data = {'1' => @product1, '2' => @product2, '3' => @product3}
|
8
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
9
|
+
set_state(@s.docname(:md) => data,@s.docname(:md_size) => '3')
|
10
|
+
post "/api/fast_delete", :api_token => @api_token,
|
11
|
+
:user_id => @u.id, :source_id => @s_fields[:name], :data => {'3' => @product3}
|
12
|
+
last_response.should be_ok
|
13
|
+
data.delete('3')
|
14
|
+
verify_result(@s.docname(:md) => data,@s.docname(:md_size)=>'2')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should not properly delete the object if fast_delete is called without all the attributes (because fast_delete doesn't ensure any data integrity)" do
|
18
|
+
data = {'1' => @product1, '2' => @product2, '3' => @product3}
|
19
|
+
delete_data = {'3' => {'price' => '1.99'}}
|
20
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
21
|
+
set_state(@s.docname(:md) => data,@s.docname(:md_size) => '3')
|
22
|
+
post "/api/fast_delete", :api_token => @api_token,
|
23
|
+
:user_id => @u.id, :source_id => @s_fields[:name], :data => delete_data
|
24
|
+
last_response.should be_ok
|
25
|
+
verify_result(@s.docname(:md) => data,@s.docname(:md_size)=>'2')
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'api_helper')
|
2
|
+
|
3
|
+
describe "RhoconnectApiFastInsert" do
|
4
|
+
it_should_behave_like "ApiHelper"
|
5
|
+
|
6
|
+
it "should append new objects to rhosync's :md" do
|
7
|
+
data = {'1' => @product1, '2' => @product2}
|
8
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
9
|
+
set_state(@s.docname(:md) => data,@s.docname(:md_size) => '2')
|
10
|
+
post "/api/fast_insert", :api_token => @api_token,
|
11
|
+
:user_id => @u.id, :source_id => @s_fields[:name], :data => {'3' => @product3}
|
12
|
+
last_response.should be_ok
|
13
|
+
data.merge!({'3' => @product3})
|
14
|
+
verify_result(@s.docname(:md) => data,@s.docname(:md_size)=>'3')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should incorrectly append data to existing object (because fast_insert doesn't ensure any data integrity)" do
|
18
|
+
data = {'1' => @product1, '2' => @product2, '3' => @product3}
|
19
|
+
incorrect_insert = {'3' => {'price' => '1.99', 'new_field' => 'value'}}
|
20
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
21
|
+
set_state(@s.docname(:md) => data,@s.docname(:md_size) => '3')
|
22
|
+
post "/api/fast_insert", :api_token => @api_token,
|
23
|
+
:user_id => @u.id, :source_id => @s_fields[:name], :data => incorrect_insert
|
24
|
+
last_response.should be_ok
|
25
|
+
data['3'].merge!(incorrect_insert['3'])
|
26
|
+
verify_result(@s.docname(:md) => data,@s.docname(:md_size)=>'4')
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'api_helper')
|
2
|
+
|
3
|
+
describe "RhoconnectApiFastUpdate" do
|
4
|
+
it_should_behave_like "ApiHelper"
|
5
|
+
|
6
|
+
it "should update an attribute and add new one for an object in rhosync's :md" do
|
7
|
+
data = {'1' => @product1, '2' => @product2, '3' => @product3}
|
8
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
9
|
+
set_state(@s.docname(:md) => data,@s.docname(:md_size) => '3')
|
10
|
+
|
11
|
+
orig_obj_attrs = {'3' => {'price' => @product3['price']}}
|
12
|
+
new_obj_attrs = {'3' => {'price' => '0.99', 'new_attr' => 'new_value'}}
|
13
|
+
|
14
|
+
post "/api/fast_update", :api_token => @api_token,
|
15
|
+
:user_id => @u.id, :source_id => @s_fields[:name], :delete_data => orig_obj_attrs, :data => new_obj_attrs
|
16
|
+
last_response.should be_ok
|
17
|
+
data['3'].merge!(new_obj_attrs['3'])
|
18
|
+
verify_result(@s.docname(:md) => data,@s.docname(:md_size)=>'3')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should update one attr, add one attr, and remove one attr for an object in rhosync's :md" do
|
22
|
+
data = {'1' => @product1, '2' => @product2, '3' => @product3}
|
23
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
24
|
+
set_state(@s.docname(:md) => data,@s.docname(:md_size) => '3')
|
25
|
+
|
26
|
+
orig_obj_attrs = {'3' => {'name' => @product3['name'], 'price' => @product3['price']}}
|
27
|
+
new_obj_attrs = {'3' => {'price' => '0.99', 'new_attr' => 'new_value'}}
|
28
|
+
|
29
|
+
post "/api/fast_update", :api_token => @api_token,
|
30
|
+
:user_id => @u.id, :source_id => @s_fields[:name], :delete_data => orig_obj_attrs, :data => new_obj_attrs
|
31
|
+
last_response.should be_ok
|
32
|
+
data['3'].delete('name')
|
33
|
+
data['3'].merge!(new_obj_attrs['3'])
|
34
|
+
verify_result(@s.docname(:md) => data,@s.docname(:md_size)=>'3')
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should remove all attributes , but leave the count incorrect (because fast_update doesn't check if the whole object is deleted)" do
|
38
|
+
data = {'1' => @product1, '2' => @product2, '3' => @product3}
|
39
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
40
|
+
set_state(@s.docname(:md) => data,@s.docname(:md_size) => '3')
|
41
|
+
|
42
|
+
orig_obj_attrs = {'3' => @product3}
|
43
|
+
new_obj_attrs = {}
|
44
|
+
|
45
|
+
post "/api/fast_update", :api_token => @api_token,
|
46
|
+
:user_id => @u.id, :source_id => @s_fields[:name], :delete_data => orig_obj_attrs, :data => new_obj_attrs
|
47
|
+
last_response.should be_ok
|
48
|
+
data.delete('3')
|
49
|
+
verify_result(@s.docname(:md) => data,@s.docname(:md_size)=>'3')
|
50
|
+
end
|
51
|
+
end
|
data/spec/api/stats_spec.rb
CHANGED
@@ -9,10 +9,12 @@ describe "RhosyncApiStats" do
|
|
9
9
|
|
10
10
|
before(:each) do
|
11
11
|
Rhosync::Server.set :stats, true
|
12
|
+
Rhosync.stats = true
|
12
13
|
end
|
13
14
|
|
14
15
|
after(:each) do
|
15
16
|
Rhosync::Server.set :stats, false
|
17
|
+
Rhosync.stats = false
|
16
18
|
end
|
17
19
|
|
18
20
|
it "should retrieve metric names" do
|
data/spec/client_sync_spec.rb
CHANGED
@@ -9,6 +9,9 @@ describe "ClientSync" do
|
|
9
9
|
lambda { ClientSync.new(nil,@c,2) }.should raise_error(ArgumentError,'Unknown source')
|
10
10
|
end
|
11
11
|
|
12
|
+
let(:mock_schema) { {"property" => { "name" => "string", "brand" => "string" }, "version" => "1.0"} }
|
13
|
+
let(:sha1) { get_sha1(mock_schema['version']) }
|
14
|
+
|
12
15
|
before(:each) do
|
13
16
|
@s = Source.load(@s_fields[:name],@s_params)
|
14
17
|
@cs = ClientSync.new(@s,@c,2)
|
@@ -372,7 +375,6 @@ describe "ClientSync" do
|
|
372
375
|
token1.should be_nil
|
373
376
|
Store.get_data(@c.docname(:search)).should == {}
|
374
377
|
end
|
375
|
-
|
376
378
|
end
|
377
379
|
|
378
380
|
describe "page methods" do
|
@@ -380,10 +382,20 @@ describe "ClientSync" do
|
|
380
382
|
Store.put_data(@s.docname(:md),@data).should == true
|
381
383
|
Store.get_data(@s.docname(:md)).should == @data
|
382
384
|
Store.put_value(@s.docname(:md_size),@data.size)
|
383
|
-
|
384
|
-
@cs.compute_page
|
385
|
+
|
386
|
+
progress_count, total_count, res = @cs.compute_page
|
387
|
+
progress_count.to_i.should == 0
|
388
|
+
total_count.to_i.should == 3
|
389
|
+
res.each do |key, value|
|
390
|
+
@data.has_key?(key).should == true
|
391
|
+
@data[key].should == value
|
392
|
+
end
|
393
|
+
|
385
394
|
Store.get_value(@cs.client.docname(:cd_size)).to_i.should == 0
|
386
|
-
Store.get_data(@cs.client.docname(:page)).
|
395
|
+
Store.get_data(@cs.client.docname(:page)).each do |key, value|
|
396
|
+
@data.has_key?(key).should == true
|
397
|
+
@data[key].should == value
|
398
|
+
end
|
387
399
|
end
|
388
400
|
|
389
401
|
it "appends diff to the client document" do
|
@@ -483,7 +495,7 @@ describe "ClientSync" do
|
|
483
495
|
token = @c.get_value(:page_token)
|
484
496
|
result.should == [{"version"=>ClientSync::VERSION},{"token"=>token},
|
485
497
|
{"count"=>1}, {"progress_count"=>0},{"total_count"=>1},{'insert'=>expected}]
|
486
|
-
@c.get_value(:schema_sha1).should ==
|
498
|
+
@c.get_value(:schema_sha1).should == sha1
|
487
499
|
end
|
488
500
|
end
|
489
501
|
|
@@ -494,8 +506,8 @@ describe "ClientSync" do
|
|
494
506
|
token = @c.get_value(:page_token)
|
495
507
|
result.should == [{"version"=>ClientSync::VERSION},{"token"=>token},
|
496
508
|
{"count"=>0}, {"progress_count"=>0},{"total_count"=>0},{'schema-changed'=>'true'}]
|
497
|
-
@c.get_value(:schema_page).should ==
|
498
|
-
@c.get_value(:schema_sha1).should ==
|
509
|
+
@c.get_value(:schema_page).should == sha1
|
510
|
+
@c.get_value(:schema_sha1).should == sha1
|
499
511
|
end
|
500
512
|
end
|
501
513
|
|
@@ -506,8 +518,8 @@ describe "ClientSync" do
|
|
506
518
|
token = @c.get_value(:page_token)
|
507
519
|
@cs.send_cud.should == [{"version"=>ClientSync::VERSION},{"token"=>token},
|
508
520
|
{"count"=>0}, {"progress_count"=>0},{"total_count"=>0},{'schema-changed'=>'true'}]
|
509
|
-
@c.get_value(:schema_page).should ==
|
510
|
-
@c.get_value(:schema_sha1).should ==
|
521
|
+
@c.get_value(:schema_page).should == sha1
|
522
|
+
@c.get_value(:schema_sha1).should == sha1
|
511
523
|
end
|
512
524
|
end
|
513
525
|
|
@@ -519,7 +531,7 @@ describe "ClientSync" do
|
|
519
531
|
@cs.send_cud(token).should == [{"version"=>ClientSync::VERSION},{"token"=>""},
|
520
532
|
{"count"=>0}, {"progress_count"=>0},{"total_count"=>0},{}]
|
521
533
|
@c.get_value(:schema_page).should be_nil
|
522
|
-
@c.get_value(:schema_sha1).should ==
|
534
|
+
@c.get_value(:schema_sha1).should == sha1
|
523
535
|
end
|
524
536
|
end
|
525
537
|
|
@@ -538,7 +550,7 @@ describe "ClientSync" do
|
|
538
550
|
@cs.send_cud(token).should == [{"version"=>ClientSync::VERSION},{"token"=>""},
|
539
551
|
{"count"=>0}, {"progress_count"=>0},{"total_count"=>0},{}]
|
540
552
|
@c.get_value(:schema_page).should be_nil
|
541
|
-
@c.get_value(:schema_sha1).should ==
|
553
|
+
@c.get_value(:schema_sha1).should == sha1
|
542
554
|
data = BulkData.load(docname)
|
543
555
|
data.refresh_time.should <= Time.now.to_i
|
544
556
|
end
|
@@ -574,6 +586,7 @@ describe "ClientSync" do
|
|
574
586
|
set_state('test_db_storage' => @data)
|
575
587
|
ClientSync.bulk_data(:user,@c)
|
576
588
|
BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,@u.id))
|
589
|
+
BulkDataJob.after_perform_x("data_name" => bulk_data_docname(@a.id,@u.id))
|
577
590
|
ClientSync.bulk_data(:user,@c).should == {:result => :url,
|
578
591
|
:url => BulkData.load(bulk_data_docname(@a.id,@u.id)).url}
|
579
592
|
verify_result(
|
@@ -581,6 +594,18 @@ describe "ClientSync" do
|
|
581
594
|
"source:#{@a_fields[:name]}:#{@u_fields[:login]}:#{@s_fields[:name]}:md" => @data,
|
582
595
|
"source:#{@a_fields[:name]}:#{@u_fields[:login]}:#{@s_fields[:name]}:md_copy" => @data)
|
583
596
|
end
|
597
|
+
|
598
|
+
it "should return empty bulk data url if there are errors in query" do
|
599
|
+
ClientSync.bulk_data(:user,@c)
|
600
|
+
BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,@u.id))
|
601
|
+
BulkDataJob.after_perform_x("data_name" => bulk_data_docname(@a.id,@u.id))
|
602
|
+
errordoc = @s.docname(:errors) # source SampleAdapter
|
603
|
+
operation = 'query'
|
604
|
+
Store.lock(errordoc) do
|
605
|
+
Store.put_data(errordoc,{"#{operation}-error"=>{'message'=>"Some exception message"}}, true)
|
606
|
+
end
|
607
|
+
ClientSync.bulk_data(:user,@c).should == {:result => :url, :url => ''}
|
608
|
+
end
|
584
609
|
|
585
610
|
it "should escape bulk data url" do
|
586
611
|
name = 'a b'
|
@@ -590,6 +615,7 @@ describe "ClientSync" do
|
|
590
615
|
:user_id => name,
|
591
616
|
:sources => [@s_fields[:name]])
|
592
617
|
BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,name))
|
618
|
+
BulkDataJob.after_perform_x("data_name" => bulk_data_docname(@a.id,name))
|
593
619
|
data = BulkData.load(bulk_data_docname(@a.id,name))
|
594
620
|
data.url.should match /a%20b/
|
595
621
|
data.delete
|
@@ -600,6 +626,7 @@ describe "ClientSync" do
|
|
600
626
|
@s.partition = :app
|
601
627
|
ClientSync.bulk_data(:app,@c)
|
602
628
|
BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,"*"))
|
629
|
+
BulkDataJob.after_perform_x("data_name" => bulk_data_docname(@a.id,"*"))
|
603
630
|
ClientSync.bulk_data(:app,@c).should == {:result => :url,
|
604
631
|
:url => BulkData.load(bulk_data_docname(@a.id,"*")).url}
|
605
632
|
verify_result(
|
@@ -613,6 +640,7 @@ describe "ClientSync" do
|
|
613
640
|
@s.sync_type = :bulk_sync_only
|
614
641
|
ClientSync.bulk_data(:user,@c)
|
615
642
|
BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,@u.id))
|
643
|
+
BulkDataJob.after_perform_x("data_name" => bulk_data_docname(@a.id,@u.id))
|
616
644
|
ClientSync.bulk_data(:user,@c).should == {:result => :url,
|
617
645
|
:url => BulkData.load(bulk_data_docname(@a.id,@u.id)).url}
|
618
646
|
verify_result(
|
@@ -626,6 +654,7 @@ describe "ClientSync" do
|
|
626
654
|
Rhosync.blackberry_bulk_sync = true
|
627
655
|
ClientSync.bulk_data(:user,@c)
|
628
656
|
BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,@u.id))
|
657
|
+
BulkDataJob.after_perform_x("data_name" => bulk_data_docname(@a.id,@u.id))
|
629
658
|
data = BulkData.load(bulk_data_docname(@a.id,@u.id))
|
630
659
|
ClientSync.bulk_data(:user,@c).should == {:result => :url, :url => data.url}
|
631
660
|
File.delete(data.dbfile)
|
@@ -12,6 +12,8 @@ describe "BulkDataJob" do
|
|
12
12
|
delete_data_directory
|
13
13
|
end
|
14
14
|
|
15
|
+
let(:mock_schema) { {"property" => { "name" => "string", "brand" => "string" }, "version" => "1.0"} }
|
16
|
+
|
15
17
|
it "should create bulk data files from master document" do
|
16
18
|
set_state('test_db_storage' => @data)
|
17
19
|
docname = bulk_data_docname(@a.id,@u.id)
|
@@ -24,6 +26,7 @@ describe "BulkDataJob" do
|
|
24
26
|
:user_id => @u.id,
|
25
27
|
:sources => [@s_fields[:name], 'FixedSchemaAdapter'])
|
26
28
|
BulkDataJob.perform("data_name" => data.name)
|
29
|
+
BulkDataJob.after_perform_x("data_name" => data.name)
|
27
30
|
data = BulkData.load(docname)
|
28
31
|
data.completed?.should == true
|
29
32
|
verify_result(@s.docname(:md) => @data,@s.docname(:md_copy) => @data)
|
@@ -51,6 +54,7 @@ describe "BulkDataJob" do
|
|
51
54
|
:user_id => @u.id,
|
52
55
|
:sources => [@s_fields[:name]])
|
53
56
|
BulkDataJob.perform("data_name" => data.name)
|
57
|
+
BulkDataJob.after_perform_x("data_name" => data.name)
|
54
58
|
data = BulkData.load(docname)
|
55
59
|
data.completed?.should == true
|
56
60
|
verify_result(@s.docname(:md) => @data,@s.docname(:md_copy) => @data)
|
@@ -69,6 +73,7 @@ describe "BulkDataJob" do
|
|
69
73
|
:user_id => @u.id,
|
70
74
|
:sources => [@s_fields[:name]])
|
71
75
|
BulkDataJob.perform("data_name" => data.name)
|
76
|
+
BulkDataJob.after_perform_x("data_name" => data.name)
|
72
77
|
data = BulkData.load(docname)
|
73
78
|
data.completed?.should == true
|
74
79
|
verify_result(@s.docname(:md) => @data,
|
@@ -88,11 +93,11 @@ describe "BulkDataJob" do
|
|
88
93
|
:user_id => @u.id,
|
89
94
|
:sources => [@s_fields[:name]])
|
90
95
|
BulkDataJob.perform("data_name" => data.name)
|
96
|
+
BulkDataJob.after_perform_x("data_name" => data.name)
|
91
97
|
data = BulkData.load(docname)
|
92
98
|
data.completed?.should == true
|
93
|
-
verify_result(@s.docname(:md) => @data,
|
94
|
-
|
95
|
-
@s.docname(:md_copy) => @data)
|
99
|
+
verify_result(@s.docname(:md) => @data, @s.docname(:md_copy) => @data)
|
100
|
+
JSON.parse(Store.get_value(@s.docname(:schema))).should == mock_schema
|
96
101
|
validate_db(data,@s.name => @data).should == true
|
97
102
|
end
|
98
103
|
end
|
@@ -108,7 +113,9 @@ describe "BulkDataJob" do
|
|
108
113
|
end
|
109
114
|
|
110
115
|
it "should delete bulk data if exception is raised" do
|
111
|
-
lambda {
|
116
|
+
lambda {
|
117
|
+
BulkDataJob.perform("data_name" => 'broken')
|
118
|
+
BulkDataJob.after_perform_x("data_name" => data.name) }.should raise_error(Exception)
|
112
119
|
Store.db.keys('bulk_data*').should == []
|
113
120
|
end
|
114
121
|
|
@@ -118,7 +125,9 @@ describe "BulkDataJob" do
|
|
118
125
|
:app_id => 'broken',
|
119
126
|
:user_id => @u.id,
|
120
127
|
:sources => [@s_fields[:name]])
|
121
|
-
lambda {
|
128
|
+
lambda {
|
129
|
+
BulkDataJob.perform("data_name" => data.name)
|
130
|
+
BulkDataJob.after_perform_x("data_name" => data.name) }.should raise_error(Exception)
|
122
131
|
Store.db.keys('bulk_data*').should == []
|
123
132
|
end
|
124
133
|
end
|
@@ -27,6 +27,7 @@ describe "BulkData Performance" do
|
|
27
27
|
:user_id => @u.id,
|
28
28
|
:sources => [@s_fields[:name]])
|
29
29
|
BulkDataJob.perform("data_name" => data.name)
|
30
|
+
BulkDataJob.after_perform_x("data_name" => data.name)
|
30
31
|
lap_timer('BulkDataJob.perform duration',start)
|
31
32
|
end
|
32
33
|
end
|
data/spec/ping/apple_spec.rb
CHANGED
@@ -41,18 +41,24 @@ describe "Ping Apple" do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should compute apn_message" do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
expected_hash = {
|
45
|
+
"aps"=>{"vibrate"=>"5", "badge"=>5, "alert"=>"hello world", "sound"=>"hello.mp3"},
|
46
|
+
"do_sync"=>["SampleAdapter"]
|
47
|
+
}
|
48
|
+
apn_message = Apple.apn_message(@params)
|
49
|
+
apn_message.start_with?("\000\000 \253\315\000g").should be_true
|
50
|
+
JSON.parse(apn_message.sub("\000\000 \253\315\000g","")).should == expected_hash
|
48
51
|
end
|
49
52
|
|
50
53
|
it "should compute apn_message with source array" do
|
51
54
|
@params['sources'] << 'SimpleAdapter'
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
55
|
+
expected_hash = {
|
56
|
+
"aps"=>{"vibrate"=>"5", "badge"=>5, "alert"=>"hello world", "sound"=>"hello.mp3"},
|
57
|
+
"do_sync"=>["SampleAdapter", "SimpleAdapter"]
|
58
|
+
}
|
59
|
+
apn_message = Apple.apn_message(@params)
|
60
|
+
apn_message.start_with?("\000\000 \253\315\000w").should be_true
|
61
|
+
JSON.parse(apn_message.sub("\000\000 \253\315\000w","")).should == expected_hash
|
56
62
|
end
|
57
63
|
|
58
64
|
it "should raise SocketError if socket fails" do
|
data/spec/server/server_spec.rb
CHANGED
@@ -70,14 +70,6 @@ describe "Server" do
|
|
70
70
|
Rhosync::Server.secret.should == "secure!"
|
71
71
|
end
|
72
72
|
|
73
|
-
it "should use Stats::Middleware if stats enabled" do
|
74
|
-
Rhosync::Server.enable :stats
|
75
|
-
Rhosync::Server.new
|
76
|
-
Rhosync.stats.should == true
|
77
|
-
Rhosync.stats = nil
|
78
|
-
Rhosync::Server.disable :stats
|
79
|
-
end
|
80
|
-
|
81
73
|
it "should update session secret to default" do
|
82
74
|
Rhosync::Server.set :secret, "<changeme>"
|
83
75
|
Rhosync::Server.secret.should == "<changeme>"
|
@@ -380,6 +372,7 @@ describe "Server" do
|
|
380
372
|
set_state('test_db_storage' => @data)
|
381
373
|
get "/application/bulk_data", :partition => :user, :client_id => @c.id
|
382
374
|
BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,@u.id))
|
375
|
+
BulkDataJob.after_perform_x("data_name" => bulk_data_docname(@a.id,@u.id))
|
383
376
|
get "/application/bulk_data", :partition => :user, :client_id => @c.id
|
384
377
|
last_response.should be_ok
|
385
378
|
data = BulkData.load(bulk_data_docname(@a.id,@u.id))
|
@@ -392,6 +385,7 @@ describe "Server" do
|
|
392
385
|
set_state('test_db_storage' => @data)
|
393
386
|
get "/application/bulk_data", :partition => :user, :client_id => @c.id
|
394
387
|
BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,@u.id))
|
388
|
+
BulkDataJob.after_perform_x("data_name" => bulk_data_docname(@a.id,@u.id))
|
395
389
|
get "/application/bulk_data", :partition => :user, :client_id => @c.id
|
396
390
|
get JSON.parse(last_response.body)["url"]
|
397
391
|
last_response.should be_ok
|
data/spec/source_sync_spec.rb
CHANGED
@@ -9,6 +9,8 @@ describe "SourceSync" do
|
|
9
9
|
@ss = SourceSync.new(@s)
|
10
10
|
end
|
11
11
|
|
12
|
+
let(:mock_schema) { {"property" => { "name" => "string", "brand" => "string" }, "version" => "1.0"} }
|
13
|
+
|
12
14
|
it "should create SourceSync" do
|
13
15
|
@ss.adapter.is_a?(SampleAdapter).should == true
|
14
16
|
end
|
@@ -78,12 +80,25 @@ describe "SourceSync" do
|
|
78
80
|
expected = {'1'=>@product1,'2'=>@product2}
|
79
81
|
set_state('test_db_storage' => expected)
|
80
82
|
@ss.process_query
|
81
|
-
verify_result(@s.docname(:md) => expected
|
82
|
-
|
83
|
-
|
83
|
+
verify_result(@s.docname(:md) => expected)
|
84
|
+
JSON.parse(Store.get_value(@s.docname(:schema))).should == mock_schema
|
85
|
+
Store.get_value(@s.docname(:schema_sha1)).should == get_sha1(mock_schema['version'])
|
84
86
|
end
|
85
87
|
end
|
86
|
-
|
88
|
+
|
89
|
+
it "should raise exception if source adapter schema has no version key/value pair" do
|
90
|
+
mock_schema_no_version_method([SampleAdapter]) do
|
91
|
+
expected = {'1'=>@product1,'2'=>@product2}
|
92
|
+
set_state('test_db_storage' => expected)
|
93
|
+
@ss.process_query
|
94
|
+
errordoc = @s.docname(:errors)
|
95
|
+
errors = {}
|
96
|
+
Store.lock(errordoc) { errors = Store.get_data(errordoc) }
|
97
|
+
errors.empty?().should == false
|
98
|
+
errors["query-error"]["message"].should == "Mandatory version key is not defined in source adapter schema method"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
87
102
|
it "should process source adapter with stash" do
|
88
103
|
expected = {'1'=>@product1,'2'=>@product2}
|
89
104
|
set_state('test_db_storage' => expected)
|
@@ -152,7 +167,6 @@ describe "SourceSync" do
|
|
152
167
|
verify_result(
|
153
168
|
@c.docname(:update_errors) =>
|
154
169
|
{"#{ERROR}-error"=>{"message"=>msg}, ERROR=>data[ERROR]},
|
155
|
-
@c.docname(:update) => {'4'=> { 'price' => '199.99'}},
|
156
170
|
@c.docname(:update_rollback) => {ERROR=>{"price"=>"99.99"}})
|
157
171
|
end
|
158
172
|
end
|
@@ -174,9 +188,7 @@ describe "SourceSync" do
|
|
174
188
|
data = add_error_object({'2'=>@product2},msg)
|
175
189
|
set_state(@c.docname(:delete) => data)
|
176
190
|
@ss.delete(@c.id)
|
177
|
-
verify_result(@c.docname(:delete_errors) =>
|
178
|
-
{"#{ERROR}-error"=>{"message"=>msg}, ERROR=>data[ERROR]},
|
179
|
-
@c.docname(:delete) => {'2'=>@product2})
|
191
|
+
verify_result(@c.docname(:delete_errors) => {"#{ERROR}-error"=>{"message"=>msg}, ERROR=>data[ERROR]})
|
180
192
|
end
|
181
193
|
end
|
182
194
|
|
data/spec/spec_helper.rb
CHANGED
@@ -194,6 +194,23 @@ module TestHelpers
|
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
|
+
def mock_schema_no_version_method(adapters, &block)
|
198
|
+
adapters.each do |klass|
|
199
|
+
klass.class_eval 'def schema
|
200
|
+
{
|
201
|
+
"property" => {
|
202
|
+
"name" => "string",
|
203
|
+
"brand" => "string"
|
204
|
+
}
|
205
|
+
}.to_json
|
206
|
+
end'
|
207
|
+
end
|
208
|
+
yield
|
209
|
+
adapters.each do |klass|
|
210
|
+
klass.class_eval "def schema; end"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
197
214
|
def unzip_file(file,file_dir)
|
198
215
|
Zip::ZipFile.open(file) do |zip_file|
|
199
216
|
zip_file.each do |f|
|
@@ -203,6 +220,11 @@ module TestHelpers
|
|
203
220
|
end
|
204
221
|
end
|
205
222
|
end
|
223
|
+
|
224
|
+
def get_sha1(str)
|
225
|
+
Digest::SHA1.hexdigest(str)
|
226
|
+
end
|
227
|
+
|
206
228
|
end #TestHelpers
|
207
229
|
|
208
230
|
describe "RhosyncHelper", :shared => true do
|
@@ -1,4 +1,7 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','spec_helper')
|
2
|
+
require File.join(File.dirname(__FILE__),'..','..','lib','rhosync','server.rb')
|
1
3
|
require 'rhosync'
|
4
|
+
|
2
5
|
STATS_RECORD_RESOLUTION = 2 unless defined? STATS_RECORD_RESOLUTION
|
3
6
|
STATS_RECORD_SIZE = 8 unless defined? STATS_RECORD_SIZE
|
4
7
|
|
@@ -12,10 +15,17 @@ describe "Middleware" do
|
|
12
15
|
Store.db.flushdb
|
13
16
|
app = mock('app')
|
14
17
|
app.stub!(:call)
|
18
|
+
Rhosync.stats = true
|
19
|
+
Rhosync::Server.enable :stats
|
15
20
|
@middleware = Middleware.new(app)
|
16
21
|
Store.stub!(:lock).and_yield
|
17
22
|
end
|
18
|
-
|
23
|
+
|
24
|
+
after(:each) do
|
25
|
+
Rhosync.stats = false
|
26
|
+
Rhosync::Server.disable :stats
|
27
|
+
end
|
28
|
+
|
19
29
|
it "should compute http average" do
|
20
30
|
Time.stub!(:now).and_return { @now += 0.3; @now }
|
21
31
|
env = {
|
metadata
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rhosync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 391570199
|
5
|
+
prerelease: 7
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
|
9
|
+
- 17
|
10
|
+
- beta
|
11
|
+
- 1
|
12
|
+
version: 2.1.17.beta1
|
11
13
|
platform: ruby
|
12
14
|
authors:
|
13
15
|
- Rhomobile
|
@@ -15,28 +17,12 @@ autorequire:
|
|
15
17
|
bindir: bin
|
16
18
|
cert_chain: []
|
17
19
|
|
18
|
-
date: 2012-
|
20
|
+
date: 2012-04-24 00:00:00 Z
|
19
21
|
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
21
|
-
name: rack
|
22
|
-
prerelease: false
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
-
none: false
|
25
|
-
requirements:
|
26
|
-
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 23
|
29
|
-
segments:
|
30
|
-
- 1
|
31
|
-
- 3
|
32
|
-
- 6
|
33
|
-
version: 1.3.6
|
34
|
-
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
22
|
- !ruby/object:Gem::Dependency
|
37
23
|
name: sinatra
|
38
24
|
prerelease: false
|
39
|
-
requirement: &
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
40
26
|
none: false
|
41
27
|
requirements:
|
42
28
|
- - ~>
|
@@ -48,11 +34,11 @@ dependencies:
|
|
48
34
|
- 1
|
49
35
|
version: 1.3.1
|
50
36
|
type: :runtime
|
51
|
-
version_requirements: *
|
37
|
+
version_requirements: *id001
|
52
38
|
- !ruby/object:Gem::Dependency
|
53
39
|
name: json
|
54
40
|
prerelease: false
|
55
|
-
requirement: &
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
56
42
|
none: false
|
57
43
|
requirements:
|
58
44
|
- - ~>
|
@@ -64,11 +50,11 @@ dependencies:
|
|
64
50
|
- 2
|
65
51
|
version: 1.4.2
|
66
52
|
type: :runtime
|
67
|
-
version_requirements: *
|
53
|
+
version_requirements: *id002
|
68
54
|
- !ruby/object:Gem::Dependency
|
69
55
|
name: sqlite3-ruby
|
70
56
|
prerelease: false
|
71
|
-
requirement: &
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
72
58
|
none: false
|
73
59
|
requirements:
|
74
60
|
- - ~>
|
@@ -80,11 +66,11 @@ dependencies:
|
|
80
66
|
- 5
|
81
67
|
version: 1.2.5
|
82
68
|
type: :runtime
|
83
|
-
version_requirements: *
|
69
|
+
version_requirements: *id003
|
84
70
|
- !ruby/object:Gem::Dependency
|
85
71
|
name: rubyzip
|
86
72
|
prerelease: false
|
87
|
-
requirement: &
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
88
74
|
none: false
|
89
75
|
requirements:
|
90
76
|
- - ~>
|
@@ -96,11 +82,11 @@ dependencies:
|
|
96
82
|
- 4
|
97
83
|
version: 0.9.4
|
98
84
|
type: :runtime
|
99
|
-
version_requirements: *
|
85
|
+
version_requirements: *id004
|
100
86
|
- !ruby/object:Gem::Dependency
|
101
87
|
name: uuidtools
|
102
88
|
prerelease: false
|
103
|
-
requirement: &
|
89
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
104
90
|
none: false
|
105
91
|
requirements:
|
106
92
|
- - ">="
|
@@ -112,11 +98,11 @@ dependencies:
|
|
112
98
|
- 1
|
113
99
|
version: 2.1.1
|
114
100
|
type: :runtime
|
115
|
-
version_requirements: *
|
101
|
+
version_requirements: *id005
|
116
102
|
- !ruby/object:Gem::Dependency
|
117
103
|
name: redis
|
118
104
|
prerelease: false
|
119
|
-
requirement: &
|
105
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
120
106
|
none: false
|
121
107
|
requirements:
|
122
108
|
- - ~>
|
@@ -128,11 +114,11 @@ dependencies:
|
|
128
114
|
- 1
|
129
115
|
version: 2.1.1
|
130
116
|
type: :runtime
|
131
|
-
version_requirements: *
|
117
|
+
version_requirements: *id006
|
132
118
|
- !ruby/object:Gem::Dependency
|
133
119
|
name: resque
|
134
120
|
prerelease: false
|
135
|
-
requirement: &
|
121
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
136
122
|
none: false
|
137
123
|
requirements:
|
138
124
|
- - ~>
|
@@ -144,11 +130,11 @@ dependencies:
|
|
144
130
|
- 0
|
145
131
|
version: 1.14.0
|
146
132
|
type: :runtime
|
147
|
-
version_requirements: *
|
133
|
+
version_requirements: *id007
|
148
134
|
- !ruby/object:Gem::Dependency
|
149
135
|
name: rest-client
|
150
136
|
prerelease: false
|
151
|
-
requirement: &
|
137
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
152
138
|
none: false
|
153
139
|
requirements:
|
154
140
|
- - ~>
|
@@ -160,11 +146,11 @@ dependencies:
|
|
160
146
|
- 1
|
161
147
|
version: 1.6.1
|
162
148
|
type: :runtime
|
163
|
-
version_requirements: *
|
149
|
+
version_requirements: *id008
|
164
150
|
- !ruby/object:Gem::Dependency
|
165
151
|
name: templater
|
166
152
|
prerelease: false
|
167
|
-
requirement: &
|
153
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
168
154
|
none: false
|
169
155
|
requirements:
|
170
156
|
- - ~>
|
@@ -176,11 +162,11 @@ dependencies:
|
|
176
162
|
- 0
|
177
163
|
version: 1.0.0
|
178
164
|
type: :runtime
|
179
|
-
version_requirements: *
|
165
|
+
version_requirements: *id009
|
180
166
|
- !ruby/object:Gem::Dependency
|
181
167
|
name: rake
|
182
168
|
prerelease: false
|
183
|
-
requirement: &
|
169
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
184
170
|
none: false
|
185
171
|
requirements:
|
186
172
|
- - ~>
|
@@ -193,11 +179,11 @@ dependencies:
|
|
193
179
|
- 2
|
194
180
|
version: 0.9.2.2
|
195
181
|
type: :runtime
|
196
|
-
version_requirements: *
|
182
|
+
version_requirements: *id010
|
197
183
|
- !ruby/object:Gem::Dependency
|
198
184
|
name: log4r
|
199
185
|
prerelease: false
|
200
|
-
requirement: &
|
186
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
201
187
|
none: false
|
202
188
|
requirements:
|
203
189
|
- - ~>
|
@@ -209,11 +195,11 @@ dependencies:
|
|
209
195
|
- 7
|
210
196
|
version: 1.1.7
|
211
197
|
type: :development
|
212
|
-
version_requirements: *
|
198
|
+
version_requirements: *id011
|
213
199
|
- !ruby/object:Gem::Dependency
|
214
200
|
name: jeweler
|
215
201
|
prerelease: false
|
216
|
-
requirement: &
|
202
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
217
203
|
none: false
|
218
204
|
requirements:
|
219
205
|
- - ">="
|
@@ -225,11 +211,11 @@ dependencies:
|
|
225
211
|
- 0
|
226
212
|
version: 1.4.0
|
227
213
|
type: :development
|
228
|
-
version_requirements: *
|
214
|
+
version_requirements: *id012
|
229
215
|
- !ruby/object:Gem::Dependency
|
230
216
|
name: rspec
|
231
217
|
prerelease: false
|
232
|
-
requirement: &
|
218
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
233
219
|
none: false
|
234
220
|
requirements:
|
235
221
|
- - ">="
|
@@ -241,11 +227,11 @@ dependencies:
|
|
241
227
|
- 0
|
242
228
|
version: 1.3.0
|
243
229
|
type: :development
|
244
|
-
version_requirements: *
|
230
|
+
version_requirements: *id013
|
245
231
|
- !ruby/object:Gem::Dependency
|
246
232
|
name: rcov
|
247
233
|
prerelease: false
|
248
|
-
requirement: &
|
234
|
+
requirement: &id014 !ruby/object:Gem::Requirement
|
249
235
|
none: false
|
250
236
|
requirements:
|
251
237
|
- - ">="
|
@@ -257,11 +243,11 @@ dependencies:
|
|
257
243
|
- 8
|
258
244
|
version: 0.9.8
|
259
245
|
type: :development
|
260
|
-
version_requirements: *
|
246
|
+
version_requirements: *id014
|
261
247
|
- !ruby/object:Gem::Dependency
|
262
248
|
name: faker
|
263
249
|
prerelease: false
|
264
|
-
requirement: &
|
250
|
+
requirement: &id015 !ruby/object:Gem::Requirement
|
265
251
|
none: false
|
266
252
|
requirements:
|
267
253
|
- - ">="
|
@@ -273,11 +259,11 @@ dependencies:
|
|
273
259
|
- 1
|
274
260
|
version: 0.3.1
|
275
261
|
type: :development
|
276
|
-
version_requirements: *
|
262
|
+
version_requirements: *id015
|
277
263
|
- !ruby/object:Gem::Dependency
|
278
264
|
name: rack-test
|
279
265
|
prerelease: false
|
280
|
-
requirement: &
|
266
|
+
requirement: &id016 !ruby/object:Gem::Requirement
|
281
267
|
none: false
|
282
268
|
requirements:
|
283
269
|
- - ">="
|
@@ -289,11 +275,11 @@ dependencies:
|
|
289
275
|
- 3
|
290
276
|
version: 0.5.3
|
291
277
|
type: :development
|
292
|
-
version_requirements: *
|
278
|
+
version_requirements: *id016
|
293
279
|
- !ruby/object:Gem::Dependency
|
294
280
|
name: thor
|
295
281
|
prerelease: false
|
296
|
-
requirement: &
|
282
|
+
requirement: &id017 !ruby/object:Gem::Requirement
|
297
283
|
none: false
|
298
284
|
requirements:
|
299
285
|
- - ">="
|
@@ -305,7 +291,7 @@ dependencies:
|
|
305
291
|
- 6
|
306
292
|
version: 0.13.6
|
307
293
|
type: :development
|
308
|
-
version_requirements: *
|
294
|
+
version_requirements: *id017
|
309
295
|
description: RhoSync Synchronization Framework and related command-line utilities
|
310
296
|
email: dev@rhomobile.com
|
311
297
|
executables:
|
@@ -368,6 +354,9 @@ files:
|
|
368
354
|
- lib/rhosync/api/create_user.rb
|
369
355
|
- lib/rhosync/api/delete_client.rb
|
370
356
|
- lib/rhosync/api/delete_user.rb
|
357
|
+
- lib/rhosync/api/fast_delete.rb
|
358
|
+
- lib/rhosync/api/fast_insert.rb
|
359
|
+
- lib/rhosync/api/fast_update.rb
|
371
360
|
- lib/rhosync/api/get_api_token.rb
|
372
361
|
- lib/rhosync/api/get_client_params.rb
|
373
362
|
- lib/rhosync/api/get_db_doc.rb
|
@@ -484,6 +473,9 @@ files:
|
|
484
473
|
- spec/api/create_user_spec.rb
|
485
474
|
- spec/api/delete_client_spec.rb
|
486
475
|
- spec/api/delete_user_spec.rb
|
476
|
+
- spec/api/fast_delete_spec.rb
|
477
|
+
- spec/api/fast_insert_spec.rb
|
478
|
+
- spec/api/fast_update_spec.rb
|
487
479
|
- spec/api/get_api_token_spec.rb
|
488
480
|
- spec/api/get_client_params_spec.rb
|
489
481
|
- spec/api/get_db_doc_spec.rb
|
@@ -579,16 +571,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
579
571
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
580
572
|
none: false
|
581
573
|
requirements:
|
582
|
-
- - "
|
574
|
+
- - ">"
|
583
575
|
- !ruby/object:Gem::Version
|
584
|
-
hash:
|
576
|
+
hash: 25
|
585
577
|
segments:
|
586
|
-
-
|
587
|
-
|
578
|
+
- 1
|
579
|
+
- 3
|
580
|
+
- 1
|
581
|
+
version: 1.3.1
|
588
582
|
requirements: []
|
589
583
|
|
590
584
|
rubyforge_project:
|
591
|
-
rubygems_version: 1.8.
|
585
|
+
rubygems_version: 1.8.20
|
592
586
|
signing_key:
|
593
587
|
specification_version: 3
|
594
588
|
summary: RhoSync Synchronization Framework
|