replicat 0.0.1 → 0.0.2

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: a4318b9a2e2e1c7e637af213a8ae09f2d292235e
4
- data.tar.gz: 5063232ce2dcc9403137e7d4ec2f5ea4d011a5b9
3
+ metadata.gz: b0943235f899b2c1ae3617e2516a4616a5eb2da8
4
+ data.tar.gz: 4a793e61900339e0b78259c86f8c9af8a1d2ea6c
5
5
  SHA512:
6
- metadata.gz: 8220a33336d837f1adfe5b848eaf9a301ddbdf9c9487abb4f7c90a6e6558f43907195e517ef435ab18c60b3b75ac08a605202646d5e08ff52b0a5d9225125e1d
7
- data.tar.gz: 66bf65c92a44b0935e92473c77a0ecae0f09b72b64668e33ef7c56a58b0fde6068e594fc24613c43fcc24f010d812d202e354993da4475e6acdf4279b39d5986
6
+ metadata.gz: 2ab0acafcf8ff55fa4feb51ccadfbbc068ef5f0ebc4409305ad84d5466fb3319bb80f6806e19663b520c7b93733e053909c3f14d842fb533fe9b389fdcab3bff
7
+ data.tar.gz: a353681af3ecae8761a906b443df27fccd4b2b7e986eec5b05785dcff62da41bb44ad0a760fc3fd8f099a4ced8d9671fa503f00221451b951c46c31af7fdda67
@@ -0,0 +1,5 @@
1
+ ## 0.0.2
2
+ * using(:slave1) can be used as scope method
3
+
4
+ ## 0.0.1
5
+ * 1st release on 2013-11-27
data/README.md CHANGED
@@ -45,33 +45,44 @@ production:
45
45
  Now SELECT queries of User model will be sent to slave connections.
46
46
 
47
47
  ```ruby
48
+ # INSERT query is sent to master.
48
49
  User.create(name: "replicat")
49
- User.first #=> nil
50
+
51
+ # SELECT query is sent to slave.
52
+ User.first
50
53
  ```
51
54
 
52
55
  ### using
53
56
  `using` can help you specify particular connection.
54
- `using(:master)` uses master connection.
57
+ When you want to send queries to master,
58
+ you can use `using(:master)` to do that (:master is reserved name for `using` method).
59
+ When you want to send queries to a particular slave,
60
+ you can use the slave's name on database.yml like `using(:slave1)`.
55
61
 
56
62
  ```ruby
57
- User.create(name: "replicat")
58
- User.using(:master) { User.first } #=> #<User id: 2, name: "replicat">
63
+ # SELECT query is sent to master.
64
+ User.using(:master).first
65
+
66
+ # INSERT query is sent to slave1.
67
+ User.using(:slave1).create(name: "replicat")
68
+
69
+ # :slave1 is used for User connection in the passed block.
70
+ User.using(:slave1) { blog.user }
59
71
  ```
60
72
 
61
73
  ### round-robin
62
74
  slave connections are balanced by round-robin way.
63
75
 
64
76
  ```ruby
65
- User.using(:slave1) { User.create(name: "replicat") }
66
- User.first #=> #<User id: 2, name: "replicat">
67
- User.first #=> nil
68
- User.first #=> nil
69
- User.first #=> #<User id: 2, name: "replicat">
70
- User.first #=> nil
71
- User.first #=> nil
72
- User.first #=> #<User id: 2, name: "replicat">
73
- User.first #=> nil
74
- User.first #=> nil
77
+ User.first # sent to slave1
78
+ User.first # sent to slave2
79
+ User.first # sent to slave3
80
+ User.first # sent to slave1
81
+ User.first # sent to slave2
82
+ User.first # sent to slave3
83
+ User.first # sent to slave1
84
+ User.first # sent to slave2
85
+ User.first # sent to slave3
75
86
  ```
76
87
 
77
88
  ### multi master-slave set
@@ -2,5 +2,6 @@ require "active_record"
2
2
  require "replicat/model"
3
3
  require "replicat/proxy"
4
4
  require "replicat/replicable"
5
+ require "replicat/scope_proxy"
5
6
  require "replicat/version"
6
7
  require "replicat/active_record"
@@ -4,6 +4,11 @@ module Replicat
4
4
  raise "You must set `connection_name` of this model class." if !connection_name && !defined?(Rails)
5
5
  include Replicat::Replicable
6
6
  self.connection_name = connection_name || Rails.env.to_s
7
+ self
8
+ end
9
+
10
+ def replicated?
11
+ ancestors.include?(Replicable)
7
12
  end
8
13
  end
9
14
  end
@@ -44,10 +44,14 @@ module Replicat
44
44
  end
45
45
 
