Last active
January 4, 2017 10:41
-
-
Save shinenelson/acdec385569e0ec37122388435f87dec to your computer and use it in GitHub Desktop.
Generate collection map (YAML) for MoSQL (mongoid => Postgres) from rails console
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 | |
# This script traverses over the fields in a model | |
# of a rails application to map them to | |
# the corresponding schema type in Postgres. | |
# The output generated is in YAML format | |
# and can be used as the collection map for MoSQL. | |
puts "#{Mongoid.default_session.options[:database]}:" # Print the database the application is connected to | |
models = Mongoid.models # Fetch all the models in the application | |
models.each do | model | | |
puts " #{model.collection_name}:" # Print Model's collection_name | |
puts " :columns:" | |
# Flags to check for common mongoid fields | |
id = false | |
created_at = false | |
updated_at = false | |
# Iterate over each field on the model and | |
# set id, created_at and updated_at if applicable | |
model.fields.each do | field | | |
case field.second.name | |
when "_id" | |
id = true | |
when "created_at" | |
created_at = true | |
when "updated_at" | |
updated_at = true | |
end | |
end | |
if id | |
puts " - id:" | |
puts " :source: _id" | |
puts " :type: TEXT" | |
end | |
if created_at | |
puts " - created_at: TIMESTAMP" | |
end | |
if updated_at | |
puts " - updated_at: TIMESTAMP" | |
end | |
# Declare Type Hash to map Mongoid :types to Postgres schema types | |
types = { | |
"Date" => "DATE", | |
"Time" => "TIMESTAMP", | |
"DateTime" => "TIMESTAMP", | |
"String" => "TEXT", | |
"Integer" => "INTEGER", | |
"Fixnum" => "INTEGER", | |
"Object" => "TEXT", | |
"Hash" => "JSON", | |
"Float" => "DOUBLE PRECISION", | |
} | |
# Declare Class Hash to map Mongoid :class to Postgres schema types | |
classes = { | |
"Mongoid::Boolean" => "BOOLEAN", | |
"BSON::Binary" => "BYTEA", | |
"BSON::Document" => "JSON", | |
"BSON::ObjectId" => "TEXT" | |
} | |
# Re-iterate over each field in the model | |
# to update the collection map with | |
# the respective field and type | |
model.fields.each do | field | | |
fs = field.second | |
unless fs.name.in? ["_id", "created_at", "updated_at"] | |
if fs.options[:type].to_s.in? (types.keys+classes.keys).uniq.map(&:to_s) | |
type = types["#{fs.options[:type]}"] || classes["#{fs.options[:type]}"] | |
puts " - #{fs.name}: #{type}" | |
elsif fs.options[:type].to_s == "Array" | |
if model.where(:"#{fs.name}".ne => []).first.attributes[:"#{fs.name}"].first.class.to_s.in? (types.keys+classes.keys).uniq.map(&:to_s) | |
type = types["#{model.where(:"#{fs.name}".ne => []).first.attributes[:"#{fs.name}"].first.class}"] || classes["#{model.where(:"#{fs.name}".ne => []).first.attributes[:"#{fs.name}"].first.class}"] | |
puts " - #{fs.name}: #{type} ARRAY" | |
# else | |
# puts " - #{fs.name}: #{model.where(:"#{fs.name}".ne => []).first.attributes[:"#{fs.name}"].first.class}" | |
end | |
# else | |
# puts " - #{fs.name}: #{fs.options[:type]}" | |
end | |
end | |
end | |
# Meta Information for Postgres | |
puts " :meta:" | |
puts " :table: #{model.collection_name}" | |
puts " :extra_props: true" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment