activerecord-shard_for 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +28 -0
- data/.travis.yml +4 -0
- data/Appraisals +26 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +5 -0
- data/Guardfile +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +296 -0
- data/Rakefile +10 -0
- data/activerecord-shard_for.gemspec +40 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/gemfiles/.bundle/config +1 -0
- data/gemfiles/ar_4.1.0.gemfile +7 -0
- data/gemfiles/ar_4.1.0.gemfile.lock +186 -0
- data/gemfiles/ar_4.1.7.gemfile +7 -0
- data/gemfiles/ar_4.1.7.gemfile.lock +186 -0
- data/gemfiles/ar_4.1.8.gemfile +7 -0
- data/gemfiles/ar_4.1.8.gemfile.lock +186 -0
- data/gemfiles/ar_4.2.gemfile +7 -0
- data/gemfiles/ar_4.2.gemfile.lock +186 -0
- data/gemfiles/ar_5.0.gemfile +7 -0
- data/gemfiles/ar_5.0.gemfile.lock +182 -0
- data/gemfiles/rails_edge.gemfile +8 -0
- data/gemfiles/rails_edge.gemfile.lock +193 -0
- data/lib/activerecord/shard_for.rb +32 -0
- data/lib/activerecord/shard_for/all_shards_in_parallel.rb +43 -0
- data/lib/activerecord/shard_for/cluster_config.rb +32 -0
- data/lib/activerecord/shard_for/config.rb +45 -0
- data/lib/activerecord/shard_for/connection_router.rb +33 -0
- data/lib/activerecord/shard_for/database_tasks.rb +185 -0
- data/lib/activerecord/shard_for/errors.rb +14 -0
- data/lib/activerecord/shard_for/hash_modulo_router.rb +18 -0
- data/lib/activerecord/shard_for/model.rb +134 -0
- data/lib/activerecord/shard_for/railtie.rb +10 -0
- data/lib/activerecord/shard_for/replication_mapping.rb +37 -0
- data/lib/activerecord/shard_for/shard_repogitory.rb +69 -0
- data/lib/activerecord/shard_for/version.rb +5 -0
- data/lib/activerecord/tasks/activerecord_shard_for.rake +42 -0
- metadata +323 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ShardFor
|
3
|
+
class Error < ::StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
# Raised when try to put new record without distkey attribute.
|
7
|
+
class MissingDistkeyAttribute < Error
|
8
|
+
end
|
9
|
+
|
10
|
+
# Inherit from AR::RecordNotFound to enable to handle as AR's one.
|
11
|
+
class RecordNotFound < ActiveRecord::RecordNotFound
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ShardFor
|
5
|
+
class HashModuloRouter < ConnectionRouter
|
6
|
+
# @param [String] key sharding key
|
7
|
+
def route(key)
|
8
|
+
hash(key) % connection_count
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def hash(v)
|
14
|
+
Zlib.crc32(v.to_s)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ShardFor
|
5
|
+
module Model
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
class_attribute :cluster_router, instance_writer: false
|
10
|
+
class_attribute :shard_repository, instance_writer: false
|
11
|
+
class_attribute :replication_mapping, instance_writer: false
|
12
|
+
class_attribute :distkey, instance_writer: false
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
# The cluster config must be defined before `use_cluster`
|
17
|
+
# @param [Symbol] name A cluster name which is set by ActiveRecord::ShardFor.configure
|
18
|
+
def use_cluster(name, router_name)
|
19
|
+
cluster_config = ActiveRecord::ShardFor.config.fetch_cluster_config(name)
|
20
|
+
cluster_router_class = ActiveRecord::ShardFor.config.fetch_cluster_router(router_name)
|
21
|
+
self.cluster_router = cluster_router_class.new(cluster_config)
|
22
|
+
self.shard_repository = ActiveRecord::ShardFor::ShardRepogitory.new(cluster_config, self)
|
23
|
+
self.abstract_class = true
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a generated model class of included model class which has proper
|
27
|
+
# connection config for the shard for given key.
|
28
|
+
# @param [String] key A value of distkey
|
29
|
+
# @return [Class] A generated model class for given distkey value
|
30
|
+
def shard_for(key)
|
31
|
+
connection_name = cluster_router.fetch_connection_name(key)
|
32
|
+
shard_repository.fetch(connection_name)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Create new record with given attributes in proper shard for given key.
|
36
|
+
# When distkey value is empty, raises ActiveRecord::ShardFor::MissingDistkeyAttribute
|
37
|
+
# error.
|
38
|
+
# @param [Hash] attributes
|
39
|
+
# @return [ActiveRecord::Base] A shard model instance
|
40
|
+
# @raise [ActiveRecord::ShardFor::MissingDistkeyAttribute]
|
41
|
+
def put!(attributes)
|
42
|
+
raise '`distkey` is not defined. Use `def_distkey`.' unless distkey
|
43
|
+
key = attributes[distkey]
|
44
|
+
raise ActiveRecord::ShardFor::MissingDistkeyAttribute unless key || attributes[distkey.to_s]
|
45
|
+
|
46
|
+
@before_put_callback.call(attributes) if @before_put_callback
|
47
|
+
|
48
|
+
shard_for(key).create!(attributes)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Register hook to assign auto-generated distkey or something.
|
52
|
+
# Sometimes you want to generates distkey value before validation. Since
|
53
|
+
# activerecord-shard_for generates sub class of your models, AR's callback is not
|
54
|
+
# useless for this usecase, so activerecord-shard_for offers its own callback method.
|
55
|
+
# @example
|
56
|
+
# class User
|
57
|
+
# include ActiveRecord::ShardFor::Model
|
58
|
+
# use_cluster :user
|
59
|
+
# def_distkey :name
|
60
|
+
# before_put do |attributes|
|
61
|
+
# attributes[:name] = generate_name unless attributes[:name]
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
def before_put(&block)
|
65
|
+
@before_put_callback = block
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns nil when not found. Except that, is same as `.get!`.
|
69
|
+
# @param [String] key
|
70
|
+
# @return [ActiveRecord::Base, nil] A shard model instance
|
71
|
+
def get(key)
|
72
|
+
shard_for(key).find_by(distkey => key)
|
73
|
+
end
|
74
|
+
|
75
|
+
# `.get!` raises ActiveRecord::ShardFor::RecordNotFound which is child class of
|
76
|
+
# `ActiveRecord::RecordNotFound` so you can rescue that exception as same
|
77
|
+
# as AR's RecordNotFound.
|
78
|
+
# @param [String] key
|
79
|
+
# @return [ActiveRecord::Base] A shard model instance
|
80
|
+
# @raise [ActiveRecord::ShardFor::RecordNotFound]
|
81
|
+
def get!(key)
|
82
|
+
model = get(key)
|
83
|
+
return model if model
|
84
|
+
|
85
|
+
raise ActiveRecord::ShardFor::RecordNotFound
|
86
|
+
end
|
87
|
+
|
88
|
+
# Distkey is a column. activerecord-shard_for gave to cluster_router that value
|
89
|
+
# and cluster_router determine which shard to store.
|
90
|
+
# @param [Symbol] column
|
91
|
+
def def_distkey(column)
|
92
|
+
self.distkey = column.to_sym
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns all generated shard model class. Useful to query to all shards.
|
96
|
+
# @return [Array<Class>] An array of shard models
|
97
|
+
# @example
|
98
|
+
# User.all_shards.flat_map {|m| m.find_by(name: 'alice') }.compact
|
99
|
+
def all_shards
|
100
|
+
shard_repository.all
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [ActiveRecord::ShardFor::AllShardsInParallel]
|
104
|
+
# @example
|
105
|
+
# User.all_shards_in_parallel.map {|m| m.where.find_by(name: 'Alice') }.compact
|
106
|
+
def all_shards_in_parallel
|
107
|
+
AllShardsInParallel.new(all_shards)
|
108
|
+
end
|
109
|
+
alias_method :parallel, :all_shards_in_parallel
|
110
|
+
|
111
|
+
# @param [Hash{Symbol => Symbol}] mapping A pairs of role name and
|
112
|
+
# AR model class name.
|
113
|
+
def replicates_with(mapping)
|
114
|
+
self.replication_mapping = ActiveRecord::ShardFor::ReplicationMapping.new(mapping)
|
115
|
+
end
|
116
|
+
|
117
|
+
# See example definitions in `spec/models.rb`.
|
118
|
+
# @param [Symbol] A role name of target cluster.
|
119
|
+
# @return [Class, Object] if block given then yielded result else
|
120
|
+
# target shard model.
|
121
|
+
# @example
|
122
|
+
# UserReadonly.all_shards.each do |m|
|
123
|
+
# target_ids = m.where(age: 1).pluck(:id)
|
124
|
+
# m.switch(:master) do |master|
|
125
|
+
# master.where(id: target_ids).delete_all
|
126
|
+
# end
|
127
|
+
# end
|
128
|
+
def switch(role_name, &block)
|
129
|
+
replication_mapping.switch(self, role_name, &block)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ShardFor
|
3
|
+
class ReplicationMapping
|
4
|
+
def initialize(mapping)
|
5
|
+
@mapping = mapping
|
6
|
+
@lock = Mutex.new
|
7
|
+
end
|
8
|
+
|
9
|
+
# @param [Class] A shard model having connection to specific shard
|
10
|
+
# @param [Symbol] A role name of target cluster.
|
11
|
+
# @return [Class, Object] if block given then yielded result else
|
12
|
+
# target shard model.
|
13
|
+
def switch(from, role_name)
|
14
|
+
@lock.synchronize { constantize! unless constantized? }
|
15
|
+
|
16
|
+
model = @mapping.fetch(role_name)
|
17
|
+
target_shard_model = model.shard_repository.fetch_by_key(from.assigned_key)
|
18
|
+
|
19
|
+
if block_given?
|
20
|
+
target_shard_model.connection_pool.with_connection { yield target_shard_model }
|
21
|
+
else
|
22
|
+
target_shard_model
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def constantize!
|
29
|
+
@mapping = Hash[@mapping.map { |k, name| [k, name.to_s.constantize] }]
|
30
|
+
end
|
31
|
+
|
32
|
+
def constantized?
|
33
|
+
@mapping.values.first.is_a? Class
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ShardFor
|
3
|
+
class ShardRepogitory
|
4
|
+
attr_reader :base_class
|
5
|
+
|
6
|
+
# @param [ClusterConfig] cluster_config
|
7
|
+
# @param [Class] base_class A AR Model
|
8
|
+
def initialize(cluster_config, base_class)
|
9
|
+
@base_class = base_class
|
10
|
+
|
11
|
+
shards = cluster_config.connection_registry.map do |key, connection_name|
|
12
|
+
[connection_name, generate_model_for_shard(connection_name, key)]
|
13
|
+
end
|
14
|
+
|
15
|
+
@shards = Hash[shards]
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [Symbol] connection_name
|
19
|
+
# @return [Class] A model class for this shard
|
20
|
+
def fetch(connection_name)
|
21
|
+
@shards.fetch(connection_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [Object] key sharding key object for connection
|
25
|
+
# @return [Class, nil] A AR model class.
|
26
|
+
def fetch_by_key(key)
|
27
|
+
@shards.find { |_, model| model.assigned_key == key }[1]
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Array<Class>]
|
31
|
+
def all
|
32
|
+
@shards.values
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @param [Symbol] connection_name
|
38
|
+
# @param [Range] slot_range
|
39
|
+
# @return [Class] A sub class of given AR model.
|
40
|
+
# A sub class has connection setting for specific shard.
|
41
|
+
def generate_model_for_shard(connection_name, key)
|
42
|
+
class_name = generate_class_name(connection_name)
|
43
|
+
|
44
|
+
model = Class.new(base_class) do
|
45
|
+
self.table_name = base_class.table_name
|
46
|
+
class << self
|
47
|
+
attr_reader :assigned_key
|
48
|
+
end
|
49
|
+
@assigned_key = key
|
50
|
+
|
51
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
52
|
+
def self.name
|
53
|
+
"#{base_class.name}::#{class_name}"
|
54
|
+
end
|
55
|
+
RUBY
|
56
|
+
end
|
57
|
+
|
58
|
+
model.class_eval { establish_connection(connection_name) }
|
59
|
+
model
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param [Symbol] connection_name
|
63
|
+
# @return [String]
|
64
|
+
def generate_class_name(connection_name)
|
65
|
+
"ShardFor#{connection_name.to_s.tr('-', '_').classify}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
namespace :activerecord do
|
2
|
+
namespace :shard_for do
|
3
|
+
desc 'Show all defined clusters and their detail'
|
4
|
+
task info: %i(environment) do
|
5
|
+
ActiveRecord::ShardFor::DatabaseTasks.info
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Setup all databases in all clusters'
|
9
|
+
task setup: %i(create_all load_schema_all) do
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Create all databases in all clusters'
|
13
|
+
task :create_all => :environment do
|
14
|
+
ActiveRecord::ShardFor::DatabaseTasks.invoke_task_for_all_clusters('create')
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Drop all databases in all clusters'
|
18
|
+
task :drop_all => :environment do
|
19
|
+
ActiveRecord::ShardFor::DatabaseTasks.invoke_task_for_all_clusters('drop')
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Load schema to all databases in all clusters'
|
23
|
+
task :load_schema_all => :environment do
|
24
|
+
ActiveRecord::ShardFor::DatabaseTasks.invoke_task_for_all_clusters('load_schema')
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Create all databases in specific cluster'
|
28
|
+
task :create, %i(cluster_name) => %i(environment) do |_, args|
|
29
|
+
ActiveRecord::ShardFor::DatabaseTasks.create_all_databases(args)
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Drop all databases in specific cluster'
|
33
|
+
task :drop, %i(cluster_name) => %i(environment) do |_, args|
|
34
|
+
ActiveRecord::ShardFor::DatabaseTasks.drop_all_databases(args)
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'Load schema to all databases in specific cluster'
|
38
|
+
task :load_schema, %i(cluster_name) => %i(environment) do |_, args|
|
39
|
+
ActiveRecord::ShardFor::DatabaseTasks.load_schema_all_databases(args)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,323 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activerecord-shard_for
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- yuemori
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: expeditor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.1.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.1.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.11'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry-doc
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry-stack_explorer
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry-inline
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: pry-rescue
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubocop
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: guard-rubocop
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: guard-rspec
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: appraisal
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: sqlite3
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
237
|
+
- !ruby/object:Gem::Dependency
|
238
|
+
name: rspec-parameterized
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
240
|
+
requirements:
|
241
|
+
- - ">="
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: '0'
|
244
|
+
type: :development
|
245
|
+
prerelease: false
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - ">="
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: '0'
|
251
|
+
description: Database sharding library for ActiveRecord
|
252
|
+
email:
|
253
|
+
- yuemori@aiming-inc.com
|
254
|
+
executables: []
|
255
|
+
extensions: []
|
256
|
+
extra_rdoc_files: []
|
257
|
+
files:
|
258
|
+
- ".gitignore"
|
259
|
+
- ".rspec"
|
260
|
+
- ".rubocop.yml"
|
261
|
+
- ".travis.yml"
|
262
|
+
- Appraisals
|
263
|
+
- CODE_OF_CONDUCT.md
|
264
|
+
- Gemfile
|
265
|
+
- Guardfile
|
266
|
+
- LICENSE.txt
|
267
|
+
- README.md
|
268
|
+
- Rakefile
|
269
|
+
- activerecord-shard_for.gemspec
|
270
|
+
- bin/console
|
271
|
+
- bin/setup
|
272
|
+
- gemfiles/.bundle/config
|
273
|
+
- gemfiles/ar_4.1.0.gemfile
|
274
|
+
- gemfiles/ar_4.1.0.gemfile.lock
|
275
|
+
- gemfiles/ar_4.1.7.gemfile
|
276
|
+
- gemfiles/ar_4.1.7.gemfile.lock
|
277
|
+
- gemfiles/ar_4.1.8.gemfile
|
278
|
+
- gemfiles/ar_4.1.8.gemfile.lock
|
279
|
+
- gemfiles/ar_4.2.gemfile
|
280
|
+
- gemfiles/ar_4.2.gemfile.lock
|
281
|
+
- gemfiles/ar_5.0.gemfile
|
282
|
+
- gemfiles/ar_5.0.gemfile.lock
|
283
|
+
- gemfiles/rails_edge.gemfile
|
284
|
+
- gemfiles/rails_edge.gemfile.lock
|
285
|
+
- lib/activerecord/shard_for.rb
|
286
|
+
- lib/activerecord/shard_for/all_shards_in_parallel.rb
|
287
|
+
- lib/activerecord/shard_for/cluster_config.rb
|
288
|
+
- lib/activerecord/shard_for/config.rb
|
289
|
+
- lib/activerecord/shard_for/connection_router.rb
|
290
|
+
- lib/activerecord/shard_for/database_tasks.rb
|
291
|
+
- lib/activerecord/shard_for/errors.rb
|
292
|
+
- lib/activerecord/shard_for/hash_modulo_router.rb
|
293
|
+
- lib/activerecord/shard_for/model.rb
|
294
|
+
- lib/activerecord/shard_for/railtie.rb
|
295
|
+
- lib/activerecord/shard_for/replication_mapping.rb
|
296
|
+
- lib/activerecord/shard_for/shard_repogitory.rb
|
297
|
+
- lib/activerecord/shard_for/version.rb
|
298
|
+
- lib/activerecord/tasks/activerecord_shard_for.rake
|
299
|
+
homepage: https://github.com/yuemori/activerecord-shard_for
|
300
|
+
licenses:
|
301
|
+
- MIT
|
302
|
+
metadata: {}
|
303
|
+
post_install_message:
|
304
|
+
rdoc_options: []
|
305
|
+
require_paths:
|
306
|
+
- lib
|
307
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
308
|
+
requirements:
|
309
|
+
- - ">="
|
310
|
+
- !ruby/object:Gem::Version
|
311
|
+
version: '0'
|
312
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
313
|
+
requirements:
|
314
|
+
- - ">="
|
315
|
+
- !ruby/object:Gem::Version
|
316
|
+
version: '0'
|
317
|
+
requirements: []
|
318
|
+
rubyforge_project:
|
319
|
+
rubygems_version: 2.5.1
|
320
|
+
signing_key:
|
321
|
+
specification_version: 4
|
322
|
+
summary: Database sharding library for ActiveRecord
|
323
|
+
test_files: []
|