ar-octopus 0.4.0 → 0.5.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 (77) hide show
  1. data/.gitignore +11 -0
  2. data/.travis.yml +22 -0
  3. data/Appraisals +18 -0
  4. data/Gemfile +3 -12
  5. data/README.mkdn +63 -24
  6. data/Rakefile +70 -92
  7. data/ar-octopus.gemspec +25 -198
  8. data/lib/ar-octopus.rb +1 -0
  9. data/lib/octopus.rb +73 -25
  10. data/lib/octopus/association.rb +6 -5
  11. data/lib/octopus/association_collection.rb +58 -4
  12. data/lib/octopus/has_and_belongs_to_many_association.rb +4 -4
  13. data/lib/octopus/logger.rb +9 -4
  14. data/lib/octopus/migration.rb +155 -50
  15. data/lib/octopus/model.rb +98 -34
  16. data/lib/octopus/proxy.rb +124 -53
  17. data/lib/octopus/rails2/association.rb +46 -93
  18. data/lib/octopus/rails2/persistence.rb +1 -1
  19. data/lib/octopus/rails2/scope.rb +17 -0
  20. data/lib/octopus/rails3.1/singular_association.rb +34 -0
  21. data/lib/octopus/rails3.2/persistence.rb +12 -0
  22. data/lib/octopus/rails3/abstract_adapter.rb +39 -0
  23. data/lib/octopus/rails3/arel.rb +5 -5
  24. data/lib/octopus/rails3/log_subscriber.rb +22 -0
  25. data/lib/octopus/rails3/persistence.rb +10 -5
  26. data/lib/octopus/railtie.rb +13 -0
  27. data/lib/octopus/scope_proxy.rb +22 -16
  28. data/lib/octopus/version.rb +3 -0
  29. data/lib/tasks/octopus.rake +20 -0
  30. data/sample_app/Gemfile +2 -2
  31. data/sample_app/config/initializers/inflections.rb +1 -1
  32. data/sample_app/config/initializers/secret_token.rb +1 -1
  33. data/sample_app/db/migrate/20100720172730_create_items.rb +1 -1
  34. data/sample_app/db/migrate/20100720210335_create_sample_users.rb +1 -1
  35. data/sample_app/db/seeds.rb +1 -1
  36. data/sample_app/features/migrate.feature +12 -12
  37. data/sample_app/features/seed.feature +3 -3
  38. data/sample_app/features/step_definitions/web_steps.rb +5 -5
  39. data/sample_app/features/support/env.rb +8 -8
  40. data/sample_app/lib/tasks/cucumber.rake +2 -2
  41. data/sample_app/public/javascripts/effects.js +1 -1
  42. data/spec/config/shards.yml +38 -28
  43. data/spec/migrations/11_add_field_in_all_slaves.rb +1 -1
  44. data/spec/migrations/12_create_users_using_block.rb +2 -2
  45. data/spec/migrations/13_create_users_using_block_and_using.rb +2 -2
  46. data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +11 -0
  47. data/spec/migrations/1_create_users_on_master.rb +1 -1
  48. data/spec/migrations/2_create_users_on_canada.rb +1 -1
  49. data/spec/migrations/3_create_users_on_both_shards.rb +1 -1
  50. data/spec/migrations/4_create_users_on_shards_of_a_group.rb +1 -1
  51. data/spec/migrations/5_create_users_on_multiples_groups.rb +1 -1
  52. data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +1 -1
  53. data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +1 -1
  54. data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +1 -1
  55. data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +1 -1
  56. data/spec/octopus/association_spec.rb +88 -70
  57. data/spec/octopus/log_subscriber_spec.rb +22 -0
  58. data/spec/octopus/logger_spec.rb +28 -15
  59. data/spec/octopus/migration_spec.rb +47 -43
  60. data/spec/octopus/model_spec.rb +179 -13
  61. data/spec/octopus/octopus_spec.rb +26 -4
  62. data/spec/octopus/proxy_spec.rb +61 -23
  63. data/spec/octopus/{replication_specs.rb → replication_spec.rb} +33 -26
  64. data/spec/octopus/scope_proxy_spec.rb +3 -3
  65. data/spec/octopus/sharded_spec.rb +9 -9
  66. data/spec/spec_helper.rb +10 -12
  67. data/spec/support/active_record/connection_adapters/modify_config_adapter.rb +17 -0
  68. data/spec/support/database_connection.rb +2 -0
  69. data/spec/{database_models.rb → support/database_models.rb} +27 -2
  70. data/spec/support/octopus_helper.rb +50 -0
  71. data/spec/tasks/octopus.rake_spec.rb +36 -0
  72. metadata +188 -169
  73. data/Gemfile.lock +0 -68
  74. data/lib/octopus/rails3/association.rb +0 -112
  75. data/spec/database_connection.rb +0 -4
  76. data/spec/octopus/controller_spec.rb +0 -34
  77. data/spec/octopus_helper.rb +0 -37
