ar-octopus 0.8.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +6 -14
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -1
  4. data/.rubocop.yml +46 -0
  5. data/.rubocop_todo.yml +56 -0
  6. data/.travis.yml +7 -12
  7. data/Appraisals +11 -4
  8. data/Gemfile +1 -1
  9. data/README.mkdn +138 -63
  10. data/Rakefile +23 -16
  11. data/ar-octopus.gemspec +23 -20
  12. data/gemfiles/rails42.gemfile +7 -0
  13. data/gemfiles/{rails32.gemfile → rails5.gemfile} +2 -2
  14. data/gemfiles/{rails4.gemfile → rails51.gemfile} +2 -2
  15. data/gemfiles/rails52.gemfile +7 -0
  16. data/lib/ar-octopus.rb +1 -1
  17. data/lib/octopus/{rails3/abstract_adapter.rb → abstract_adapter.rb} +4 -15
  18. data/lib/octopus/association.rb +8 -99
  19. data/lib/octopus/association_shard_tracking.rb +74 -0
  20. data/lib/octopus/collection_association.rb +17 -0
  21. data/lib/octopus/collection_proxy.rb +16 -0
  22. data/lib/octopus/exception.rb +4 -0
  23. data/lib/octopus/finder_methods.rb +8 -0
  24. data/lib/octopus/load_balancing/round_robin.rb +20 -0
  25. data/lib/octopus/load_balancing.rb +4 -0
  26. data/lib/octopus/{rails3/log_subscriber.rb → log_subscriber.rb} +6 -2
  27. data/lib/octopus/migration.rb +187 -110
  28. data/lib/octopus/model.rb +151 -131
  29. data/lib/octopus/persistence.rb +45 -0
  30. data/lib/octopus/proxy.rb +297 -232
  31. data/lib/octopus/proxy_config.rb +251 -0
  32. data/lib/octopus/query_cache_for_shards.rb +24 -0
  33. data/lib/octopus/railtie.rb +1 -3
  34. data/lib/octopus/relation_proxy.rb +70 -0
  35. data/lib/octopus/result_patch.rb +19 -0
  36. data/lib/octopus/scope_proxy.rb +54 -36
  37. data/lib/octopus/shard_tracking/attribute.rb +22 -0
  38. data/lib/octopus/shard_tracking/dynamic.rb +11 -0
  39. data/lib/octopus/shard_tracking.rb +46 -0
  40. data/lib/octopus/singular_association.rb +9 -0
  41. data/lib/octopus/slave_group.rb +13 -0
  42. data/lib/octopus/version.rb +1 -1
  43. data/lib/octopus.rb +125 -33
  44. data/lib/tasks/octopus.rake +2 -2
  45. data/sample_app/Gemfile +3 -3
  46. data/sample_app/autotest/discover.rb +2 -2
  47. data/sample_app/config/application.rb +1 -1
  48. data/sample_app/config/boot.rb +1 -1
  49. data/sample_app/config/environments/test.rb +1 -1
  50. data/sample_app/config/initializers/session_store.rb +1 -1
  51. data/sample_app/config/initializers/wrap_parameters.rb +1 -1
  52. data/sample_app/config/routes.rb +1 -1
  53. data/sample_app/db/migrate/20100720210335_create_sample_users.rb +2 -2
  54. data/sample_app/db/schema.rb +10 -10
  55. data/sample_app/db/seeds.rb +3 -3
  56. data/sample_app/features/step_definitions/seeds_steps.rb +4 -4
  57. data/sample_app/features/step_definitions/web_steps.rb +3 -4
  58. data/sample_app/features/support/env.rb +3 -4
  59. data/sample_app/features/support/paths.rb +4 -4
  60. data/sample_app/lib/tasks/cucumber.rake +43 -44
  61. data/sample_app/spec/spec_helper.rb +3 -3
  62. data/spec/config/shards.yml +78 -0
  63. data/spec/migrations/10_create_users_using_replication.rb +4 -4
  64. data/spec/migrations/11_add_field_in_all_slaves.rb +4 -4
  65. data/spec/migrations/12_create_users_using_block.rb +8 -8
  66. data/spec/migrations/13_create_users_using_block_and_using.rb +5 -5
  67. data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +3 -3
  68. data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +3 -3
  69. data/spec/migrations/1_create_users_on_master.rb +4 -4
  70. data/spec/migrations/2_create_users_on_canada.rb +4 -4
  71. data/spec/migrations/3_create_users_on_both_shards.rb +4 -4
  72. data/spec/migrations/4_create_users_on_shards_of_a_group.rb +4 -4
  73. data/spec/migrations/5_create_users_on_multiples_groups.rb +3 -3
  74. data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +4 -4
  75. data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +4 -4
  76. data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +4 -4
  77. data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +5 -5
  78. data/spec/octopus/association_shard_tracking_spec.rb +1036 -0
  79. data/spec/octopus/collection_proxy_spec.rb +16 -0
  80. data/spec/octopus/load_balancing/round_robin_spec.rb +15 -0
  81. data/spec/octopus/log_subscriber_spec.rb +5 -5
  82. data/spec/octopus/migration_spec.rb +83 -49
  83. data/spec/octopus/model_spec.rb +544 -292
  84. data/spec/octopus/octopus_spec.rb +64 -31
  85. data/spec/octopus/proxy_spec.rb +145 -141
  86. data/spec/octopus/query_cache_for_shards_spec.rb +40 -0
  87. data/spec/octopus/relation_proxy_spec.rb +132 -0
  88. data/spec/octopus/replicated_slave_grouped_spec.rb +91 -0
  89. data/spec/octopus/replication_spec.rb +140 -65
  90. data/spec/octopus/scope_proxy_spec.rb +90 -10
  91. data/spec/octopus/sharded_replicated_slave_grouped_spec.rb +55 -0
  92. data/spec/octopus/sharded_spec.rb +10 -10
  93. data/spec/spec_helper.rb +8 -6
  94. data/spec/support/active_record/connection_adapters/modify_config_adapter.rb +1 -3
  95. data/spec/support/database_connection.rb +2 -2
  96. data/spec/support/database_models.rb +18 -17
  97. data/spec/support/octopus_helper.rb +32 -25
  98. data/spec/support/query_count.rb +1 -3
  99. data/spec/support/shared_contexts.rb +3 -3
  100. data/spec/tasks/octopus.rake_spec.rb +10 -10
  101. metadata +112 -70
  102. data/.ruby-version +0 -1
  103. data/init.rb +0 -1
  104. data/lib/octopus/association_collection.rb +0 -49
  105. data/lib/octopus/has_and_belongs_to_many_association.rb +0 -17
  106. data/lib/octopus/rails3/persistence.rb +0 -39
  107. data/lib/octopus/rails3/singular_association.rb +0 -34
  108. data/rails/init.rb +0 -1
  109. data/spec/octopus/association_spec.rb +0 -712
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MTRmYWZkMTg0YzU4MTM4YmNjYTM3MDE3MDVjZjQ1MjdiYmE2NDkwMg==
5
- data.tar.gz: !binary |-
6
- ODhhZTJjNDQzZDVhMWZhYzc1NzRjYWNjOTdlYTQ5MTNlYzk5YWJkMA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- Y2JiNmI0MjEzYWRjYTFhYjMwN2IyYWQwMTQyMDI1M2UyYTdiNzU3NGY4ZDlm
10
- MGYwNDQ2NGViMjhjOGRjMTZiNjdjN2VhODZiOGQ3ZWQ2Njg5OTFjZWE1ZDQ5
11
- ZThjNjUxOTNhYzYyNTMwMjk3MjkwYmYzNmU3YjA0Y2MzMjMyZmE=
12
- data.tar.gz: !binary |-
13
- MjU1YzZlNzczNGM2OGQ2YzMxYmZhMWE4M2QzYTQ5ZjM1NjEwYTQ4MDJiMDY5
14
- YzM0Mjg4OTc4MmI4ZGYxMTlhNDJmYWMxMzA3MjU5ZDdmNjIwNmNmNmNlMmY3
15
- OWZjY2RkNTViY2MzOTdjMjU5NTg2NjFkNDcyZmRiMWU5NDA2MWM=
2
+ SHA256:
3
+ metadata.gz: be74de9c9b6dfacee338dfa5d500da6ce758f501e3be7fa0f154afda07f31f40
4
+ data.tar.gz: 1892942a155383583a054e4d61cc588ebca2b33749ca191762d550bf9bf13022
5
+ SHA512:
6
+ metadata.gz: c0b21eb7e0fa5397b77c5df6c0bdce5fced41b7284ee7fc4869539ec6219bfcbe2f02a7e85239979b7534a298e2b7ad34e6833fdeb0fd81c67c536b17ea73ae9
7
+ data.tar.gz: 34bd15fbfb892fca1329f69abf85ba4421d563278d846a67014b710b473919d50cfc3425ed76de1580484a4f10554d4464a490e5ac49b3339553b810acdacfd5
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.sqlite3
3
3
  .bundle
