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