@@ -1,6 +1,6 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require "spec_helper"
2
2
 
3
- describe Octopus do
3
+ describe Octopus, :shards => [] do
4
4
  describe "#config" do
5
5
  it "should load shards.yml file to start working" do
6
6
  Octopus.config().should be_kind_of(HashWithIndifferentAccess)
@@ -34,14 +34,14 @@ describe Octopus do
34
34
  describe "#shards=" do
35
35
  after(:each) do
36
36
  Octopus.instance_variable_set(:@config, nil)
37
- Thread.current[:connection_proxy] = Octopus::Proxy.new(Octopus.config())
37
+ Octopus::Model.send(:class_variable_set, :@@connection_proxy, nil)
38
38
  end
39
39
 
40
40
  it "should permit users to configure shards on initializer files, instead of on a yml file." do
41
41
  lambda { User.using(:crazy_shard).create!(:name => "Joaquim") }.should raise_error
42
42
 
43
43
  Octopus.setup do |config|
44
- config.shards = {:crazy_shard => {:adapter => "mysql2", :database => "octopus_shard5", :username => "root", :password => ""}}
44
+ config.shards = {:crazy_shard => {:adapter => "mysql", :database => "octopus_shard_5", :username => "root", :password => ""}}
45
45
  end
46
46
 
47
47
  lambda { User.using(:crazy_shard).create!(:name => "Joaquim") }.should_not raise_error
@@ -65,4 +65,26 @@ describe Octopus do
65
65
  end
66
66
  end
67
67
  end
68
+
69
+ describe "#enabled?" do
70
+ before do
71
+ Rails = mock()
72
+ end
73
+
74
+ after do
75
+ Object.send(:remove_const, :Rails)
76
+ end
77
+
78
+ it "should be if octopus is configured and should hook into current environment" do
79
+ Rails.stub!(:env).and_return('production')
80
+
81
+ Octopus.should be_enabled
82
+ end
83
+
84
+ it "should not be if octopus should not hook into current environment" do
85
+ Rails.stub!(:env).and_return('staging')
86
+
87
+ Octopus.should_not be_enabled
88
+ end
89
+ end
68
90
  end
@@ -1,12 +1,21 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require "spec_helper"
2
2
 
3
3
  describe Octopus::Proxy do
4
- let(:proxy) { Octopus::Proxy.new(Octopus.config()) }
4
+ let(:proxy) { subject }
5
5
 
6
- describe "creating a new instance" do
6
+ describe "creating a new instance", :shards => [] do
7
7
  it "should initialize all shards and groups" do
8
- proxy.instance_variable_get(:@shards).keys.to_set.should == ["canada", "brazil", "master", "sqlite_shard", "russia", "alone_shard", "aug2009", "postgresql_shard", "aug2010", "aug2011"].to_set
9
- proxy.instance_variable_get(:@groups).should == {"country_shards" => [:canada, :brazil, :russia], "history_shards" => [:aug2009, :aug2010, :aug2011]}
8
+ # FIXME: Don't test implementation details
9
+ proxy.instance_variable_get(:@shards).should include("canada", "brazil", "master", "sqlite_shard", "russia", "alone_shard",
10
+ "aug2009", "postgresql_shard", "aug2010", "aug2011")
11
+
12
+ proxy.instance_variable_get(:@shards).should include("protocol_shard") if Octopus.rails32?
13
+
14
+ proxy.has_group?("country_shards").should be_true
15
+ proxy.shards_for_group("country_shards").should include(:canada, :brazil, :russia)
16
+
17
+ proxy.has_group?("history_shards").should be_true
18
+ proxy.shards_for_group("history_shards").should include(:aug2009, :aug2010, :aug2011)
10
19
  end