4
4
  .rvmrc
5
+ .ruby-version
5
6
  Gemfile.lock
6
7
  gemfiles/*.lock
7
8
  pkg/*
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
1
  --color
2
- --format=documentation
2
+ --format=documentation
data/.rubocop.yml ADDED
@@ -0,0 +1,46 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ ActionFilter:
4
+ EnforcedStyle: filter
5
+
6
+ CaseIndentation:
7
+ IndentWhenRelativeTo: end
8
+
9
+ CollectionMethods:
10
+ PreferredMethods:
11
+ find: detect
12
+
13
+ EmptyLineBetweenDefs:
14
+ AllowAdjacentOneLineDefs: true
15
+
16
+ Encoding:
17
+ Enabled: false
18
+
19
+ EndAlignment:
20
+ AlignWith: variable
21
+
22
+ HashSyntax:
23
+ EnforcedStyle: hash_rockets
24
+
25
+ Style/IndentHash:
26
+ EnforcedStyle: consistent
27
+
28
+ Loop:
29
+ Enabled: false
30
+
31
+ PredicateName:
32
+ Enabled: false
33
+
34
+ RegexpLiteral:
35
+ Enabled: false
36
+
37
+ Semicolon:
38
+ AllowAsExpressionSeparator: true
39
+
40
+ Style/TrailingComma:
41
+ EnforcedStyleForMultiline: comma
42
+
43
+ Style/TrivialAccessors:
44
+ AllowDSLWriters: true
45
+ AllowPredicates: true
46
+ ExactNameMatch: true
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,56 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2014-09-25 20:13:18 -0700 using RuboCop version 0.26.1.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 27
9
+ Lint/AmbiguousRegexpLiteral:
10
+ Enabled: false
11
+
12
+ # Offense count: 1
13
+ Lint/HandleExceptions:
14
+ Enabled: false
15
+
16
+ # Offense count: 1
17
+ # Configuration parameters: CountComments.
18
+ Metrics/ClassLength:
19
+ Max: 324
20
+
21
+ # Offense count: 3
22
+ Metrics/CyclomaticComplexity:
23
+ Max: 14
24
+
25
+ # Offense count: 300
26
+ # Configuration parameters: AllowURI, URISchemes.
27
+ Metrics/LineLength:
28
+ Max: 180
29
+
30
+ # Offense count: 10
31
+ # Configuration parameters: CountComments.
32
+ Metrics/MethodLength:
33
+ Max: 52
34
+
35
+ # Offense count: 3
36
+ Metrics/PerceivedComplexity:
37
+ Max: 15
38
+
39
+ # Offense count: 80
40
+ Style/Documentation:
41
+ Enabled: false
42
+
43
+ # Offense count: 1
44
+ # Configuration parameters: Exclude.
45
+ Style/FileName:
46
+ Enabled: false
47
+
48
+ # Offense count: 1
49
+ # Configuration parameters: MinBodyLength.
50
+ Style/GuardClause:
51
+ Enabled: false
52
+
53
+ # Offense count: 2
54
+ # Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
55
+ Style/Next:
56
+ Enabled: false
data/.travis.yml CHANGED
@@ -4,20 +4,15 @@ env:
4
4
  before_script:
5
5
  - "bundle exec rake db:prepare"
6
6
  rvm:
7
- - 1.9.3
8
-
7
+ - 2.2.7
8
+ - 2.3.4
9
+ - 2.4.1
9
10
  gemfile:
10
- - gemfiles/rails32.gemfile
11
- - gemfiles/rails4.gemfile
12
-
11
+ - gemfiles/rails42.gemfile
12
+ - gemfiles/rails5.gemfile
13
+ - gemfiles/rails51.gemfile
14
+ - gemfiles/rails52.gemfile
13
15
  notifications:
14
16
  recipients:
15
17
  - gabriel.sobrinho@gmail.com
16
18
  - thiago.pradi@gmail.com
17
-
18
- matrix:
19
- include:
20
- - rvm: 2.0.0
21
- gemfile: gemfiles/rails32.gemfile
22
- - rvm: 2.0.0
23
- gemfile: gemfiles/rails4.gemfile
data/Appraisals CHANGED
@@ -1,9 +1,16 @@
1
- appraise "rails32" do
2
- gem "activerecord", "~> 3.2.0"
1
+ appraise "rails42" do
2
+ gem "activerecord", "~> 4.2.0"
3
3
  end
4
4
 
5
- appraise "rails4" do
6
- gem "activerecord", "~> 4.0.0"
5
+ appraise "rails5" do
6
+ gem "activerecord", "~> 5.0.0"
7
7
  end
8
8
 
9
+ appraise "rails51" do
10
+ gem "activerecord", "~> 5.1.0"
11
+ end
12
+
13
+ appraise "rails52" do
14
+ gem "activerecord", "~> 5.2.0"
15
+ end
9
16
  # vim: ft=ruby
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in ar-octopus.gemspec
4
4
  gemspec
data/README.mkdn CHANGED
@@ -1,11 +1,16 @@
1
+ # Important Notice:
2
+
3
+ Octopus will enter into maintainance mode once Rails 6 is released - since Rails 6 will include all the features for Database Sharding / Replication into Rails Core (PR: https://github.com/rails/rails/pull/34052).
4
+ Once the first version of Rails 6 beta is released, there will be a migration guide to help users migrate from Octopus to Rails 6.
5
+
1
6
  # Octopus - Easy Database Sharding for ActiveRecord
2
7
 
3
- <a href='http://www.pledgie.com/campaigns/20950'><img alt='Click here to lend your support to: Octopus and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/20950.png?skin_name=chrome' border='0' /></a> [![Build Status](https://travis-ci.org/tchandy/octopus.png)](https://travis-ci.org/tchandy/octopus) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/tchandy/octopus)
8
+ [![Build Status](https://travis-ci.org/thiagopradi/octopus.svg)](https://travis-ci.org/thiagopradi/octopus) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/thiagopradi/octopus)
4
9
 
5
10
  Octopus is a better way to do Database Sharding in ActiveRecord. Sharding allows multiple databases in the same rails application. While there are several projects that implement Sharding (e.g. DbCharmer, DataFabric, MultiDb), each project has its own limitations. The main goal of octopus project is to provide a better way of doing Database Sharding.
6
11
 
7
12
  ## Feature list:
8
- The api is designed to be simple as possible. Octopus focuses on the end user, giving the power of multiple databases but with reliable code and flexibility. Octopus is compatible with Rails 3.2 and Rails 4.
13
+ The api is designed to be simple as possible. Octopus focuses on the end user, giving the power of multiple databases but with reliable code and flexibility. Octopus is compatible with Rails 4 and Rails 5.
9
14
 
10
15
  Octopus supports:
11
16
 
@@ -15,19 +20,23 @@ Octopus supports:
15
20
  - Tools to manage database configurations. (soon)
16
21
 
17
22
  ### Replication
18
- When using replication, all writes queries will be sent to master, and read queries to slaves. More info could be found at: <a href="http://wiki.github.com/tchandy/octopus/replication"> Wiki</a>
23
+ When using replication, all writes queries will be sent to master, and read queries to slaves. More info could be found at: <a href="http://wiki.github.com/thiagopradi/octopus/replication"> Wiki</a>
19
24
 
20
25
  ### Sharding
21
- When using sharding, you need to specify which shard to send the query. Octopus supports selecting the shard inside a controller, or manually in each object. More could be found at <a href="http://wiki.github.com/tchandy/octopus/sharding"> Wiki</a>
26
+ When using sharding, you need to specify which shard to send the query. Octopus supports selecting the shard inside a controller, or manually in each object. More could be found at <a href="http://wiki.github.com/thiagopradi/octopus/sharding"> Wiki</a>
22
27
 
23
28
  ### Replication + Sharding
24
- Replication + Sharding isn't supported yet. This is on our TODO list and will be done ASAP. If you need, feel free to fork and implement it.
29
+ When using replication and sharding concurrently, you must specify a shard, and can optionally specify a <a href="https://github.com/thiagopradi/octopus/wiki/Slave-Groups">slave group</a>.
30
+ All write queries will be sent to each shard's master. If the slave group is specified read queries will be sent to slaves in it, or else to shard's master.
31
+ More info could be found at <a href="https://github.com/thiagopradi/octopus/wiki/Slave-Groups"> Wiki</a>
25
32
 
26
33
  ## Install
27
34
 
28
35
  Add this line to Gemfile:
29
36
 
30
- gem 'ar-octopus'
37
+ ```
38
+ gem 'ar-octopus'
39
+ ```
31
40
 
32
41
  Currently, Octopus doesn't support Rails 2. If you need support for rails 2, please use the version 0.5.0.
33
42
 
@@ -42,122 +51,188 @@ information for each shard is stored within that shard's database.
42
51
  If you are upgrading from < 0.5.0 run the `copy_schema_versions` rake task to copy the schema version information in the
43
52
  master database to each of the shards:
44
53
 
45
- rake octopus:copy_schema_versions
54
+ ```bash
55
+ rake octopus:copy_schema_versions
56
+ ```
46
57
 
47
58
  Once the task completes migrations will operate normally and schema information will be stored in each shard database
48
59
  going forward.
49
60
 
50
61
  ## How to use Octopus?
51
62
 
52
- First, you need to create a config file, shards.yml, inside your config/ directory. to see the syntax and how this file should look, please checkout <a href="http://wiki.github.com/tchandy/octopus/config-file">this page on wiki</a>.
63
+ First, you need to create a config file, shards.yml, inside your config/ directory. to see the syntax and how this file should look, please checkout <a href="http://wiki.github.com/thiagopradi/octopus/config-file">this page on wiki</a>.
53
64
 
54
65
  ### Syntax
55
66
 
56
67
  Octopus adds a method to each AR Class and object: the using method is used to select the shard like this:
57
68
 
58
- User.where(:name => "Thiago").limit(3).using(:slave_one)
69
+ ```ruby
70
+ User.where(:name => "Boba").limit(3).using(:read_replica_one)
71
+ ```
59
72
 
60
73
  Octopus also supports queries within a block. When you pass a block to the using method, all queries inside the block will be sent to the specified shard.
61
74
 
62
- Octopus.using(:slave_two) do
63
- User.create(:name => "Mike")
64
- end
75
+ ```ruby
76
+ Octopus.using(:read_replica_two) do
77
+ User.create(:name => "Thiago")
78
+ end
79
+ ```
80
+
81
+ If you want to use the same code for all shards or all shards in a specific group (for example in `db/seeds.rb`), you can use this syntax.
82
+
83
+ ```ruby
84
+ # This will return a list of the given block's results, per shard.
85
+ Octopus.using_all do
86
+ User.create_from_csv!
87
+ end
88
+
89
+ # This will return a list of the given block's results, per shard in history_shards group.
90
+ Octopus.using_group(:history_shards) do
91
+ HistoryCategory.create_from_csv!
92
+ end
93
+ ```
65
94
 
66
95
  Each model instance knows which shard it came from so this will work automatically:
67
96
 
68
- # This will find the user in the shard1
69
- @user = User.using(:shard1).find_by_name("Joao")
97
+ ```ruby
98
+ # This will find the user in the shard1
99
+ @user = User.using(:shard1).find_by_name("Joao")
70
100
 
71
- # This will find the user in the master database
72
- @user2 = User.find_by_name("Jose")
101
+ # This will find the user in the master database
102
+ @user2 = User.find_by_name("Jose")
73
103
 
74
- #Sets the name
75
- @user.name = "Mike"
104
+ #Sets the name
105
+ @user.name = "Mike"
76
106
 
77
- # Save the user in the correct shard, shard1.
78
- @user.save
107
+ # Save the user in the correct shard, shard1.
108
+ @user.save
109
+ ```
79
110
 
80
111
  ### Migrations
81
112
 
82
113
  In migrations, you also have access to the using method. The syntax is basically the same. This migration will run in the brazil and canada shards.
83
114
 
84
- class CreateUsersOnBothShards < ActiveRecord::Migration
85
- using(:brazil, :canada)
115
+ ```ruby
116
+ class CreateUsersOnBothShards < ActiveRecord::Migration
117
+ using(:brazil, :canada)
86
118
 
87
- def self.up
88
- User.create!(:name => "Both")
89
- end
119
+ def self.up
120
+ User.create!(:name => "Both")
121
+ end
90
122
 
91
- def self.down
92
- User.delete_all
93
- end
94
- end
123
+ def self.down
124
+ User.delete_all
125
+ end
126
+ end
127
+ ```
95
128
 
96
129
  You also could send a migration to a group of shards. This migration will be sent to all shards that belongs to history_shards group, specified in shards.yml:
97
130
 
98
- class CreateUsersOnMultiplesGroups < ActiveRecord::Migration
99
- using_group(:history_shards)
131
+ ```ruby
132
+ class CreateUsersOnMultiplesGroups < ActiveRecord::Migration
133
+ using_group(:history_shards)
100
134
 
101
- def self.up
102
- User.create!(:name => "MultipleGroup")
103
- end
135
+ def self.up
136
+ User.create!(:name => "MultipleGroup")
137
+ end
104
138
 
105
- def self.down
106
- User.delete_all
107
- end
108
- end
139
+ def self.down
140
+ User.delete_all
141
+ end
142
+ end
143
+ ```
109
144
 
110
145
  You can specify a `default_migration_group` for migrations, so that modifications to each individual migration file are not needed:
111
-
112
- octopus:
113
- default_migration_group: europe_databases
146
+ ```yaml
147
+ octopus:
148
+ default_migration_group: europe_databases
149
+ ```
114
150
 
115
151
  There is no need for a corresponding `default_migration_shard` - simply define that database to be your master. You might want this setting if all of your databases have identical schemas, but are not replicated.
116
152
 
153
+ You can configure a master shard for the rails application, to connect to when rails is going up. The safest would be to configure this to the shard specified in `database.yml` (some things still use it).
154
+
155
+ ```yaml
156
+ octopus:
157
+ master_shard: <%= ENV['SHARD'] || 'shard1' %>
158
+ ```
159
+
160
+ Then you can use the `SHARD` environment variable to override the `master_shard` specified in `config/shards.yml`, useful for running rake tasks.
161
+
162
+ ```bash
163
+ SHARD=shard1 rake db:setup && SHARD=shard2 rake db:setup
164
+ ```
165
+
117
166
  ### Rails Controllers
118
167
 
119
168
  If you want to send a specified action, or all actions from a controller, to a specific shard, use this syntax:
120
169
 
121
- class ApplicationController < ActionController::Base
122
- around_filter :select_shard
170
+ ```ruby
171
+ class ApplicationController < ActionController::Base
172
+ around_filter :select_shard
123
173
 
124
- def select_shard(&block)
125
- Octopus.using(:brazil, &block)
126
- end
127
- end
174
+ def select_shard(&block)
175
+ Octopus.using(:brazil, &block)
176
+ end
177
+ end
178
+ ```
128
179
 
129
- To see the complete list of features and syntax, please check out our <a href="http://wiki.github.com/tchandy/octopus/"> Wiki</a>
130
- Want to see sample rails applications using octopus features? please check it out: <a href="http://github.com/tchandy/octopus_sharding_example">Sharding Example</a> and <a href="http://github.com/tchandy/octopus_replication_example">Replication Example</a>. Also, we have an example that shows how to use Octopus without Rails: <a href="http://github.com/tchandy/octopus_sinatra"> Octopus + Sinatra Example</a>.
180
+ To see the complete list of features and syntax, please check out our <a href="http://wiki.github.com/thiagopradi/octopus/"> Wiki</a>
181
+ Want to see sample rails applications using octopus features? please check it out: <a href="http://github.com/thiagopradi/octopus_sharding_example">Sharding Example</a> and <a href="http://github.com/thiagopradi/octopus_replication_example">Replication Example</a>. Also, we have an example that shows how to use Octopus without Rails: <a href="http://github.com/thiagopradi/octopus_sinatra"> Octopus + Sinatra Example</a>.
131
182
 
132
183
  ## Mixing Octopus with the Rails multiple database model
133
184
  If you want to set a custom connection to a specific model, use the syntax `octopus_establish_connection` syntax:
134
185
 
135
- #This class sets its own connection
136
- class CustomConnection < ActiveRecord::Base
137
- octopus_establish_connection(:adapter => "mysql", :database => "octopus_shard2")
138
- end
186
+ ```ruby
187
+ #This class sets its own connection
188
+ class CustomConnection < ActiveRecord::Base
189
+ octopus_establish_connection(:adapter => "mysql", :database => "octopus_shard2")
190
+ end
191
+ ```
192
+
193
+ ### allow_shard
194
+ If you'd like to use specific shards with a model that has a Rails-managed connection, you can use `allow_shard`:
195
+
196
+ ```ruby
197
+ class CustomConnectedModel
198
+ octopus_establish_connection(...)
199
+ allow_shard :my_shard
200
+ end
201
+
202
+ #This uses :my_shard
203
+ CustomConnectedModel.using(:my_shard).first
204
+
205
+ #This uses the Rails-managed connection pool (the call to 'using' is ignored)
206
+ CustomConnectedModel.using(:some_other_shard).first
207
+ ```
208
+
209
+ This can be useful if you have a model that lives in a separate database and would like to add sharding or replication to it. For other use cases, you may be better off with <a href="https://github.com/thiagopradi/octopus/wiki/Slave-Groups">slave groups</a>.
139
210
 
140
211
  ## Contributing with Octopus
141
212
  Contributors are welcome! To run the test suite, you need mysql, postgresql and sqlite3 installed. This is what you need to setup your Octopus development environment:
142
213
 
143
- git clone http://github.com/tchandy/octopus.git
144
- cd octopus
145
- bundle install
146
- bundle exec rake db:prepare
147
- bundle exec rake appraisal:install
148
- bundle exec rake spec
214
+ ```bash
215
+ git clone http://github.com/thiagopradi/octopus.git
216
+ cd octopus
217
+ bundle install
218
+ bundle exec rake db:prepare
219
+ bundle exec rake appraisal:install
220
+ bundle exec rake spec
221
+ ```
149
222
 
150
223
  This command will run the spec suite for all rails versions supported.
151
224
  To run our integrations tests inside sample_app, you need to following commands:
152
225
 
153
- cd sample_app
154
- bundle install
155
- cucumber
226
+ ```bash
227
+ cd sample_app
228
+ bundle install
229
+ cucumber
230
+ ```
156
231
 
157
232
  If you are having issues running the octopus spec suite, verify your database users and passwords match those inside the config files and your permissions are correct.
158
233
 
159
234
  ## Contributors:
160
- - <a href="https://github.com/tchandy/octopus/contributors">All Contributors</a>
235
+ - <a href="https://github.com/thiagopradi/octopus/contributors">All Contributors</a>
161
236
 
162
237
  ## Mailing List:
163
238
  - <a href="http://groups.google.com/group/octopus-activerecord/">Octopus Mailing List</a>
data/Rakefile CHANGED
@@ -1,11 +1,12 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
3
4
  require 'appraisal'
4
5
 
5
- task :default => :spec
6
+ RSpec::Core::RakeTask.new
7
+ RuboCop::RakeTask.new
6
8
 
7
- RSpec::Core::RakeTask.new(:spec) do |spec|
8
- end
9
+ task :default => [:spec]
9
10
 
10
11
  namespace :db do
11
12
  desc 'Build the databases for tests'
@@ -13,20 +14,20 @@ namespace :db do
13
14
  pg_spec = {
14
15
  :adapter => 'postgresql',
15
16
  :host => 'localhost',
16
- :username => (ENV['POSTGRES_USER'] || "postgres"),
17
- :encoding => 'utf8'
17
+ :username => (ENV['POSTGRES_USER'] || 'postgres'),
18
+ :encoding => 'utf8',
18
19
  }
19
20
 
20
21
  mysql_spec = {
21
22
  :adapter => 'mysql2',
22
23
  :host => 'localhost',
23
- :username => (ENV['MYSQL_USER'] || "root"),
24
- :encoding => 'utf8'
24
+ :username => (ENV['MYSQL_USER'] || 'root'),
25
+ :encoding => 'utf8',
25
26
  }
26
27
 
27
- %x( rm -f /tmp/database.sqlite3 )
28
+ ` rm -f /tmp/database.sqlite3 `
28
29
 
29
- require "active_record"
30
+ require 'active_record'
30
31
 
31
32
  # Connects to PostgreSQL
32
33
  ActiveRecord::Base.establish_connection(pg_spec.merge('database' => 'postgres', 'schema_search_path' => 'public'))
@@ -49,9 +50,9 @@ namespace :db do
49
50
 
50
51
  desc 'Create tables on tests databases'
51
52
  task :create_tables do
52
- require "octopus"
53
+ require 'octopus'
53
54
  # Set the octopus variable directory to spec dir, in order to load the config/shards.yml file.
54
- Octopus.instance_variable_set(:@directory, "#{File.dirname(__FILE__)}/spec/" )
55
+ Octopus.instance_variable_set(:@directory, "#{File.dirname(__FILE__)}/spec/")
55
56
 
56
57
  # Require the database connection
57
58
  require "#{File.dirname(__FILE__)}/spec/support/database_connection"
@@ -61,9 +62,10 @@ namespace :db do
61
62
  shard_symbols.each do |shard_symbol|
62
63
  # Rails 3.1 needs to do some introspection around the base class, which requires
63
64
  # the model be a descendent of ActiveRecord::Base.
64
- class BlankModel < ActiveRecord::Base; end;
65
+ class BlankModel < ActiveRecord::Base; end
65
66
 
66
- BlankModel.using(shard_symbol).connection.initialize_schema_migrations_table()
67
+ BlankModel.using(shard_symbol).connection.initialize_schema_migrations_table
68
+ BlankModel.using(shard_symbol).connection.initialize_metadata_table if Octopus.atleast_rails50?
67
69
 
68
70
  BlankModel.using(shard_symbol).connection.create_table(:users) do |u|
69
71
  u.string :name
@@ -126,6 +128,7 @@ namespace :db do
126
128
  u.string :name
127
129
  u.string :commentable_type
128
130
  u.integer :commentable_id
131
+ u.boolean :open, default: false
129
132
  end
130
133
 
131
134
  BlankModel.using(shard_symbol).connection.create_table(:parts) do |u|
@@ -141,6 +144,10 @@ namespace :db do
141
144
  u.string :name
142
145
  end
143
146
 
147
+ BlankModel.using(shard_symbol).connection.create_table(:custom) do |u|
148
+ u.string :value
149
+ end
150
+
144
151
  if shard_symbol == :alone_shard
145
152
  BlankModel.using(shard_symbol).connection.create_table(:mmorpg_players) do |u|
146
153
  u.string :player_name
@@ -148,14 +155,14 @@ namespace :db do
148
155
 
149
156
  BlankModel.using(shard_symbol).connection.create_table(:weapons) do |u|
150
157
  u.integer :mmorpg_player_id
151
- u.string :name
152
- u.string :hand
158
+ u.string :name
159
+ u.string :hand
153
160
  end
154
161
 
155
162
  BlankModel.using(shard_symbol).connection.create_table(:skills) do |u|
156
163
  u.integer :mmorpg_player_id
157
164
  u.integer :weapon_id
158
- u.string :name
165
+ u.string :name
159
166
  end
160
167
  end
161
168
  end
data/ar-octopus.gemspec CHANGED
@@ -1,36 +1,39 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "octopus/version"
2
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
+ require 'octopus/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
- s.name = "ar-octopus"
6
+ s.name = 'ar-octopus'
7
7
  s.version = Octopus::VERSION
8
- s.authors = ["Thiago Pradi", "Mike Perham", "Gabriel Sobrinho"]
9
- s.email = ["tchandy@gmail.com", "mperham@gmail.com", "gabriel.sobrinho@gmail.com"]
10
- s.homepage = "https://github.com/tchandy/octopus"
11
- s.summary = %q{Easy Database Sharding for ActiveRecord}
12
- s.description = %q{This gem allows you to use sharded databases with ActiveRecord. This also provides a interface for replication and for running migrations with multiples shards.}
8
+ s.authors = ['Thiago Pradi', 'Mike Perham', 'Gabriel Sobrinho']
9
+ s.email = ['tchandy@gmail.com', 'mperham@gmail.com', 'gabriel.sobrinho@gmail.com']
10
+ s.homepage = 'https://github.com/tchandy/octopus'
11
+ s.summary = 'Easy Database Sharding for ActiveRecord'
12
+ s.description = 'This gem allows you to use sharded databases with ActiveRecord. This also provides a interface for replication and for running migrations with multiples shards.'
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
- s.require_paths = ["lib"]
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
17
+ s.require_paths = ['lib']
18
18
 
19
19
  s.post_install_message = "Important: If you are upgrading from < Octopus 0.5.0 you need to run:\n" \
20
20
  "$ rake octopus:copy_schema_versions\n\n" \
21
- "Octopus now stores schema version information in each shard and migrations will not " \
22
- "work properly unless this task is invoked."
21
+ 'Octopus now stores schema version information in each shard and migrations will not ' \
22
+ 'work properly unless this task is invoked.'
23
23
 
24
- s.add_dependency 'activerecord', '>= 3.2.0'
25
- s.add_dependency 'activesupport', '>= 3.2.0'
24
+ s.required_ruby_version = '>= 2.2.0'
25
+
26
+ s.add_dependency 'activerecord', '>= 4.2.0'
27
+ s.add_dependency 'activesupport', '>= 4.2.0'
26
28
 
27
- s.add_development_dependency 'rake', '>= 0.8.7'
28
- s.add_development_dependency 'rspec', '>= 2.0.0'
29
- s.add_development_dependency 'mysql2', '> 0.3'
30
- s.add_development_dependency 'pg', '>= 0.11.0'
31
- s.add_development_dependency 'sqlite3', '>= 1.3.4'
32
- s.add_development_dependency 'pry-debugger'
33
29
  s.add_development_dependency 'appraisal', '>= 0.3.8'
30
+ s.add_development_dependency 'mysql2', '>= 0.3.18', "< 0.5"
31
+ s.add_development_dependency 'pg', '~> 0.18'
32
+ s.add_development_dependency 'rake'
33
+ s.add_development_dependency 'rspec', '>= 3'
34
+ s.add_development_dependency 'rubocop'
35
+ s.add_development_dependency 'sqlite3', '~> 1.3.6'
36
+ s.add_development_dependency 'pry-byebug'
34
37
 
35
38
  s.license = 'MIT'
36
39
  end
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 4.2.0"
6
+ gem "mysql2", "0.4.10"
7
+ gemspec path: "../"