46
46
  def using(connection_name)
47
- proxy.current_connection_name = connection_name
48
- yield
47
+ if block_given?
48
+ proxy.current_connection_name = connection_name
49
+ yield
50
+ else
51
+ ScopeProxy.new(klass: self, connection_name: connection_name)
52
+ end
49
53
  ensure
50
- proxy.current_connection_name = nil
54
+ proxy.current_connection_name = nil if block_given?
51
55
  end
52
56
  end
53
57
  end
@@ -0,0 +1,24 @@
1
+ module Replicat
2
+ class ScopeProxy
3
+ def initialize(attributes)
4
+ @klass = attributes[:klass]
5
+ @connection_name = attributes[:connection_name]
6
+ end
7
+
8
+ private
9
+
10
+ def method_missing(method_name, *args, &block)
11
+ result = using { @klass.send(method_name, *args, &block) }
12
+ if result.respond_to?(:scoped)
13
+ @klass = result
14
+ self
15
+ else
16
+ result
17
+ end
18
+ end
19
+
20
+ def using
21
+ @klass.using(@connection_name) { yield }
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Replicat
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.add_dependency "activesupport"
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "coffee-rails", ">= 3.0.10"
23
+ spec.add_development_dependency "database_cleaner", "1.2.0"
23
24
  spec.add_development_dependency "jquery-rails"
24
25
  spec.add_development_dependency "pry"
25
26
  spec.add_development_dependency "pry-rails"
@@ -0,0 +1,5 @@
1
+ class Ingredient < ActiveRecord::Base
2
+ replicate "test"
3
+
4
+ belongs_to :recipe
5
+ end
@@ -1,3 +1,5 @@
1
1
  class Recipe < ActiveRecord::Base
2
2
  replicate "test"
3
+
4
+ has_many :ingredients
3
5
  end
@@ -23,4 +23,11 @@ ActiveRecord::Schema.define(version: 0) do
23
23
  t.datetime "created_at"
24
24
  t.datetime "updated_at"
25
25
  end
26
+
27
+ create_table "ingredients", force: true do |t|
28
+ t.string "name", null: false
29
+ t.integer "recipe_id", null: false
30
+ t.datetime "created_at"
31
+ t.datetime "updated_at"
32
+ end
26
33
  end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ describe Replicat::Model do
4
+ let(:model_class) do
5
+ Class.new(ActiveRecord::Base)
6
+ end
7
+
8
+ describe ".replicate" do
9
+ context "with no args" do
10
+ it "includes Replicat::Replicable" do
11
+ model_class.replicate.ancestors.should include Replicat::Replicable
12
+ end
13
+
14
+ it "assigns connection_name attribute with Rails.env" do
15
+ model_class.replicate.connection_name.should == Rails.env
16
+ end
17
+
18
+ it "returns itself" do
19
+ model_class.replicate.should == model_class
20
+ end
21
+ end
22
+
23
+ context "with args" do
24
+ it "uses given value as connection_name attribute" do
25
+ model_class.replicate("master1").connection_name.should == "master1"
26
+ end
27
+ end
28
+ end
29
+
30
+ describe ".replicated?" do
31
+ context "with replicated model" do
32
+ it "returns true" do
33
+ model_class.replicate.should be_replicated
34
+ end
35
+ end
36
+
37
+ context "with non-replicated model" do
38
+ it "returns false" do
39
+ model_class.should_not be_replicated
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,14 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Replicat::Replicable do
4
- describe ".has_any_replication?" do
5
- context "with any replication in connection settings" do
6
- it "returns true" do
7
- Recipe.should have_any_replication
8
- end
9
- end
10
- end
11
-
12
4
  describe ".connection_with_proxy" do
13
5
  context "with non-replicable model" do
14
6
  it "returns normal connection" do
@@ -52,6 +44,48 @@ describe Replicat::Replicable do
52
44
  end
53
45
  end
54
46
  end
47
+
48
+ context "with no block" do
49
+ it "can be used as scope" do
50
+ Recipe.using(:slave1).create(title: "test")
51
+ Recipe.using(:slave1).first.should_not == nil
52
+ end
53
+ end
54
+
55
+ context "with scope" do
56
+ it "works well" do
57
+ Recipe.all.using(:slave1).create(title: "test")
58
+ Recipe.where(title: "test").using(:slave1).first.should_not == nil
59
+ end
60
+ end
61
+
62
+ context "with belongs_to association" do
63
+ let!(:ingredient) do
64
+ Ingredient.using(:slave1).create(name: "test", recipe_id: recipe.id)
65
+ end
66
+
67
+ let(:recipe) do
68
+ Recipe.using(:slave1).create(title: "test")
69
+ end
70
+
71
+ it "works well" do
72
+ Recipe.using(:slave1) { ingredient.recipe.should == recipe }
73
+ end
74
+ end
75
+
76
+ context "with has_many association" do
77
+ let!(:ingredient) do
78
+ Ingredient.using(:slave1) { Ingredient.create(name: "test", recipe_id: recipe.id) }
79
+ end
80
+
81
+ let(:recipe) do
82
+ Recipe.using(:slave1) { Recipe.create(title: "test") }
83
+ end
84
+
85
+ it "works well" do
86
+ Ingredient.using(:slave1) { recipe.ingredients.should == [ingredient] }
87
+ end
88
+ end
55
89
  end