11
20
 
12
21
  it "should initialize the block attribute as false" do
@@ -22,13 +31,16 @@ describe Octopus::Proxy do
22
31
  end
23
32
 
24
33
  it "should work with thiking sphinx" do
25
- proxy.instance_variable_get(:@config).should == {:adapter=>"mysql2", :password=>"", :database=>"octopus_shard1", :username=>"root", :flags=>2}
34
+ config = proxy.instance_variable_get(:@config)
35
+ config[:adapter].should == "mysql"
36
+ config[:database].should == "octopus_shard_1"
37
+ config[:username].should == "root"
26
38
  end
27
39
 
28
40
  it 'should create a set with all adapters, to ensure that is needed to clean the table name.' do
29
41
  adapters = proxy.instance_variable_get(:@adapters)
30
42
  adapters.should be_kind_of(Set)
31
- adapters.to_a.should == ["sqlite3", "mysql2", "postgresql"]
43
+ adapters.to_a.should =~ ["sqlite3", "mysql", "postgresql"]
32
44
  end
33
45
 
34
46
  it 'should respond correctly to respond_to?(:pk_and_sequence_for)' do
@@ -39,6 +51,19 @@ describe Octopus::Proxy do
39
51
  proxy.respond_to?(:primary_key).should be_true
40
52
  end
41
53
 
54
+ context 'when an adapter that modifies the config' do
55
+ before(:all) { OctopusHelper.set_octopus_env("modify_config") }
56
+ after(:all) { OctopusHelper.set_octopus_env("octopus") }
57
+
58
+ it 'should not fail with missing adapter second time round' do
59
+ Thread.current["octopus.current_shard"] = :modify_config_read
60
+
61
+ lambda { Octopus::Proxy.new(Octopus.config()) }.should_not raise_error("Please install the adapter: `gem install activerecord--adapter` (cannot load such file -- active_record/connection_adapters/_adapter)")
62
+
63
+ Thread.current["octopus.current_shard"] = nil
64
+ end
65
+ end
66
+
42
67
  describe "#should_clean_table_name?" do
43
68
  it 'should return true when you have a environment with multiple database types' do
44
69
  proxy.should_clean_table_name?.should be_true
@@ -46,7 +71,7 @@ describe Octopus::Proxy do
46
71
 
47
72
  context "when using a environment with a single table name" do
48
73
  before(:each) do
49
- set_octopus_env("production_replicated")
74
+ OctopusHelper.set_octopus_env("production_replicated")
50
75
  end
51
76
 
52
77
  it 'should return false' do
@@ -57,7 +82,7 @@ describe Octopus::Proxy do
57
82
 
58
83
  describe "should raise error if you have duplicated shard names" do
59
84
  before(:each) do
60
- set_octopus_env("production_raise_error")
85
+ OctopusHelper.set_octopus_env("production_raise_error")
61
86
  end
62
87
 
63
88
  it "should raise the error" do
@@ -67,17 +92,13 @@ describe Octopus::Proxy do
67
92
 
68
93
  describe "should initialize just the master when you don't have a shards.yml file" do
69
94
  before(:each) do
70
- set_octopus_env("crazy_environment")
95
+ OctopusHelper.set_octopus_env("crazy_environment")
71
96
  end
72
97
 
73
98
  it "should initialize just the master shard" do
74
99
  proxy.instance_variable_get(:@shards).keys.should == ["master"]
75
100
  end
76
101
 
77
- it "should not initialize the groups variable" do
78
- proxy.instance_variable_get(:@groups).should == {}
79
- end
80
-
81
102
  it "should not initialize replication" do
82
103
  proxy.instance_variable_get(:@replicated).should be_nil
83
104
  end
