mongar 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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.4
1
+ 0.0.5
@@ -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 = Time.now
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.4"
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-14"
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 = [
@@ -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)
@@ -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: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
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-14 00:00:00 Z
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