Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
- "7.1"
- "7.2"
- "8.0"
- "8.1"
sequel:
- "~> 5.0"
ruby:
Expand Down Expand Up @@ -97,6 +98,16 @@ jobs:
rails: "8.0"
- ruby: "jruby"
rails: "8.0"
- ruby: "2.6"
rails: "8.1"
- ruby: "2.7"
rails: "8.1"
- ruby: "3.0"
rails: "8.1"
- ruby: "3.1"
rails: "8.1"
- ruby: "jruby"
rails: "8.1"
name: Rails ${{ matrix.rails }}, Ruby ${{ matrix.ruby }}, Sequel ${{ matrix.sequel }}

env:
Expand Down
27 changes: 27 additions & 0 deletions ci/rails-8.1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
source 'https://rubygems.org'

gem 'railties', '~> 8.1.0'
gem 'activemodel', '~> 8.1.0'
gem 'actionpack', '~> 8.1.0'

gemspec :path => '../'

gem 'sequel', "#{ENV['SEQUEL']}"

gem 'fakefs', '>= 1.8.0', :require => 'fakefs/safe'

gem 'rspec-rails', '~> 5.0'

# MRI/Rubinius Adapter Dependencies
platform :ruby do
gem 'pg'
gem 'mysql2'
gem 'sqlite3'
end

# JRuby Adapter Dependencies
platform :jruby do
gem 'jdbc-sqlite3'
gem 'jdbc-mysql'
gem 'jdbc-postgres'
end
1 change: 1 addition & 0 deletions lib/sequel_rails/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
require 'sequel_rails/railties/log_subscriber'
require 'sequel_rails/railties/i18n_support'
require 'sequel_rails/railties/controller_runtime'
require 'sequel_rails/railties/test_databases'
require 'sequel_rails/sequel/database/active_support_notification'
require 'action_dispatch/middleware/session/sequel_store'

Expand Down
4 changes: 2 additions & 2 deletions lib/sequel_rails/railties/database.rake
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ namespace sequel_rails_namespace do
db_for_current_env
args.with_defaults(:env => Rails.env)

filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, 'db', 'structure.sql')
filename = SequelRails::Storage.structure_path
if SequelRails::Storage.dump_environment args.env, filename
::File.open filename, 'a' do |file|
file << SequelRails::Migrations.dump_schema_information(:sql => true)
Expand All @@ -69,7 +69,7 @@ namespace sequel_rails_namespace do
task :load, [:env] => :environment do |_t, args|
args.with_defaults(:env => Rails.env)

filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, 'db', 'structure.sql')
filename = SequelRails::Storage.structure_path
unless SequelRails::Storage.load_environment args.env, filename
abort "Could not load structure for #{args.env}."
end
Expand Down
59 changes: 59 additions & 0 deletions lib/sequel_rails/railties/test_databases.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

module SequelRails
module Railties
module TestDatabases # :nodoc:
if ActiveSupport.respond_to?(:parallelize_test_databases)
require 'tempfile'
require 'sequel_rails/storage'
require 'active_support/testing/parallelization'

ActiveSupport::Testing::Parallelization.after_fork_hook do |i|
# On macOS, libpq's TCP connection path logs through the os_log subsystem while
# establishing a connection. After fork, os_log's per-process state is invalid in
# the child and the first connection segfaults inside _os_log_preferences_refresh.
# Disabling os_log activity tracing avoids this.
ENV['OS_ACTIVITY_MODE'] = 'disable'

# Contstruct a worker-specific db config.
base_config = SequelRails.configuration.environments[Rails.env.to_s]
base_database = base_config['database']

db_config = base_config.except('url').merge('database' => "#{base_database}_#{i}")

Kernel.silence_warnings do
SequelRails::Storage.drop_environment(db_config)

# Attempt to create a database from a template (postgres only) if supported,
# otherwise create an empty database and load the schema into it.
if base_config.respond_to?(:template)
# Clone the parent database. This is faster and ensures OIDs and other
# database-level state is identical.
db_config.merge!('template' => base_database, 'maintenance_db' => 'postgres')
SequelRails::Storage.create_environment(db_config)
else
# Create a blank worker database and load the schema into it.
SequelRails::Storage.create_environment(db_config)
filename = SequelRails::Storage.structure_path
SequelRails::Storage.load_environment(db_config, filename)
end
end

# Model classes capture their database object when they are defined, so
# every already-loaded model references the boot-time database object.
# Update the reference to the worker database.
db = Sequel::Model.db

# TODO: Ideally the logic below is captured in a reconnect() method on the db.
db.disconnect
db.opts[:database] = db_config['database']

# Re-initialize extensions with the new database connection.
db.instance_variable_get(:@loaded_extensions).each do |ext|
::Sequel::Database::EXTENSIONS[ext].call(db)
end
end
end
end
end
end
4 changes: 4 additions & 0 deletions lib/sequel_rails/storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

module SequelRails
module Storage
def self.structure_path
ENV['DB_STRUCTURE'] || File.join(Rails.root, 'db', 'structure.sql')
end

def self.create_all
with_local_repositories { |config| create_environment(config) }
end
Expand Down
7 changes: 4 additions & 3 deletions lib/sequel_rails/storage/postgres.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def _drop
commands = ['dropdb']
add_connection_settings commands
add_flag commands, '--if-exists'
add_flag commands, '--force'
commands << database
safe_exec commands
end
Expand All @@ -32,9 +33,9 @@ def _dump(filename)
with_pgpassword do
commands = ['pg_dump']
add_connection_settings commands
add_flag commands, '-s'
add_flag commands, '-x'
add_flag commands, '-O'
add_flag commands, '--schema-only'
add_flag commands, '--no-privileges'
add_flag commands, '--no-owner'
add_option commands, '--file', filename
commands << database
safe_exec commands
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/sequel_rails/storage/postgres_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
describe '#_drop' do
it 'uses the dropdb command' do
expect(subject).to receive(:`).with(
"dropdb --username\\=#{username} --host\\=#{host} --port\\=#{port} --if-exists #{database}"
"dropdb --username\\=#{username} --host\\=#{host} --port\\=#{port} --if-exists --force #{database}"
)
subject._drop
end
Expand Down Expand Up @@ -98,7 +98,7 @@
let(:dump_file_name) { 'dump.sql' }
it 'uses the pg_dump command' do
expect(subject).to receive(:`).with(
"pg_dump --username\\=#{username} --host\\=#{host} --port\\=#{port} -s -x -O --file\\=#{dump_file_name} #{database}"
"pg_dump --username\\=#{username} --host\\=#{host} --port\\=#{port} --schema-only --no-privileges --no-owner --file\\=#{dump_file_name} #{database}"
)
subject._dump dump_file_name
end
Expand Down
22 changes: 22 additions & 0 deletions spec/lib/sequel_rails/storage_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,26 @@
end
end
end
describe '.structure_path' do
around do |example|
original = ENV['DB_STRUCTURE']
example.run
ensure
if original.nil?
ENV.delete('DB_STRUCTURE')
else
ENV['DB_STRUCTURE'] = original
end
end

it 'defaults to db/structure.sql under the Rails root' do
ENV.delete('DB_STRUCTURE')
expect(described_class.structure_path).to eq(File.join(Rails.root, 'db', 'structure.sql'))
end

it 'uses the DB_STRUCTURE environment variable when set' do
ENV['DB_STRUCTURE'] = '/custom/path/structure.sql'
expect(described_class.structure_path).to eq('/custom/path/structure.sql')
end
end
end
Loading