mongar 0.0.4 → 0.0.5
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 +7 -1
- data/VERSION +1 -1
- data/lib/mongar/replica.rb +29 -3
- data/mongar.gemspec +2 -2
- data/spec/fixtures/sources.rb +10 -0
- data/spec/mongar/replica_spec.rb +97 -0
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -52,6 +52,10 @@ Run it with rails runner (rails 3.x) or script/runner (rails 2.x) script/mongar.
|
|
52
52
|
end
|
53
53
|
|
54
54
|
replicate Client do
|
55
|
+
db_time_selector do
|
56
|
+
current_time_on_db_server
|
57
|
+
end
|
58
|
+
|
55
59
|
column :id do
|
56
60
|
primary_index
|
57
61
|
end
|
@@ -84,7 +88,9 @@ Run it with rails runner (rails 3.x) or script/runner (rails 2.x) script/mongar.
|
|
84
88
|
end
|
85
89
|
|
86
90
|
== Contributing to mongar
|
87
|
-
|
91
|
+
|
92
|
+
Find this project on Pivotal Tracker here: https://www.pivotaltracker.com/projects/434475
|
93
|
+
|
88
94
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
89
95
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
90
96
|
* Fork the project
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.5
|
data/lib/mongar/replica.rb
CHANGED
@@ -4,7 +4,7 @@ class Mongar
|
|
4
4
|
|
5
5
|
attr_accessor :source, :destination, :log_level
|
6
6
|
attr_accessor :mongodb_name
|
7
|
-
attr_accessor :created_finder, :deleted_finder, :updated_finder
|
7
|
+
attr_accessor :created_finder, :deleted_finder, :updated_finder, :db_time_selector
|
8
8
|
attr_accessor :columns
|
9
9
|
|
10
10
|
def initialize(args = {})
|
@@ -24,11 +24,12 @@ class Mongar
|
|
24
24
|
end
|
25
25
|
self.updated_finder = Proc.new do |last_replicated_at|
|
26
26
|
find(:all, :conditions => ["updated_at > ? AND deleted_at IS NULL", last_replicated_at])
|
27
|
-
end
|
27
|
+
end
|
28
28
|
end
|
29
29
|
|
30
30
|
def run
|
31
|
-
time =
|
31
|
+
time = current_time_on_database_server
|
32
|
+
|
32
33
|
if do_full_refresh?
|
33
34
|
info "Running full refresh on Replica #{source.to_s} to #{destination.name}"
|
34
35
|
|
@@ -149,5 +150,30 @@ class Mongar
|
|
149
150
|
self.send("#{finder_type}_finder=".to_sym, nil)
|
150
151
|
end
|
151
152
|
end
|
153
|
+
|
154
|
+
def db_time_selector &block
|
155
|
+
return @db_time_selector unless block_given?
|
156
|
+
|
157
|
+
@db_time_selector = block
|
158
|
+
end
|
159
|
+
|
160
|
+
def default_time_selector(object)
|
161
|
+
adapter = object.connection.class.to_s
|
162
|
+
adapter = $1 if adapter =~ /::([^:]+)$/
|
163
|
+
|
164
|
+
time = if adapter == 'MysqlAdapter'
|
165
|
+
Time.parse(object.connection.execute("SELECT UTC_TIMESTAMP()").fetch_row.first)
|
166
|
+
elsif adapter == 'Mysql2Adapter'
|
167
|
+
object.connection.execute("SELECT UTC_TIMESTAMP()").first.first
|
168
|
+
elsif adapter == 'SQLServerAdapter'
|
169
|
+
object.connection.select_one("SELECT getutcdate() AS date")['date']
|
170
|
+
end
|
171
|
+
|
172
|
+
time.is_a?(Time) ? time : nil
|
173
|
+
end
|
174
|
+
|
175
|
+
def current_time_on_database_server
|
176
|
+
@db_time_selector.nil? ? default_time_selector(source) : source.instance_exec(&@db_time_selector)
|
177
|
+
end
|
152
178
|
end
|
153
179
|
end
|
data/mongar.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "mongar"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Philippe Green"]
|
12
|
-
s.date = "2011-12-
|
12
|
+
s.date = "2011-12-15"
|
13
13
|
s.description = "Replicates data from ActiveRecord (or other Ruby data mapping class) to MongoDB"
|
14
14
|
s.email = "phil@greenviewdata.com"
|
15
15
|
s.extra_rdoc_files = [
|
data/spec/fixtures/sources.rb
CHANGED
@@ -1,7 +1,17 @@
|
|
1
|
+
class Mysql2Adapter
|
2
|
+
def execute(sql)
|
3
|
+
[[Time.now.utc]]
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
1
7
|
class Domain
|
2
8
|
attr_accessor :name, :client_id
|
3
9
|
attr_accessor :created_at, :updated_at, :deleted_at
|
4
10
|
|
11
|
+
def self.connection
|
12
|
+
return Mysql2Adapter.new
|
13
|
+
end
|
14
|
+
|
5
15
|
def initialize(args = {})
|
6
16
|
args.each do |key, value|
|
7
17
|
self.send(:"#{key}=", value)
|
data/spec/mongar/replica_spec.rb
CHANGED
@@ -26,6 +26,8 @@ describe "Mongar::Replica" do
|
|
26
26
|
@mongo = Mongar::Mongo.new
|
27
27
|
Mongar::Mongo.databases[:default] = @mongo
|
28
28
|
|
29
|
+
@replica.stub!(:default_time_selector).and_return(@time)
|
30
|
+
|
29
31
|
@last_replicated_time = Time.now - 86400
|
30
32
|
@collection.stub!(:last_replicated_at).and_return(@last_replicated_time)
|
31
33
|
|
@@ -60,6 +62,8 @@ describe "Mongar::Replica" do
|
|
60
62
|
before do
|
61
63
|
@time = Time.parse("1/1/2011 00:00:00")
|
62
64
|
Time.stub!(:now).and_return(@time)
|
65
|
+
@replica.stub!(:default_time_selector).and_return(@time)
|
66
|
+
|
63
67
|
@replica.stub!(:do_full_refresh?).and_return(false)
|
64
68
|
|
65
69
|
@deleted_client1 = Client.new(:name => "Widget Co", :employee_count => 500)
|
@@ -370,4 +374,97 @@ describe "Mongar::Replica" do
|
|
370
374
|
@replica.mongodb.should == @fake_db
|
371
375
|
end
|
372
376
|
end
|
377
|
+
|
378
|
+
describe "#db_time_selector" do
|
379
|
+
before do
|
380
|
+
@block = lambda {}
|
381
|
+
end
|
382
|
+
|
383
|
+
it "should default to nil" do
|
384
|
+
@replica.db_time_selector.should be_nil
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should set the time sql to something else given an argument" do
|
388
|
+
@replica.db_time_selector &@block
|
389
|
+
@replica.db_time_selector.should == @block
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
describe "#current_time_on_database_server" do
|
394
|
+
before do
|
395
|
+
class Client; end
|
396
|
+
@replica.source = Client
|
397
|
+
@time = Time.now
|
398
|
+
end
|
399
|
+
context "default time selector" do
|
400
|
+
it "should call default_time_selector" do
|
401
|
+
@replica.should_receive(:default_time_selector).with(Client).and_return(@time)
|
402
|
+
@replica.current_time_on_database_server.should == @time
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
context "custom time selector" do
|
407
|
+
before do
|
408
|
+
@replica.db_time_selector do
|
409
|
+
current_db_time
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
it "should call the custom time selector function on the source class" do
|
414
|
+
Client.should_receive(:current_db_time).and_return(@time)
|
415
|
+
@replica.current_time_on_database_server.should == @time
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
describe "#default_time_selector" do
|
421
|
+
before do
|
422
|
+
class MockAdapters
|
423
|
+
class MysqlAdapter
|
424
|
+
end
|
425
|
+
|
426
|
+
class Mysql2Adapter
|
427
|
+
end
|
428
|
+
|
429
|
+
class SQLServerAdapter
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
@time = Time.now
|
434
|
+
end
|
435
|
+
|
436
|
+
context "mysql server backend" do
|
437
|
+
before do
|
438
|
+
@mock_connection = MockAdapters::MysqlAdapter.new
|
439
|
+
@mock_source = mock(Object, :connection => @mock_connection)
|
440
|
+
@mock_result = mock(Object, :fetch_row => [@time.to_s])
|
441
|
+
end
|
442
|
+
it "should run SELECT UTC_TIMESTAMP()" do
|
443
|
+
@mock_connection.should_receive(:execute).with("SELECT UTC_TIMESTAMP()").and_return(@mock_result)
|
444
|
+
@replica.default_time_selector(@mock_source).to_s.should == @time.to_s
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
context "mysql server backend with mysql2 adapter" do
|
449
|
+
before do
|
450
|
+
@mock_connection = MockAdapters::Mysql2Adapter.new
|
451
|
+
@mock_source = mock(Object, :connection => @mock_connection)
|
452
|
+
end
|
453
|
+
it "should run SELECT UTC_TIMESTAMP()" do
|
454
|
+
@mock_connection.should_receive(:execute).with("SELECT UTC_TIMESTAMP()").and_return([[@time]])
|
455
|
+
@replica.default_time_selector(@mock_source).should == @time
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
context "sql server backend" do
|
460
|
+
before do
|
461
|
+
@mock_connection = MockAdapters::SQLServerAdapter.new
|
462
|
+
@mock_source = mock(Object, :connection => @mock_connection)
|
463
|
+
end
|
464
|
+
it "should run SELECT getutcdate() as date" do
|
465
|
+
@mock_connection.should_receive(:select_one).with("SELECT getutcdate() AS date").and_return({"date" => @time})
|
466
|
+
@replica.default_time_selector(@mock_source).should == @time
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
373
470
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Philippe Green
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-12-
|
18
|
+
date: 2011-12-15 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
requirement: &id001 !ruby/object:Gem::Requirement
|