56
90
 
57
91
  describe ".proxy" do
@@ -4,12 +4,24 @@ require "replicat"
4
4
  ENV["RAILS_ENV"] ||= "test"
5
5
  require File.expand_path("../dummy/config/environment", __FILE__)
6
6
  require "rspec/rails"
7
-
8
- 3.times {|i| FileUtils.copy("#{Rails.root}/db/test.sqlite3", "#{Rails.root}/db/test_slave#{i + 1}.sqlite3") }
7
+ require "database_cleaner"
9
8
 
10
9
  RSpec.configure do |config|
11
10
  config.run_all_when_everything_filtered = true
12
11
  config.treat_symbols_as_metadata_keys_with_true_values = true
13
- config.use_transactional_fixtures = true
14
12
  config.filter_run :focus
13
+
14
+ config.before(:suite) do
15
+ DatabaseCleaner.strategy = :deletion
16
+ 3.times do |i|
17
+ FileUtils.copy("#{Rails.root}/db/test.sqlite3", "#{Rails.root}/db/test_slave#{i + 1}.sqlite3")
18
+ end
19
+ end
20
+
21
+ config.after do
22
+ DatabaseCleaner.clean
23
+ 3.times do |i|
24
+ FileUtils.copy("#{Rails.root}/db/test.sqlite3", "#{Rails.root}/db/test_slave#{i + 1}.sqlite3")
25
+ end
26
+ end
15
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: replicat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-28 00:00:00.000000000 Z
11
+ date: 2013-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: 3.0.10
69
+ - !ruby/object:Gem::Dependency
70
+ name: database_cleaner
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 1.2.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: jquery-rails
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -214,6 +228,7 @@ extensions: []
214
228
  extra_rdoc_files: []
215
229
  files:
216
230
  - .gitignore
231
+ - CHANGELOG.md
217
232
  - Gemfile
218
233
  - LICENSE.txt
219
234
  - README.md
@@ -223,6 +238,7 @@ files:
223
238
  - lib/replicat/model.rb
224
239
  - lib/replicat/proxy.rb
225
240
  - lib/replicat/replicable.rb
241
+ - lib/replicat/scope_proxy.rb
226
242
  - lib/replicat/version.rb
227
243
  - replicat.gemspec
228
244
  - spec/dummy/Rakefile
@@ -232,6 +248,7 @@ files:
232
248
  - spec/dummy/app/helpers/application_helper.rb
233
249
  - spec/dummy/app/mailers/.gitkeep
234
250
  - spec/dummy/app/models/.gitkeep
251
+ - spec/dummy/app/models/ingredient.rb
235
252
  - spec/dummy/app/models/recipe.rb
236
253
  - spec/dummy/app/models/user.rb
237
254
  - spec/dummy/app/views/layouts/application.html.erb
@@ -259,6 +276,7 @@ files:
259
276
  - spec/dummy/public/500.html
260
277
  - spec/dummy/public/favicon.ico
261
278
  - spec/dummy/script/rails
279
+ - spec/replicat/model_spec.rb
262
280
  - spec/replicat/replicable_spec.rb
263
281
  - spec/spec_helper.rb
264
282
  homepage: https://github.com/r7kamura/replicat
@@ -293,6 +311,7 @@ test_files:
293
311
  - spec/dummy/app/helpers/application_helper.rb
294
312
  - spec/dummy/app/mailers/.gitkeep
295
313
  - spec/dummy/app/models/.gitkeep
314
+ - spec/dummy/app/models/ingredient.rb
296
315
  - spec/dummy/app/models/recipe.rb
297
316
  - spec/dummy/app/models/user.rb
298
317
  - spec/dummy/app/views/layouts/application.html.erb
@@ -320,5 +339,6 @@ test_files:
320
339
  - spec/dummy/public/500.html
321
340
  - spec/dummy/public/favicon.ico
322
341
  - spec/dummy/script/rails
342
+ - spec/replicat/model_spec.rb
323
343
  - spec/replicat/replicable_spec.rb
324
344
  - spec/spec_helper.rb