ar-octopus 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ pkg/*.*
@@ -12,7 +12,8 @@
12
12
  - Moving data between shards with migrations.
13
13
  - Tools to manage database configurations. (soon)
14
14
 
15
- <p> To see the complete list of features and syntax, please check out our <a href="http://wiki.github.com/tchandy/octopus/"> Wiki</a>
15
+ <p> To see the complete list of features and syntax, please check out our <a href="http://wiki.github.com/tchandy/octopus/"> Wiki</a></p>
16
+ <p>Wanna see sample rails applications using octopus features? please check it out: <a href="http://github.com/tchandy/octopus_sharding_example">Sharding Example</a> and <a href="http://github.com/tchandy/octopus_replication_example">Replication Example</a> </p>
16
17
 
17
18
  <h2>Thanks</h2>
18
19
 
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ begin
12
12
  gem.homepage = "http://github.com/tchandy/octopus"
13
13
  gem.authors = ["Thiago Pradi", "Mike Perham", "Amit Agarwal"]
14
14
  gem.add_development_dependency "rspec", ">= 1.2.9"
15
- gem.version = "0.0.1"
15
+ gem.version = "0.0.2"
16
16
  end
17
17
  Jeweler::GemcutterTasks.new
18
18
  rescue LoadError
@@ -0,0 +1,95 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ar-octopus}
8
+ s.version = "0.0.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Thiago Pradi", "Mike Perham", "Amit Agarwal"]
12
+ s.date = %q{2010-06-14}
13
+ s.description = %q{This gem allows you to use sharded databases with ActiveRecord. this also provides a interface for replication and for running migrations with multiples shards.}
14
+ s.email = %q{tchandy@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README.mkdn"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README.mkdn",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "ar-octopus.gemspec",
24
+ "doc/api.textile",
25
+ "doc/features.textile",
26
+ "doc/libraries.textile",
27
+ "doc/shards.yml",
28
+ "lib/octopus.rb",
29
+ "lib/octopus/controller.rb",
30
+ "lib/octopus/migration.rb",
31
+ "lib/octopus/model.rb",
32
+ "lib/octopus/proxy.rb",
33
+ "spec/config/shards.yml",
34
+ "spec/database_connection.rb",
35
+ "spec/database_models.rb",
36
+ "spec/migrations/10_create_users_using_replication.rb",
37
+ "spec/migrations/11_add_field_in_all_slaves.rb",
38
+ "spec/migrations/1_create_users_on_master.rb",
39
+ "spec/migrations/2_create_users_on_canada.rb",
40
+ "spec/migrations/3_create_users_on_both_shards.rb",
41
+ "spec/migrations/4_create_users_on_shards_of_a_group.rb",
42
+ "spec/migrations/5_create_users_on_multiples_groups.rb",
43
+ "spec/migrations/6_raise_exception_with_invalid_shard_name.rb",
44
+ "spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb",
45
+ "spec/migrations/8_raise_exception_with_invalid_group_name.rb",
46
+ "spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb",
47
+ "spec/octopus/controller_spec.rb",
48
+ "spec/octopus/migration_spec.rb",
49
+ "spec/octopus/model_spec.rb",
50
+ "spec/octopus/octopus_spec.rb",
51
+ "spec/octopus/proxy_spec.rb",
52
+ "spec/spec.opts",
53
+ "spec/spec_helper.rb"
54
+ ]
55
+ s.homepage = %q{http://github.com/tchandy/octopus}
56
+ s.rdoc_options = ["--charset=UTF-8"]
57
+ s.require_paths = ["lib"]
58
+ s.rubygems_version = %q{1.3.6}
59
+ s.summary = %q{Easy Database Sharding for ActiveRecord}
60
+ s.test_files = [
61
+ "spec/database_connection.rb",
62
+ "spec/database_models.rb",
63
+ "spec/migrations/10_create_users_using_replication.rb",
64
+ "spec/migrations/11_add_field_in_all_slaves.rb",
65
+ "spec/migrations/1_create_users_on_master.rb",
66
+ "spec/migrations/2_create_users_on_canada.rb",
67
+ "spec/migrations/3_create_users_on_both_shards.rb",
68
+ "spec/migrations/4_create_users_on_shards_of_a_group.rb",
69
+ "spec/migrations/5_create_users_on_multiples_groups.rb",
70
+ "spec/migrations/6_raise_exception_with_invalid_shard_name.rb",
71
+ "spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb",
72
+ "spec/migrations/8_raise_exception_with_invalid_group_name.rb",
73
+ "spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb",
74
+ "spec/octopus/controller_spec.rb",
75
+ "spec/octopus/migration_spec.rb",
76
+ "spec/octopus/model_spec.rb",
77
+ "spec/octopus/octopus_spec.rb",
78
+ "spec/octopus/proxy_spec.rb",
79
+ "spec/spec_helper.rb"
80
+ ]
81
+
82
+ if s.respond_to? :specification_version then
83
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
84
+ s.specification_version = 3
85
+
86
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
87
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
88
+ else
89
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
90
+ end
91
+ else
92
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
93
+ end
94
+ end
95
+
@@ -2,25 +2,17 @@ require "yaml"
2
2
 
3
3
  module Octopus
4
4
  def self.env()
5
- if defined?(Rails)
6
- Rails.env.to_s
7
- else
8
- "production"
9
- end
5
+ @@env ||= defined?(Rails) ? Rails.env.to_s : "production"
10
6
  end
11
7
 
12
8
  def self.config()
13
9
  @@config ||= YAML.load_file(Octopus.directory() + "/config/shards.yml")
14
10
  end
15
11
 
12
+ # Returns the Rails.root_to_s when you are using rails
13
+ # Running the current directory in a generic Ruby process
16
14
  def self.directory()
17
- if defined?(Rails)
18
- # Running in a normal Rails application
19
- Rails.root.to_s
20
- else
21
- # Running in a generic Ruby process
22
- Dir.pwd
23
- end
15
+ @@directory ||= defined?(Rails) ? Rails.root.to_s : Dir.pwd
24
16
  end
25
17
  end
26
18
 
@@ -1,2 +1,15 @@
1
- class Octopus::Controller
2
- end
1
+ module Octopus::Controller
2
+ def using(shard, &block)
3
+ older_shard = ActiveRecord::Base.connection_proxy.current_shard
4
+ ActiveRecord::Base.connection_proxy.block = true
5
+ ActiveRecord::Base.connection_proxy.current_shard = shard
6
+ begin
7
+ yield
8
+ ensure
9
+ ActiveRecord::Base.connection_proxy.block = false
10
+ ActiveRecord::Base.connection_proxy.current_shard = older_shard
11
+ end
12
+ end
13
+ end
14
+
15
+ ActionController::Base.send(:include, Octopus::Controller) if defined?(ActionController)
@@ -28,6 +28,8 @@ module Octopus::Model
28
28
  end
29
29
  end
30
30
 
31
+ self.reset_table_name() if self != ActiveRecord::Base && self.respond_to?(:reset_table_name)
32
+
31
33
  if block_given?
32
34
  older_shard = self.connection_proxy.current_shard
33
35
  self.connection_proxy.block = true
@@ -40,6 +42,7 @@ module Octopus::Model
40
42
  end
41
43
  else
42
44
  self.connection_proxy.current_shard = shard
45
+ self.connection_proxy.using_enabled = true
43
46
  return self
44
47
  end
45
48
  end
@@ -1,7 +1,7 @@
1
1
  require "set"
2
2
 
3
3
  class Octopus::Proxy
4
- attr_accessor :shards, :current_shard, :block, :groups, :current_group, :replicated, :slaves_list, :replicated_models
4
+ attr_accessor :shards, :current_shard, :block, :groups, :current_group, :replicated, :slaves_list, :replicated_models, :using_enabled
5
5
 
6
6
  delegate :increment_open_transactions, :decrement_open_transactions, :to => :select_connection
7
7
 
@@ -13,6 +13,7 @@ class Octopus::Proxy
13
13
  @replicated = config[Octopus.env()]["replicated"] || false
14
14
  @shards[:master] = ActiveRecord::Base.connection_pool()
15
15
  @current_shard = :master
16
+ @using_enabled = false
16
17
 
17
18
  config[Octopus.env()]["shards"].each do |key, value|
18
19
  if value.has_key?("adapter")
@@ -72,19 +73,25 @@ class Octopus::Proxy
72
73
  def set_replicated_model(model)
73
74
  replicated_models << model.to_s
74
75
  end
76
+
77
+ def add_transaction_record(record)
78
+ if !select_connection().instance_variable_get(:@_current_transaction_records).nil?
79
+ select_connection().add_transaction_record(record)
80
+ end
81
+ end
75
82
 
76
- def transaction(start_db_transaction = true, &block)
83
+ def transaction(options = {}, &block)
77
84
  if should_send_queries_to_multiple_shards?
78
- self.send_transaction_to_multiple_shards(current_shard, start_db_transaction, &block)
85
+ self.send_transaction_to_multiple_shards(current_shard, options, &block)
79
86
  self.current_shard = :master
80
87
  elsif should_send_queries_to_multiple_groups?
81
- self.send_transaction_to_multiple_groups(start_db_transaction, &block)
88
+ self.send_transaction_to_multiple_groups(options, &block)
82
89
  self.current_group = nil
83
90
  elsif should_send_queries_to_a_group_of_shards?
84
- self.send_transaction_to_multiple_shards(@groups[current_group], start_db_transaction, &block)
91
+ self.send_transaction_to_multiple_shards(@groups[current_group], options, &block)
85
92
  self.current_group = nil
86
93
  else
87
- select_connection.transaction(start_db_transaction, &block)
94
+ select_connection.transaction(options, &block)
88
95
  end
89
96
  end
90
97
 
@@ -92,6 +99,7 @@ class Octopus::Proxy
92
99
  if should_clean_connection?(method)
93
100
  conn = select_connection()
94
101
  self.current_shard = :master
102
+ @using_enabled = nil
95
103
  conn.send(method, *args, &block)
96
104
  elsif should_send_queries_to_replicated_databases?(method)
97
105
  send_queries_to_selected_slave(method, *args, &block)
@@ -166,30 +174,33 @@ class Octopus::Proxy
166
174
  end
167
175
 
168
176
  def send_queries_to_selected_slave(method, *args, &block)
169
- #TODO: ugly code, needs refactor
177
+ #TODO: UGLY code, needs refactor
178
+ old_shard = self.current_shard
179
+
170
180
  if args.last =~ /#{replicated_models.to_a.join('|')}/
171
- old_shard = self.current_shard
172
- self.current_shard = slaves_list.shift.to_sym
173
- slaves_list << self.current_shard
181
+ if !using_enabled
182
+ self.current_shard = slaves_list.shift.to_sym
183
+ slaves_list << self.current_shard
184
+ end
174
185
  else
175
- old_shard = self.current_shard
176
186
  self.current_shard = :master
177
187
  end
178
188
 
179
189
  sql = select_connection().send(method, *args, &block)
180
190
  self.current_shard = old_shard
191
+ @using_enabled = nil
181
192
  return sql
182
193
  end
183
194
 
184
- def send_transaction_to_multiple_shards(shard_array, start_db_transaction, &block)
195
+ def send_transaction_to_multiple_shards(shard_array, options, &block)
185
196
  shard_array.each do |shard_symbol|
186
- @shards[shard_symbol].connection().transaction(start_db_transaction, &block)
197
+ @shards[shard_symbol].connection().transaction(options, &block)
187
198
  end
188
199
  end
189
200
 
190
- def send_transaction_to_multiple_groups(start_db_transaction, &block)
201
+ def send_transaction_to_multiple_groups(options, &block)
191
202
  current_group.each do |group_symbol|
192
- self.send_transaction_to_multiple_shards(@groups[group_symbol], start_db_transaction, &block)
203
+ self.send_transaction_to_multiple_shards(@groups[group_symbol], options, &block)
193
204
  end
194
205
  end
195
206
  end
@@ -0,0 +1,9 @@
1
+ class CreateUsersUsingReplication < ActiveRecord::Migration
2
+ def self.up
3
+ Cat.create!(:name => "Replication")
4
+ end
5
+
6
+ def self.down
7
+ Cat.delete_all()
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class AddFieldInAllSlaves < ActiveRecord::Migration
2
+ using(:slave1, :slave2, :slave3, :slave4)
3
+
4
+ def self.up
5
+ Cat.create!(:name => "Slaves")
6
+ end
7
+
8
+ def self.down
9
+ Cat.delete_all()
10
+ end
11
+ end
@@ -2,6 +2,36 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Octopus::Controller do
4
4
  it "should have the using method to select the shard" do
5
- pending()
5
+ a = ActionController::Base.new
6
+ a.respond_to?(:using).should be_true
7
+ end
8
+
9
+ it "should use #using method to in all requests" do
10
+ class UsersControllers < ActionController::Base
11
+ around_filter :select_shard
12
+ def create
13
+ User.create!(:name => "ActionController")
14
+ render :nothing => true
15
+ end
16
+
17
+ def select_shard
18
+ using(:brazil) do
19
+ yield
20
+ end
21
+ end
22
+
23
+ def self._router
24
+ ActionDispatch::Routing::RouteSet.new
25
+ end
26
+ end
27
+
28
+ UsersControllers.action_methods.include?("create").should be_true
29
+ a = UsersControllers.new
30
+ a.stub!(:request).and_return(mock({:fullpath => "", :filtered_parameters => {}, :formats => ["xml"], :method => "GET"}))
31
+ a.instance_variable_set(:@_response, mock(:content_type => "xml", :body= => "", :status => 401))
32
+ a.process(:create)
33
+
34
+ User.using(:brazil).find_by_name("ActionController").should_not be_nil
35
+ User.using(:master).find_by_name("ActionController").should be_nil
6
36
  end
7
37
  end
@@ -2,50 +2,40 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Octopus::Migration do
4
4
  it "should run just in the master shard" do
5
- ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT, 1)
6
-
7
- User.using(:master).find_by_name("Master").should_not be_nil
8
- User.using(:canada).find_by_name("Master").should be_nil
9
-
10
- ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT, 1)
5
+ migrating_to_version 1 do
6
+ User.using(:master).find_by_name("Master").should_not be_nil
7
+ User.using(:canada).find_by_name("Master").should be_nil
8
+ end
11
9
  end
12
10
 
13
11
  it "should run on specific shard" do
14
- ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT, 2)
15
-
16
- User.using(:master).find_by_name("Sharding").should be_nil
17
- User.using(:canada).find_by_name("Sharding").should_not be_nil
18
-
19
- ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT, 2)
12
+ migrating_to_version 2 do
13
+ User.using(:master).find_by_name("Sharding").should be_nil
14
+ User.using(:canada).find_by_name("Sharding").should_not be_nil
15
+ end
20
16
  end
21
17
 
22
18
  it "should run on specifieds shards" do
23
- ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT, 3)
24
-
25
- User.using(:brazil).find_by_name("Both").should_not be_nil
26
- User.using(:canada).find_by_name("Both").should_not be_nil
27
-
28
- ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT, 3)
19
+ migrating_to_version 3 do
20
+ User.using(:brazil).find_by_name("Both").should_not be_nil
21
+ User.using(:canada).find_by_name("Both").should_not be_nil
22
+ end
29
23
  end
30
24
 
31
25
  it "should run on specified group" do
32
- ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT, 4)
33
-
34
- User.using(:canada).find_by_name("Group").should_not be_nil
35
- User.using(:brazil).find_by_name("Group").should_not be_nil
36
- User.using(:russia).find_by_name("Group").should_not be_nil
37
-
38
- ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT, 4)
26
+ migrating_to_version 4 do
27
+ User.using(:canada).find_by_name("Group").should_not be_nil
28
+ User.using(:brazil).find_by_name("Group").should_not be_nil
29
+ User.using(:russia).find_by_name("Group").should_not be_nil
30
+ end
39
31
  end
40
32
 
41
33
  it "should run on multiples groups" do
42
- ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT, 5)
43
-
44
- User.using(:canada).where(:name => "MultipleGroup").all.size.should == 2
45
- User.using(:brazil).where(:name => "MultipleGroup").all.size.should == 2
46
- User.using(:russia).where(:name => "MultipleGroup").all.size.should == 2
47
-
48
- ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT, 5)
34
+ migrating_to_version 5 do
35
+ User.using(:canada).where(:name => "MultipleGroup").all.size.should == 2
36
+ User.using(:brazil).where(:name => "MultipleGroup").all.size.should == 2
37
+ User.using(:russia).where(:name => "MultipleGroup").all.size.should == 2
38
+ end
49
39
  end
50
40
 
51
41
  describe "should raise a exception when" do
@@ -66,13 +56,26 @@ describe Octopus::Migration do
66
56
  end
67
57
  end
68
58
 
69
- describe "when using replication" do
59
+ describe "when using replication" do
70
60
  it "should run writes on master when you use replication" do
71
- pending()
61
+ using_enviroment :production_replicated do
62
+ migrating_to_version 10 do
63
+ Cat.using(:master).where(:name => "Replication").first.should_not be_nil
64
+ Cat.where(:name => "Replication").first.should be_nil
65
+ end
66
+ end
72
67
  end
73
68
 
74
69
  it "should run in all shards, master or another shards" do
75
- pending()
70
+ using_enviroment :production_replicated do
71
+ migrating_to_version 11 do
72
+ [:slave4, :slave1, :slave2, :slave3].each do |sym|
73
+ Cat.using(sym).find_by_name("Slaves").should_not be_nil
74
+ end
75
+
76
+ Cat.using(:master).find_by_name("Slaves").should be_nil
77
+ end
78
+ end
76
79
  end
77
80
  end
78
81
  end
@@ -30,26 +30,26 @@ describe Octopus::Model do
30
30
  User.using(:brazil).count.should == 0
31
31
  User.count.should == 0
32
32
  end
33
-
33
+
34
34
  describe "passing a block" do
35
35
  it "should allow queries be executed inside the block, ponting to a specific shard" do
36
- User.using(:canada) do
37
- User.create(:name => "oi")
38
- end
36
+ User.using(:canada) do
37
+ User.create(:name => "oi")
38
+ end
39
39
 
40
- User.using(:canada).count.should == 1
41
- User.using(:master).count.should == 0
42
- User.count.should == 0
43
- end
40
+ User.using(:canada).count.should == 1
41
+ User.using(:master).count.should == 0
42
+ User.count.should == 0
43
+ end
44
44
 
45
- it "should allow execute queries inside a model" do
46
- u = User.new
47
- u.awesome_queries()
48
- User.using(:canada).count.should == 1
49
- User.count.should == 0
50
- end
45
+ it "should allow execute queries inside a model" do
46
+ u = User.new
47
+ u.awesome_queries()
48
+ User.using(:canada).count.should == 1
49
+ User.count.should == 0
50
+ end
51
51
  end
52
-
52
+
53
53
  describe "when you have a relationship" do
54
54
  it "should find all models in the specified shard" do
55
55
  pending()
@@ -63,7 +63,7 @@ describe Octopus::Model do
63
63
  # c.items.should == [item_brazil]
64
64
  end
65
65
  end
66
-
66
+
67
67
  describe "raising errors" do
68
68
  it "should raise a error when you specify a shard that doesn't exist" do
69
69
  lambda { User.using(:crazy_shard) }.should raise_error("Nonexistent Shard Name: crazy_shard")
@@ -72,51 +72,30 @@ describe Octopus::Model do
72
72
  end
73
73
 
74
74
  describe "using a postgresql shard" do
75
- after(:each) do
76
- User.using(:postgresql_shard).delete_all
77
- end
78
-
79
75
  it "should update the Arel Engine" do
80
76
  User.using(:postgresql_shard).arel_engine.connection.adapter_name.should == "PostgreSQL"
81
77
  User.using(:alone_shard).arel_engine.connection.adapter_name.should == "MySQL"
82
78
  end
83
-
79
+
84
80
  it "should works with writes and reads" do
85
- pending()
86
- #u = User.using(:postgresql_shard).create!(:name => "PostgreSQL User")
87
- # #User.using(:postgresql_shard).arel_table.columns.should == ""
88
- # User.using(:postgresql_shard).scoped.should == ""
89
- # User.using(:alone_shard).find(:all).should == []
81
+ u = User.using(:postgresql_shard).create!(:name => "PostgreSQL User")
82
+ User.using(:postgresql_shard).all.should == [u]
83
+ User.using(:alone_shard).find(:all).should == []
90
84
  end
91
85
  end
92
-
86
+
93
87
  describe "#replicated_model method" do
94
- before(:each) do
95
- Octopus.stub!(:env).and_return("production_replicated")
96
- @proxy = Octopus::Proxy.new(Octopus.config())
97
- #TODO - This is ugly, but is better than mocking
98
- ActiveRecord::Base.class_eval("@@connection_proxy = nil")
99
- #TODO - This is ugly, but is better than mocking
100
- end
101
-
102
- after(:each) do
103
- #TODO - One little Kitten dies each time this code is executed.
104
- ActiveRecord::Base.class_eval("@@connection_proxy = nil")
105
- end
106
-
107
88
  it "should be replicated" do
108
- ActiveRecord::Base.connection_proxy.replicated.should be_true
89
+ using_enviroment :production_replicated do
90
+ ActiveRecord::Base.connection_proxy.replicated.should be_true
91
+ end
109
92
  end
110
-
93
+
111
94
  it "should mark the Cat model as replicated" do
112
- Cat.all.should == []
113
- ActiveRecord::Base.connection_proxy.replicated_models.first.should == "Cat"
114
- end
115
- end
116
-
117
- describe "#sharded_by method" do
118
- it "should send all queries to the specify shard" do
119
- pending()
95
+ using_enviroment :production_replicated do
96
+ Cat.all.should == []
97
+ ActiveRecord::Base.connection_proxy.replicated_models.first.should == "Cat"
98
+ end
120
99
  end
121
100
  end
122
101
  end
@@ -62,7 +62,6 @@ describe Octopus::Proxy do
62
62
  before(:each) do
63
63
  Octopus.stub!(:env).and_return("production_replicated")
64
64
  @proxy = Octopus::Proxy.new(Octopus.config())
65
- #TODO - THIS IS SO UGLY
66
65
  ActiveRecord::Base.class_eval("@@connection_proxy = nil")
67
66
  end
68
67
 
@@ -2,6 +2,8 @@ MIGRATIONS_ROOT = File.expand_path(File.join(File.dirname(__FILE__), 'migration
2
2
  require 'spec'
3
3
  require 'spec/autorun'
4
4
  require "database_connection"
5
+ require "action_pack"
6
+ require "action_controller"
5
7
  require 'octopus'
6
8
 
7
9
  Spec::Runner.configure do |config|
@@ -24,4 +26,24 @@ def clean_all_shards()
24
26
  ActiveRecord::Base.using(shard_symbol).connection.execute("DELETE FROM #{tables};")
25
27
  end
26
28
  end
29
+ end
30
+
31
+ def migrating_to_version(version, &block)
32
+ begin
33
+ ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT, version)
34
+ yield
35
+ ensure
36
+ ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT, version)
37
+ end
38
+ end
39
+
40
+ def using_enviroment(enviroment, &block)
41
+ begin
42
+ Octopus.class_eval("@@env = '#{enviroment.to_s}'")
43
+ ActiveRecord::Base.class_eval("@@connection_proxy = nil")
44
+ yield
45
+ ensure
46
+ Octopus.class_eval("@@env = 'production'")
47
+ ActiveRecord::Base.class_eval("@@connection_proxy = nil")
48
+ end
27
49
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Thiago Pradi
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-06-11 00:00:00 -03:00
19
+ date: 2010-06-14 00:00:00 -03:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -42,9 +42,11 @@ extensions: []
42
42
  extra_rdoc_files:
43
43
  - README.mkdn
44
44
  files:
45
+ - .gitignore
45
46
  - README.mkdn
46
47
  - Rakefile
47
48
  - VERSION
49
+ - ar-octopus.gemspec
48
50
  - doc/api.textile
49
51
  - doc/features.textile
50
52
  - doc/libraries.textile
@@ -57,6 +59,8 @@ files:
57
59
  - spec/config/shards.yml
58
60
  - spec/database_connection.rb
59
61
  - spec/database_models.rb
62
+ - spec/migrations/10_create_users_using_replication.rb
63
+ - spec/migrations/11_add_field_in_all_slaves.rb
60
64
  - spec/migrations/1_create_users_on_master.rb
61
65
  - spec/migrations/2_create_users_on_canada.rb
62
66
  - spec/migrations/3_create_users_on_both_shards.rb
@@ -106,6 +110,8 @@ summary: Easy Database Sharding for ActiveRecord
106
110
  test_files:
107
111
  - spec/database_connection.rb
108
112
  - spec/database_models.rb
113
+ - spec/migrations/10_create_users_using_replication.rb
114
+ - spec/migrations/11_add_field_in_all_slaves.rb
109
115
  - spec/migrations/1_create_users_on_master.rb
110
116
  - spec/migrations/2_create_users_on_canada.rb
111
117
  - spec/migrations/3_create_users_on_both_shards.rb