Skip to content

Commit

Permalink
Merge pull request rails#52266 from Shopify/mariadb-options
Browse files Browse the repository at this point in the history
Add mariadb options to application generator
  • Loading branch information
rafaelfranca authored Aug 27, 2024
2 parents 63a532e + 2202ddf commit f0fd6ab
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 71 deletions.
8 changes: 8 additions & 0 deletions railties/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
* Introduce `mariadb-mysql` and `mariadb-trilogy` database options for `rails new`

When used with the `--devcontainer` flag, these options will use `mariadb` as the database for the
Dev Container. The original `mysql` and `trilogy` options will use `mysql`. Users who are not
generating a Dev Container do not need to use the new options.

*Andrew Novoselac*

* Deprecate `::STATS_DIRECTORIES`.

The global constant `STATS_DIRECTORIES` has been deprecated in favor of
Expand Down
166 changes: 100 additions & 66 deletions railties/lib/rails/generators/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,91 @@
module Rails
module Generators
class Database
DATABASES = %w( mysql trilogy postgresql sqlite3 )
DATABASES = %w( mysql trilogy postgresql sqlite3 mariadb-mysql mariadb-trilogy )

module MySQL
def name
"mysql"
end

def port
3306
end

def service
{
"image" => "mysql/mysql-server:8.0",
"restart" => "unless-stopped",
"environment" => {
"MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
"MYSQL_ROOT_HOST" => "%"
},
"volumes" => ["mysql-data:/var/lib/mysql"],
"networks" => ["default"],
}
end

def socket
@socket ||= [
"/tmp/mysql.sock", # default
"/var/run/mysqld/mysqld.sock", # debian/gentoo
"/var/tmp/mysql.sock", # freebsd
"/var/lib/mysql/mysql.sock", # fedora
"/opt/local/lib/mysql/mysql.sock", # fedora
"/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
"/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
"/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
"/opt/lampp/var/mysql/mysql.sock" # xampp for linux
].find { |f| File.exist?(f) } unless Gem.win_platform?
end

def host
"localhost"
end
end

module MariaDB
def name
"mariadb"
end

def port
3306
end

def service
{
"image" => "mariadb:10.5",
"restart" => "unless-stopped",
"networks" => ["default"],
"volumes" => ["mariadb-data:/var/lib/mysql"],
"environment" => {
"MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
},
}
end
end

class << self
def build(database_name)
case database_name
when "mysql" then MySQL.new
when "mysql" then MySQL2.new
when "postgresql" then PostgreSQL.new
when "trilogy" then MariaDB.new
when "trilogy" then Trilogy.new
when "sqlite3" then SQLite3.new
when "mariadb-mysql" then MariaDBMySQL2.new
when "mariadb-trilogy" then MariaDBTrilogy.new
else Null.new
end
end

def all
@all ||= [
MySQL.new,
MySQL2.new,
PostgreSQL.new,
MariaDB.new,
SQLite3.new,
MariaDBMySQL2.new,
MariaDBTrilogy.new
]
end
end
Expand All @@ -30,6 +96,10 @@ def name
raise NotImplementedError
end

def template
raise NotImplementedError
end

def service
raise NotImplementedError
end
Expand Down Expand Up @@ -69,48 +139,11 @@ def volume
"#{name}-data"
end

module MySqlSocket
def socket
@socket ||= [
"/tmp/mysql.sock", # default
"/var/run/mysqld/mysqld.sock", # debian/gentoo
"/var/tmp/mysql.sock", # freebsd
"/var/lib/mysql/mysql.sock", # fedora
"/opt/local/lib/mysql/mysql.sock", # fedora
"/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
"/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
"/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
"/opt/lampp/var/mysql/mysql.sock" # xampp for linux
].find { |f| File.exist?(f) } unless Gem.win_platform?
end

def host
"localhost"
end
end

class MySQL < Database
include MySqlSocket

def name
"mysql"
end

def service
{
"image" => "mysql/mysql-server:8.0",
"restart" => "unless-stopped",
"environment" => {
"MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
"MYSQL_ROOT_HOST" => "%"
},
"volumes" => ["mysql-data:/var/lib/mysql"],
"networks" => ["default"],
}
end
class MySQL2 < Database
include MySQL

def port
3306
def template
"config/databases/mysql.yml"
end

def gem
Expand All @@ -135,6 +168,10 @@ def name
"postgres"
end

def template
"config/databases/postgresql.yml"
end

