Skip to content

Commit 2202ddf

Browse files
andrewn617rafaelfranca
authored andcommitted
Add mariadb options to application generator
Until now, the database option has conflated the datbase adapter and the database itself. It's fine for postgres and sqlite, but for mysql2 and trilogy adapters we could either use mysql or mariadb as the database. This becomes a problem for generating a dev container, since we need to add a service to docker compose with the correct database. Previously, we gave the user a mysql database for the mysql option, and a mariadb database for the trilogy option. But that is no good as it is common to use a mysql database with trilogy. In this PR I disambiguate the adapter-database issue by introducing two new options, mariadb-mysql and mariadb-trilogy. When generating a dev container, the mysql and trilogy options will create a mysql database, and the maria specific options will generate a mariadb database. Users not generating a dev container do not need to worry about the new options and can continue using the original options, as this change only effects dev container setup.
1 parent 4bb2227 commit 2202ddf

File tree

7 files changed

+173
-71
lines changed

7 files changed

+173
-71
lines changed

railties/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
* Introduce `mariadb-mysql` and `mariadb-trilogy` database options for `rails new`
2+
3+
When used with the `--devcontainer` flag, these options will use `mariadb` as the database for the
4+
Dev Container. The original `mysql` and `trilogy` options will use `mysql`. Users who are not
5+
generating a Dev Container do not need to use the new options.
6+
7+
*Andrew Novoselac*
8+
19
* Deprecate `::STATS_DIRECTORIES`.
210

311
The global constant `STATS_DIRECTORIES` has been deprecated in favor of

railties/lib/rails/generators/database.rb

Lines changed: 100 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,91 @@
33
module Rails
44
module Generators
55
class Database
6-
DATABASES = %w( mysql trilogy postgresql sqlite3 )
6+
DATABASES = %w( mysql trilogy postgresql sqlite3 mariadb-mysql mariadb-trilogy )
7+
8+
module MySQL
9+
def name
10+
"mysql"
11+
end
12+
13+
def port
14+
3306
15+
end
16+
17+
def service
18+
{
19+
"image" => "mysql/mysql-server:8.0",
20+
"restart" => "unless-stopped",
21+
"environment" => {
22+
"MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
23+
"MYSQL_ROOT_HOST" => "%"
24+
},
25+
"volumes" => ["mysql-data:/var/lib/mysql"],
26+
"networks" => ["default"],
27+
}
28+
end
29+
30+
def socket
31+
@socket ||= [
32+
"/tmp/mysql.sock", # default
33+
"/var/run/mysqld/mysqld.sock", # debian/gentoo
34+
"/var/tmp/mysql.sock", # freebsd
35+
"/var/lib/mysql/mysql.sock", # fedora
36+
"/opt/local/lib/mysql/mysql.sock", # fedora
37+
"/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
38+
"/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
39+
"/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
40+
"/opt/lampp/var/mysql/mysql.sock" # xampp for linux
41+
].find { |f| File.exist?(f) } unless Gem.win_platform?
42+
end
43+
44+
def host
45+
"localhost"
46+
end
47+
end
48+
49+
module MariaDB
50+
def name
51+
"mariadb"
52+
end
53+
54+
def port
55+
3306
56+
end
57+
58+
def service
59+
{
60+
"image" => "mariadb:10.5",
61+
"restart" => "unless-stopped",
62+
"networks" => ["default"],
63+
"volumes" => ["mariadb-data:/var/lib/mysql"],
64+
"environment" => {
65+
"MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
66+
},
67+
}
68+
end
69+
end
770

871
class << self
972
def build(database_name)
1073
case database_name
11-
when "mysql" then MySQL.new
74+
when "mysql" then MySQL2.new
1275
when "postgresql" then PostgreSQL.new
13-
when "trilogy" then MariaDB.new
76+
when "trilogy" then Trilogy.new
1477
when "sqlite3" then SQLite3.new
78+
when "mariadb-mysql" then MariaDBMySQL2.new
79+
when "mariadb-trilogy" then MariaDBTrilogy.new
1580
else Null.new
1681
end
1782
end
1883

1984
def all
2085
@all ||= [
21-
MySQL.new,
86+
MySQL2.new,
2287
PostgreSQL.new,
23-
MariaDB.new,
2488
SQLite3.new,
89+
MariaDBMySQL2.new,
90+
MariaDBTrilogy.new
2591
]
2692
end
2793
end
@@ -30,6 +96,10 @@ def name
3096
raise NotImplementedError
3197
end
3298