@@ -86,7 +107,7 @@ describe Octopus::Proxy do
86
107
 
87
108
  describe "when you have a replicated environment" do
88
109
  before(:each) do
89
- set_octopus_env("production_replicated")
110
+ OctopusHelper.set_octopus_env("production_replicated")
90
111
  end
91
112
 
92
113
  it "should have the replicated attribute as true" do
@@ -101,12 +122,20 @@ describe Octopus::Proxy do
101
122
  describe "when you have a rails application" do
102
123
  before(:each) do
103
124
  Rails = mock()
104
- set_octopus_env("octopus_rails")
125
+ OctopusHelper.set_octopus_env("octopus_rails")
126
+ end
127
+
128
+ after(:each) do
129
+ Object.send(:remove_const, :Rails)
130
+ Octopus.instance_variable_set(:@config, nil)
131
+ Octopus.instance_variable_set(:@rails_env, nil)
132
+ OctopusHelper.clean_connection_proxy()
105
133
  end
106
134
 
107
135
  it "should initialize correctly octopus common variables for the environments" do
108
136
  Rails.stub!(:env).and_return('staging')
109
137
  Octopus.instance_variable_set(:@rails_env, nil)
138
+ Octopus.instance_variable_set(:@environments, nil)
110
139
  Octopus.config()
111
140
 
112
141
  proxy.instance_variable_get(:@replicated).should be_true
@@ -116,17 +145,32 @@ describe Octopus::Proxy do
116
145
 
117
146
  it "should initialize correctly the shards for the staging environment" do
118
147
  Rails.stub!(:env).and_return('staging')
148
+ Octopus.instance_variable_set(:@rails_env, nil)
149
+ Octopus.instance_variable_set(:@environments, nil)
150
+ Octopus.config()
119
151
 
120
152
  proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new(["slave1", "slave2", "master"])
121
153
  end
122
154
 
155
+ it "should initialize correctly the shard octopus_shard value for logging" do
156
+ Rails.stub!(:env).and_return('staging')
157
+ Octopus.instance_variable_set(:@rails_env, nil)
158
+ Octopus.instance_variable_set(:@environments, nil)
159
+ Octopus.config()
160
+
161
+ proxy.instance_variable_get(:@shards)['slave1'].spec.config.should have_key :octopus_shard
162
+ end
163
+
123
164
  it "should initialize correctly the shards for the production environment" do
124
165
  Rails.stub!(:env).and_return('production')
166
+ Octopus.instance_variable_set(:@rails_env, nil)
167
+ Octopus.instance_variable_set(:@environments, nil)
168
+ Octopus.config()
125
169
 
126
170
  proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new(["slave3", "slave4", "master"])
127
171
  end
128
172
 
129
- describe "using the master connection" do
173
+ describe "using the master connection", :shards => [:russia, :master] do
130
174
  before(:each) do
131
175
  Rails.stub!(:env).and_return('development')
132
176
  end
@@ -163,12 +207,6 @@ describe Octopus::Proxy do
163
207
  u.save()
164
208
  end
165
209
  end
166
-
167
- after(:each) do
168
- Object.send(:remove_const, :Rails)
169
- Octopus.instance_variable_set(:@config, nil)
170
- Octopus.instance_variable_set(:@rails_env, nil)
171
- end
172
210
  end
173
211
 
174
212
  describe "returning the correct connection" do
@@ -1,8 +1,8 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require "spec_helper"
2
2
 
3
3
  describe "when the database is replicated" do
4
4
  it "should send all writes/reads queries to master when you have a non replicated model" do
5
- using_environment :production_replicated do
5
+ OctopusHelper.using_environment :production_replicated do
6
6
  u = User.create!(:name => "Replicated")
7
7
  User.count.should == 1
8
8
  User.find(u.id).should == u
@@ -10,8 +10,8 @@ describe "when the database is replicated" do
10
10
  end
11
11
 
12
12
  it "should send all writes queries to master" do
13
- using_environment :production_replicated do
14
- Cat.create!(:name => "Slave Cat")
13
+ OctopusHelper.using_environment :production_replicated do
14
+ Cat.create!(:name => "Slave Cat")
15
15
  Cat.find_by_name("Slave Cat").should be_nil
