Skip to content

Instantly share code, notes, and snippets.

@GavinRay97
Created August 24, 2020 00:42
Show Gist options
  • Save GavinRay97/37bb385ba0e52f2c153d416333105981 to your computer and use it in GitHub Desktop.
Save GavinRay97/37bb385ba0e52f2c153d416333105981 to your computer and use it in GitHub Desktop.
Hasura SQL + Metadata models CLI script
#!/usr/bin/env ruby
require 'pp'
require 'ostruct'
require 'optparse'
default_identifiers = ["/* TABLE */", "/* FOREIGN KEYS */", "/* TRIGGERS */"]
# Process a list of SQL file names by opening + reading text from each,
# then finding matching sections based on identifiers + putting them in hash
def process_sql_files(sql_files, identifiers)
output = identifiers.product([""]).to_h
current_identifier = nil
sql_files.each do |name|
File.foreach(name) do |line|
# For each line, if the line matches one of the identifiers, switch current_identifier to it
matched_identifier = identifiers.select { |it| line.include? it }.first
if matched_identifier then
current_identifier = matched_identifier
next
end
# Else, add the line to the identifier block key that it belongs to in results hash
output[current_identifier] += line if current_identifier
end
end
return output
end
# Create options struct and set defaults
options = OpenStruct.new
# Output defaults to stdout, but if a file is passed, output will be a writestream to that file instead.
# Calling options.output.puts(str) will either print to stdout or write a line to the file.
options.output = $stdout
options.identifiers = default_identifiers
# If a list of files was given as args, use those, else default to globbing current dir for SQL files
options.files = if ARGV.length != 0 then ARGV else Dir.glob('./**.sql').sort end
OptionParser.new do |opts|
opts.on('-o file', '--out file', String, "Output file") do |file|
options.output = File.open(file, "w")
end
opts.on("-i '/* TABLES */','/* FOREIGN KEYS */,'/* Triggers */'",
"--identifiers '/* TABLES */','/* FOREIGN KEYS */,'/* Triggers */'",
Array, "Set identifiers") do |identifiers|
options.identifiers = identifiers
end
end.parse!
results = process_sql_files(options.files, options.identifiers)
results.each do |identifier, text|
options.output.puts(text)
end
#!/usr/bin/env ruby
require 'pp'
require 'yaml'
require 'ostruct'
require 'optparse'
def process_tables_yaml_files(filenames)
filenames.map { |it| YAML.load_file(it) }
end
# Create options struct and set defaults
options = OpenStruct.new
options.output = $stdout
# If a list of files was given as args, use those, else default to globbing current dir for YAML files
options.yaml_files = if ARGV.length != 0 then ARGV else Dir.glob('./**.y*ml').sort end
OptionParser.new do |opts|
opts.on('-o file', '--out file', String, "Output file") do |file|
options.output = File.open(file, "w")
end
end.parse!
yaml_res = options.yaml_files.map { |it| YAML.load_file(it) }.select(&:itself)
options.output.puts YAML.dump(yaml_res)
.PHONY: generate_sql generate_tables_yaml generate_schema_and_tables_metadata
generate_sql: ## Generate single SQL file schema from all models
ruby ./generate-sql.rb \
--identifiers '/* TABLE */,/* FOREIGN KEYS */,/* TRIGGERS */' \
--out schema.sql \
./models/**/**.sql
generate_tables_yaml: ## Generate tables.yaml file from all models
ruby ./generate-tables-metadata.rb \
--out tables.yaml \
./models/**/table.yaml
generate_schema_and_tables_metadata: ## Generate single SQL file schema and tables.yaml from all models
generate_schema_and_tables_metadata: generate_sql generate_tables_yaml
help:
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.DEFAULT_GOAL := help
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment