app_config 2.4.1 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 61b54a9e60063869d1fb5dd8195685012c09d27a
4
- data.tar.gz: abe0121e7d221f4510548c5e5d2517f2bf0a1fed
3
+ metadata.gz: a48c0515f2ec849d64e47343c4df57df7de7e80a
4
+ data.tar.gz: b2151f2cd3beb98a8065376b1d791a3f0918a6c2
5
5
  SHA512:
6
- metadata.gz: a430884e1eaeee82e0ec768a5fbdd745604c7b8589be4210a697fa1f6fb4237138ea88b74a93194484ce81da2b08c4611db3aaf7feb14e1bc7ce44264a73c292
7
- data.tar.gz: 3b0b28c1a51c0f37d884f63d9f4591365a9305222048794b83e03ee4d6f379bd286c7b73db8e9f91a8ff951b5ca17f8738cf7b73ce756239e0dc98fb313af08f
6
+ metadata.gz: 79ff5cf7464a593064a60a8410a23047867c807f98f572f9f5baff66492a8a01af049c18791c4111a26f91b86b3726da9403ecfe9cbfe5d6622577290f555200
7
+ data.tar.gz: 735ee7a382344299dbe7f979f47050b5de6616f478dc9e66ea6aa9a3bbc1a058d46e99ddd71a45a3a7556b5ada8e03fecf92ec7c298a458e2ea3b257ae0fda1c
@@ -3,12 +3,17 @@ rvm:
3
3
  - 1.9.2
4
4
  - 1.9.3
5
5
  - 2.0.0
6
+ - 2.1.2
6
7
 
7
8
  before_script:
8
9
  # Setup test Postgres database.
9
10
  - psql -c 'create database app_config_test;' -U postgres
10
- - psql -d app_config_test -U postgres -c 'CREATE TABLE app_config (id bigserial primary key, admin_email character varying(255), api_name character varying(255), api_key character varying(255));'
11
- - psql -d app_config_test -U postgres -c "INSERT INTO app_config (admin_email, api_name, api_key) VALUES ('admin@example.com', 'Supr Webz 2.0', 'SUPERAWESOMESERVICE')"
11
+ - psql -d app_config_test -U postgres -c 'CREATE TABLE app_config (id bigserial primary key, admin_email character varying(255), api_name character varying(255), api_key character varying(255), true_option boolean, false_option boolean);'
12
+ - psql -d app_config_test -U postgres -c "INSERT INTO app_config (admin_email, api_name, api_key, true_option, false_option) VALUES ('admin@example.com', 'Supr Webz 2.0', 'SUPERAWESOMESERVICE', true, false);"
13
+ # Setup test MySQL database.
14
+ - mysql -u root -e 'create database app_config_test;'
15
+ - mysql -u root -D app_config_test -e 'CREATE TABLE app_config (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, admin_email VARCHAR(255), api_key VARCHAR(255), true_option BOOLEAN, false_option BOOLEAN);'
16
+ - mysql -u root -D app_config_test -e "INSERT INTO app_config (admin_email, api_key, true_option, false_option) VALUES ('admin@example.com', 'SUPERAWESOMESERVICE', true, false);"
12
17
 
13
18
  env:
14
19
  # Ignore warnings when running specs.
@@ -12,6 +12,7 @@ GEM
12
12
  mongo (1.3.1)
13
13
  bson (>= 1.3.1)
14
14
  multi_json (1.3.6)
15
+ mysql2 (0.3.15)
15
16
  pg (0.15.1)
16
17
  rake (0.9.2.2)
17
18
  redcarpet (2.3.0)
@@ -37,6 +38,7 @@ DEPENDENCIES
37
38
  app_config!
38
39
  bson_ext
39
40
  mongo
41
+ mysql2
40
42
  pg
41
43
  rake
42
44
  redcarpet
