nd_sync 0.0.1 → 0.0.3

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.
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