16
16
  Client.create!(:name => "Slave Client")
17
17
  Client.find_by_name("Slave Client").should_not be_nil
@@ -19,27 +19,26 @@ describe "when the database is replicated" do
19
19
  end
20
20
 
21
21
  it "should allow to create multiple models on the master" do
22
- using_environment :production_replicated do
23
- Cat.create!([{:name => "Slave Cat 1"}, {:name => "Slave Cat 2"}])
22
+ OctopusHelper.using_environment :production_replicated do
23
+ Cat.create!([{:name => "Slave Cat 1"}, {:name => "Slave Cat 2"}])
24
24
  Cat.find_by_name("Slave Cat 1").should be_nil
25
25
  Cat.find_by_name("Slave Cat 2").should be_nil
26
26
  end
27
27
  end
28
-
28
+
29
29
  it "should allow #using syntax to send queries to master" do
30
- Cat.create!(:name => "Master Cat")
31
-
32
- using_environment :production_fully_replicated do
30
+ Cat.create!(:name => "Master Cat")
31
+
32
+ OctopusHelper.using_environment :production_fully_replicated do
33
33
  Cat.using(:master).find_by_name("Master Cat").should_not be_nil
34
34
  end
35
35
  end
36
36
 
37
37
  it "should send the count query to a slave" do
38
- pending()
39
- # using_environment :production_replicated do
40
- # Cat.create!(:name => "Slave Cat")
41
- # Cat.count.should == 0
42
- # end
38
+ OctopusHelper.using_environment :production_replicated do
39
+ Cat.create!(:name => "Slave Cat")
40
+ Cat.count.should == 0
41
+ end
43
42
  end
44
43
  end
45
44
 
@@ -47,31 +46,39 @@ end
47
46
  describe "when the database is replicated and the entire application is replicated" do
48
47
  before(:each) do
49
48
  Octopus.stub!(:env).and_return("production_fully_replicated")
50
- clean_connection_proxy()
49
+ OctopusHelper.clean_connection_proxy()
50
+ end
51
+
52
+ it "should send all writes queries to master" do
53
+ OctopusHelper.using_environment :production_fully_replicated do
54
+ Cat.create!(:name => "Slave Cat")
55
+ Cat.find_by_name("Slave Cat").should be_nil
56
+ Client.create!(:name => "Slave Client")
57
+ Client.find_by_name("Slave Client").should be_nil
58
+ end
51
59
  end
52
60
 
53
61
  it "should send all writes queries to master" do
54
- using_environment :production_fully_replicated do
55
- Cat.create!(:name => "Slave Cat")
62
+ OctopusHelper.using_environment :production_fully_replicated do
63
+ Cat.create!(:name => "Slave Cat")
56
64
  Cat.find_by_name("Slave Cat").should be_nil
57
65
  Client.create!(:name => "Slave Client")
58
66
  Client.find_by_name("Slave Client").should be_nil
59
67
  end
60
- end
61
-
68
+ end
69
+
62
70
  it "should work with validate_uniquess_of" do
63
71
  Keyboard.create!(:name => "thiago")
64
-
65
- using_environment :production_fully_replicated do
72
+
73
+ OctopusHelper.using_environment :production_fully_replicated do
66
74
  k = Keyboard.new(:name => "thiago")
67
75
  k.save.should be_false
68
- k.errors.should == {:name=>["has already been taken"]}
76
+ k.errors.full_messages.should == ["Name has already been taken"]
69
77
  end
70
78
  end
71
-
79
+
72
80
  it "should reset current shard if slave throws an exception" do
73
-
74
- using_environment :production_fully_replicated do
81
+ OctopusHelper.using_environment :production_fully_replicated do
75
82
  Cat.create!(:name => "Slave Cat")
76
83
  Cat.connection.current_shard.should eql(:master)
77
84
  begin
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require "spec_helper"
2
2
 
3
3
  describe Octopus::ScopeProxy do
4
4
  it "should allow nested queries" do