data/README.md CHANGED
@@ -22,7 +22,7 @@ end
22
22
  AppConfig.admin_email # => 'admin@example.com'
23
23
  ```
24
24
 
25
- AppConfig also supports many different 'storage types', such as YAML and MongoDB,
25
+ AppConfig also supports many different 'storage methods', such as YAML and MongoDB,
26
26
  allowing you to tailor AppConfig to many different use cases. For example,
27
27
  storing your configuration in the same database as your development/production environment.
28
28
 
@@ -49,22 +49,6 @@ AppConfig.api_name # => 'Supr Webz 2.0'
49
49
  AppConfig.api_key # => 'SUPERAWESOMESERVICE'
50
50
  ```
51
51
 
52
- You can also use environments in the YAML file (like Rails `database.yml`):
53
-
54
- ```yaml
55
- ---
56
- development:
57
- api_url: 'http://localhost:3000/endpoint.json'
58
-
59
- production:
60
- api_url: 'http://api.example.com/endpoint.json'
61
- ```
62
-
63
- ```ruby
64
- AppConfig.setup!(yaml: '/path/to/app_config.yml', env: :development)
65
- AppConfig.api_url # => 'http://localhost:3000/endpoint.json'
66
- ```
67
-
68
52
 
69
53
  ## Mongo
70
54
 
@@ -72,6 +56,8 @@ You can pass a `:mongo` options hash to `AppConfig.setup!` which should contain
72
56
  configuration values for a Mongo database. Check the `AppConfig::Storage::Mongo::DEFAULTS`
73
57
  constant for the default Mongo connection options.
74
58
 
59
+ The '[mongo](https://rubygems.org/gems/mongo)' gem is required in order to use Mongo storage.
60
+
75
61
  ```ruby
76
62
  # These are the defaults.
77
63
  mongo_opts = {
@@ -105,6 +91,8 @@ Using PostgreSQL is similar to a Mongo setup.
105
91
  The only current requirement is that the table have a primary key named `id`.
106
92
  All other columns are used as configuration keys.
107
93
 
94
+ The '[pg](https://rubygems.org/gems/pg)' gem is required in order to use Postgres storage.
95
+
108
96
  **Note:** The database and schema must exist prior to calling `AppConfig.setup!`.
109
97
 
110
98
  Given this schema:
@@ -142,11 +130,75 @@ AppConfig.save!
142
130
  ```
143
131
 
144
132
 
133
+ ## MySQL
134
+
135
+ Using MySQL is similar to Postgres, including the required primary key named `id`.
136
+ All other columns are used as configuration keys.
137
+
138
+ The '[mysql2](https://rubygems.org/gems/mysql2)' gem is required in order to use MySQL storage.
139
+
140
+ **Note:** The database and schema must exist prior to calling `AppConfig.setup!`.
141
+
142
+ Given this schema:
143
+
144
+ ```sql
145
+ CREATE TABLE app_config (
146
+ id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
147
+ admin_email VARCHAR(255) DEFAULT "admin@example.com",
148
+ api_key VARCHAR(255) DEFAULT "SOME_API_KEY",
149
+ true_option BOOLEAN DEFAULT true,
150
+ false_option BOOLEAN DEFAULT false
151
+ );
152
+ ```
153
+
154
+ Setup AppConfig:
155
+
156
+ ```ruby
157
+ # These are the defaults:
158
+ mysql_opts = {
159
+ host: 'localhost',
160
+ port: 3306,
161
+ database: 'app_config',
162
+ table: 'app_config',
163
+ username: nil,
164
+ password: nil,
165
+ }
166
+
167
+ AppConfig.setup!(mysql: mysql_opts)
168
+
169
+ AppConfig.admin_email # => 'admin@example.com'
170
+
171
+ # Update an existing value and save changes:
172
+ AppConfig.admin_email = 'another_admin@example.com'
173
+ AppConfig.save!
174
+ ```
175
+
176
+
177
+ ## SQLite
178
+
179
+ SQLite storage works the same as the other SQL storage methods, including the mandatory
180
+ primary key `id` column.
181
+
182
+ The '[sqlite3](https://rubygems.org/gems/sqlite3)' gem is required in order to use SQLite storage.
183
+
184
+ **Note:** The database schema must exist prior to calling `AppConfig.setup!`.
185
+
186
+ ```ruby
187
+ # These are the defaults:
188
+ sqlite_opts = {
189
+ database: File.join(Dir.home, '.app_config.sqlite3'),
190
+ table: 'app_config',
191
+ }
192
+
193
+ AppConfig.setup!(sqlite: sqlite_opts)
194
+ ```
195
+
196
+
145
197
  ## Using Storage Defaults
