activerecord-turntable 1.0.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.
Files changed (130) hide show
  1. data/.document +5 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +25 -0
  5. data/Guardfile +9 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.rdoc +290 -0
  8. data/Rakefile +101 -0
  9. data/activerecord-turntable.gemspec +47 -0
  10. data/lib/active_record/turntable.rb +58 -0
  11. data/lib/active_record/turntable/active_record_ext.rb +26 -0
  12. data/lib/active_record/turntable/active_record_ext/.gitkeep +0 -0
  13. data/lib/active_record/turntable/active_record_ext/abstract_adapter.rb +50 -0
  14. data/lib/active_record/turntable/active_record_ext/clever_load.rb +90 -0
  15. data/lib/active_record/turntable/active_record_ext/fixtures.rb +131 -0
  16. data/lib/active_record/turntable/active_record_ext/log_subscriber.rb +64 -0
  17. data/lib/active_record/turntable/active_record_ext/persistence.rb +95 -0
  18. data/lib/active_record/turntable/active_record_ext/schema_dumper.rb +107 -0
  19. data/lib/active_record/turntable/active_record_ext/sequencer.rb +28 -0
  20. data/lib/active_record/turntable/active_record_ext/transactions.rb +33 -0
  21. data/lib/active_record/turntable/algorithm.rb +7 -0
  22. data/lib/active_record/turntable/algorithm/.gitkeep +0 -0
  23. data/lib/active_record/turntable/algorithm/base.rb +11 -0
  24. data/lib/active_record/turntable/algorithm/range_algorithm.rb +37 -0
  25. data/lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb +41 -0
  26. data/lib/active_record/turntable/base.rb +130 -0
  27. data/lib/active_record/turntable/cluster.rb +70 -0
  28. data/lib/active_record/turntable/compatible.rb +19 -0
  29. data/lib/active_record/turntable/config.rb +24 -0
  30. data/lib/active_record/turntable/connection_proxy.rb +218 -0
  31. data/lib/active_record/turntable/connection_proxy/mixable.rb +39 -0
  32. data/lib/active_record/turntable/error.rb +8 -0
  33. data/lib/active_record/turntable/helpers.rb +5 -0
  34. data/lib/active_record/turntable/helpers/test_helper.rb +25 -0
  35. data/lib/active_record/turntable/master_shard.rb +28 -0
  36. data/lib/active_record/turntable/migration.rb +132 -0
  37. data/lib/active_record/turntable/mixer.rb +203 -0
  38. data/lib/active_record/turntable/mixer/fader.rb +34 -0
  39. data/lib/active_record/turntable/mixer/fader/calculate_shards_sum_result.rb +15 -0
  40. data/lib/active_record/turntable/mixer/fader/insert_shards_merge_result.rb +24 -0
  41. data/lib/active_record/turntable/mixer/fader/select_shards_merge_result.rb +22 -0
  42. data/lib/active_record/turntable/mixer/fader/specified_shard.rb +12 -0
  43. data/lib/active_record/turntable/mixer/fader/update_shards_merge_result.rb +17 -0
  44. data/lib/active_record/turntable/pool_proxy.rb +56 -0
  45. data/lib/active_record/turntable/rack.rb +5 -0
  46. data/lib/active_record/turntable/rack/connection_management.rb +18 -0
  47. data/lib/active_record/turntable/railtie.rb +14 -0
  48. data/lib/active_record/turntable/railties/databases.rake +205 -0
  49. data/lib/active_record/turntable/seq_shard.rb +14 -0
  50. data/lib/active_record/turntable/sequencer.rb +46 -0
  51. data/lib/active_record/turntable/sequencer/api.rb +36 -0
  52. data/lib/active_record/turntable/sequencer/mysql.rb +32 -0
  53. data/lib/active_record/turntable/shard.rb +48 -0
  54. data/lib/active_record/turntable/sql_tree_patch.rb +199 -0
  55. data/lib/active_record/turntable/version.rb +5 -0
  56. data/lib/activerecord-turntable.rb +2 -0
  57. data/lib/generators/active_record/turntable/install_generator.rb +14 -0
  58. data/lib/generators/templates/turntable.yml +40 -0
  59. data/sample_app/.gitignore +16 -0
  60. data/sample_app/Gemfile +41 -0
  61. data/sample_app/README.rdoc +261 -0
  62. data/sample_app/Rakefile +7 -0
  63. data/sample_app/app/assets/images/rails.png +0 -0
  64. data/sample_app/app/assets/javascripts/application.js +15 -0
  65. data/sample_app/app/assets/stylesheets/application.css +13 -0
  66. data/sample_app/app/controllers/application_controller.rb +3 -0
  67. data/sample_app/app/helpers/application_helper.rb +2 -0
  68. data/sample_app/app/mailers/.gitkeep +0 -0
  69. data/sample_app/app/models/.gitkeep +0 -0
  70. data/sample_app/app/models/user.rb +4 -0
  71. data/sample_app/app/views/layouts/application.html.erb +14 -0
  72. data/sample_app/config.ru +4 -0
  73. data/sample_app/config/application.rb +65 -0
  74. data/sample_app/config/boot.rb +6 -0
  75. data/sample_app/config/database.yml +70 -0
  76. data/sample_app/config/environment.rb +5 -0
  77. data/sample_app/config/environments/development.rb +37 -0
  78. data/sample_app/config/environments/production.rb +67 -0
  79. data/sample_app/config/environments/test.rb +37 -0
  80. data/sample_app/config/initializers/backtrace_silencers.rb +7 -0
  81. data/sample_app/config/initializers/inflections.rb +15 -0
  82. data/sample_app/config/initializers/mime_types.rb +5 -0
  83. data/sample_app/config/initializers/secret_token.rb +7 -0
  84. data/sample_app/config/initializers/session_store.rb +8 -0
  85. data/sample_app/config/initializers/wrap_parameters.rb +14 -0
  86. data/sample_app/config/locales/en.yml +5 -0
  87. data/sample_app/config/routes.rb +58 -0
  88. data/sample_app/config/turntable.yml +64 -0
  89. data/sample_app/db/migrate/20120316073058_create_users.rb +11 -0
  90. data/sample_app/db/seeds.rb +7 -0
  91. data/sample_app/lib/assets/.gitkeep +0 -0
  92. data/sample_app/lib/tasks/.gitkeep +0 -0
  93. data/sample_app/log/.gitkeep +0 -0
  94. data/sample_app/public/404.html +26 -0
  95. data/sample_app/public/422.html +26 -0
  96. data/sample_app/public/500.html +25 -0
  97. data/sample_app/public/favicon.ico +0 -0
  98. data/sample_app/public/index.html +241 -0
  99. data/sample_app/public/robots.txt +5 -0
  100. data/sample_app/script/rails +6 -0
  101. data/sample_app/vendor/assets/javascripts/.gitkeep +0 -0
  102. data/sample_app/vendor/assets/stylesheets/.gitkeep +0 -0
  103. data/sample_app/vendor/plugins/.gitkeep +0 -0
  104. data/script/performance/algorithm +32 -0
  105. data/spec/active_record/turntable/active_record_ext/clever_load_spec.rb +81 -0
  106. data/spec/active_record/turntable/active_record_ext/persistence_spec.rb +151 -0
  107. data/spec/active_record/turntable/algorithm/range_algorithm_spec.rb +35 -0
  108. data/spec/active_record/turntable/algorithm_spec.rb +69 -0
  109. data/spec/active_record/turntable/base_spec.rb +13 -0
  110. data/spec/active_record/turntable/cluster_spec.rb +18 -0
  111. data/spec/active_record/turntable/config_spec.rb +17 -0
  112. data/spec/active_record/turntable/connection_proxy_spec.rb +186 -0
  113. data/spec/active_record/turntable/finder_spec.rb +27 -0
  114. data/spec/active_record/turntable/mixer/fader_spec.rb +4 -0
  115. data/spec/active_record/turntable/mixer_spec.rb +114 -0
  116. data/spec/active_record/turntable/shard_spec.rb +21 -0
  117. data/spec/active_record/turntable_spec.rb +30 -0
  118. data/spec/config/database.yml +45 -0
  119. data/spec/config/turntable.yml +17 -0
  120. data/spec/fabricators/.gitkeep +0 -0
  121. data/spec/fabricators/turntable_fabricator.rb +14 -0
  122. data/spec/migrations/.gitkeep +0 -0
  123. data/spec/migrations/001_create_users.rb +16 -0
  124. data/spec/migrations/002_create_user_statuses.rb +16 -0
  125. data/spec/migrations/003_create_cards.rb +14 -0
  126. data/spec/migrations/004_create_cards_users.rb +15 -0
  127. data/spec/spec_helper.rb +23 -0
  128. data/spec/test_models.rb +27 -0
  129. data/spec/turntable_helper.rb +29 -0
  130. metadata +367 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ doc