99+
def template
100+
raise NotImplementedError
101+
end
102+
33103
def service
34104
raise NotImplementedError
35105
end
@@ -69,48 +139,11 @@ def volume
69139
"#{name}-data"
70140
end
71141

72-
module MySqlSocket
73-
def socket
74-
@socket ||= [
75-
"/tmp/mysql.sock", # default
76-
"/var/run/mysqld/mysqld.sock", # debian/gentoo
77-
"/var/tmp/mysql.sock", # freebsd
78-
"/var/lib/mysql/mysql.sock", # fedora
79-
"/opt/local/lib/mysql/mysql.sock", # fedora
80-
"/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
81-
"/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
82-
"/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
83-
"/opt/lampp/var/mysql/mysql.sock" # xampp for linux
84-
].find { |f| File.exist?(f) } unless Gem.win_platform?
85-
end
86-
87-
def host
88-
"localhost"
89-
end
90-
end
91-
92-
class MySQL < Database
93-
include MySqlSocket
94-
95-
def name
96-
"mysql"
97-
end
98-
99-
def service
100-
{
101-
"image" => "mysql/mysql-server:8.0",
102-
"restart" => "unless-stopped",
103-
"environment" => {
104-
"MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
105-
"MYSQL_ROOT_HOST" => "%"
106-
},
107-
"volumes" => ["mysql-data:/var/lib/mysql"],
108-
"networks" => ["default"],
109-
}
110-
end
142+
class MySQL2 < Database
143+
include MySQL
111144

112-
def port
113-
3306
145+
def template
146+
"config/databases/mysql.yml"
114147
end
115148

116149
def gem
@@ -135,6 +168,10 @@ def name
135168
"postgres"
136169
end
137170

