dynashard 0.2.0 → 0.3.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.
data/README.md CHANGED
@@ -2,17 +2,22 @@
2
2
 
3
3
  This package provides database sharding functionality for ActiveRecord models.
4
4
 
5
- Sharding is disabled by default and is enabled with +Dynashard.enable+. This allows
6
- sharding behavior to be enabled globally or only for specific environments so for
7
- example production environments could be sharded while development environments could
5
+ Sharding is disabled by default and is enabled with `Dynashard.enable`. This allows
6
+ sharding behavior to be enabled globally or only for specific environments; for example,
7
+ production environments could be sharded while development environments could
8
8
  use a single database.
9
9
 
10
10
  Models may be configured to determine the appropriate shard (database connection) to
11
- use based on context defined prior to performing queries.
11
+ use based on context defined prior to performing queries. Different
12
+ models may shard using different contexts.
12
13
 
13
14
  class Widget < ActiveRecord::Base
14
15
  shard :by => :user
15
16
  end
17
+
18
+ class Doohickie < ActiveRecord::Base
19
+ shard :by => :vhost
20
+ end
16
21
 
17
22
  class WidgetController < ApplicationController
18
23
  around_filter :set_shard_context
@@ -20,12 +25,15 @@ use based on context defined prior to performing queries.
20
25
  def index
21
26
  # Widgets will be loaded using the connection for the current user's shard
22
27
  @widgets = Widget.find(:all)
28
+
29
+ # Doohickies will be loaded using the connection for the vhost's shard
30
+ @doohickies = Doohickie.find(:all)
23
31
  end
24
32
 
25
33
  private
26
34
 
27
35
  def set_shard_context
28
- Dynashard.with_context(:user => current_user.shard) do
36
+ Dynashard.with_context(:user => current_user.shard, :vhost => request.env['HTTP_HOST']) do
29
37
  yield
30
38
  end
31
39
  end
@@ -65,6 +73,77 @@ association's owner.
65
73
 
66
74
  New associations are saved on the Company's shard.
67
75
 
76
+ Shard context values may be a valid argument to establish_connection()
77
+ such as a string reference to a configuration from config/database.yml
78
+ or a hash with database connection parameters. Values may also be an
79
+ object that responds to :call and returns a valid argument to
80
+ establish_connection().
81
+
82
+ Load widgets from a shard defined in database.yml
83
+
84
+ $ cat config/database.yml
85
+
86
+ development:
87
+ database: db/development.sqlite3
88
+ <<: *defaults
89
+
90
+ shard1:
91
+ database: db/shard1.sqlite3
92
+ <<: *defaults
93
+
94
+ shard2:
95
+ database: db/shard2.sqlite3
96
+ <<: *defaults
97
+
98
+ > @widgets = Dynashard.with_context(:user => 'shard1') { Widget.find(:all) }
99
+ => [#<Widget id:1>, #<Widget id:2>]
100
+
101
+ Load widgets from a shard using a hash of connection params
102
+
103
+ > conn = {:adapter => 'sqlite3', :database => 'db/shard3.sqlite3'}
104
+ > @widgets = Dynashard.with_context(:user => conn) { Widget.find(:all) }
105
+ => [#<Widget id:1>, #<Widget id:2>]
106
+
107
+ Create a widget using a method to determine the shard
108
+
109
+ widget_shard = lambda do
110
+ # Store widgets by month/day
111
+ {:adapter => 'sqlite3', :database => "db/dayslice#{Time.now.strftime("%m%d")}"}
112
+ end
113
+
114
+ > Time.now
115
+ => Mon Jan 31 17:37:23 -0800 2011
116
+
117
+ > widget_shard.call
118
+ => {:database=>"db/dayslice0131", :adapter=>"sqlite3"}
119
+
120
+ > new_widget = Dynashard.with_context(:user => widget_shard) do
121
+ Widget.create(:name => 'The newest of the widgets')
122
+ end
123
+ => <#Widget id:3>
124
+
125
+ Use a Rails initializer for one-time configuration of shard context
126
+
127
+ $ cat config/initializers/dynashard.rb
128
+
129
+ # Put user-sharded data on the smallest shard
130
+ Dynashard.shard_context[:user] = lambda do
131
+ Shard.order(:size).find(:first).dsn
132
+ end
133
+
134
+ > new_widget = Widget.create(:name => 'Put this on the smallest shard')
135
+ => <#Widget id:4>
136
+
137
+ Use with_context to override an earlier context setting
138
+
139
+ > Dynashard.shard_context[:user] = 'shard1'
140
+ > new_widget = Widget.create(:name => 'Put this on shard1')
141
+ => <#Widget id:5>
142
+ > new_widget = Dynashard.with_context(:user => 'shard2') do
143
+ Widget.create(:name => 'Put this on shard2')
144
+ do
145
+ > <#Widget id:6>
146
+
68
147
  ## TODO: add gotcha section, eg:
69
148
 
70
149
  - uniqueness validations should be scoped by whatever is sharding
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/dynashard.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dynashard}
8
- s.version = "0.2.0"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nick Hengeveld"]
12
- s.date = %q{2011-01-31}
12
+ s.date = %q{2011-02-01}
13
13
  s.description = %q{Dynashard allows you to shard your ActiveRecord models. Models can be configured to shard based on context that can be defined dynamically.}
14
14
  s.email = %q{nickh@verticalresponse.com}
15
15
  s.extra_rdoc_files = [
@@ -32,6 +32,8 @@ Gem::Specification.new do |s|
32
32
  "lib/dynashard/validations.rb",
33
33
  "spec/associations_spec.rb",
34
34
  "spec/connection_handler_spec.rb",
35
+ "spec/db/database.yml",
36
+ "spec/db/schema.rb",
35
37
  "spec/dynashard_spec.rb",
36
38
  "spec/model_spec.rb",
37
39
  "spec/spec_helper.rb",
@@ -0,0 +1,16 @@
1
+ shared: &shared
2
+ adapter: sqlite3
3
+ pool: 5
4
+ timeout: 5000
5
+
6
+ test:
7
+ database: <%= plugin_test_dir %>/db/base.sqlite3
8
+ <<: *shared
9
+
10
+ shard1:
11
+ database: <%= plugin_test_dir %>/db/shard1.sqlite3
12
+ <<: *shared
13
+
14
+ shard2:
15
+ database: <%= plugin_test_dir %>/db/shard2.sqlite3
16
+ <<: *shared
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
7
+ - 3
8
8
  - 0
9
- version: 0.2.0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Nick Hengeveld
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-31 00:00:00 -08:00
17
+ date: 2011-02-01 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -140,13 +140,14 @@ files:
140
140
  - lib/dynashard/validations.rb
141
141
  - spec/associations_spec.rb
142
142
  - spec/connection_handler_spec.rb
143
+ - spec/db/database.yml
144
+ - spec/db/schema.rb
143
145
  - spec/dynashard_spec.rb
144
146
  - spec/model_spec.rb
145
147
  - spec/spec_helper.rb
146
148
  - spec/support/factories.rb
147
149
  - spec/support/models.rb
148
150
  - spec/validation_spec.rb
149
- - spec/db/schema.rb
150
151
  has_rdoc: true
151
152
  homepage: http://github.com/nickh/dynashard
152
153
  licenses:
@@ -161,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
162
  requirements:
162
163
  - - ">="
163
164
  - !ruby/object:Gem::Version
164
- hash: -2881092534266890665
165
+ hash: 2742474365578406990
165
166
  segments:
166
167
  - 0
167
168
  version: "0"