rails-sharding 0.1.1 → 1.0.0

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: 05fd12669243e14c2d6f1b1748acf461b8316dbb
4
- data.tar.gz: d1508fddee17b0a5c7eb0203b8dd1c9b52b74c66
3
+ metadata.gz: cbec123e1537bac8bf7f3b6d2e711cfefa156f41
4
+ data.tar.gz: 4fae6ab76f8b687746436585a74d618c5f4a2308
5
5
  SHA512:
6
- metadata.gz: 5ea75e62463c090f6806baedfd648768007c192d4e3a9e162c162083eb015cacb8eb6dfbc8ed0ce739bb9cc17c9a3889abc6b0bd02bb24f3f76470478996e85c
7
- data.tar.gz: 524dfe1e8c7ea123209746accfdb726ea0a6011f43c460cbcf2cff3c11531b2ee7afa99c26091d54ad8792dd05dca62aff2badaee5290babb1f72631ed0e94d0
6
+ metadata.gz: f8488d56f2e5eb38df46f138d4ad7ac28bc12008ee08383f984268fd3201629bb3eebeb54c96120bddf846e2e1f39f171e38fc4ab52457bbcdbcafa805b0e72c
7
+ data.tar.gz: 95a78672f724efa645c911d0d824b57be1dcf43d96257be54aab15e92ba544b81ce370e3a9131ee5abdd27f4605a8a49a5e45dd66dd00f4e4f58b3c7dfc48f28
data/README.md CHANGED
@@ -27,7 +27,8 @@ You can also use the block syntax, where all your queries inside will be directe
27
27
  You can also pick and choose which models will be shardable, so that all the models that are not shardable will still be retrieved from the master database, even if inside a using_shard block.
28
28
 
29
29
  ## Compatibility
30
- As of now this gem has been tested only with Rails 4.2. It does not work yet with Rails 5.
30
+ Gem version 0.1.1 -> compatible with Rails 4.2
31
+ Gem version 1.0.0 -> compatible with Rails 5.0
31
32
 
32
33
  ## Installation
33
34
 
@@ -83,7 +84,7 @@ rake shards:create
83
84
  Go to the directory `db/shards_migrations/shard_group1` and add all migrations that you want to run on the shards of `shard_group1`. By design, all shards in a same group should always have the same schema. For example, add the following migration to your `db/shards_migrations/shard_group1`:
