activerecord-turntable 1.1.2 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/.travis.yml +3 -5
- data/CHANGELOG.md +70 -0
- data/Guardfile +7 -5
- data/README.md +490 -0
- data/Rakefile +37 -22
- data/activerecord-turntable.gemspec +37 -34
- data/gemfiles/rails4_0.gemfile +6 -0
- data/gemfiles/rails4_1.gemfile +6 -0
- data/lib/active_record/turntable/active_record_ext/abstract_adapter.rb +14 -29
- data/lib/active_record/turntable/active_record_ext/activerecord_import_ext.rb +45 -0
- data/lib/active_record/turntable/active_record_ext/acts_as_archive_extension.rb +21 -0
- data/lib/active_record/turntable/active_record_ext/association.rb +85 -0
- data/lib/active_record/turntable/active_record_ext/association_preloader.rb +37 -0
- data/lib/active_record/turntable/active_record_ext/clever_load.rb +33 -76
- data/lib/active_record/turntable/active_record_ext/connection_handler_extension.rb +31 -0
- data/lib/active_record/turntable/active_record_ext/database_tasks.rb +81 -0
- data/lib/active_record/turntable/active_record_ext/fixtures.rb +54 -42
- data/lib/active_record/turntable/active_record_ext/locking_optimistic.rb +101 -0
- data/lib/active_record/turntable/active_record_ext/log_subscriber.rb +28 -46
- data/lib/active_record/turntable/active_record_ext/migration_proxy.rb +7 -0
- data/lib/active_record/turntable/active_record_ext/persistence.rb +96 -94
- data/lib/active_record/turntable/active_record_ext/relation.rb +31 -0
- data/lib/active_record/turntable/active_record_ext/schema_dumper.rb +18 -28
- data/lib/active_record/turntable/active_record_ext/transactions.rb +9 -3
- data/lib/active_record/turntable/active_record_ext.rb +26 -11
- data/lib/active_record/turntable/algorithm/base.rb +1 -1
- data/lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb +1 -1
- data/lib/active_record/turntable/algorithm.rb +7 -3
- data/lib/active_record/turntable/base.rb +67 -14
- data/lib/active_record/turntable/cluster.rb +46 -2
- data/lib/active_record/turntable/config.rb +1 -1
- data/lib/active_record/turntable/connection_proxy/mixable.rb +7 -29
- data/lib/active_record/turntable/connection_proxy.rb +61 -72
- data/lib/active_record/turntable/error.rb +5 -6
- data/lib/active_record/turntable/helpers.rb +5 -1
- data/lib/active_record/turntable/migration.rb +9 -49
- data/lib/active_record/turntable/mixer/fader/calculate_shards_sum_result.rb +13 -2
- data/lib/active_record/turntable/mixer/fader/select_shards_merge_result.rb +17 -6
- data/lib/active_record/turntable/mixer/fader/specified_shard.rb +3 -1
- data/lib/active_record/turntable/mixer/fader.rb +12 -10
- data/lib/active_record/turntable/mixer.rb +59 -29
- data/lib/active_record/turntable/plugin.rb +6 -0
- data/lib/active_record/turntable/pool_proxy.rb +12 -19
- data/lib/active_record/turntable/rack/query_cache.rb +20 -23
- data/lib/active_record/turntable/rack.rb +4 -2
- data/lib/active_record/turntable/railtie.rb +4 -3
- data/lib/active_record/turntable/railties/databases.rake +81 -122
- data/lib/active_record/turntable/seq_shard.rb +1 -1
- data/lib/active_record/turntable/sequencer/api.rb +1 -1
- data/lib/active_record/turntable/sequencer/barrage.rb +28 -0
- data/lib/active_record/turntable/sequencer.rb +27 -9
- data/lib/active_record/turntable/shard.rb +2 -2
- data/lib/active_record/turntable/sql_tree_patch.rb +1 -1
- data/lib/active_record/turntable/version.rb +1 -1
- data/lib/active_record/turntable.rb +26 -16
- data/lib/generators/templates/turntable.yml +9 -7
- data/spec/active_record/turntable/active_record_ext/association_preloader_spec.rb +78 -0
- data/spec/active_record/turntable/active_record_ext/association_spec.rb +72 -0
- data/spec/active_record/turntable/active_record_ext/clever_load_spec.rb +25 -46
- data/spec/active_record/turntable/active_record_ext/locking_optimistic_spec.rb +28 -0
- data/spec/active_record/turntable/active_record_ext/persistence_spec.rb +46 -25
- data/spec/active_record/turntable/algorithm/range_algorithm_spec.rb +4 -4
- data/spec/active_record/turntable/algorithm/range_bsearch_algorithm_spec.rb +35 -0
- data/spec/active_record/turntable/algorithm_spec.rb +28 -12
- data/spec/active_record/turntable/base_spec.rb +1 -1
- data/spec/active_record/turntable/cluster_spec.rb +27 -5
- data/spec/active_record/turntable/config_spec.rb +2 -2
- data/spec/active_record/turntable/connection_proxy_spec.rb +112 -45
- data/spec/active_record/turntable/finder_spec.rb +24 -11
- data/spec/active_record/turntable/mixer_spec.rb +21 -21
- data/spec/active_record/turntable/rack/query_cache_spec.rb +19 -0
- data/spec/active_record/turntable/sequencer/api_spec.rb +38 -0
- data/spec/active_record/turntable/sequencer/barrage_spec.rb +22 -0
- data/spec/active_record/turntable/sequencer/mysql_spec.rb +22 -0
- data/spec/active_record/turntable/shard_spec.rb +1 -1
- data/spec/active_record/turntable/transaction_spec.rb +35 -0
- data/spec/active_record/turntable_spec.rb +4 -4
- data/spec/config/database.yml +24 -34
- data/spec/config/turntable.yml +18 -1
- data/spec/fabricators/turntable_fabricator.rb +0 -2
- data/spec/models/card.rb +3 -0
- data/spec/models/cards_user.rb +10 -0
- data/spec/models/cards_users_histories.rb +7 -0
- data/spec/models/events_users_history.rb +7 -0
- data/spec/models/user.rb +7 -0
- data/spec/models/user_status.rb +6 -0
- data/spec/spec_helper.rb +10 -4
- data/spec/support/matchers/be_saved_to.rb +6 -0
- data/spec/support/turntable_helper.rb +29 -0
- metadata +124 -74
- data/README.rdoc +0 -294
- data/gemfiles/rails3_0.gemfile +0 -7
- data/gemfiles/rails3_1.gemfile +0 -6
- data/gemfiles/rails3_2.gemfile +0 -6
- data/lib/active_record/turntable/compatible.rb +0 -19
- data/sample_app/.gitignore +0 -16
- data/sample_app/Gemfile +0 -41
- data/sample_app/README.rdoc +0 -261
- data/sample_app/Rakefile +0 -7
- data/sample_app/app/assets/images/rails.png +0 -0
- data/sample_app/app/assets/javascripts/application.js +0 -15
- data/sample_app/app/assets/stylesheets/application.css +0 -13
- data/sample_app/app/controllers/application_controller.rb +0 -3
- data/sample_app/app/helpers/application_helper.rb +0 -2
- data/sample_app/app/mailers/.gitkeep +0 -0
- data/sample_app/app/models/.gitkeep +0 -0
- data/sample_app/app/models/user.rb +0 -4
- data/sample_app/app/views/layouts/application.html.erb +0 -14
- data/sample_app/config/application.rb +0 -65
- data/sample_app/config/boot.rb +0 -6
- data/sample_app/config/database.yml +0 -70
- data/sample_app/config/environment.rb +0 -5
- data/sample_app/config/environments/development.rb +0 -37
- data/sample_app/config/environments/production.rb +0 -67
- data/sample_app/config/environments/test.rb +0 -37
- data/sample_app/config/initializers/backtrace_silencers.rb +0 -7
- data/sample_app/config/initializers/inflections.rb +0 -15
- data/sample_app/config/initializers/mime_types.rb +0 -5
- data/sample_app/config/initializers/secret_token.rb +0 -7
- data/sample_app/config/initializers/session_store.rb +0 -8
- data/sample_app/config/initializers/wrap_parameters.rb +0 -14
- data/sample_app/config/locales/en.yml +0 -5
- data/sample_app/config/routes.rb +0 -58
- data/sample_app/config/turntable.yml +0 -64
- data/sample_app/config.ru +0 -4
- data/sample_app/db/migrate/20120316073058_create_users.rb +0 -11
- data/sample_app/db/seeds.rb +0 -7
- data/sample_app/lib/assets/.gitkeep +0 -0
- data/sample_app/lib/tasks/.gitkeep +0 -0
- data/sample_app/log/.gitkeep +0 -0
- data/sample_app/public/404.html +0 -26
- data/sample_app/public/422.html +0 -26
- data/sample_app/public/500.html +0 -25
- data/sample_app/public/favicon.ico +0 -0
- data/sample_app/public/index.html +0 -241
- data/sample_app/public/robots.txt +0 -5
- data/sample_app/script/rails +0 -6
- data/sample_app/vendor/assets/javascripts/.gitkeep +0 -0
- data/sample_app/vendor/assets/stylesheets/.gitkeep +0 -0
- data/sample_app/vendor/plugins/.gitkeep +0 -0
- data/spec/test_models.rb +0 -27
- data/spec/turntable_helper.rb +0 -29
@@ -1,41 +1,38 @@
|
|
1
|
+
require 'rack/body_proxy'
|
1
2
|
require 'active_record/query_cache'
|
2
3
|
|
3
4
|
module ActiveRecord
|
4
5
|
module Turntable
|
5
6
|
module Rack
|
6
7
|
class QueryCache < ActiveRecord::QueryCache
|
7
|
-
class BodyProxy < ActiveRecord::QueryCache::BodyProxy
|
8
|
-
def close
|
9
|
-
@target.close if @target.respond_to?(:close)
|
10
|
-
ensure
|
11
|
-
klasses = [ActiveRecord::Base, *ActiveRecord::Base.turntable_connections.values]
|
12
|
-
ActiveRecord::Base.connection_id = @connection_id
|
13
|
-
klasses.each do |k|
|
14
|
-
k.connection.clear_query_cache
|
15
|
-
unless @original_cache_value
|
16
|
-
k.connection.disable_query_cache!
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
8
|
def call(env)
|
23
|
-
|
24
|
-
|
9
|
+
enabled = ActiveRecord::Base.connection.query_cache_enabled
|
10
|
+
connection_id = ActiveRecord::Base.connection_id
|
11
|
+
klasses = ActiveRecord::Base.turntable_connections.values
|
25
12
|
klasses.each do |k|
|
26
13
|
k.connection.enable_query_cache!
|
27
14
|
end
|
28
15
|
|
29
|
-
|
30
|
-
[
|
16
|
+
response = @app.call(env)
|
17
|
+
response[2] = ::Rack::BodyProxy.new(response[2]) do
|
18
|
+
restore_query_cache_settings(connection_id, enabled)
|
19
|
+
end
|
20
|
+
|
21
|
+
response
|
31
22
|
rescue Exception => e
|
23
|
+
restore_query_cache_settings(connection_id, enabled)
|
24
|
+
raise e
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def restore_query_cache_settings(connection_id, enabled)
|
30
|
+
klasses = ActiveRecord::Base.turntable_connections.values
|
32
31
|
klasses.each do |k|
|
32
|
+
ActiveRecord::Base.connection_id = connection_id
|
33
33
|
k.connection.clear_query_cache
|
34
|
-
unless
|
35
|
-
k.connection.disable_query_cache!
|
36
|
-
end
|
34
|
+
k.connection.disable_query_cache! unless enabled
|
37
35
|
end
|
38
|
-
raise e
|
39
36
|
end
|
40
37
|
end
|
41
38
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module ActiveRecord::Turntable
|
2
2
|
module Rack
|
3
|
-
|
4
|
-
|
3
|
+
extend ActiveSupport::Autoload
|
4
|
+
|
5
|
+
autoload :ConnectionManagement
|
6
|
+
autoload :QueryCache
|
5
7
|
end
|
6
8
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module ActiveRecord::Turntable
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
rake_tasks do
|
4
|
+
require 'active_record/turntable/active_record_ext/database_tasks'
|
4
5
|
load "active_record/turntable/railties/databases.rake"
|
5
6
|
end
|
6
7
|
|
@@ -11,9 +12,9 @@ module ActiveRecord::Turntable
|
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
|
-
#
|
15
|
-
initializer "turntable.
|
16
|
-
app.middleware.
|
15
|
+
# QueryCache Middleware for turntable shards
|
16
|
+
initializer "turntable.insert_query_cache_middleware" do |app|
|
17
|
+
app.middleware.insert_after ActiveRecord::QueryCache, ActiveRecord::Turntable::Rack::QueryCache
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -1,43 +1,69 @@
|
|
1
1
|
require 'active_record/turntable'
|
2
2
|
ActiveRecord::SchemaDumper.send(:include, ActiveRecord::Turntable::ActiveRecordExt::SchemaDumper)
|
3
3
|
|
4
|
+
# TODO: implement schema:cache:xxxx
|
5
|
+
|
4
6
|
db_namespace = namespace :db do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
dbs += ActiveRecord::Base.configurations["test"]["seq"].values if ActiveRecord::Base.configurations["test"]["seq"]
|
9
|
-
dbs.each do |shard_config|
|
10
|
-
create_database(shard_config)
|
11
|
-
end
|
7
|
+
namespace :create do
|
8
|
+
task :all => :load_config do
|
9
|
+
ActiveRecord::Tasks::DatabaseTasks.create_all_turntable_cluster
|
12
10
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'Create current turntable databases config/database.yml for the current Rails.env'
|
14
|
+
task :create => [:load_config] do
|
15
|
+
unless ENV['DATABASE_URL']
|
16
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current_turntable_cluster
|
19
17
|
end
|
20
|
-
config = ActiveRecord::Base.configurations[Rails.env || 'development']
|
21
|
-
ActiveRecord::Base.establish_connection(config)
|
22
18
|
end
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
20
|
+
namespace :drop do
|
21
|
+
task :all => :load_config do
|
22
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_all_turntable_cluster
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Drops current turntable databases for the current Rails.env'
|
27
|
+
task :drop => [:load_config] do
|
28
|
+
unless ENV['DATABASE_URL']
|
29
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_current_turntable_cluster
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Migrate turntable databases (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
34
|
+
task :migrate => [:environment, :load_config] do
|
35
|
+
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
36
|
+
|
37
|
+
ActiveRecord::Tasks::DatabaseTasks.each_current_turntable_cluster_connected do |name, configuration|
|
38
|
+
puts "[turntable] *** Migrating database: #{configuration['database']}(Shard: #{name})"
|
39
|
+
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
40
|
+
db_namespace['_dump'].invoke
|
37
41
|
end
|
38
|
-
ActiveRecord::Base.establish_connection(config)
|
39
42
|
end
|
40
43
|
|
44
|
+
desc 'Rolls the turntable cluster schema back to the previous version (specify steps w/ STEP=n).'
|
45
|
+
task :rollback => [:environment, :load_config] do
|
46
|
+
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
47
|
+
|
48
|
+
ActiveRecord::Tasks::DatabaseTasks.each_current_turntable_cluster_connected do |name, configuration|
|
49
|
+
puts "[turntable] *** Migrating database: #{configuration['database']}(Shard: #{name})"
|
50
|
+
ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
|
51
|
+
end
|
52
|
+
db_namespace['_dump'].invoke
|
53
|
+
end
|
54
|
+
|
55
|
+
# desc 'Pushes the turntable cluster schema to the next version (specify steps w/ STEP=n).'
|
56
|
+
task :forward => [:environment, :load_config] do
|
57
|
+
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
58
|
+
|
59
|
+
ActiveRecord::Tasks::DatabaseTasks.each_current_turntable_cluster_connected do |name, configuration|
|
60
|
+
puts "[turntable] *** Migrating database: #{configuration['database']}(Shard: #{name})"
|
61
|
+
ActiveRecord::Migrator.forward(ActiveRecord::Migrator.migrations_paths, step)
|
62
|
+
end
|
63
|
+
db_namespace['_dump'].invoke
|
64
|
+
end
|
65
|
+
|
66
|
+
|
41
67
|
namespace :schema do
|
42
68
|
task :dump do
|
43
69
|
require 'active_record/schema_dumper'
|
@@ -46,6 +72,7 @@ db_namespace = namespace :db do
|
|
46
72
|
shard_configs.merge!(config["seq"]) if config["seq"]
|
47
73
|
if shard_configs
|
48
74
|
shard_configs.each do |name, config|
|
75
|
+
next unless config["database"]
|
49
76
|
filename = ENV['SCHEMA'] || "#{Rails.root}/db/schema-#{name}.rb"
|
50
77
|
File.open(filename, "w:utf-8") do |file|
|
51
78
|
ActiveRecord::Base.establish_connection(config)
|
@@ -64,6 +91,7 @@ db_namespace = namespace :db do
|
|
64
91
|
shard_configs.merge!(config["seq"]) if config["seq"]
|
65
92
|
if shard_configs
|
66
93
|
shard_configs.each do |name, config|
|
94
|
+
next unless config["database"]
|
67
95
|
ActiveRecord::Base.establish_connection(config)
|
68
96
|
file = ENV['SCHEMA'] || "#{Rails.root}/db/schema-#{name}.rb"
|
69
97
|
if File.exists?(file)
|
@@ -80,90 +108,45 @@ db_namespace = namespace :db do
|
|
80
108
|
namespace :structure do
|
81
109
|
desc 'Dump the database structure to an SQL file'
|
82
110
|
task :dump => :environment do
|
83
|
-
|
84
|
-
shard_configs =
|
111
|
+
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
112
|
+
shard_configs = current_config["shards"]
|
85
113
|
shard_configs.merge!(config["seq"]) if config["seq"]
|
86
114
|
if shard_configs
|
87
115
|
shard_configs.each do |name, config|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
when /postgresql/
|
93
|
-
ENV['PGHOST'] = config['host'] if config['host']
|
94
|
-
ENV['PGPORT'] = config["port"].to_s if config['port']
|
95
|
-
ENV['PGPASSWORD'] = config['password'].to_s if config['password']
|
96
|
-
search_path = config['schema_search_path']
|
97
|
-
unless search_path.blank?
|
98
|
-
search_path = search_path.split(",").map{|search_path| "--schema=#{search_path.strip}" }.join(" ")
|
99
|
-
end
|
100
|
-
`pg_dump -i -U "#{config['username']}" -s -x -O -f db/#{Rails.env}_#{name}_structure.sql #{search_path} #{config['database']}`
|
101
|
-
raise 'Error dumping database' if $?.exitstatus == 1
|
102
|
-
when /sqlite/
|
103
|
-
dbfile = config['database'] || config['dbfile']
|
104
|
-
`sqlite3 #{dbfile} .schema > db/#{Rails.env}_#{name}_structure.sql`
|
105
|
-
when 'sqlserver'
|
106
|
-
`smoscript -s #{config['host']} -d #{config['database']} -u #{config['username']} -p #{config['password']} -f db\\#{Rails.env}_#{name}_structure.sql -A -U`
|
107
|
-
when "firebird"
|
108
|
-
set_firebird_env(config)
|
109
|
-
db_string = firebird_db_string(config)
|
110
|
-
sh "isql -a #{db_string} > #{Rails.root}/db/#{Rails.env}_#{name}_structure.sql"
|
111
|
-
else
|
112
|
-
raise "Task not supported by '#{config["adapter"]}'"
|
113
|
-
end
|
116
|
+
next unless config["database"]
|
117
|
+
ActiveRecord::Base.establish_connection(config)
|
118
|
+
filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure_#{name}.sql")
|
119
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_dump(config, filename)
|
114
120
|
|
115
121
|
if ActiveRecord::Base.connection.supports_migrations?
|
116
|
-
File.open(
|
122
|
+
File.open(filename, "a") do |f|
|
123
|
+
f.puts ActiveRecord::Base.connection.dump_schema_information
|
124
|
+
end
|
117
125
|
end
|
118
126
|
end
|
127
|
+
ActiveRecord::Base.establish_connection(current_config)
|
119
128
|
end
|
120
|
-
|
129
|
+
db_namespace['structure:dump'].reenable
|
121
130
|
end
|
122
|
-
end
|
123
|
-
|
124
131
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
shard_configs = config["shards"]
|
132
|
+
# desc "Recreate the databases from the structure.sql file"
|
133
|
+
task :load => [:environment, :load_config] do
|
134
|
+
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
135
|
+
shard_configs = current_config["shards"]
|
130
136
|
shard_configs.merge!(config["seq"]) if config["seq"]
|
131
137
|
if shard_configs
|
132
138
|
shard_configs.each do |name, config|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
IO.readlines("#{Rails.root}/db/#{Rails.env}_#{name}_structure.sql").join.split("\n\n").each do |table|
|
138
|
-
ActiveRecord::Base.connection.execute(table)
|
139
|
-
end
|
140
|
-
when /postgresql/
|
141
|
-
ENV['PGHOST'] = config['host'] if config['host']
|
142
|
-
ENV['PGPORT'] = config['port'].to_s if config['port']
|
143
|
-
ENV['PGPASSWORD'] = config['password'].to_s if config['password']
|
144
|
-
`psql -U "#{config['username']}" -f "#{Rails.root}/db/#{Rails.env}#{name}_structure.sql" #{config['database']} #{config['template']}`
|
145
|
-
when /sqlite/
|
146
|
-
dbfile = config['database'] || config['dbfile']
|
147
|
-
`sqlite3 #{dbfile} < "#{Rails.root}/db/#{Rails.env}#{name}_structure.sql"`
|
148
|
-
when 'sqlserver'
|
149
|
-
`sqlcmd -S #{config['host']} -d #{config['database']} -U #{config['username']} -P #{config['password']} -i db\\#{Rails.env}#{name}_structure.sql`
|
150
|
-
when 'oci', 'oracle'
|
151
|
-
ActiveRecord::Base.establish_connection(config)
|
152
|
-
IO.readlines("#{Rails.root}/db/#{Rails.env}#{name}_structure.sql").join.split(";\n\n").each do |ddl|
|
153
|
-
ActiveRecord::Base.connection.execute(ddl)
|
154
|
-
end
|
155
|
-
when 'firebird'
|
156
|
-
set_firebird_env(config)
|
157
|
-
db_string = firebird_db_string(config)
|
158
|
-
sh "isql -i #{Rails.root}/db/#{Rails.env}#{name}_structure.sql #{db_string}"
|
159
|
-
else
|
160
|
-
raise "Task not supported by '#{config['adapter']}'"
|
161
|
-
end
|
139
|
+
next unless config["database"]
|
140
|
+
ActiveRecord::Base.establish_connection(config)
|
141
|
+
filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure_#{name}.sql")
|
142
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_load(config, filename)
|
162
143
|
end
|
144
|
+
ActiveRecord::Base.establish_connection(current_config)
|
163
145
|
end
|
164
|
-
ActiveRecord::Base.establish_connection(config)
|
165
146
|
end
|
147
|
+
end
|
166
148
|
|
149
|
+
namespace :test do
|
167
150
|
# desc "Empty the test database"
|
168
151
|
task :purge => :environment do
|
169
152
|
config = ActiveRecord::Base.configurations[Rails.env]
|
@@ -171,35 +154,11 @@ db_namespace = namespace :db do
|
|
171
154
|
shard_configs.merge!(config["seq"]) if config["seq"]
|
172
155
|
if shard_configs
|
173
156
|
shard_configs.each do |name, config|
|
174
|
-
|
175
|
-
|
176
|
-
ActiveRecord::Base.establish_connection(config)
|
177
|
-
ActiveRecord::Base.connection.recreate_database(config['database'], mysql_creation_options(config))
|
178
|
-
when /postgresql/
|
179
|
-
ActiveRecord::Base.clear_active_connections!
|
180
|
-
drop_database(config)
|
181
|
-
create_database(config)
|
182
|
-
when /sqlite/
|
183
|
-
dbfile = config['database'] || config['dbfile']
|
184
|
-
File.delete(dbfile) if File.exist?(dbfile)
|
185
|
-
when 'sqlserver'
|
186
|
-
# TODO
|
187
|
-
when "oci", "oracle"
|
188
|
-
ActiveRecord::Base.establish_connection(config)
|
189
|
-
ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
|
190
|
-
ActiveRecord::Base.connection.execute(ddl)
|
191
|
-
end
|
192
|
-
when 'firebird'
|
193
|
-
ActiveRecord::Base.establish_connection(config)
|
194
|
-
ActiveRecord::Base.connection.recreate_database!
|
195
|
-
else
|
196
|
-
raise "Task not supported by '#{config['adapter']}'"
|
197
|
-
end
|
157
|
+
next unless config["database"]
|
158
|
+
ActiveRecord::Tasks::DatabaseTasks.purge config
|
198
159
|
end
|
199
160
|
end
|
200
161
|
ActiveRecord::Base.establish_connection(config)
|
201
162
|
end
|
202
163
|
end
|
203
|
-
|
204
164
|
end
|
205
|
-
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActiveRecord::Turntable
|
2
|
+
class Sequencer
|
3
|
+
class Barrage < Sequencer
|
4
|
+
@@unique_barrage_instance = {}
|
5
|
+
|
6
|
+
def initialize(klass, options = {})
|
7
|
+
require 'barrage'
|
8
|
+
@klass = klass
|
9
|
+
@options = options["options"]
|
10
|
+
@barrage = get_barrage_instance
|
11
|
+
end
|
12
|
+
|
13
|
+
def next_sequence_value(sequence_name)
|
14
|
+
@barrage.next
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_sequence_value(sequence_name)
|
18
|
+
@barrage.current
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def get_barrage_instance
|
24
|
+
@@unique_barrage_instance[@options] ||= ::Barrage.new(@options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -5,20 +5,27 @@
|
|
5
5
|
|
6
6
|
module ActiveRecord::Turntable
|
7
7
|
class Sequencer
|
8
|
-
|
9
|
-
|
8
|
+
extend ActiveSupport::Autoload
|
9
|
+
|
10
|
+
eager_autoload do
|
11
|
+
autoload :Api
|
12
|
+
autoload :Mysql
|
13
|
+
autoload :Barrage
|
14
|
+
end
|
15
|
+
|
10
16
|
@@sequence_types = {
|
11
17
|
:api => Api,
|
12
|
-
:mysql => Mysql
|
18
|
+
:mysql => Mysql,
|
19
|
+
:barrage => Barrage
|
13
20
|
}
|
14
21
|
|
15
22
|
@@sequences = {}
|
16
23
|
@@tables = {}
|
17
24
|
cattr_reader :sequences, :tables
|
18
25
|
|
19
|
-
def self.build(klass)
|
20
|
-
|
21
|
-
seq_config =
|
26
|
+
def self.build(klass, sequence_name = nil, cluster_name = nil)
|
27
|
+
sequence_name ||= current_cluster_config_for(cluster_name || klass)["seq"].keys.first
|
28
|
+
seq_config = current_cluster_config_for(cluster_name || klass)["seq"][sequence_name]
|
22
29
|
seq_type = (seq_config["seq_type"] ? seq_config["seq_type"].to_sym : :mysql)
|
23
30
|
@@tables[klass.table_name] ||= (@@sequences[sequence_name(klass.table_name, klass.primary_key)] ||= @@sequence_types[seq_type].new(klass, seq_config))
|
24
31
|
end
|
@@ -28,7 +35,7 @@ module ActiveRecord::Turntable
|
|
28
35
|
end
|
29
36
|
|
30
37
|
def self.sequence_name(table_name, pk)
|
31
|
-
"#{
|
38
|
+
"#{table_name}_#{pk || 'id'}_seq"
|
32
39
|
end
|
33
40
|
|
34
41
|
def self.table_name(seq_name)
|
@@ -36,11 +43,22 @@ module ActiveRecord::Turntable
|
|
36
43
|
end
|
37
44
|
|
38
45
|
def next_sequence_value
|
39
|
-
raise
|
46
|
+
raise NotImplementedError
|
40
47
|
end
|
41
48
|
|
42
49
|
def current_sequence_value
|
43
|
-
raise
|
50
|
+
raise NotImplementedError
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def self.current_cluster_config_for(klass_or_name)
|
56
|
+
cluster_name = if klass_or_name.is_a?(Symbol)
|
57
|
+
klass_or_name
|
58
|
+
else
|
59
|
+
klass_or_name.turntable_cluster_name.to_s
|
60
|
+
end
|
61
|
+
ActiveRecord::Base.turntable_config["clusters"][cluster_name]
|
44
62
|
end
|
45
63
|
end
|
46
64
|
end
|
@@ -41,8 +41,8 @@ module ActiveRecord::Turntable
|
|
41
41
|
raise "Please install the #{config['adapter']} adapter: `gem install activerecord-#{config['adapter']}-adapter` (#{e})"
|
42
42
|
end
|
43
43
|
adapter_method = "#{config['adapter']}_connection"
|
44
|
-
|
44
|
+
|
45
|
+
ActiveRecord::ConnectionAdapters::ConnectionSpecification.new(config, adapter_method)
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
48
|
-
|
@@ -46,7 +46,7 @@ module SQLTree::Node
|
|
46
46
|
sql << " GROUP BY " << group_by.map { |g| g.to_sql(options) }.join(', ') if group_by
|
47
47
|
sql << " ORDER BY " << order_by.map { |o| o.to_sql(options) }.join(', ') if order_by
|
48
48
|
sql << " HAVING " << having.to_sql(options) if having
|
49
|
-
sql << " LIMIT " << limit.map {|f| f.to_sql(options) }.join(', ') if limit
|
49
|
+
sql << " LIMIT " << Array(limit).map {|f| f.to_sql(options) }.join(', ') if limit
|
50
50
|
sql << " OFFSET " << offset.to_sql(options) if offset
|
51
51
|
return sql
|
52
52
|
end
|
@@ -13,23 +13,25 @@ require 'singleton'
|
|
13
13
|
|
14
14
|
module ActiveRecord::Turntable
|
15
15
|
extend ActiveSupport::Concern
|
16
|
+
extend ActiveSupport::Autoload
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
autoload :
|
18
|
+
eager_autoload do
|
19
|
+
autoload :ActiveRecordExt
|
20
|
+
autoload :Algorithm
|
21
|
+
autoload :Base
|
22
|
+
autoload :Cluster
|
23
|
+
autoload :Config
|
24
|
+
autoload :ConnectionProxy
|
25
|
+
autoload :MasterShard
|
26
|
+
autoload :Migration
|
27
|
+
autoload :Mixer
|
28
|
+
autoload :PoolProxy
|
29
|
+
autoload :Shard
|
30
|
+
autoload :SeqShard
|
31
|
+
autoload :Sequencer
|
32
|
+
end
|
33
|
+
autoload :Rack
|
34
|
+
autoload :Helpers
|
33
35
|
|
34
36
|
included do
|
35
37
|
include ActiveRecordExt
|
@@ -54,5 +56,13 @@ module ActiveRecord::Turntable
|
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
59
|
+
def self.rails4?
|
60
|
+
ActiveRecord::VERSION::MAJOR == 4
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.rails41_later?
|
64
|
+
rails4? && ActiveRecord::VERSION::MINOR >= 1
|
65
|
+
end
|
66
|
+
|
57
67
|
require "active_record/turntable/railtie" if defined?(Rails)
|
58
68
|
end
|
@@ -5,9 +5,10 @@
|
|
5
5
|
development:
|
6
6
|
clusters:
|
7
7
|
user_cluster:
|
8
|
-
algorithm:
|
8
|
+
algorithm: range_bsearch
|
9
9
|
seq:
|
10
|
-
|
10
|
+
user_seq:
|
11
|
+
connection: user_seq
|
11
12
|
shards:
|
12
13
|
- connection: user_shard_1
|
13
14
|
less_than: 100
|
@@ -19,9 +20,10 @@ development:
|
|
19
20
|
test:
|
20
21
|
clusters:
|
21
22
|
user_cluster:
|
22
|
-
algorithm:
|
23
|
+
algorithm: range_bsearch
|
23
24
|
seq:
|
24
|
-
|
25
|
+
user_seq:
|
26
|
+
connection: user_seq
|
25
27
|
shards:
|
26
28
|
- connection: user_shard_1
|
27
29
|
less_than: 20000
|
@@ -33,9 +35,10 @@ test:
|
|
33
35
|
production:
|
34
36
|
clusters:
|
35
37
|
user_cluster:
|
36
|
-
algorithm:
|
38
|
+
algorithm: range_bsearch
|
37
39
|
seq:
|
38
|
-
|
40
|
+
user_seq:
|
41
|
+
connection: user_seq
|
39
42
|
shards:
|
40
43
|
- connection: user_shard_1
|
41
44
|
less_than: 20000
|
@@ -43,4 +46,3 @@ production:
|
|
43
46
|
less_than: 40000
|
44
47
|
- connection: user_shard_3
|
45
48
|
less_than: 10000000
|
46
|
-
|