├── Rakefile ├── CHANGELOG.md ├── .gitignore ├── lib └── sqldef │ ├── rails │ ├── version.rb │ ├── railtie.rb │ └── tasks │ │ ├── databases.rake │ │ └── sqldef.rake │ └── rails.rb ├── bin ├── setup └── console ├── Gemfile ├── .github └── workflows │ └── main.yml ├── LICENSE.txt ├── README.md └── sqldef-rails.gemspec /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | task default: %i[] 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # v0.1.1 2 | 3 | * Initial support of `DATABASE_URL` 4 | 5 | # v0.1.0 6 | 7 | * Initial release 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | /Gemfile.lock 10 | -------------------------------------------------------------------------------- /lib/sqldef/rails/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Sqldef 4 | module Rails 5 | VERSION = '0.1.1' 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | # Specify your gem's dependencies in sqldef-rails.gemspec 6 | gemspec 7 | 8 | gem 'rake' 9 | -------------------------------------------------------------------------------- /lib/sqldef/rails/railtie.rb: -------------------------------------------------------------------------------- 1 | require 'rails/railtie' 2 | 3 | class Sqldef::Rails::Railtie < ::Rails::Railtie 4 | initializer :sqldef do |app| 5 | Sqldef.bin = Rails.root.join('bin').to_s 6 | end 7 | 8 | rake_tasks do 9 | load File.expand_path('./tasks/sqldef.rake', __dir__) 10 | load File.expand_path('./tasks/databases.rake', __dir__) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Ruby 2 | 3 | on: [push,pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: Set up Ruby 11 | uses: ruby/setup-ruby@v1 12 | with: 13 | ruby-version: 3.0.0 14 | - name: Run the default task 15 | run: | 16 | gem install bundler -v 2.2.3 17 | bundle install 18 | bundle exec rake 19 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "bundler/setup" 5 | require "sqldef/rails" 6 | 7 | # You can add fixtures and/or initialization code here to make experimenting 8 | # with your gem easier. You can also use a different console, if you like. 9 | 10 | # (If you use this, don't forget to add pry to your Gemfile!) 11 | # require "pry" 12 | # Pry.start 13 | 14 | require "irb" 15 | IRB.start(__FILE__) 16 | -------------------------------------------------------------------------------- /lib/sqldef/rails.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | require 'sqldef' 3 | require 'sqldef/rails/version' 4 | require 'sqldef/rails/railtie' 5 | 6 | module Sqldef 7 | module Rails 8 | def self.database_config 9 | database = ::Rails.application.config_for(:database) 10 | if ENV.key?('DATABASE_URL') 11 | database = database.merge( 12 | ActiveRecord::DatabaseConfigurations::ConnectionUrlResolver.new(ENV['DATABASE_URL']).to_hash 13 | ) 14 | end 15 | database 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/sqldef/rails/tasks/databases.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rake::Task.tasks.each do |task| 4 | case task.name 5 | when /\Adb:schema:/, /\Adb:migrate(:|\z)/, 'db:rollback' 6 | task.clear 7 | end 8 | end 9 | 10 | namespace :db do 11 | { 12 | 'migrate:status' => 'sqldef:dry-run', 13 | 'migrate' => 'sqldef:apply', 14 | 'schema:load' => 'sqldef:apply', 15 | 'schema:dump' => 'sqldef:export', 16 | }.each do |db, sqldef| 17 | desc Rake::Task[sqldef].comment 18 | task db => sqldef 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Takashi Kokubun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sqldef-rails 2 | 3 | Run [sqldef](https://github.com/k0kubun/sqldef) on Rails. 4 | 5 | ## Installation 6 | 7 | ```ruby 8 | gem 'sqldef-rails' 9 | ``` 10 | 11 | ## Usage 12 | ### Configuration 13 | 14 | Just configure `config/database.yml` normally. 15 | 16 | ```yml 17 | default: &default 18 | adapter: postgresql 19 | username: postgres 20 | password: 21 | host: 127.0.0.1 22 | 23 | development: 24 | <<: *default 25 | database: sqldef_development 26 | 27 | test: 28 | <<: *default 29 | database: sqldef_test 30 | ``` 31 | 32 | ### Export 33 | 34 | Dump the current schema to `db/schema.sql`. 35 | 36 | ```bash 37 | bundle exec rake db:schema:dump 38 | ``` 39 | 40 | You may use `bin/rails` instead of `bundle exec rake` too. 41 | 42 | ### Dry Run 43 | 44 | You can show DDLs to be executed to match `db/schema.sql`. 45 | 46 | ```bash 47 | bundle exec rake db:migrate:status 48 | ``` 49 | 50 | ### Aplly 51 | 52 | You can run DDLs to match `db/schema.sql`. 53 | 54 | ```bash 55 | bundle exec rake db:migrate 56 | ``` 57 | 58 | ## License 59 | 60 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 61 | -------------------------------------------------------------------------------- /sqldef-rails.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'lib/sqldef/rails/version' 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = 'sqldef-rails' 7 | spec.version = Sqldef::Rails::VERSION 8 | spec.authors = ['Takashi Kokubun'] 9 | spec.email = ['takashikkbn@gmail.com'] 10 | 11 | spec.summary = 'Idempotent MySQL/PostgreSQL schema management by SQL' 12 | spec.description = 'Idempotent MySQL/PostgreSQL schema management by SQL' 13 | spec.homepage = 'https://github.com/sqldef/sqldef-rails' 14 | spec.license = 'MIT' 15 | spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0') 16 | 17 | spec.metadata['homepage_uri'] = spec.homepage 18 | spec.metadata['source_code_uri'] = spec.homepage 19 | 20 | # Specify which files should be added to the gem when it is released. 21 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 22 | spec.files = Dir.chdir(File.expand_path(__dir__)) do 23 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) } 24 | end 25 | spec.bindir = 'exe' 26 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 27 | spec.require_paths = ['lib'] 28 | 29 | spec.add_dependency 'sqldef' 30 | end 31 | -------------------------------------------------------------------------------- /lib/sqldef/rails/tasks/sqldef.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | namespace :sqldef do 4 | commands = { 5 | 'mysql2' => :mysqldef, 6 | 'postgresql' => :psqldef, 7 | 'sqlite3' => :sqlite3def, 8 | } 9 | 10 | desc 'Export the database' 11 | task export: [:environment] do 12 | database = Sqldef::Rails.database_config 13 | Sqldef.export( 14 | host: database.fetch(:host), 15 | port: database[:port], 16 | user: database.fetch(:username), 17 | password: database[:password], 18 | database: database.fetch(:database), 19 | command: commands.fetch(database.fetch(:adapter)), 20 | path: Rails.root.join('db/schema.sql').to_s, 21 | ) 22 | end 23 | 24 | desc 'Dry-run the database' 25 | task 'dry-run': [:environment] do 26 | database = Sqldef::Rails.database_config 27 | Sqldef.dry_run( 28 | host: database.fetch(:host), 29 | port: database[:port], 30 | user: database.fetch(:username), 31 | password: database[:password], 32 | database: database.fetch(:database), 33 | command: commands.fetch(database.fetch(:adapter)), 34 | path: Rails.root.join('db/schema.sql').to_s, 35 | ) 36 | end 37 | 38 | desc 'Apply the database' 39 | task apply: [:environment] do 40 | database = Sqldef::Rails.database_config 41 | Sqldef.apply( 42 | host: database.fetch(:host), 43 | port: database[:port], 44 | user: database.fetch(:username), 45 | password: database[:password], 46 | database: database.fetch(:database), 47 | command: commands.fetch(database.fetch(:adapter)), 48 | path: Rails.root.join('db/schema.sql').to_s, 49 | ) 50 | end 51 | end 52 | --------------------------------------------------------------------------------