7
+ .yardoc
8
+
9
+ # For TextMate
10
+ #*.tmproj
11
+ #tmtags
12
+
13
+ # For emacs:
14
+ *~
15
+ \#*
16
+ .\#*
17
+
18
+ # For vim:
19
+ *.swp
20
+
21
+ # For redcar:
22
+ #.redcar
23
+
24
+ # For rubinius:
25
+ #*.rbc
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format=documentation
3
+
data/Gemfile ADDED
@@ -0,0 +1,25 @@
1
+ source :rubygems
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem 'activerecord', ">= 3.1.0"
7
+ gem 'activesupport', ">=3.1.0"
8
+ gem "sql_tree", "=0.2.0"
9
+ gem "bsearch", "~>1.5"
10
+ gem "httpclient"
11
+
12
+ # Add dependencies to develop your gem here.
13
+ # Include everything needed to run rake, tests, features, etc.
14
+ group :development, :test do
15
+ gem "rake", "~>0.9.2"
16
+ gem "rspec"
17
+ gem "rr"
18
+ gem "mysql2"
19
+ gem "fabrication"
20
+ gem "faker"
21
+ gem "activerecord-import"
22
+ gem "pry"
23
+ gem "guard-rspec"
24
+ gem "growl"
25
+ end
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Drecom Co.,Ltd.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,290 @@
1
+ = ActiveRecord::Turntable
2
+
3
+ ActiveRecord::Turntable is a database sharding extension for ActiveRecord.
4
+
5
+ == Dependencies
6
+ activerecord(>=3.0.0)
7
+
8
+ == Supported Database
9
+ Currently supports mysql only.
10
+
11
+ == Installation
12
+
13
+ Add 'activerecord-turntable' to Gemfile:
14
+
15
+ gem 'activerecord-turntable', '1.0.0'
16
+
17
+ Run a bundle install:
18
+
19
+ bundle install
20
+
21
+ Run install generator:
22
+
23
+ bundle exec rails g active_record:turntable:install
24
+
25
+ generator creates Rails.root/config/turntable.yml
26
+
27
+ == ActiveRecord::Turntable terms
28
+
29
+ *Shard
30
+ *Cluster - a cluster of shards.
31
+ *Master - default ActiveRecord::Base's connection
32
+ *Sequencer - a module that creates global sequence number
33
+
34
+ == Example
35
+
36
+ === Example Databases Structure
37
+ one main database(default ActiveRecord::Base connection) and
38
+ three user databases sharded by user_id.
39
+
40
+ +-------+
41
+ | App |
42
+ +-------+
43
+ |
44
+ +---------+-----------+---------+---------+
45
+ | | | | |
46
+ +--------+ +---------+ +-------+ +-------+ +-------+
47
+ | Master | |Sequencer| |UserDB1| |UserDB2| |UserDB3|
48
+ +--------+ +---------+ +-------+ +-------+ +-------+
49
+
50
+ === Example Configuration
51
+
52
+ Edit turntable.yml and database.yml. See below example config.
53
+
54
+ example turntable.yml:
55
+
56
+ development:
57
+ clusters:
58
+ user_cluster: # <-- cluster name
59
+ algorithm: range # <-- only range or range_bsearch sharding is supported currently.
60
+ shards:
61
+ - connection: user_shard_1 # <-- shard name
62
+ less_than: 100 # <-- shard range(like mysql partitioning)
63
+ - connection: user_shard_2
64
+ less_than: 200
65
+ - connection: user_shard_3
66
+ less_than: 2000000000
67
+
68
+ database.yml:
69
+ connection_spec: &spec
70
+ adapter: mysql2
71
+ encoding: utf8
72
+ reconnect: false
73
+ pool: 5
74
+ username: root
75
+ password: root
76
+ socket: /tmp/mysql.sock
77
+
78
+ development:
79
+ <<: *spec
80
+ database: sample_app_development
81
+ seq: # <-- sequence definition
82
+ user_seq_1:
83
+ <<: *spec
84
+ database: sample_app_user_seq_development
85
+ shards: # <-- shards definition
86
+ user_shard_1:
87
+ <<: *spec
88
+ database: sample_app_user1_development
89
+ user_shard_2:
90
+ <<: *spec
91
+ database: sample_app_user2_development
92
+ user_shard_3:
93
+ <<: *spec
94
+ database: sample_app_user3_development
95
+
96
+
97
+ === Migration Example
98
+
99
+ Generate a model:
100
+
101
+ bundle exec rails g model user name:string
102
+
103
+ Edit migration file:
104
+
105
+ class CreateUsers < ActiveRecord::Migration
106
+ clusters :user_cluster # <-- the cluster that executes migration
107
+
108
+ def change
109
+ create_table :users do |t|
110
+ t.string :name
111
+ t.timestamps
112
+ end
113
+ create_sequence_for(:users)
114
+ end
115
+ end
116
+
117
+ then please execute rake tasks:
118
+
119
+ bundle exec rake db:create
120
+ bundle exec rake db:migrate
121
+
122
+ Those rake tasks would be executed to shards too.
123
+
124
+ === Model Example
125
+ add turntable [shard_key_name] to the model class:
126
+
127
+ class User < ActiveRecord::Base
128
+ turntable :user_cluster, :id
129
+ sequencer
130
+ has_one :status
131
+ end
132
+
133
+ class Status < ActiveRecord::Base
134
+ turntable :user_cluster, :user_id
135
+ sequencer
136
+ belongs_to :user
137
+ end
138
+
139
+ == Usage
140
+
141
+ === Create
142
+ > User.create(name: "hoge")
143
+ (0.0ms) [Shard: user_seq_1] BEGIN
144
+ (0.3ms) [Shard: user_seq_1] UPDATE `users_id_seq` SET id=LAST_INSERT_ID(id+1)
145
+ (0.8ms) [Shard: user_seq_1] COMMIT
146
+ (0.1ms) [Shard: user_seq_1] SELECT LAST_INSERT_ID()
147
+ (0.1ms) [Shard: user_shard_1] BEGIN
148
+ [ActiveRecord::Turntable] Sending method: insert, sql: #<Arel::InsertManager:0x007f8503685b48>, shards: ["user_shard_1"]
149
+ SQL (0.8ms) [Shard: user_shard_1] INSERT INTO `users` (`created_at`, `id`, `name`, `updated_at`) VALUES ('2012-04-10 03:59:42', 2, 'hoge', '2012-04-10 03:59:42')
150
+ (0.4ms) [Shard: user_shard_1] COMMIT
151
+ => #<User id: 2, name: "hoge", created_at: "2012-04-10 03:59:42", updated_at: "2012-04-10 03:59:42">
152
+
153
+ === Retrieve
154
+ > user = User.find(2)
155
+ [ActiveRecord::Turntable] Sending method: select_all, sql: #<Arel::SelectManager:0x007f850466e668>, shards: ["user_shard_1"]
156
+ User Load (0.3ms) [Shard: user_shard_1] SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
157
+ => #<User id: 2, name: "hoge", created_at: "2012-04-10 03:59:42", updated_at: "2012-04-10 03:59:42">
158
+
159
+ === Update
160
+ > user.update_attributes(name: "hogefoo")
161
+ (0.1ms) [Shard: user_shard_1] BEGIN
162
+ [ActiveRecord::Turntable] Sending method: update, sql: UPDATE `users` SET `name` = 'hogefoo', `updated_at` = '2012-04-10 04:07:52' WHERE `users`.`id` = 2, shards: ["user_shard_1"]
163
+ (0.3ms) [Shard: user_shard_1] UPDATE `users` SET `name` = 'hogefoo', `updated_at` = '2012-04-10 04:07:52' WHERE `users`.`id` = 2
164
+ (0.8ms) [Shard: user_shard_1] COMMIT
165
+ => true
166
+
167
+ === Delete
168
+ > user.destroy
169
+ (0.2ms) [Shard: user_shard_1] BEGIN
170
+ [ActiveRecord::Turntable] Sending method: delete, sql: #<Arel::DeleteManager:0x007f8503677ea8>, shards: ["user_shard_1"]
171
+ SQL (0.3ms) [Shard: user_shard_1] DELETE FROM `users` WHERE `users`.`id` = 2
172
+ (1.7ms) [Shard: user_shard_1] COMMIT
173
+ => #<User id: 2, name: "hogefoo", created_at: "2012-04-10 03:59:42", updated_at: "2012-04-10 04:07:52">
174
+
175
+ === Count
176
+
177
+ > User.count
178
+ [ActiveRecord::Turntable] Sending method: select_value, sql: #<Arel::SelectManager:0x007f9e82ccebb0>, shards: ["user_shard_1", "user_shard_2", "user_shard_3"]
179
+ (0.8ms) [Shard: user_shard_1] SELECT COUNT(*) FROM `users`
180
+ (0.3ms) [Shard: user_shard_2] SELECT COUNT(*) FROM `users`
181
+ (0.2ms) [Shard: user_shard_3] SELECT COUNT(*) FROM `users`
182
+ => 1
183
+
184
+ === Sequencer
185
+ Sequencer provides generating global IDs.
186
+
187
+ Add below to the migration:
188
+
189
+ create_sequence_for(:users) # <-- this line creates sequence table
190
+
191
+ This will creates sequence table.
192
+
193
+ Next, add sequencer to the model:
194
+
195
+ class User < ActiveRecord::Base
196
+ turntable :id
197
+ sequencer # <-- this line enables sequencer module
198
+ has_one :status
199
+ end
200
+
201
+
202
+ === Transaction
203
+ > user = User.find(2)
204
+ > user3 = User.create(name: "hoge3")
205
+ > User.shards_transaction([user, user3]) do
206
+ > user.name = "hogehoge"
207
+ > user3.name = "hogehoge3"
208
+ > user.save!
209
+ > user3.save!
210
+ > end
211
+
212
+ === Send query to a specific shard.
213
+ use with_shard method:
214
+
215
+ AR::Base.connection.with_shard(shard1) do
216
+ # something queries to shard1
217
+ end
218
+
219
+ To access shard objects, use below:
220
+ * AR::Base.connection.shards # \\{shard_name => shard_obj,....}
221
+ * AR::Base#turntable_shard
222
+ * AR::Base.connection.select_shard(shard_key_value) #=> shard
223
+
224
+ === Send query to all shards
225
+ use with_all method:
226
+
227
+ User.connection.with_all do
228
+ User.order("created_at DESC").limit(3).all
229
+ end
230
+
231
+
232
+ === Migration
233
+ If you specify cluster or shard, migration will be executed to the cluster(or shard) and master database.
234
+
235
+ to specify cluster:
236
+
237
+ class CreateUsers < ActiveRecord::Migration
238
+ clusters :user_cluster
239
+ ....
240
+ end
241
+
242
+ to specify shard:
243
+
244
+ class CreateUsers < ActiveRecord::Migration
245
+ shards :user_shard_01
246
+ ....
247
+ end
248
+
249
+ if you would like to execute a migration to all databases in the environments, use :all symbol:
250
+
251
+ class CreateUsers < ActiveRecord::Migration
252
+ clusters :all
253
+ ....
254
+ end
255
+
256
+ == Connection Management
257
+ Rails's ConnectionManagement middleware keeps ActiveRecord's connection during the process is alive, but Turntable keeps more connections.
258
+ This may cause flooding max connections on your database. So, we made a middleware that disconnects on each request.
259
+ To use turntable's ConnectionManagement middleware, add below line to your initializer.
260
+
261
+ app.middleware.swap ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::Turntable::Rack::ConnectionManagement
262
+
263
+ == Inability
264
+ * Queries includes "ORDER BY", "GROUP BY" and "LIMIT" clauses cannot be distributed.
265
+ * "has many through" and "habtm" relationships causes wrong results. ex) User-Friend-User relation
266
+
267
+ == Thanks to
268
+ ConnectionProxy, Distributed Migration implementation is inspired by Octopus and DataFabric.
269
+
270
+ == LICENSE
271
+ Copyright (c) 2012 Drecom Co.,Ltd.
272
+
273
+ Permission is hereby granted, free of charge, to any person obtaining
274
+ a copy of this software and associated documentation files (the
275
+ "Software"), to deal in the Software without restriction, including
276
+ without limitation the rights to use, copy, modify, merge, publish,
277
+ distribute, sublicense, and/or sell copies of the Software, and to
278
+ permit persons to whom the Software is furnished to do so, subject to
279
+ the following conditions:
280
+
281
+ The above copyright notice and this permission notice shall be
282
+ included in all copies or substantial portions of the Software.
283
+
284
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
285
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
286
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
287
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
288
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
289
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
290
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,101 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rubygems'
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ namespace :turntable do
11
+ namespace :db do
12
+ task :rails_env do
13
+ unless defined? RAILS_ENV
14
+ RAILS_ENV = ENV['RAILS_ENV'] ||= 'test'
15
+ end
16
+ end
17
+
18
+ task :load_config => :rails_env do
19
+ require 'active_record'
20
+ ActiveRecord::Base.configurations = YAML.load_file(File.join(File.dirname(__FILE__), 'spec/config/database.yml'))
21
+ end
22
+
23
+ desc "create turntable test database"
24
+ task :create => :load_config do
25
+ database_configs = [ActiveRecord::Base.configurations[RAILS_ENV]] + ActiveRecord::Base.configurations[RAILS_ENV]["shards"].values + ActiveRecord::Base.configurations[RAILS_ENV]["seq"].values
26
+ database_configs.each do |dbconf|
27
+ %x{ echo "CREATE DATABASE #{dbconf["database"]}" | mysql -u #{dbconf["username"]} -p#{dbconf["password"]} -h #{dbconf["host"]} }
28
+ end
29
+ end
30
+
31
+ desc "migrate turntable test tables"
32
+ task :migrate => :load_config do
33
+ ActiveRecord::Base.establish_connection RAILS_ENV
34
+ require 'active_record/turntable'
35
+ ActiveRecord::Base.send(:include, ActiveRecord::Turntable)
36
+ ActiveRecord::ConnectionAdapters::SchemaStatements.send(:include, Turntable::Migration::SchemaStatementsExt)
37
+ database_configs = [ActiveRecord::Base.configurations[RAILS_ENV]] + ActiveRecord::Base.configurations[RAILS_ENV]["shards"].values + ActiveRecord::Base.configurations[RAILS_ENV]["seq"].values
38
+
39
+ database_configs.each do |dbconf|
40
+ ActiveRecord::Base.establish_connection dbconf
41
+
42
+ ActiveRecord::Base.connection.create_table :users do |t|
43
+ t.string :nickname
44
+ t.string :thumbnail_url
45
+ t.datetime :joined_at
46
+ t.datetime :deleted_at
47
+ t.timestamps
48
+ end
49
+ ActiveRecord::Base.connection.create_sequence_for :users
50
+
51
+ ActiveRecord::Base.connection.create_table :user_statuses do |t|
52
+ t.belongs_to :user, :null => false
53
+ t.integer :hp, :null => false, :default => 0
54
+ t.integer :mp, :null => false, :default => 0
55
+ t.datetime :deleted_at, :default => nil
56
+ t.timestamps
57
+ end
58
+ ActiveRecord::Base.connection.create_sequence_for :user_statuses
59
+
60
+ ActiveRecord::Base.connection.create_table :cards do |t|
61
+ t.string :name, :null => false
62
+ t.integer :hp, :null => false, :default => 0
63
+ t.integer :mp, :null => false, :default => 0
64
+ t.timestamps
65
+ end
66
+ ActiveRecord::Base.connection.create_table :archived_cards do |t|
67
+ t.string :name, :null => false
68
+ t.integer :hp, :null => false, :default => 0
69
+ t.integer :mp, :null => false, :default => 0
70
+ t.timestamps
71
+ t.datetime :deleted_at, :default => nil
72
+ end
73
+
74
+ ActiveRecord::Base.connection.create_table :cards_users do |t|
75
+ t.belongs_to :card, :null => false
76
+ t.belongs_to :user, :null => false
77
+ t.timestamps
78
+ end
79
+ ActiveRecord::Base.connection.create_sequence_for :cards_users
80
+
81
+ ActiveRecord::Base.connection.create_table :archived_cards_users do |t|
82
+ t.belongs_to :card, :null => false
83
+ t.belongs_to :user, :null => false
84
+ t.timestamps
85
+ t.datetime :deleted_at, :default => nil
86
+ end
87
+ ActiveRecord::Base.connection.create_sequence_for :archived_cards_users
88
+ end
89
+ end
90
+
91
+ desc "drop turntable test database"
92
+ task :drop => :load_config do
93
+ database_configs = [ActiveRecord::Base.configurations[RAILS_ENV]] + ActiveRecord::Base.configurations[RAILS_ENV]["shards"].values + ActiveRecord::Base.configurations[RAILS_ENV]["seq"].values
94
+ database_configs.each do |dbconf|
95
+ %x{ echo "DROP DATABASE #{dbconf["database"]}" | mysql -u #{dbconf["username"]} -p#{dbconf["password"]} -h #{dbconf["host"]} }
96
+ end
97
+ end
98
+
99
+ task :reset => ["turntable:db:drop", "turntable:db:create", "turntable:db:migrate"]
100
+ end
101
+ end