146
198
 
147
199
  All storage options accept `true` as a value, which uses the default options for that storage.
148
200
 
149
- For example, to use the [Mongo](https://github.com/Oshuma/app_config/blob/master/lib/app_config/storage/mongo.rb#L9) defaults:
201
+ For example, to use the [Mongo](lib/app_config/storage/mongo.rb#L9) defaults:
150
202
 
151
203
  ```ruby
152
204
  AppConfig.setup!(mongo: true)
@@ -154,9 +206,38 @@ AppConfig.setup!(mongo: true)
154
206
 
155
207
  ### Storage Defaults
156
208
 
157
- * [Mongo](https://github.com/Oshuma/app_config/blob/master/lib/app_config/storage/mongo.rb#L9)
158
- * [Postgres](https://github.com/Oshuma/app_config/blob/master/lib/app_config/storage/postgres.rb#L8)
159
- * [YAML](https://github.com/Oshuma/app_config/blob/master/lib/app_config/storage/yaml.rb#L9)
209
+ * [Mongo](lib/app_config/storage/mongo.rb#L9)
210
+ * [MySQL](lib/app_config/storage/mysql.rb#L8)
211
+ * [Postgres](lib/app_config/storage/postgres.rb#L8)
212
+ * [SQLite](lib/app_config/storage/sqlite.rb#L9)
213
+ * [YAML](lib/app_config/storage/yaml.rb#L9)
214
+
215
+
216
+ ### Environment Mode
217
+
218
+ The YAML storage method provides an `:env` option where you can organize the config like Rails `database.yml`:
219
+
220
+ ```yaml
221
+ # Rails.root/config/app_config.yml
222
+ development:
223
+ title: 'Development Mode'
224
+
225
+ production:
226
+ title: 'Production Mode'
227
+ ```
228
+
229
+ Pass a string or symbol to the `:env` option.
230
+
231
+ ```ruby
232
+ # Rails.root/config/initializers/app_config.rb
233
+ AppConfig.setup!({
234
+ yaml: "#{Rails.root}/config/app_config.yml",
235
+ env: Rails.env
236
+ })
237
+
238
+ # Uses the given environment section of the config.
239
+ AppConfig.title # => 'Production Mode'
240
+ ```
160
241
 
161
242
 
162
243
  ## Deprecation Note
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.add_development_dependency 'bson_ext'
18
18
  s.add_development_dependency 'mongo'
19
+ s.add_development_dependency 'mysql2'
19
20
  s.add_development_dependency 'pg'
20
21
  s.add_development_dependency 'rake'
21
22
  s.add_development_dependency 'redcarpet'
@@ -23,6 +23,8 @@ module AppConfig
23
23
  @@storage = AppConfig::Storage::YAML.new(@@options.delete(:yaml), @@options)
24
24
  elsif @@options[:mongo]
25
25
  @@storage = AppConfig::Storage::Mongo.new(@@options.delete(:mongo))
26
+ elsif @@options[:mysql]
27
+ @@storage = AppConfig::Storage::MySQL.new(@@options.delete(:mysql))
26
28
  elsif @@options[:postgres]
27
29
  @@storage = AppConfig::Storage::Postgres.new(@@options.delete(:postgres))
28
30
  elsif @@options[:sqlite]
@@ -3,6 +3,7 @@ module AppConfig
3
3
  autoload :Base, 'app_config/storage/base'
4
4
  autoload :ConfigData, 'app_config/storage/config_data'
5
5
  autoload :Mongo, 'app_config/storage/mongo'
6
+ autoload :MySQL, 'app_config/storage/mysql'
6
7
  autoload :Postgres, 'app_config/storage/postgres'
7
8
  autoload :SQLite, 'app_config/storage/sqlite'
8
9
  autoload :YAML, 'app_config/storage/yaml'
@@ -0,0 +1,100 @@
1
+ module AppConfig
2
+ module Storage
3
+
4
+ require 'mysql2'
5
+
6
+ class MySQL < Storage::Base
7
+
8
+ DEFAULTS = {
9
+ host: 'localhost',
10
+ port: 3306,
11
+ database: 'app_config',
12
+ table: 'app_config',
13
+ username: nil,
14
+ password: nil,
15
+ }
16
+
17
+ def initialize(options)
18
+ # Allows passing `true` as an option, which uses the defaults.
19
+ if options.is_a?(Hash)
20
+ @options = DEFAULTS.merge(options)
21
+ else
22
+ @options = DEFAULTS
23
+ end
24
+
25
+ @table = @options.delete(:table)
26
+
27
+ setup_client!
28
+ fetch_data!
29
+ end
30
+
31
+ def reload!
32
+ fetch_data!
33
+ end
34
+
35
+ def save!
36
+ data_hash = @data.to_h
37
+ data_hash.delete(:id)
38
+
39
+ if @id
40
+ # Update existing row.
41
+ set_attrs = data_hash.map do |k, v|
42
+ if v.is_a?(TrueClass) || v.is_a?(FalseClass)
43
+ "#{k} = #{v}" # Don't quote booleans.
44
+ else
45
+ "#{k} = '#{v}'"
46
+ end
47
+ end.join(', ')
48
+ save_query = "UPDATE #{@table} SET #{set_attrs} WHERE id = #{@id};"
49
+ else
50
+ # Create a new row.
51
+ if data_hash.empty?
52
+ # Use defaults.
53
+ save_query = "INSERT INTO #{@table}(id) VALUES(NULL);"
54
+ else
55
+ columns = data_hash.keys.join(', ')
56
+ values = data_hash.map do |_, v|
57
+ if v.is_a?(TrueClass) || v.is_a?(FalseClass)
58
+ "#{v}" # Don't quote booleans.
59
+ else
60
+ "'#{v}'"
61
+ end
62
+ end.join(', ')
63
+
64
+ save_query = "INSERT INTO #{@table} (#{columns}) VALUES (#{values});"
65
+ end
66
+ end
67
+
68
+ @client.query(save_query)
69
+ @client.affected_rows == 1
70
+ end
71
+
72
+ private
73
+
74
+ def connected?
75
+ @client && @client.ping
76
+ end
77
+
78
+ def fetch_data!
79
+ raise 'Not connected to MySQL' unless connected?
80
+
81
+ fetch_query = "SELECT * FROM #{@table} ORDER BY id DESC LIMIT 1;"
82
+
83
+ result = @client.query(fetch_query, cast_booleans: true, symbolized_keys: true)
84
+ if result.size == 0
85
+ @data = Storage::ConfigData.new
86
+ else
87
+ result.each do |row|
88
+ @data = Storage::ConfigData.new(row)
89
+ @id = @data.id
90
+ end
91
+ end
92
+ end
93
+
94
+ def setup_client!
95
+ @client = Mysql2::Client.new(@options)
96
+ end
97
+
98
+ end
99
+ end
100
+ end
@@ -25,6 +25,35 @@ module AppConfig
25
25
  fetch_data!
26
26
  end
27
27
 
28
+ def reload!
29
+ fetch_data!
30
+ end
31
+
32
+ def save!
33
+ data_hash = @data.to_h
34
+ data_hash.delete(:id)
35
+
36
+ if @id
37
+ # Update existing row.
38
+ set_attrs = data_hash.map { |k, v| "#{k} = '#{v}'" }.join(', ')
39
+ save_query = "UPDATE #{@table} SET #{set_attrs} WHERE id = #{@id};"
40
+ else
41
+ # Insert a new row.
42
+ if data_hash.empty?
43
+ # Use table defaults.
44
+ save_query = "INSERT INTO #{@table}(id) VALUES(NULL);"
45
+ else
46
+ columns = data_hash.keys.join(', ')
47
+ values = data_hash.map { |_, v| "'#{v}'" }.join(', ')
48
+
49
+ save_query = "INSERT INTO #{@table} (#{columns}) VALUES (#{values});"
50
+ end
51
+ end
52
+
53
+ @database.execute(save_query)
54
+ @database.changes == 1
55
+ end
56
+
28
57
  private
29
58
 
30
59
  def fetch_data!
@@ -46,6 +75,7 @@ module AppConfig
46
75
  end
47
76
 
48
77
  @data = Storage::ConfigData.new(config)
78
+ @id = @data.id
49
79
  end
50
80
 
51
81
  end
@@ -13,15 +13,19 @@ module AppConfig
13
13
  #
14
14
  # Defaults to `Dir.home/.app_config.yml`
15
15
  def initialize(path = DEFAULT_PATH, options = {})
16
- # Allows passing `true` as an option.
17
- path = DEFAULT_PATH if path == true
16
+ # Allow passing `true` as an option to use `DEFAULT_PATH`.
17
+ @path = path.is_a?(TrueClass) ? DEFAULT_PATH : path
18
+ @options = options
19
+ reload!
20
+ end
18
21
 
22
+ def reload!
19
23
  # Make sure to use the top-level YAML module here.
20
- if options.has_key?(:env)
21
- env = options[:env].to_s # Force a String here since YAML's keys are strings.
22
- @data = Storage::ConfigData.new(::YAML.load_file(path)[env])
24
+ if @options.has_key?(:env)
25
+ env = @options[:env].to_s # Force a String here since YAML's keys are strings.
26
+ @data = Storage::ConfigData.new(::YAML.load_file(@path)[env])
23
27
  else
24
- @data = Storage::ConfigData.new(::YAML.load_file(path))
28
+ @data = Storage::ConfigData.new(::YAML.load_file(@path))
25
29
  end
26
30
  end
27
31
 
@@ -1,3 +1,3 @@
1
1
  module AppConfig
2
- VERSION = '2.4.1'
2
+ VERSION = '2.5.0'
3
3
  end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe AppConfig::Storage::MySQL do
4
+
5
+ before(:all) do
6
+ config_for_mysql(true)
7
+ end
8
+
9
+ it 'should have some values' do
10
+ AppConfig.api_key.should_not be_nil
11
+ end
12
+
13
+ it 'should reload the data' do
14
+ # Set a value, but don't call AppConfig.save!
15
+ AppConfig.true_option = false
16
+
17
+ AppConfig.reload!
18
+
19
+ AppConfig.true_option.should == true
20
+ end
21
+
22
+ it 'should update the values' do
23
+ new_api_key = 'NEW_API_KEY'
24
+ new_admin_email = 'new_admin@example.com'
25
+
26
+ AppConfig.api_key = new_api_key
27
+ AppConfig.admin_email = new_admin_email
28
+
29
+ AppConfig.save!.should be_true
30
+
31
+ # Reload AppConfig
32
+ config_for_mysql
33
+
34
+ AppConfig.api_key.should == new_api_key
35
+ AppConfig.admin_email.should == new_admin_email
36
+ end
37
+
38
+ it "uses the defaults when 'true' is passed" do
39
+ AppConfig.reset!
40
+
41
+ # HACK: Use a test database as the 'default'.
42
+ old_dbname = AppConfig::Storage::MySQL::DEFAULTS[:database]
43
+ AppConfig::Storage::MySQL::DEFAULTS[:database] = 'app_config_test'
44
+
45
+ begin
46
+ AppConfig.setup!(mysql: true)
47
+ rescue Mysql2::Error => e
48
+ config_for_mysql
49
+ end
50
+
51
+ AppConfig.class_variable_get(:@@storage)
52
+ .instance_variable_get(:@options)
53
+ .should == AppConfig::Storage::MySQL::DEFAULTS
54
+
55
+ # HACK: Reset dbname default to original value.
56
+ AppConfig::Storage::MySQL::DEFAULTS[:database] = old_dbname
57
+ end
58
+
59
+ it "should create a new row if @id is not set" do
60
+ # HACK: Save the old id so we can reset it.
61
+ original_id = AppConfig.class_variable_get(:@@storage)
62
+ .instance_variable_get(:@id)
63
+
64
+ AppConfig.class_variable_get(:@@storage)
65
+ .instance_variable_set(:@id, nil)
66
+
67
+ AppConfig.api_key = 'foobar'
68
+ AppConfig.save!.should be_true
69
+
70
+ # HACK: Reset the original id.
71
+ AppConfig.class_variable_get(:@@storage)
72
+ .instance_variable_set(:@id, original_id)
73
+ end
74
+
75
+ end
@@ -10,4 +10,48 @@ describe AppConfig::Storage::SQLite do
10
10
  AppConfig.api_key.should_not be_nil
11
11
  end
12
12
 
13
+ it 'should reload the data' do
14
+ # Save the old value, so we can make sure it hasn't changed.
15
+ admin_email = AppConfig.admin_email
16
+
17
+ # Set a value, but don't call AppConfig.save!
18
+ AppConfig.admin_email = 'CHANGED'
19
+
20
+ AppConfig.reload!
21
+
22
+ AppConfig.admin_email.should == admin_email
23
+ end
24
+
25
+ it 'should update the values' do
26
+ new_api_key = 'NEW_API_KEY'
27
+ new_admin_email = 'new_admin@example.com'
28
+
29
+ AppConfig.api_key = new_api_key
30
+ AppConfig.admin_email = new_admin_email
31
+
32
+ AppConfig.save!.should be_true
33
+
34
+ # Reload AppConfig (passing `false` to avoid wiping test db).
35
+ config_for_sqlite(false)
36
+
37
+ AppConfig.api_key.should == new_api_key
38
+ AppConfig.admin_email.should == new_admin_email
39
+ end
40
+
41
+ it 'should create a new row if @id is not set' do
42
+ # HACK: Save the old id so we can reset it.
43
+ original_id = AppConfig.class_variable_get(:@@storage)
44
+ .instance_variable_get(:@id)
45
+
46
+ AppConfig.class_variable_get(:@@storage)
47
+ .instance_variable_set(:@id, nil)
48
+
49
+ AppConfig.api_key = 'foobar'
50
+ AppConfig.save!.should be_true
51
+
52
+ # HACK: Reset the original id.
53
+ AppConfig.class_variable_get(:@@storage)
54
+ .instance_variable_set(:@id, original_id)
55
+ end
56
+
13
57
  end
@@ -45,4 +45,15 @@ describe AppConfig::Storage::YAML do
45
45
  AppConfig.production.should be_true
46
46
  end
47
47
 
48
+ it 'should reload the data' do
49
+ config_for_yaml
50
+ original_api_key = AppConfig.api_key
51
+
52
+ # Set to some random value:
53
+ AppConfig.api_key = "foobar-#{rand(100)}"
54
+
55
+ AppConfig.reload!
56
+ AppConfig.api_key.should == original_api_key
57
+ end
58
+
48
59
  end
@@ -30,6 +30,7 @@ RSpec.configure do |config|
30
30
  mongo = AppConfig::Storage::Mongo::DEFAULTS.merge({
31
31
  database: 'app_config_test',
32
32
  })
33
+
33
34
  begin
34
35
  load_mongo_test_config(mongo) if load_test_data
35
36
  config_for({mongo: mongo}.merge(opts))
@@ -44,6 +45,23 @@ RSpec.configure do |config|
44
45
  end
45
46
  end
46
47
 
48
+ def config_for_mysql(load_test_data = false, opts = {})
49
+ mysql = AppConfig::Storage::MySQL::DEFAULTS.merge({
50
+ database: 'app_config_test'
51
+ })
52
+
53
+ begin
54
+ load_mysql_test_config(mysql) if load_test_data
55
+ config_for({mysql: mysql}.merge(opts))
56
+ rescue Mysql2::Error => e
57
+ if e.to_s =~ /Can't connect/
58
+ pending "***** MySQL specs require a running MySQL server *****"
59
+ else
60
+ raise e
61
+ end
62
+ end
63
+ end
64
+
47
65
  def config_for_postgres(load_test_data = false, opts = {})
48
66
  postgres = AppConfig::Storage::Postgres::DEFAULTS.merge({
49
67
  dbname: 'app_config_test'
@@ -115,6 +133,63 @@ RSpec.configure do |config|
115
133
  end
116
134
  end
117
135
 
136
+ def load_mysql_test_config(options)
137
+ original_options = options.dup
138
+
139
+ options.delete(:username) if options[:username].nil?
140
+ options.delete(:password) if options[:password].nil?
141
+
142
+ table = options.delete(:table)
143
+
144
+ begin
145
+ config = ::YAML.load_file(fixture('app_config.yml'))
146
+ attrs = config.map do |k, v|
147
+ if v.is_a?(String)
148
+ "#{k} VARCHAR(255)"
149
+ elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
150
+ "#{k} BOOLEAN"
151
+ end
152
+ end.join(', ')
153
+
154
+ values = config.values.map do |v|
155
+ if v.is_a?(TrueClass) || v.is_a?(FalseClass)
156
+ # Boolean types shouldn't be quoted.
157
+ "#{v}"
158
+ else
159
+ # But VARCHAR types should be.
160
+ "'#{v}'"
161
+ end
162
+ end.join(', ')
163
+
164
+ create_query = "CREATE TABLE #{table} (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, #{attrs});"
165
+ insert_query = "INSERT INTO #{table} (#{config.keys.join(', ')}) VALUES (#{values});"
166
+
167
+ client = Mysql2::Client.new(options)
168
+ client.query("USE #{options[:database]};")
169
+
170
+ begin
171
+ client.query(create_query)
172
+ rescue Mysql2::Error => e
173
+ case e.to_s
174
+ when /Table '#{table}' already exists/
175
+ # no-op
176
+ else
177
+ raise e
178
+ end
179
+ end
180
+
181
+ client.query(insert_query)
182
+ rescue Mysql2::Error => e
183
+ case e.to_s
184
+ when /Unknown database/
185
+ Mysql2::Client.new.query("CREATE DATABASE #{options[:database]};")
186
+ load_mysql_test_config(original_options)
187
+ else
188
+ raise e
189
+ end
190
+ end
191
+ end
192
+
118
193
  def load_postgres_test_config(options)
119
194
  original_options = options.dup
120
195
 
metadata CHANGED
@@ -1,139 +1,153 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.1
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dale Campbell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-06 00:00:00.000000000 Z
11
+ date: 2014-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bson_ext
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mongo
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
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mysql2
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: pg
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - '>='
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
61
  version: '0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - '>='
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - '>='
73
+ - - ">="
60
74
  - !ruby/object:Gem::Version
61
75
  version: '0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - '>='
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: redcarpet
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - '>='
87
+ - - ">="
74
88
  - !ruby/object:Gem::Version
75
89
  version: '0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - '>='
94
+ - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rspec
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '>='
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
103
  version: '0'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - '>='
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: simplecov
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - '>='
115
+ - - ">="
102
116
  - !ruby/object:Gem::Version
103
117
  version: '0'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - '>='
122
+ - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: sqlite3
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - '>='
129
+ - - ">="
116
130
  - !ruby/object:Gem::Version
117
131
  version: '0'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - '>='
136
+ - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: yard
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - '>='
143
+ - - ">="
130
144
  - !ruby/object:Gem::Version
131
145
  version: '0'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - '>='
150
+ - - ">="
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0'
139
153
  description: An easy to use, framework agnostic, customizable library to easily store
@@ -144,9 +158,9 @@ executables: []
144
158
  extensions: []
145
159
  extra_rdoc_files: []
146
160
  files:
147
- - .gitignore
148
- - .rspec
149
- - .travis.yml
161
+ - ".gitignore"
162
+ - ".rspec"
163
+ - ".travis.yml"
150
164
  - Gemfile
151
165
  - Gemfile.lock
152
166
  - README.md
@@ -159,12 +173,14 @@ files:
159
173
  - lib/app_config/storage/base.rb
160
174
  - lib/app_config/storage/config_data.rb
161
175
  - lib/app_config/storage/mongo.rb
176
+ - lib/app_config/storage/mysql.rb
162
177
  - lib/app_config/storage/postgres.rb
163
178
  - lib/app_config/storage/sqlite.rb
164
179
  - lib/app_config/storage/yaml.rb
165
180
  - lib/app_config/version.rb
166
181
  - spec/app_config/storage/config_data_spec.rb
167
182
  - spec/app_config/storage/mongo_spec.rb
183
+ - spec/app_config/storage/mysql_spec.rb
168
184
  - spec/app_config/storage/postgres_spec.rb
169
185
  - spec/app_config/storage/sqlite_spec.rb
170
186
  - spec/app_config/storage/yaml_spec.rb
@@ -179,35 +195,25 @@ licenses:
179
195
  metadata: {}
180
196
  post_install_message:
181
197
  rdoc_options:
182
- - --inline-source
183
- - --charset=UTF-8
198
+ - "--inline-source"
199
+ - "--charset=UTF-8"
184
200
  require_paths:
185
201
  - lib
186
202
  required_ruby_version: !ruby/object:Gem::Requirement
187
203
  requirements:
188
- - - '>='
204
+ - - ">="
189
205
  - !ruby/object:Gem::Version
190
206
  version: '0'
191
207
  required_rubygems_version: !ruby/object:Gem::Requirement
192
208
  requirements:
193
- - - '>='
209
+ - - ">="
194
210
  - !ruby/object:Gem::Version
195
211
  version: '0'
196
212
  requirements: []
197
213
  rubyforge_project:
198
- rubygems_version: 2.0.2
214
+ rubygems_version: 2.0.14
199
215
  signing_key:
200
216
  specification_version: 4
201
217
  summary: Quick and easy application configuration.
202
- test_files:
203
- - spec/app_config/storage/config_data_spec.rb
204
- - spec/app_config/storage/mongo_spec.rb
205
- - spec/app_config/storage/postgres_spec.rb
206
- - spec/app_config/storage/sqlite_spec.rb
207
- - spec/app_config/storage/yaml_spec.rb
208
- - spec/app_config/storage_spec.rb
209
- - spec/app_config_spec.rb
210
- - spec/fixtures/app_config.yml
211
- - spec/fixtures/app_config_env.yml
212
- - spec/spec_helper.rb
218
+ test_files: []
213
219
  has_rdoc: true