171+
def template
172+
"config/databases/postgresql.yml"
173+
end
174+
138175
def service
139176
{
140177
"image" => "postgres:16.1",
@@ -169,27 +206,11 @@ def feature_name
169206
end
170207
end
171208

172-
class MariaDB < Database
173-
include MySqlSocket
174-
175-
def name
176-
"mariadb"
177-
end
178-
179-
def service
180-
{
181-
"image" => "mariadb:10.5",
182-
"restart" => "unless-stopped",
183-
"networks" => ["default"],
184-
"volumes" => ["mariadb-data:/var/lib/mysql"],
185-
"environment" => {
186-
"MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
187-
},
188-
}
189-
end
209+
class Trilogy < Database
210+
include MySQL
190211

191-
def port
192-
3306
212+
def template
213+
"config/databases/trilogy.yml"
193214
end
194215

195216
def gem
@@ -214,6 +235,10 @@ def name
214235
"sqlite3"
215236
end
216237

238+
def template
239+
"config/databases/sqlite3.yml"
240+
end
241+
217242
def service
218243
nil
219244
end
@@ -239,8 +264,17 @@ def feature_name
239264
end
240265
end
241266

267+
class MariaDBMySQL2 < MySQL2
268+
include MariaDB
269+
end
270+
271+
class MariaDBTrilogy < Trilogy
272+
include MariaDB
273+
end
274+
242275
class Null < Database
243276
def name; end
277+
def template; end
244278
def service; end
245279
def port; end
246280
def volume; end

railties/lib/rails/generators/rails/app/app_generator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def credentials_diff_enroll
206206
end
207207

208208
def database_yml
209-
template "config/databases/#{options[:database]}.yml", "config/database.yml"
209+
template database.template, "config/database.yml"
210210
end
211211

212212
def db

railties/lib/rails/generators/rails/db/system/change/change_generator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def initialize(*)
3535
end
3636

3737
def edit_database_config
38-
template("config/databases/#{options[:database]}.yml", "config/database.yml")
38+
template(database.template, "config/database.yml")
3939
end
4040

4141
def edit_gemfile

railties/test/commands/db_system_change_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Rails::Command::DbSystemChangeTest < ActiveSupport::TestCase
2525
assert_match <<~MSG.squish, output
2626
Invalid value for --to option.
2727
Supported preconfigurations are:
28-
mysql, trilogy, postgresql, sqlite3.
28+
mysql, trilogy, postgresql, sqlite3, mariadb-mysql, mariadb-trilogy.
2929
MSG
3030
end
3131

railties/test/generators/app_generator_test.rb

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1369,9 +1369,65 @@ def test_devcontainer_mysql
13691369
end
13701370
end
13711371

1372-
def test_devcontainer_mariadb
1372+
def test_devcontainer_trilogy
13731373
run_generator [ destination_root, "--devcontainer", "-d", "trilogy" ]
13741374

1375+
assert_compose_file do |compose_config|
1376+
assert_includes compose_config["services"]["rails-app"]["depends_on"], "mysql"
1377+
expected_mysql_config = {
1378+
"image" => "mysql/mysql-server:8.0",
1379+
"restart" => "unless-stopped",
1380+
"environment" => {
1381+
"MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
1382+
"MYSQL_ROOT_HOST" => "%"
1383+
},
1384+
"volumes" => ["mysql-data:/var/lib/mysql"],
1385+
"networks" => ["default"],
1386+
}
1387+
1388+
assert_equal expected_mysql_config, compose_config["services"]["mysql"]
1389+
assert_includes compose_config["volumes"].keys, "mysql-data"
1390+
end
1391+
assert_devcontainer_json_file do |content|
1392+
assert_equal "mysql", content["containerEnv"]["DB_HOST"]
1393+
assert_includes(content["forwardPorts"], 3306)
1394+
end
1395+
assert_file("config/database.yml") do |content|
1396+
assert_match(/host: <%= ENV.fetch\("DB_HOST"\) \{ "localhost" } %>/, content)
1397+
end
1398+
end
1399+
1400+
def test_devcontainer_mariadb_mysql
1401+
run_generator [ destination_root, "--devcontainer", "-d", "mariadb-mysql" ]
1402+
1403+
assert_compose_file do |compose_config|
1404+
assert_includes compose_config["services"]["rails-app"]["depends_on"], "mariadb"
1405+
expected_mariadb_config = {
1406+
"image" => "mariadb:10.5",
1407+
"restart" => "unless-stopped",
1408+
"networks" => ["default"],
1409+
"volumes" => ["mariadb-data:/var/lib/mysql"],
1410+
"environment" => {
1411+
"MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
1412+
},
1413+
}
1414+
1415+
assert_equal expected_mariadb_config, compose_config["services"]["mariadb"]
1416+
assert_includes compose_config["volumes"].keys, "mariadb-data"
1417+
end
1418+
assert_devcontainer_json_file do |content|
1419+
assert_equal "mariadb", content["containerEnv"]["DB_HOST"]
1420+
assert_includes content["features"].keys, "ghcr.io/rails/devcontainer/features/mysql-client"
1421+
assert_includes(content["forwardPorts"], 3306)
1422+
end
1423+
assert_file("config/database.yml") do |content|
1424+
assert_match(/host: <%= ENV.fetch\("DB_HOST"\) \{ "localhost" } %>/, content)
1425+
end
1426+
end
1427+
1428+
def test_devcontainer_mariadb_trilogy
1429+
run_generator [ destination_root, "--devcontainer", "-d", "mariadb-trilogy" ]
1430+
13751431
assert_compose_file do |compose_config|
13761432
assert_includes compose_config["services"]["rails-app"]["depends_on"], "mariadb"
13771433
expected_mariadb_config = {

railties/test/generators/db_system_change_generator_test.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ChangeGeneratorTest < Rails::Generators::TestCase
2828
assert_match <<~MSG.squish, output
2929
Invalid value for --to option.
3030
Supported preconfigurations are:
31-
mysql, trilogy, postgresql, sqlite3.
31+
mysql, trilogy, postgresql, sqlite3, mariadb-mysql, mariadb-trilogy.
3232
MSG
3333
end
3434

@@ -159,6 +159,10 @@ class ChangeGeneratorTest < Rails::Generators::TestCase
159159
assert_match "curl libvips", content
160160
assert_no_match "default-libmysqlclient-dev", content
161161
end
162+
end
163+
164+
test "change to mariadb" do
165+
run_generator ["--to", "mariadb-mysql"]
162166

163167
assert_devcontainer_json_file do |content|
164168
assert_match "mariadb", content["containerEnv"]["DB_HOST"]

0 commit comments

Comments
 (0)