sengiri 0.0.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0cf2b0a2d6136b98587fdc922d0af979bc5615dc
4
- data.tar.gz: 11669c7daa1637126d51e6688d399bd4b9dc1e74
3
+ metadata.gz: 67662e531d8b2b6162bc5c40345d2a2c8483cb86
4
+ data.tar.gz: 33fd768534533e6fee349213b71cac79dd3aa523
5
5
  SHA512:
6
- metadata.gz: 13d32f1573dfa4cd9ca730a4c1007af735996f1290416dba0233b6ad1f67cbeee604e63a9b64bfa34adf169fdb4d0b0ace2f9a46610ad6ebc290b9ce80e6ff8e
7
- data.tar.gz: 3bb32d54a802c7ba3f7d76cb5c7c16291af7969496322dffec9fed8935bf7d906cae272f11d8854e07536e7b1cf8dfbac4823b34c329a14594136493af6f5f25
6
+ metadata.gz: af81bf63aab412b0ead03aa961f4c3885013ac2b3a4d65dc43c04832c2d8b12e7ea5fe16dbee40a12f53ed141f78a688e0d549bbaf9f25c36a7460b7fd2d42e5
7
+ data.tar.gz: 25de11297f6a2e58bf254363b6d36288f3e58dd096d8eff47522934273234fbec666d165b708a3568a5663aced39a3264ca8018d14d53a7956db130f7864c32d
data/README.md CHANGED
@@ -4,10 +4,13 @@ Flexible sharding access for Ruby on Rails with ActiveRecord
4
4
 
5
5
  ## Sharding model generator
6
6
 
7
+ ```
7
8
  rails g sengiri:model mygroup user name:string
9
+ ```
8
10
 
9
11
  ## database.yml
10
12
 
13
+ ```ruby
11
14
  mysql: &mysql
12
15
  adapter: mysql2
13
16
  encoding: utf8
@@ -17,60 +20,86 @@ Flexible sharding access for Ruby on Rails with ActiveRecord
17
20
  password:
18
21
  host: localhost
19
22
 
20
- mygroup_shards_first: # define shard as 'first'
23
+ mygroup_shard_first: # define shard as 'first'
21
24
  <<: *mysql
22
25
  database: mygroup_1
23
26
  host: hosta
24
- mygroup_shards_second: # define shard as 'second'
27
+ mygroup_shard_second: # define shard as 'second'
25
28
  <<: *mysql
26
29
  database: mygroup_2
27
30
  host: hostb
28
- mygroup_shards_third: # define shard as 'third'
31
+ mygroup_shard_third: # define shard as 'third'
29
32
  <<: *mysql
30
33
  database: mygroup_3
31
34
  host: hostc
32
35
  .
33
36
  .
34
37
  .
38
+ ```
35
39
 
36
40
  ## Sharding migration
37
41
 
42
+ ActiveRecord task is available on every shard.
43
+
44
+ ```ruby
38
45
  rake sengiri:mygroup:db:create
39
46
  rake sengiri:mygroup:db:migrate
40
-
47
+ rake sengiri:mygroup:db:rollback
48
+ ...
49
+ ```
41
50
 
42
51
  ## Sharding access
43
52
 
53
+ On a shard, ActiveRecord class is given.
54
+
55
+ ```ruby
44
56
  User.shard('second') do |shard|
45
- shard.all.limit(10) # query on db 'mygroup_1'
57
+ shard.all.limit(10) # query on db 'mygroup_2'
58
+ shard.find(1) # query on db 'mygroup_2'
46
59
  end
60
+ ```
47
61
 
62
+ Every shard.
48
63
 
64
+ ```ruby
49
65
  User.shards do |shard|
50
- shard.all.limit(10) # query on all db 'mygroup_1', 'mygroup_2', 'mygroup_3'
66
+ shard.all.limit(10) # query on all shards 'mygroup_1', 'mygroup_2', 'mygroup_3'
51
67
  end
68
+ ```
69
+
70
+ All records from all shards.
71
+
72
+ ```ruby
73
+ all_records = User.all.broadcast
74
+ ```
52
75
 
53
76
  ## Transaction
54
77
 
78
+ In a shard transaction.
79
+
80
+ ```ruby
55
81
  User.shard('second').transaction do
56
82
  # in mygroup_2 transaction
57
83
  end
84
+ ```
58
85
 
86
+ In all shards transaction.
59
87
 
88
+ ```ruby
60
89
  User.transaction do
61
90
  # in mygroup_1, mygroup_2 and mygroup_3 transaction
62
91
  end
92
+ ```
63
93
 
94
+ This is same as below
64
95
 
65
- # This is same as below
66
-
67
-
96
+ ```ruby
68
97
  User.shard('first').transaction do
69
98
  User.shard('second').transaction do
70
99
  User.shard('third').transaction do
71
100
  end
72
101
  end
73
102
  end
74
-
103
+ ```
75
104
 
