Created
March 31, 2022 18:26
-
-
Save kddnewton/02ba1c07290ee2af6bcd9c713be470e4 to your computer and use it in GitHub Desktop.
Migration stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module ActiveRecord | |
class Migration | |
class MigrationError < StandardError | |
end | |
RenameColumn = Struct.new(:table_name, :column_name, :new_column_name, keyword_init: true) | |
RemoveColumn = Struct.new(:table_name, :column_name, keyword_init: true) | |
AddColumn = Struct.new(:table_name, :column_name, :type, :options, keyword_init: true) | |
attr_reader :changes | |
def initialize | |
@changes = [] | |
end | |
def rename_column(table_name, column_name, new_column_name) | |
changes << RenameColumn.new(table_name: table_name, column_name: column_name, new_column_name: new_column_name) | |
end | |
def remove_column(table_name, column_name) | |
changes << RemoveColumn.new(table_name: table_name, column_name: column_name) | |
end | |
def add_column(table_name, column_name, type, options = {}) | |
changes << AddColumn.new(table_name: table_name, column_name: column_name, type: type, options: options) | |
end | |
def method_missing(method, *args, &block) | |
raise MigrationError, method | |
end | |
# You need this method so that you can run ActiveRecord::Migration[7.0] and | |
# get the same object back. | |
def self.[](version) | |
self | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class MyMigration < ActiveRecord::Migration[7.0] | |
def change | |
rename_column :my_table, :old_column, :new_column | |
add_column :my_table, :foobars, :string | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# frozen_string_literal: true | |
# USAGE: ./runner.rb <path_to_migration_file> | |
filepath = ARGV.first | |
# Start a separate process in which to run our custom ActiveRecord::Migration | |
# object. This is going to record all of the changes that are made within | |
# structs that will then serialize and validate. | |
rd, wr = IO.pipe | |
pid = Process.fork do | |
rd.close | |
# Require our library and the migration(s). | |
require_relative "./library" | |
require_relative filepath | |
# TODO: get constant name from filepath | |
# Create an instance of the migration and call the change method. | |
migration = MyMigration.new | |
begin | |
migration.change | |
rescue ActiveRecord::Migration::MigrationError => error | |
# Serialize the error | |
wr.puts("error") | |
wr.puts(error.message) | |
else | |
# Serialize the changes to Marshal and write them to the pipe. | |
wr.puts("success") | |
wr.puts(Marshal.dump(migration.changes)) | |
end | |
wr.close | |
end | |
# Close the write end of the pipe in the parent process and wait for the child | |
# process to exit. | |
wr.close | |
Process.wait | |
# Now that the child process has exited, read the changes from the pipe and load | |
# them back into their respective structs. | |
require_relative "./library" | |
if rd.readline.chomp == "success" | |
changes = Marshal.load(rd.read) | |
rd.close | |
# TODO: require the application in order to do any validation. | |
# For an example here, we're just going to loop through the various changes. | |
changes.each.with_index(1) do |change, index| | |
puts "CHANGE %d: #{change}" % index | |
end | |
else | |
error = rd.read.chomp | |
rd.close | |
warn("You tried to call #{error}, but that's not allowed. Silly.") | |
exit(1) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment