ar-octopus 0.0.1 → 0.0.2

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