@@ -6,13 +6,13 @@ describe Octopus::ScopeProxy do
6
6
  @user1 = User.using(:brazil).create!(:name => "Thiago P", :number => 3)
7
7
  @user2 = User.using(:brazil).create!(:name => "Thiago", :number => 1)
8
8
  @user3 = User.using(:brazil).create!(:name => "Thiago", :number => 2)
9
-
9
+
10
10
  User.using(:brazil).where(:name => "Thiago").where(:number => 4).order(:number).all.should == []
11
11
  User.using(:brazil).where(:name => "Thiago").using(:canada).where(:number => 2).using(:brazil).order(:number).all.should == [@user3]
12
12
  User.using(:brazil).where(:name => "Thiago").using(:canada).where(:number => 4).using(:brazil).order(:number).all.should == []
13
13
  end
14
14
  end
15
-
15
+
16
16
  it "should raise a exception when trying to send a query to a shard that don't exists" do
17
17
  lambda { User.using(:dont_exists).all }.should raise_exception("Nonexistent Shard Name: dont_exists")
18
18
  end
@@ -1,33 +1,33 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require "spec_helper"
2
2
 
3
3
  describe "when the database is not entire sharded" do
4
4
  before(:each) do
5
5
  Octopus.stub!(:env).and_return("not_entire_sharded")
6
- clean_connection_proxy()
6
+ OctopusHelper.clean_connection_proxy()
7
7
  end
8
-
8
+
9
9
  it "should not send all queries to the specified slave" do
10
10
  pending()
11
11
  # User.create!(:name => "Thiago")
12
- #
13
- # using_environment :not_entire_sharded do
12
+ #
13
+ # using_environment :not_entire_sharded do
14
14
  # Octopus.using(:russia) do
15
15
  # User.create!(:name => "Thiago")
16
16
  # end
17
17
  # end
18
- #
18
+ #
19
19
  # User.count.should == 2
20
20
  end
21
-
21
+
22
22
  it "should pick the shard based on current_shard when you have a sharded model" do
23
23
  Cat.create!(:name => "Thiago")
24
24
 
25
- using_environment :not_entire_sharded do
25
+ OctopusHelper.using_environment :not_entire_sharded do
26
26
  Octopus.using(:russia) do
27
27
  Cat.create!(:name => "Thiago")
28
28
  end
29
29
  end
30
-
30
+
31
31
  Cat.count.should == 1
32
32
  end
33
33
  end
@@ -1,20 +1,18 @@
1
1
  require "rubygems"
2
- require "bundler"
3
-
4
- Bundler.setup()
5
-
6
- require File.expand_path(File.dirname(__FILE__)) + "/database_connection"
2
+ require "pry"
3
+ require "bundler/setup"
7
4
  require "octopus"
8
- require "octopus_helper"
9
- require "action_controller"
10
- require 'rspec/core'
11
5
 
12
- MIGRATIONS_ROOT = File.expand_path(File.join(File.dirname(__FILE__), 'migrations'))
6
+ Octopus.instance_variable_set(:@directory, File.dirname(__FILE__))
7
+
8
+ # Requires supporting files with custom matchers and macros, etc,
9
+ # in ./support/ and its subdirectories.
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
13
11
 
14
12
  RSpec.configure do |config|
15
13
  config.before(:each) do
16
- Octopus.stub!(:directory).and_return(File.dirname(__FILE__))
17
- require "database_models"
18
- clean_all_shards()
14
+ OctopusHelper.clean_all_shards(example.metadata[:shards])
19
15
  end
20
16
  end
17
+
18
+ $: << File.expand_path(File.join(File.dirname(__FILE__), "support"))
@@ -0,0 +1,17 @@
1
+ module ActiveRecord
2
+ class Base
3
+ def self.modify_config_connection(config)
4
+ ConnectionAdapters::ModifyConfigAdapter.new(config)
5
+ end
6
+ end
7
+
8
+ module ConnectionAdapters
9
+ class ModifyConfigAdapter < AbstractAdapter
10
+
11
+ def initialize(config)
12
+ config.replace(config.symbolize_keys)
13
+ end
14
+
15
+ end
16
+ end
17
+ end