76
105
  This project rocks and uses MIT-LICENSE.
@@ -9,7 +9,7 @@ module ActiveRecord
9
9
  def broadcast
10
10
  records = []
11
11
  klass.shard_names.each do |shard_name|
12
- records += shard(shard_name).find_by_sql(arel.to_sql)
12
+ records += shard(shard_name).find_by_sql(to_sql)
13
13
  end
14
14
  @records = records
15
15
  @records
@@ -17,6 +17,11 @@ module Sengiri
17
17
  self.class.instance_variable_get :@shard_name
18
18
  end
19
19
 
20
+ def narrowcast(association)
21
+ foreign_key = self.class.table_name.singularize.foreign_key
22
+ association.to_s.classify.constantize.shard(shard_name).where(foreign_key => id)
23
+ end
24
+
20
25
  class << self
21
26
  def shard_name ; @shard_name end
22
27
  def sharding_group_name; @sharding_group_name end
@@ -26,17 +31,23 @@ module Sengiri
26
31
  []
27
32
  end
28
33
 
29
- def sharding_group(name, confs=nil)
34
+ def sharding_group(name, confs: nil, suffix: nil)
30
35
  @dbconfs = confs if confs
31
36
  @sharding_group_name = name
32
37
  @shard_class_hash = {}
38
+ @sharding_database_suffix = if suffix.present? then "_#{suffix}" else nil end
33
39
  first = true
40
+ raise "Databases are not found" if shard_names.blank?
34
41
  shard_names.each do |s|
35
42
  klass = Class.new(self)
36
- Object.const_set self.name + s, klass
43
+ module_name = self.name.deconstantize
44
+ module_name = "Object" if module_name.blank?
45
+ module_name.constantize.const_set self.name.demodulize + s, klass
37
46
  klass.instance_variable_set :@shard_name, s
38
47
  klass.instance_variable_set :@dbconfs, dbconfs
39
48
  klass.instance_variable_set :@sharding_group_name, name
49
+ klass.instance_variable_set :@sharding_database_suffix, @sharding_database_suffix
50
+
40
51
  #
41
52
  # first shard shares connection with base class
42
53
  #
@@ -55,7 +66,11 @@ module Sengiri
55
66
 
56
67
  def dbconfs
57
68
  if defined? Rails
