nd_sync 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cce675682e7a7f0a78a93f0f5be783107e690078
4
- data.tar.gz: c3212526ae9ad9d056df3b35d0d37817b1a0893b
3
+ metadata.gz: 1d0aed4d787144688f5724075f552fb90d6ea48e
4
+ data.tar.gz: 2b3f8eda58da146fa9430948f37319c67ab41942
5
5
  SHA512:
6
- metadata.gz: bbe4e79761a011dbe646caa7aac31abfaa0ace18d9db64195ba7650f601f788b0a1066e6bb5f211e50088199344cad039ed6954b82669179a44f5efb4cd1b864
7
- data.tar.gz: 4754b12c29103a7eda38961ec44e1342561a1a60916779d3b19fa5876d55c23dbbf42499fb9865ecc11ccc724d51db86af80e829514683c7d361cf25b3366094
6
+ metadata.gz: ce0c50d0c5fef26e25a8ca16115cb000991425b7c87197714561eeebe7cef451fa7cc38061c1b80e48d59ad815d52e01123fcc608cee9ae97ce4c84b27584aa2
7
+ data.tar.gz: 31bb939ebbf10114342493b1d71a73894e8a885a4084c03f0f2127aecfef4807b93d0be071004b3d197dbe917cfaf676b8a384d54d7955aa3c10e6377942ec7d
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'sqlite3'
7
+ gem 'webmock'
8
+ end
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ nd_sync (0.0.1)
5
+ activerecord (~> 3)
6
+ activeresource (~> 3)
7
+ activesupport (~> 3)
8
+ jbuilder (~> 2.0)
9
+ nd_transcriber (~> 0.0)
10
+ nd_transmission (~> 0.0)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ activemodel (3.2.17)
16
+ activesupport (= 3.2.17)
17
+ builder (~> 3.0.0)
18
+ activerecord (3.2.17)
19
+ activemodel (= 3.2.17)
20
+ activesupport (= 3.2.17)
21
+ arel (~> 3.0.2)
22
+ tzinfo (~> 0.3.29)
23
+ activeresource (3.2.17)
24
+ activemodel (= 3.2.17)
25
+ activesupport (= 3.2.17)
26
+ activesupport (3.2.17)
27
+ i18n (~> 0.6, >= 0.6.4)
28
+ multi_json (~> 1.0)
29
+ addressable (2.3.6)
30
+ arel (3.0.3)
31
+ builder (3.0.4)
32
+ crack (0.4.2)
33
+ safe_yaml (~> 1.0.0)
34
+ i18n (0.6.11)
35
+ jbuilder (2.0.6)
36
+ activesupport (>= 3.0.0, < 5)
37
+ multi_json (~> 1.2)
38
+ multi_json (1.10.1)
39
+ nd_transcriber (0.0.1)
40
+ nd_transmission (0.0.1)
41
+ safe_yaml (1.0.3)
42
+ sqlite3 (1.3.9)
43
+ tzinfo (0.3.41)
44
+ webmock (1.18.0)
45
+ addressable (>= 2.3.6)
46
+ crack (>= 0.3.2)
47
+
48
+ PLATFORMS
49
+ ruby
50
+
51
+ DEPENDENCIES
52
+ nd_sync!
53
+ sqlite3
54
+ webmock
@@ -0,0 +1,3 @@
1
+ # Transmission
2
+
3
+ Moving objects around using chunks
@@ -0,0 +1,50 @@
1
+ module NdSync
2
+ module Local
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include NdTranscriber
7
+
8
+ scope :pending, -> { where('step = desired_step - 1') }
9
+ scope :synched, -> { where('step = desired_step') }
10
+
11
+ def model_object
12
+ model_class.find(origin_id)
13
+ end
14
+
15
+ def model_class
16
+ @model_class ||= Class.new(ActiveRecord::Base)
17
+ @model_class.table_name = origin_table
18
+ @model_class.primary_key = origin_id_field
19
+ @model_class
20
+ end
21
+
22
+ def transmitted_to web
23
+ updates = {}
24
+
25
+ if web.try(:errors).try(:any?)
26
+ updates[origin_step_field] = -1
27
+ else
28
+ updates[origin_step_field] = desired_step
29
+ updates[:web_id] = web.id if web.id && respond_to?(:web_id)
30
+ end
31
+
32
+ model_class.where(origin_id_field => origin_id).update_all(updates)
33
+ end
34
+ end
35
+
36
+ module ClassMethods
37
+ def to_transmit
38
+ pending.to_a
39
+ end
40
+
41
+ def receive(collection)
42
+ collection.each do |remote|
43
+ local = transcribe(remote)
44
+ local.save
45
+ remote.transmitted_to(local)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,38 @@
1
+ module NdSync
2
+ module Remote
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include NdTranscriber
7
+
8
+ def transmitted_to(local)
9
+ put("synched/#{local.id}")
10
+ end
11
+
12
+ self.site = NdSync.remote_site
13
+ end
14
+
15
+ module ClassMethods
16
+ def to_transmit
17
+ find(:all, params: { sync_pending: true }).to_a
18
+ end
19
+
20
+ def receive(locals)
21
+ response = post(:batch, {}, to_batch(transcribe_all(locals)))
22
+ JSON.parse(response.body).each_with_index do |remote_hash, idx|
23
+ locals[idx].transmitted_to new(remote_hash)
24
+ end
25
+ end
26
+
27
+ def to_batch(collection)
28
+ Jbuilder.encode do |json|
29
+ json.set! collection_name do
30
+ json.array! collection do |item|
31
+ item.to_batch json
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'nd_sync'
3
+ s.version = '0.0.3'
4
+ s.date = '2014-09-01'
5
+ s.summary = "Synchronizing local and remote objects."
6
+ s.description = "Synchronizes database with RESTful web service."
7
+ s.authors = ["Diego Aguir Selzlein"]
8
+ s.email = 'diegoselzlein@gmail.com'
9
+ s.homepage = 'https://github.com/nerde/nd_sync'
10
+ s.license = 'MIT'
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.require_paths = ["lib"]
14
+
15
+ s.add_dependency("jbuilder" , '~> 2.0')
16
+ s.add_dependency("activesupport" , '~> 3')
17
+ s.add_dependency("activerecord" , '~> 3')
18
+ s.add_dependency("activeresource" , '~> 3')
19
+ s.add_dependency("nd_transcriber" , '~> 0.0')
20
+ s.add_dependency("nd_transmission", '~> 0.0')
21
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ describe NdSync::Local do
4
+ before(:all) do
5
+ class Model < ActiveRecord::Base
6
+ end
7
+
8
+ class View < ActiveRecord::Base
9
+ include NdSync::Local
10
+ attr_accessor :transcribed
11
+
12
+ alias :transcribed? :transcribed
13
+ end
14
+
15
+ Model.connection.create_table :models do |t|
16
+ t.integer :paso
17
+ t.integer :web_id
18
+ end
19
+ Model.connection.create_table :views do |t|
20
+ t.integer :step
21
+ t.integer :desired_step
22
+ t.string :origin_table
23
+ t.string :origin_id_field
24
+ t.string :origin_step_field
25
+ t.integer :origin_id
26
+ end
27
+ end
28
+
29
+ before do
30
+ Model.delete_all
31
+ View.delete_all
32
+ end
33
+
34
+ it "makes transcriber available" do
35
+ View.transcriber do
36
+ self.transcribed = true
37
+ end
38
+
39
+ expect(View.transcribe(nil)).to be_transcribed
40
+ end
41
+
42
+ it "transmits objects where step is desired_step - 1" do
43
+ vi1 = View.create! step: 0, desired_step: 2
44
+ vi2 = View.create! step: 1, desired_step: 2
45
+ vi3 = View.create! step: 2, desired_step: 2
46
+
47
+ pendings = View.to_transmit
48
+
49
+ expect(pendings ).to be_kind_of Array
50
+ expect(pendings.size).to eq 1
51
+ expect(pendings ).not_to include vi1
52
+ expect(pendings ).to include vi2
53
+ expect(pendings ).not_to include vi3
54
+ end
55
+
56
+ it "generates model class dinamically" do
57
+ vi = View.new(origin_table: 'models', origin_id_field: 'code')
58
+
59
+ expect(vi.model_class.superclass ).to be ActiveRecord::Base
60
+ expect(vi.model_class.table_name ).to eq 'models'
61
+ expect(vi.model_class.primary_key).to eq 'code'
62
+ end
63
+
64
+ it "loads it's model's object" do
65
+ vi = View.new(origin_table: 'models', origin_id_field: 'id', origin_id: 3)
66
+ Model.create!(id: 1)
67
+ mo = Model.create!(id: 3)
68
+
69
+ expect(vi.model_object.id).to eq mo.id
70
+ end
71
+
72
+ describe 'transmitted_to' do
73
+ it "marks model as synched" do
74
+ vi = View.new(origin_table: 'models', origin_id_field: 'id', origin_id: 3,
75
+ origin_step_field: 'paso', step: 1, desired_step: 2)
76
+ mo1 = Model.create!(id: 3, paso: 1)
77
+ mo2 = Model.create!(id: 1, paso: 1)
78
+
79
+ vi.transmitted_to double(id: 5)
80
+
81
+ mo1.reload
82
+ mo2.reload
83
+ expect(mo1.paso).to eq 2
84
+ expect(mo2.paso).to eq 1
85
+ end
86
+
87
+ context 'view responds to web_id' do
88
+ it "updates its model's web_id" do
89
+ vi = View.new(origin_table: 'models', origin_id_field: 'id', origin_id: 3,
90
+ origin_step_field: 'paso', step: 1, desired_step: 2)
91
+ def vi.web_id
92
+ nil
93
+ end
94
+ mo1 = Model.create!(id: 3, paso: 1)
95
+
96
+ vi.transmitted_to double(id: 5)
97
+
98
+ mo1.reload
99
+ expect(mo1.web_id).to eq 5
100
+ end
101
+ end
102
+
103
+ context 'received object contains errors' do
104
+ it "marks object as problematic" do
105
+ vi = View.new(origin_table: 'models', origin_id_field: 'id', origin_id: 3,
106
+ origin_step_field: 'paso', step: 1, desired_step: 2)
107
+ mo1 = Model.create!(id: 3, paso: 1)
108
+ mo2 = Model.create!(id: 1, paso: 1)
109
+
110
+ vi.transmitted_to double(id: 5, errors: ['error'])
111
+
112
+ mo1.reload
113
+ mo2.reload
114
+ expect(mo1.paso).to eq -1
115
+ expect(mo2.paso).to eq 1
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe NdSync::Remote do
4
+ NdSync.remote_site = 'http://localhost:3210'
5
+
6
+ class RemoteModel < ActiveResource::Base
7
+ include NdSync::Remote
8
+
9
+ def to_batch json
10
+ json.(self, :name)
11
+ end
12
+ end
13
+
14
+ it "loads site from NdSync" do
15
+ expect(RemoteModel.site).to eq URI('http://localhost:3210')
16
+ end
17
+
18
+ it "transmits objects requesting by sync_pending" do
19
+ stub_request(:get, "localhost:3210/remote_models.json").with(query: {sync_pending: 'true'}).
20
+ to_return(body: [{id: 5}].to_json, :status => 200)
21
+
22
+ webs = RemoteModel.to_transmit
23
+ expect(webs.size ).to eq 1
24
+ expect(webs.first.id).to eq 5
25
+ end
26
+
27
+ it "generates objects in JSON to be uploaded" do
28
+ rm = RemoteModel.new(name: 'test')
29
+
30
+ expect(RemoteModel.to_batch([rm])).to eq({remote_models: [{name: 'test'}]}.to_json)
31
+ end
32
+
33
+ describe "transmitted_to" do
34
+ it "updates remote object with local ID" do
35
+ req = stub_request(:put, "localhost:3210/remote_models/3/synched/5.json")
36
+
37
+ RemoteModel.new(id: 3).transmitted_to double(id: 5)
38
+
39
+ expect(req).to have_been_requested
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe NdSync do
4
+ NdSync.remote_site = 'http://localhost:3210'
5
+
6
+ class Local < ActiveRecord::Base
7
+ include NdSync::Local
8
+
9
+ transcriber do
10
+ copy_fields :id => :web_id
11
+ end
12
+
13
+ def origin_step_field
14
+ :step
15
+ end
16
+
17
+ def origin_table
18
+ self.class.table_name
19
+ end
20
+
21
+ def origin_id_field
22
+ self.class.primary_key
23
+ end
24
+
25
+ alias :origin_id :id
26
+ end
27
+
28
+ class Remote < ActiveResource::Base
29
+ include NdSync::Remote
30
+
31
+ def to_batch(json)
32
+ json.(self, :id)
33
+ end
34
+
35
+ transcriber do
36
+ copy_fields :web_id => :id
37
+ end
38
+ end
39
+
40
+ before(:all) do
41
+ Local.connection.create_table :locals do |t|
42
+ t.integer :web_id
43
+ t.integer :step
44
+ t.integer :desired_step
45
+ end
46
+ end
47
+
48
+ before do
49
+ Local.delete_all
50
+ end
51
+
52
+ it "allows to download data" do
53
+ stub_request(:get, "localhost:3210/remotes.json").with(query: {sync_pending: 'true'}).
54
+ to_return(body: [{id: 5}].to_json, :status => 200)
55
+ req = stub_request(:put, /localhost:3210\/remotes\/5\/synched\/\d\.json/)
56
+
57
+ expect do
58
+ NdTransmission::Base.new(Remote => Local).transmit
59
+ end.to change(Local, :count).by(1)
60
+ expect(req).to have_been_requested
61
+ end
62
+
63
+ it "allows to upload data" do
64
+ Local.create!(web_id: 5, step: 1, desired_step: 2)
65
+ req = stub_request(:post, "localhost:3210/remotes/batch.json").
66
+ with(body: {remotes: [{id: 5}]}).
67
+ to_return(body: [{id: 5}].to_json, :status => 200)
68
+
69
+ expect do
70
+ NdTransmission::Base.new(Local => Remote).transmit
71
+ end.to change(Local.pending, :count).by(-1)
72
+ expect(req).to have_been_requested
73
+ end
74
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../../lib/nd_sync', __FILE__)
2
+ require 'sqlite3'
3
+ require 'webmock/rspec'
4
+
5
+ RSpec.configure do |config|
6
+ config.order = "random"
7
+ config.before { GC.disable }
8
+ config.after { GC.enable }
9
+ config.before(:all) do
10
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
11
+ end
12
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nd_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Diego Aguir Selzlein
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-22 00:00:00.000000000 Z
11
+ date: 2014-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jbuilder
@@ -30,42 +30,42 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '4.0'
33
+ version: '3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '4.0'
40
+ version: '3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activerecord
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '4.0'
47
+ version: '3'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '4.0'
54
+ version: '3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: activeresource
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '4.0'
61
+ version: '3'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '4.0'
68
+ version: '3'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: nd_transcriber
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -100,7 +100,18 @@ executables: []
100
100
  extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
+ - ".rspec"
104
+ - Gemfile
105
+ - Gemfile.lock
106
+ - README.md
103
107
  - lib/nd_sync.rb
108
+ - lib/nd_sync/local.rb
109
+ - lib/nd_sync/remote.rb
110
+ - nd_sync.gemspec
111
+ - spec/lib/nd_sync/local_spec.rb
112
+ - spec/lib/nd_sync/remote_spec.rb
113
+ - spec/lib/nd_sync_spec.rb
114
+ - spec/spec_helper.rb
104
115
  homepage: https://github.com/nerde/nd_sync
105
116
  licenses:
106
117
  - MIT