def service
{
"image" => "postgres:16.1",
Expand Down Expand Up @@ -169,27 +206,11 @@ def feature_name
end
end

class MariaDB < Database
include MySqlSocket

def name
"mariadb"
end

def service
{
"image" => "mariadb:10.5",
"restart" => "unless-stopped",
"networks" => ["default"],
"volumes" => ["mariadb-data:/var/lib/mysql"],
"environment" => {
"MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
},
}
end
class Trilogy < Database
include MySQL

def port
3306
def template
"config/databases/trilogy.yml"
end

def gem
Expand All @@ -214,6 +235,10 @@ def name
"sqlite3"
end

def template
"config/databases/sqlite3.yml"
end

def service
nil
end
Expand All @@ -239,8 +264,17 @@ def feature_name
end
end

class MariaDBMySQL2 < MySQL2
include MariaDB
end

class MariaDBTrilogy < Trilogy
include MariaDB
end

class Null < Database
def name; end
def template; end
def service; end
def port; end
def volume; end
Expand Down
2 changes: 1 addition & 1 deletion railties/lib/rails/generators/rails/app/app_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def credentials_diff_enroll
end

def database_yml
template "config/databases/#{options[:database]}.yml", "config/database.yml"
template database.template, "config/database.yml"
end

def db
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def initialize(*)
end

def edit_database_config
template("config/databases/#{options[:database]}.yml", "config/database.yml")
template(database.template, "config/database.yml")
end

def edit_gemfile
Expand Down
2 changes: 1 addition & 1 deletion railties/test/commands/db_system_change_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Rails::Command::DbSystemChangeTest < ActiveSupport::TestCase
assert_match <<~MSG.squish, output
Invalid value for --to option.
Supported preconfigurations are:
mysql, trilogy, postgresql, sqlite3.
mysql, trilogy, postgresql, sqlite3, mariadb-mysql, mariadb-trilogy.
MSG
end

Expand Down
58 changes: 57 additions & 1 deletion railties/test/generators/app_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1369,9 +1369,65 @@ def test_devcontainer_mysql
end
end

def test_devcontainer_mariadb
def test_devcontainer_trilogy
run_generator [ destination_root, "--devcontainer", "-d", "trilogy" ]

assert_compose_file do |compose_config|
assert_includes compose_config["services"]["rails-app"]["depends_on"], "mysql"
expected_mysql_config = {
"image" => "mysql/mysql-server:8.0",
"restart" => "unless-stopped",
"environment" => {
"MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
"MYSQL_ROOT_HOST" => "%"
},
"volumes" => ["mysql-data:/var/lib/mysql"],
"networks" => ["default"],
}

assert_equal expected_mysql_config, compose_config["services"]["mysql"]
assert_includes compose_config["volumes"].keys, "mysql-data"
end
assert_devcontainer_json_file do |content|
assert_equal "mysql", content["containerEnv"]["DB_HOST"]
assert_includes(content["forwardPorts"], 3306)
end
assert_file("config/database.yml") do |content|
assert_match(/host: <%= ENV.fetch\("DB_HOST"\) \{ "localhost" } %>/, content)
end
end

def test_devcontainer_mariadb_mysql
run_generator [ destination_root, "--devcontainer", "-d", "mariadb-mysql" ]

assert_compose_file do |compose_config|
assert_includes compose_config["services"]["rails-app"]["depends_on"], "mariadb"
expected_mariadb_config = {
"image" => "mariadb:10.5",
"restart" => "unless-stopped",
"networks" => ["default"],
"volumes" => ["mariadb-data:/var/lib/mysql"],
"environment" => {
"MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
},
}

assert_equal expected_mariadb_config, compose_config["services"]["mariadb"]
assert_includes compose_config["volumes"].keys, "mariadb-data"
end
assert_devcontainer_json_file do |content|
assert_equal "mariadb", content["containerEnv"]["DB_HOST"]
assert_includes content["features"].keys, "ghcr.io/rails/devcontainer/features/mysql-client"
assert_includes(content["forwardPorts"], 3306)
end
assert_file("config/database.yml") do |content|
assert_match(/host: <%= ENV.fetch\("DB_HOST"\) \{ "localhost" } %>/, content)
end
end

def test_devcontainer_mariadb_trilogy
run_generator [ destination_root, "--devcontainer", "-d", "mariadb-trilogy" ]

assert_compose_file do |compose_config|
assert_includes compose_config["services"]["rails-app"]["depends_on"], "mariadb"
expected_mariadb_config = {
Expand Down
6 changes: 5 additions & 1 deletion railties/test/generators/db_system_change_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ChangeGeneratorTest < Rails::Generators::TestCase
assert_match <<~MSG.squish, output
Invalid value for --to option.
Supported preconfigurations are:
mysql, trilogy, postgresql, sqlite3.
mysql, trilogy, postgresql, sqlite3, mariadb-mysql, mariadb-trilogy.
MSG
end

Expand Down Expand Up @@ -159,6 +159,10 @@ class ChangeGeneratorTest < Rails::Generators::TestCase
assert_match "curl libvips", content
assert_no_match "default-libmysqlclient-dev", content
end
end

test "change to mariadb" do
run_generator ["--to", "mariadb-mysql"]

assert_devcontainer_json_file do |content|
assert_match "mariadb", content["containerEnv"]["DB_HOST"]
Expand Down

0 comments on commit f0fd6ab

Please sign in to comment.