84
85
  ```ruby
85
86
  # 20160808000000_create_users.rb
86
- class CreateClients < ActiveRecord::Migration
87
+ class CreateClients < ActiveRecord::Migration[5.0]
87
88
  def up
88
89
  create_table :users do |t|
89
90
  t.string :username, :limit => 100
@@ -154,4 +155,4 @@ The gem is available as open source under the terms of the [MIT License](http://
154
155
 
155
156
  ## Acknowledgements
156
157
 
157
- This gem was inspired and based on several other gems like: [octopus](https://github.com/thiagopradi/octopus), [shard_handler](https://github.com/locaweb/shard_handler) and [active_record_shards](https://github.com/zendesk/active_record_shards).
158
+ This gem was inspired on several other gems like: [octopus](https://github.com/thiagopradi/octopus), [shard_handler](https://github.com/locaweb/shard_handler) and [active_record_shards](https://github.com/zendesk/active_record_shards).
@@ -17,40 +17,43 @@ module Rails::Sharding
17
17
  def self.establish_connection(shard_group, shard_name, environment=nil)
18
18
  self.setup unless defined? @@connection_handler
19
19
 
20
- unless configurations = (environment.nil? ? Core.configurations : Core.configurations(environment))
20
+ configurations = (environment.nil? ? Core.configurations : Core.configurations(environment))
21
+ if configurations.nil?
21
22
  raise Errors::ConfigNotFoundError, "Cannot find configuration for environment '#{environment}' in #{Config.shards_config_file}"
22
23
  end
23
24
 
24
- unless shard_group_configurations = configurations[shard_group.to_s]
25
+ shard_group_configurations = configurations[shard_group.to_s]
26
+ if shard_group_configurations.nil?
25
27
  raise Errors::ConfigNotFoundError, "Cannot find configuration for shard_group '#{shard_group}' in environment '#{environment}' in #{Config.shards_config_file}"
26
28
  end
27
29
 
28
30
  resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(shard_group_configurations)
29
31
  begin
30
- connection_spec = resolver.spec(shard_name.to_sym)
31
- rescue ActiveRecord::AdapterNotSpecified => e
32
+ connection_name = connection_name(shard_group, shard_name)
33
+ connection_spec = resolver.spec(shard_name.to_sym, connection_name)
34
+ rescue ActiveRecord::AdapterNotSpecified
32
35
  raise Errors::ConfigNotFoundError, "Cannot find configuration for shard '#{shard_group}:#{shard_name}' in environment '#{environment}' in #{Config.shards_config_file}"
33
36
  end
34
37
 
35
- # since rails requires a class to be the connection owner, we trick rails passing
36
- # an instance of the ConnectionPoolOwner class, that responds to the #name method
37
- connection_handler.establish_connection(connection_pool_owner(shard_group, shard_name), connection_spec)
38
+ connection_handler.establish_connection(connection_spec)
38
39
  end
39
40
 
40
41
  def self.connection_pool(shard_group, shard_name)
41
- connection_handler.retrieve_connection_pool(connection_pool_owner(shard_group, shard_name))
42
- rescue Errors::ConnectionPoolRetrievalError
42
+ if connection_pool = connection_handler.retrieve_connection_pool(connection_name(shard_group, shard_name))
43
+ return connection_pool
44
+ end
45
+
43
46
  # mimicking behavior of rails at:
44
- # https://github.com/rails/rails/blob/4-2-stable/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#507
45
- raise ActiveRecord::ConnectionNotEstablished, "No connection pool for shard #{connection_name(shard_group, shard_name)}"
47
+ # https://github.com/rails/rails/blob/v5.0.0.1/activerecord/lib/active_record/connection_handling.rb#124
48
+ raise ActiveRecord::ConnectionNotEstablished, "No connection pool for shard #{connection_name(shard_group, shard_name)}" if connection_pool.nil?
46
49
  end
47
50
 
48
51
  def self.retrieve_connection(shard_group, shard_name)
49
- connection_handler.retrieve_connection(connection_pool_owner(shard_group, shard_name))
52
+ connection_handler.retrieve_connection(connection_name(shard_group, shard_name))
50
53
  end
51
54
 
52
55
  def self.connected?(shard_group, shard_name)
53
- connection_handler.connected?(connection_pool_owner(shard_group, shard_name))
56
+ connection_handler.connected?(connection_name(shard_group, shard_name))
54
57
  end
55
58
 
56
59
  def self.with_connection(shard_group, shard_name, &block)
@@ -58,7 +61,7 @@ module Rails::Sharding
58
61
  end
59
62
 
60
63
  def self.remove_connection(shard_group, shard_name)
61
- connection_handler.remove_connection(connection_pool_owner(shard_group, shard_name))
64
+ connection_handler.remove_connection(connection_name(shard_group, shard_name))
62
65
  end
63
66
 
64
67
  private
@@ -70,35 +73,11 @@ module Rails::Sharding
70
73
 
71
74
  def self.setup
72
75
  @@connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
73
- @@connection_pool_owners = {}
74
- end
75
-
76
- def self.connection_pool_owner(shard_group, shard_name)
77
- connection_name = self.connection_name(shard_group, shard_name)
78
- @@connection_pool_owners[connection_name] ||= ConnectionPoolOwner.new(connection_name)
79
76
  end
80
77
 
81
78
  # Assembles connection name in the format "shard_group:shard_name"
82
79
  def self.connection_name(shard_group, shard_name)
83
80
  shard_group.to_s + ':' + shard_name.to_s
84
81
  end
85
-
86
- class ConnectionPoolOwner
87
- attr_reader :name
88
-
89
- def initialize(name)
90
- @name = name
91
- end
92
-
93
- # Safeguard in case pool cannot be retrieved for owner. This makes the error clear
94
- def superclass
95
- raise Errors::ConnectionPoolRetrievalError, "ConnectionPool could not be retrieved for #{self}. See https://github.com/rails/rails/blob/4-2-stable/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#607"
96
- end
97
-
98
- # in case owner ends up printed by rails in an error message when retrieving connection
99
- def to_s
100
- "ConnectionPoolOwner with name #{self.name}"
101
- end
102
- end
103
82
  end
104
83
  end
@@ -14,8 +14,14 @@ module Rails::Sharding
14
14
 
15
15
  ShardThreadRegistry.current_shard_group = shard_group
16
16
  ShardThreadRegistry.current_shard_name = shard_name
17
+ ShardThreadRegistry.shard_connection_used = false
17
18
  yield
18
19
  ensure
20
+ # shows warning to user
21
+ if !ShardThreadRegistry.shard_connection_used
22
+ puts "Warning: no connection to shard '#{ShardThreadRegistry.current_shard_group}:#{ShardThreadRegistry.current_shard_name}' was made inside the using_shard block. Make sure you don't forget to include Rails::Sharding::ShardableModel to the models you want to be sharded"
23
+ end
24
+
19
25
  # Releases connections in case user left some connection in the reserved state
20
26
  # (by calling retrieve_connection instead of with_connection). Also, using
21
27
  # normal activerecord queries leaves a connection in the reserved state
@@ -26,7 +32,7 @@ module Rails::Sharding
26
32
  def self.configurations(environment=Rails.env)
27
33
  @@db_configs ||= YAML.load_file(Config.shards_config_file)
28
34
  @@db_configs[environment]
29
- rescue Errno::ENOENT => e
35
+ rescue Errno::ENOENT
30
36
  raise Errors::ConfigNotFoundError, Config.shards_config_file.to_s + ' file was not found'
31
37
  end
32
38
 
@@ -46,6 +52,23 @@ module Rails::Sharding
46
52
  self.configurations[shard_group.to_s].keys
47
53
  end
48
54
 
55
+ # yields a block for each shard in each shard group, with its configurations
56
+ # shard_group_filter: if passed yields only shards of this group
57
+ # shard_name_filter: if passed yields only shards with this name
58
+ def self.for_each_shard(shard_group_filter=nil, shard_name_filter=nil)
59
+ shard_group_filter.to_s if shard_group_filter
60
+ shard_name_filter.to_s if shard_name_filter
61
+
62
+ configurations.each do |shard_group, shards_configurations|
63
+ next if shard_group_filter && shard_group_filter != shard_group.to_s
64
+
65
+ shards_configurations.each do |shard, configuration|
66
+ next if shard_name_filter && shard_name_filter != shard.to_s
67
+ yield shard_group, shard, configuration
68
+ end
69
+ end
70
+ end
71
+
49
72
  # Method that should be called on a rails initializer
50
73
  def self.setup
51
74
  if block_given?
@@ -1,11 +1,13 @@
1
- require 'active_support/per_thread_registry'
2
1
 
3
2
  module Rails::Sharding
4
3
  class ShardThreadRegistry
5
- # creates two thread-specific variables
6
- extend ActiveSupport::PerThreadRegistry
7
- attr_accessor :_current_shard_group
8
- attr_accessor :_current_shard_name
4
+ # creates two thread-specific variables to store the current shard of connection
5
+ thread_mattr_accessor :_current_shard_group
6
+ thread_mattr_accessor :_current_shard_name
7
+
8
+ # auxiliary variable used to check if shard connectio was used inside an
9
+ # using_shard block (so we can print an alert if not)
10
+ thread_mattr_accessor :shard_connection_used
9
11
 
10
12
  def self.connecting_to_master?
11
13
  current_shard_group.nil? || current_shard_name.nil?
@@ -18,6 +20,7 @@ module Rails::Sharding
18
20
  def self.connect_back_to_master!
19
21
  self.current_shard_group = nil
20
22
  self.current_shard_name = nil
23
+ self.shard_connection_used = false
21
24
  end
22
25
 
23
26
  # Returns the current shard group (for the current Thread)
@@ -35,6 +35,7 @@ module Rails::Sharding
35
35
  if ShardThreadRegistry.connecting_to_master?
36
36
  return original_connection_pool
37
37
  else
38
+ ShardThreadRegistry.shard_connection_used = true # records that shard connection was used at least once
38
39
  return ConnectionHandler.connection_pool(*ShardThreadRegistry.current_shard_group_and_name)
39
40
  end
40
41
  end
@@ -44,6 +45,7 @@ module Rails::Sharding
44
45
  if ShardThreadRegistry.connecting_to_master?
45
46
  return original_retrieve_connection
46
47
  else
48
+ ShardThreadRegistry.shard_connection_used = true # records that shard connection was used at least once
47
49
  return ConnectionHandler.retrieve_connection(*ShardThreadRegistry.current_shard_group_and_name)
48
50
  end
49
51
  end
@@ -1,5 +1,5 @@
1
1
  module Rails
2
2
  module Sharding
3
- VERSION = "0.1.1"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -8,29 +8,36 @@ shards_namespace = namespace :shards do
8
8
  ActiveRecord::Base.include(Rails::Sharding::ShardableModel) unless ActiveRecord::Base.ancestors.include? Rails::Sharding::ShardableModel
9
9
  end
10
10
 
11
- desc "Creates database shards (options: RAILS_ENV=x SHARD_GROUP=x SHARD=x)"
12
- task create: [:environment] do
11
+ # for each of the shards, check that 1) the environment set in the ar_internal_metadata
12
+ # table matches the current rails env and 2) it is not a protected environment
13
+ # (defined in ActiveRecord::Base.protected_environments)
14
+ desc "Checks if the environment is not protected and if the shards match the current environment (options: RAILS_ENV=x SHARD_GROUP=x SHARD=x)"
15
+ task check_protected_environments: [:_make_activerecord_base_shardable] do
13
16
  Rails::Sharding.configurations.each do |shard_group, shards_configurations|
14
17
  next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
15
18
 
16
- shards_configurations.each do |shard, configuration|
19
+ shards_configurations.each do |shard, _|
17
20
  next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
18
- puts "== Creating shard #{shard_group}:#{shard}"
19
- ActiveRecord::Tasks::DatabaseTasks.create(configuration)
21
+ Rails::Sharding.using_shard(shard_group, shard) do
22
+ ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!
23
+ end
20
24
  end
21
25
  end
22
26
  end
23
27
 
24
- desc "Drops database shards (options: RAILS_ENV=x SHARD_GROUP=x SHARD=x)"
25
- task drop: [:environment] do
26
- Rails::Sharding.configurations.each do |shard_group, shards_configurations|
27
- next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
28
+ desc "Creates database shards (options: RAILS_ENV=x SHARD_GROUP=x SHARD=x)"
29
+ task create: [:environment] do
30
+ Rails::Sharding.for_each_shard(ENV["SHARD_GROUP"], ENV["SHARD"]) do |shard_group, shard, configuration|
31
+ puts "== Creating shard #{shard_group}:#{shard}"
32
+ ActiveRecord::Tasks::DatabaseTasks.create(configuration)
33
+ end
34
+ end
28
35
 
29
- shards_configurations.each do |shard, configuration|
30
- next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
31
- puts "== Dropping shard #{shard_group}:#{shard}"
32
- ActiveRecord::Tasks::DatabaseTasks.drop(configuration)
33
- end
36
+ desc "Drops database shards (options: RAILS_ENV=x SHARD_GROUP=x SHARD=x)"
37
+ task drop: [:environment, :check_protected_environments] do
38
+ Rails::Sharding.for_each_shard(ENV["SHARD_GROUP"], ENV["SHARD"]) do |shard_group, shard, configuration|
39
+ puts "== Dropping shard #{shard_group}:#{shard}"
40
+ ActiveRecord::Tasks::DatabaseTasks.drop(configuration)
34
41
  end
35
42
  end
36
43
 
@@ -40,11 +47,9 @@ shards_namespace = namespace :shards do
40
47
  next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
41
48
 
42
49
  # configures path for migrations of this shard group and creates dir if necessary
43
- shard_group_migrations_dir = File.join(Rails::Sharding::Config.shards_migrations_dir, shard_group.to_s)
44
- ActiveRecord::Tasks::DatabaseTasks.migrations_paths = shard_group_migrations_dir
45
- FileUtils.mkdir_p(shard_group_migrations_dir)
50
+ setup_migrations_path(shard_group)
46
51
 
47
- shards_configurations.each do |shard, configuration|
52
+ shards_configurations.each do |shard, _|
48
53
  next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
49
54
  puts "== Migrating shard #{shard_group}:#{shard}"
50
55
  Rails::Sharding.using_shard(shard_group, shard) do
@@ -78,18 +83,13 @@ shards_namespace = namespace :shards do
78
83
  task dump: [:_make_activerecord_base_shardable] do
79
84
  require "active_record/schema_dumper"
80
85
 
81
- Rails::Sharding.configurations.each do |shard_group, shards_configurations|
82
- next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
86
+ Rails::Sharding.for_each_shard(ENV["SHARD_GROUP"], ENV["SHARD"]) do |shard_group, shard, _configuration|
87
+ puts "== Dumping schema of #{shard_group}:#{shard}"
83
88
 
84
- shards_configurations.each do |shard, configuration|
85
- next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
86
- puts "== Dumping schema of #{shard_group}:#{shard}"
87
-
88
- schema_filename = shard_schema_path(shard_group, shard)
89
- File.open(schema_filename, "w:utf-8") do |file|
90
- Rails::Sharding.using_shard(shard_group, shard) do
91
- ActiveRecord::SchemaDumper.dump(Rails::Sharding::ConnectionHandler.retrieve_connection(shard_group, shard), file)
92
- end
89
+ schema_filename = shard_schema_path(shard_group, shard)
90
+ File.open(schema_filename, "w:utf-8") do |file|
91
+ Rails::Sharding.using_shard(shard_group, shard) do
92
+ ActiveRecord::SchemaDumper.dump(Rails::Sharding::ConnectionHandler.retrieve_connection(shard_group, shard), file)
93
93
  end
94
94
  end
95
95
  end
@@ -100,13 +100,14 @@ shards_namespace = namespace :shards do
100
100
  end
101
101
 
102
102
  desc "Loads schema.rb file into the shards (options: RAILS_ENV=x, SHARD_GROUP=x, SHARD=x)"
103
- task load: [:_make_activerecord_base_shardable] do
103
+ task load: [:_make_activerecord_base_shardable, :check_protected_environments] do
104
104
  Rails::Sharding.configurations.each do |shard_group, shards_configurations|
105
105
  next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
106
106
 
107
+ # configures path for migrations of this shard group and creates dir if necessary
107
108
  setup_migrations_path(shard_group)
108
109
 
109
- shards_configurations.each do |shard, configuration|
110
+ shards_configurations.each do |shard, _|
110
111
  next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
111
112
  puts "== Loading schema of #{shard_group}:#{shard}"
112
113
 
@@ -125,7 +126,7 @@ shards_namespace = namespace :shards do
125
126
  end
126
127
 
127
128
  namespace :migrate do
128
- desc 'Rollbacks the shards one migration and re migrate up (options: RAILS_ENV=x, VERSION=x, STEP=x, SHARD_GROUP=x, SHARD=x).'
129
+ desc 'Rollbacks the shards one migration and re migrate up (options: RAILS_ENV=x, VERSION=x, STEP=x, SHARD_GROUP=x, SHARD=x).'
129
130
  task redo: [:environment] do
130
131
  if ENV["VERSION"]
131
132
  shards_namespace["migrate:down"].invoke
@@ -141,15 +142,15 @@ shards_namespace = namespace :shards do
141
142
 
142
143
  desc 'Runs the "up" for a given migration VERSION.'
143
144
  task up: [:_make_activerecord_base_shardable] do
144
- version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
145
- raise "VERSION is required" unless version
145
+ version = get_version_or_else "VERSION is required"
146
146
 
147
147
  Rails::Sharding.configurations.each do |shard_group, shards_configurations|
148
148
  next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
149
149
 
150
+ # configures path for migrations of this shard group and creates dir if necessary
150
151
  setup_migrations_path(shard_group)
151
152
 
152
- shards_configurations.each do |shard, configuration|
153
+ shards_configurations.each do |shard, _|
153
154
  next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
154
155
  puts "== Migrating up shard #{shard_group}:#{shard}"
155
156
  Rails::Sharding.using_shard(shard_group, shard) do
@@ -163,15 +164,15 @@ shards_namespace = namespace :shards do
163
164
 
164
165
  desc 'Runs the "down" for a given migration VERSION.'
165
166
  task down: [:_make_activerecord_base_shardable] do
166
- version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
167
- raise "VERSION is required - To go down one migration, run db:rollback" unless version
167
+ version = get_version_or_else "VERSION is required - To go down one migration, run db:rollback"
168
168
 
169
169
  Rails::Sharding.configurations.each do |shard_group, shards_configurations|
170
170
  next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
171
171
 
172
+ # configures path for migrations of this shard group and creates dir if necessary
172
173
  setup_migrations_path(shard_group)
173
174
 
174
- shards_configurations.each do |shard, configuration|
175
+ shards_configurations.each do |shard, _|
175
176
  next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
176
177
  puts "== Migrating down shard #{shard_group}:#{shard}"
177
178
  Rails::Sharding.using_shard(shard_group, shard) do
@@ -190,9 +191,10 @@ shards_namespace = namespace :shards do
190
191
  Rails::Sharding.configurations.each do |shard_group, shards_configurations|
191
192
  next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
192
193
 
194
+ # configures path for migrations of this shard group and creates dir if necessary
193
195
  setup_migrations_path(shard_group)
194
196
 
195
- shards_configurations.each do |shard, configuration|
197
+ shards_configurations.each do |shard, _|
196
198
  next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
197
199
  puts "== Rolling back shard #{shard_group}:#{shard}"
198
200
  Rails::Sharding.using_shard(shard_group, shard) do
@@ -206,15 +208,9 @@ shards_namespace = namespace :shards do
206
208
 
207
209
  desc "Retrieves the current schema version number"
208
210
  task version: [:_make_activerecord_base_shardable] do
209
- Rails::Sharding.configurations.each do |shard_group, shards_configurations|
210
- next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
211
-
212
- shards_configurations.each do |shard, configuration|
213
- next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
214
-
215
- Rails::Sharding.using_shard(shard_group, shard) do
216
- puts "Shard #{shard_group}:#{shard} version: #{ActiveRecord::Migrator.current_version}"
217
- end
211
+ Rails::Sharding.for_each_shard(ENV["SHARD_GROUP"], ENV["SHARD"]) do |shard_group, shard, _configuration|
212
+ Rails::Sharding.using_shard(shard_group, shard) do
213
+ puts "Shard #{shard_group}:#{shard} version: #{ActiveRecord::Migrator.current_version}"
218
214
  end
219
215
  end
220
216
  end
@@ -226,9 +222,10 @@ shards_namespace = namespace :shards do
226
222
  Rails::Sharding.test_configurations.each do |shard_group, shards_configurations|
227
223
  next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
228
224
 
225
+ # configures path for migrations of this shard group and creates dir if necessary
229
226
  setup_migrations_path(shard_group)
230
227
 
231
- shards_configurations.each do |shard, configuration|
228
+ shards_configurations.each do |shard, _|
232
229
  next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
233
230
 
234
231
  puts "== Loading test schema on shard #{shard_group}:#{shard}"
@@ -237,6 +234,10 @@ shards_namespace = namespace :shards do
237
234
  should_reconnect = Rails::Sharding::ConnectionHandler.connection_pool(shard_group, shard).active_connection?
238
235
  Rails::Sharding::ConnectionHandler.establish_connection(shard_group, shard, 'test')
239
236
 
237
+ # saves the current RAILS_ENV (we must change it so the environment is set correcly on the metadata table)
238
+ initial_rails_env = Rails.env
239
+ Rails.env = 'test'
240
+
240
241
  schema_filename = shard_schema_path(shard_group, shard)
241
242
  ActiveRecord::Tasks::DatabaseTasks.check_schema_file(schema_filename)
242
243
  Rails::Sharding.using_shard(shard_group, shard) do
@@ -244,6 +245,9 @@ shards_namespace = namespace :shards do
244
245
  load(schema_filename)
245
246
  end
246
247
  ensure
248
+ # restores rails env
249
+ Rails.env = initial_rails_env
250
+
247
251
  if should_reconnect
248
252
  # reestablishes connection for RAILS_ENV environment (whatever that is)
249
253
  Rails::Sharding::ConnectionHandler.establish_connection(shard_group, shard)
@@ -262,26 +266,20 @@ shards_namespace = namespace :shards do
262
266
 
263
267
  desc "Empty the test shards (drops all tables) (options: SHARD_GROUP=x, SHARD=x)"
264
268
  task :purge => [:_make_activerecord_base_shardable] do
265
- Rails::Sharding.test_configurations.each do |shard_group, shards_configurations|
266
- next if ENV["SHARD_GROUP"] && ENV["SHARD_GROUP"] != shard_group.to_s
267
-
268
- shards_configurations.each do |shard, configuration|
269
- next if ENV["SHARD"] && ENV["SHARD"] != shard.to_s
270
-
271
- puts "== Purging test shard #{shard_group}:#{shard}"
272
- begin
273
- # establishes connection with test shard, saving if it was connected before (rails 4.2 doesn't do this, but should)
274
- should_reconnect = Rails::Sharding::ConnectionHandler.connection_pool(shard_group, shard).active_connection?
275
- Rails::Sharding::ConnectionHandler.establish_connection(shard_group, shard, 'test')
269
+ Rails::Sharding.for_each_shard(ENV["SHARD_GROUP"], ENV["SHARD"]) do |shard_group, shard, configuration|
270
+ puts "== Purging test shard #{shard_group}:#{shard}"
271
+ begin
272
+ # establishes connection with test shard, saving if it was connected before (rails 4.2 doesn't do this, but should)
273
+ should_reconnect = Rails::Sharding::ConnectionHandler.connection_pool(shard_group, shard).active_connection?
274
+ Rails::Sharding::ConnectionHandler.establish_connection(shard_group, shard, 'test')
276
275
 
277
- Rails::Sharding.using_shard(shard_group, shard) do
278
- ActiveRecord::Tasks::DatabaseTasks.purge(configuration)
279
- end
280
- ensure
281
- if should_reconnect
282
- # reestablishes connection for RAILS_ENV environment (whatever that is)
283
- Rails::Sharding::ConnectionHandler.establish_connection(shard_group, shard)
284
- end
276
+ Rails::Sharding.using_shard(shard_group, shard) do
277
+ ActiveRecord::Tasks::DatabaseTasks.purge(configuration)
278
+ end
279
+ ensure
280
+ if should_reconnect
281
+ # reestablishes connection for RAILS_ENV environment (whatever that is)
282
+ Rails::Sharding::ConnectionHandler.establish_connection(shard_group, shard)
285
283
  end
286
284
  end
287
285
  end
@@ -304,4 +302,10 @@ shards_namespace = namespace :shards do
304
302
  FileUtils.mkdir_p(shard_group_schemas_dir)
305
303
  File.join(shard_group_schemas_dir, shard_name + "_schema.rb")
306
304
  end
305
+
306
+ def get_version_or_else(error_message='VERSION is required')
307
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
308
+ raise error_message unless version
309
+ version
310
+ end
307
311
  end
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  spec.require_paths = ["lib"]
25
25
 
26
- spec.add_runtime_dependency 'rails', '>= 4.2', '< 5.0'
26
+ spec.add_runtime_dependency 'rails', '~> 5.0'
27
27
 
28
28
  spec.add_development_dependency "bundler", "~> 1.12"
29
29
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,33 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-sharding
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrique Gubert
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-07 00:00:00.000000000 Z
11
+ date: 2016-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '4.2'
20
- - - "<"
17
+ - - "~>"
21
18
  - !ruby/object:Gem::Version
22
19
  version: '5.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: '4.2'
30
- - - "<"
24
+ - - "~>"
31
25
  - !ruby/object:Gem::Version
32
26
  version: '5.0'
33
27
  - !ruby/object:Gem::Dependency