58
- @dbconfs ||= Rails.application.config.database_configuration.select {|name| /^#{@sharding_group_name}/ =~ name }
69
+ @dbconfs ||= Rails.application.config.database_configuration.select {|name|
70
+ /^#{@sharding_group_name}/ =~ name
71
+ }.select {|name|
72
+ /#{env}#{@sharding_database_suffix}$/ =~ name
73
+ }
59
74
 
60
75
  end
61
76
  @dbconfs
@@ -63,7 +78,7 @@ module Sengiri
63
78
 
64
79
  def shard_names
65
80
  @shard_names ||= dbconfs.map do |k,v|
66
- k.gsub("#{@sharding_group_name}_shards_", '')
81
+ k.gsub("#{@sharding_group_name}_shard_", '').gsub(/_#{env}#{@sharding_database_suffix}$/, '')
67
82
  end
68
83
  @shard_names
69
84
  end
@@ -98,9 +113,70 @@ module Sengiri
98
113
  end
99
114
  end
100
115
 
116
+ def env
117
+ ENV["SENGIRI_ENV"] ||= ENV["RAILS_ENV"] || 'development'
118
+ end
119
+
101
120
  def establish_shard_connection(name)
102
- establish_connection dbconfs["#{@sharding_group_name}_shards_#{name}"]
121
+ establish_connection dbconfs["#{@sharding_group_name}_shard_#{name}_#{env}#{@sharding_database_suffix}"]
122
+ end
123
+
124
+ def has_many_with_sharding(name, scope = nil, options = {}, &extension)
125
+ class_name, scope, options = *prepare_association(name, scope, options)
126
+ shard_classes.each do |klass|
127
+ new_options = options.merge({
128
+ class_name: class_name.to_s.classify + klass.shard_name,
129
+ foreign_key: options[:foreign_key] || self.to_s.foreign_key
130
+ })
131
+ klass.has_many_without_sharding(name, scope, new_options, extension) if block_given?
132
+ klass.has_many_without_sharding(name, scope, new_options) unless block_given?
133
+ end
134
+ has_many_without_sharding(name, scope, options, extension) if block_given?
135
+ has_many_without_sharding(name, scope, options) unless block_given?
136
+ end
137
+
138
+ def has_one_with_sharding(name, scope = nil, options = {})
139
+ class_name, scope, options = *prepare_association(name, scope, options)
140
+ shard_classes.each do |klass|
141
+ new_options = options.merge({
142
+ class_name: class_name.to_s.classify + klass.shard_name,
143
+ foreign_key: options[:foreign_key] || self.to_s.foreign_key
144
+ })
145
+ klass.has_one_without_sharding(name, scope, new_options)
146
+ end
147
+ has_one_without_sharding(name, scope, options)
103
148
  end
149
+
150
+ def belongs_to_with_sharding(name, scope = nil, options = {})
151
+ class_name, scope, options = *prepare_association(name, scope, options)
152
+ shard_classes.each do |klass|
153
+ new_options = options.merge({
154
+ class_name: class_name.to_s.classify + klass.shard_name,
155
+ foreign_key: options[:foreign_key] || name.to_s.foreign_key
156
+ })
157
+ klass.belongs_to_without_sharding(name, scope, new_options)
158
+ end
159
+ belongs_to_without_sharding(name, scope, options)
160
+ end
161
+
162
+ def constantize(name)
163
+ name.to_s.singularize.classify.constantize
164
+ end
165
+
166
+ def prepare_association(name, scope, options)
167
+ if scope.is_a?(Hash)
168
+ options = scope
169
+ scope = nil
170
+ end
171
+ class_name = options[:class_name] || name
172
+ constantize(class_name)
173
+ [class_name, scope, options]
174
+ end
175
+
176
+ alias_method_chain :has_many, :sharding
177
+ alias_method_chain :has_one, :sharding
178
+ alias_method_chain :belongs_to, :sharding
179
+
104
180
  end
105
181
  end
106
182
  end
@@ -1,6 +1,12 @@
1
1
  require 'active_record'
2
2
 
3
3
  shard = ENV['SHARD']
4
+ rails_env = ENV['RAILS_ENV']
5
+ if rails_env
6
+ rails_env_list = [rails_env]
7
+ else
8
+ rails_env_list = ['development', 'test']
9
+ end
4
10
 
5
11
  namespace :sengiri do
6
12
  db_ns = namespace :db do
@@ -12,9 +18,15 @@ namespace :sengiri do
12
18
 
13
19
  namespace :db do
14
20
 
15
- dbconfs = Rails.application.config.database_configuration.select {|name| /^#{shard}/ =~ name }
21
+ dbconfs = Rails.application.config.database_configuration.select {|name|
22
+ /^#{shard}/ =~ name
23
+ }.select {|name|
24
+ rails_env_list.select {|env|
25
+ /_#{env}$/ =~ name
26
+ }.present?
27
+ }
16
28
  switch_db_config = lambda do
17
- puts "now on '#{shard}' sharding"
29
+ puts "now on '#{shard}' shard."
18
30
 
19
31
  shard_group_dir = "db/sengiri/#{shard}"
20
32
  ActiveRecord::Base.configurations = dbconfs
@@ -1,3 +1,3 @@
1
1
  module Sengiri
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sengiri
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mewlist
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-28 00:00:00.000000000 Z
11
+ date: 2015-07-17 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
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 4.1.0
19
+ version: 4.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 4.1.0
26
+ version: 4.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sqlite3
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: Database sharding for Ruby on Rails. Supports sharding migration, access
@@ -60,8 +60,10 @@ executables: []
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
- - db/sengiri_shards_1.sqlite3
64
- - db/sengiri_shards_2.sqlite3
63
+ - MIT-LICENSE
64
+ - README.md
65
+ - Rakefile
66
+ - lib/sengiri.rb
65
67
  - lib/sengiri/generators/migration_generator.rb
66
68
  - lib/sengiri/generators/model_generator.rb
67
69
  - lib/sengiri/generators/sharding_generator.rb
@@ -73,11 +75,7 @@ files:
73
75
  - lib/sengiri/railtie.rb
74
76
  - lib/sengiri/railties/sharding.rake
75
77
  - lib/sengiri/version.rb
76
- - lib/sengiri.rb
77
78
  - lib/tasks/sengiri.rake
78
- - MIT-LICENSE
79
- - Rakefile
80
- - README.md
81
79
  homepage: https://github.com/mewlist
82
80
  licenses: []
83
81
  metadata: {}
@@ -87,17 +85,17 @@ require_paths:
87
85
  - lib
88
86
  required_ruby_version: !ruby/object:Gem::Requirement
89
87
  requirements:
90
- - - '>='
88
+ - - ">="
91
89
  - !ruby/object:Gem::Version
92
90
  version: '0'
93
91
  required_rubygems_version: !ruby/object:Gem::Requirement
94
92
  requirements:
95
- - - '>='
93
+ - - ">="
96
94
  - !ruby/object:Gem::Version
97
95
  version: '0'
98
96
  requirements: []
99
97
  rubyforge_project:
100
- rubygems_version: 2.0.3
98
+ rubygems_version: 2.4.5
101
99
  signing_key:
102
100
  specification_version: 4
103
101
  summary: Database sharding for Ruby on Rails
Binary file
Binary file