Skip to content

Instantly share code, notes, and snippets.

@mieko
Created September 3, 2020 01:23
Show Gist options
  • Save mieko/bb2750403a51b943b4d1e0789abe94b4 to your computer and use it in GitHub Desktop.
Save mieko/bb2750403a51b943b4d1e0789abe94b4 to your computer and use it in GitHub Desktop.
`rake schema FOR=Model` as an alternative to `annotate`
require "shellwords"
def terminal_width
%x(tput cols).chomp.to_i
rescue StandardError
80
end
def sql_table_command(model_class)
table_name = model_class.table_name
case (adapter_name = model_class.connection.adapter_name)
when "PostgreSQL"
"\\d #{table_name}"
when "Mysql2"
# mariadb doesn't have a terminal command to go into table mode, only a command-line
# switch, -t. mySQL does, but it'll error if not supported on the version you're
# running. If you're using mySQL, I'm sure you're used to things working janky, so
# here you go.
"DESCRIBE #{table_name};"
when "SQLite"
# What's left after spaces between cols and the nn?/pk columns
full_width = terminal_width
w = full_width - 13
col_widths = [(w / 3.0).ceil, (w / 3.0).floor, (w / 3.0).floor, 2, 3]
<<~"SQL"
.header on
.mode column
.width #{col_widths.join ' '}
SELECT name as "Column", type as "Type", dflt_value as "Default", pk, "notnull" as "nn?"
FROM pragma_table_info(\"#{table_name}\");
.print "#{col_widths.map { |wx| '-' * wx }.join(' ')}"
.print
.schema "#{table_name}"
SQL
else
abort "fatal: don't know table schema command for #{adapter_name}"
end
end
desc "Display DB schema for model in variable FOR=Model"
task :schema => :environment do
model = ENV["FOR"]
abort "fatal: FOR=ModelName required" if model.nil?
begin
model_class = model.constantize
unless model_class.respond_to?(:table_name)
abort "fatal: #{model_class.name} does not have a table_name"
end
exec "echo '#{sql_table_command(model_class)}'" \
" | #{Shellwords.escape(Rails.root.join('bin/rails'))} dbconsole"
rescue NameError
abort "fatal: could not locate model '#{model}'"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment