require "activesupport" class Sqld4r_core def initialize(options) super() @options = options @logfile = File::new( @options["log_file"], "a" ) if @options["logging"] end def run notice "sqld4r: Starting at " + Time.now.strftime("%Y/%m/%d %H:%M:%S") notice "start to parse about SQLDesigner xml file" @structure = Sqld4r_parser.new.parse(@options["sqld_path"]) notice "finish to parse" @structure.each do |table| generate_model_for(table) end @structure.each do |table| add_relationship_to(table) unless @options["skip-relation"] add_index_to(table) unless @options["skip-index"] end notice "sqld4r: Complete at " + Time.now.strftime("%Y/%m/%d %H:%M:%S") @logfile.close if @logfile end def paramaters_for_model_generator param_string = " " param_string << "--svn " if @options["svn"] param_string << "--git " if @options["git"] param_string << "--skip-timestamps " if @options["skip-timestamps"] param_string << "--skip-migration " if @options["skip-migration"] param_string << "--skip-fixture " if @options["skip-fixture"] param_string << "--quiet " unless @options["verbose"] param_string end # script/generate model post title:string body:text published:boolean owner:references def model_and_columns_from_structure(table) model_columns_string = "" model_name = tablename2modelname(table["tablename"]) model_columns_string << model_name + " " table["colums"].each do |column| #puts column.inspect next if "id" == column["name"] if column["relation"].nil? model_columns_string << column["name"] + ":" + column["datatype"] + " " else rel_table = Inflector.singularize(column["relation"]["table"]) model_columns_string << rel_table + ":references " end end model_columns_string end =begin script/generate model post title:string body:text published:boolean owner:references =end def generate_model_for(table) notice "generate for " + table["tablename"] command = "script/generate " if @options["rspec"] command << "rspec_model " + paramaters_for_model_generator else command << "model " + paramaters_for_model_generator end command << model_and_columns_from_structure(table) exec_shell_command(command) end =begin { "tablename" => "comments", # => "has_many :comments" to Item model "colums" => [ { "relation" => nil, "comment" => "com", }, { "relation" => {"table" => "items", "column" => "id"}, # => "belongs_to :item" to Comment model "comment" => "has_many", }, ], "comment" => "user has many actions" }, class Post < ActiveRecord::Base end relation_models = [ "app/model/comment.rb", "app/model/sometable.rb", ] =end def add_relationship_to(table) notice "add relationship to " + table["tablename"] current_model_name = tablename2modelname(table["tablename"]) relation_models = [] current_model_relations = [] table["colums"].each do |column| next if column["relation"].nil? current_model_relations << tablename2modelname(column["relation"]["table"]) relation_models << tablename2modelname(column["relation"]["table"]) end # current model notice "-add belongs_to relationship to " + table["tablename"] + " about:" if 0 == current_model_relations.size notice "--skip. becase this model dose not have relationship." else notice "--" + current_model_relations.join(",") text_insert_to(modelname2modelpath(current_model_name)) do |file, line| file.puts line if /^class\s.+\s<\sActiveRecord::Base$/ =~ line file.puts '#' + table["comment"] unless table["comment"].nil? current_model_relations.each do |rel| file.puts " belongs_to :" + Inflector.singularize(rel) end end end end # target models notice "-add has_one/has_many relationship to:" if 0 == relation_models.size notice "--skip. because this model dose not have relationship" else notice "--" + relation_models.join(",") relation_models.each do |target_model| text_insert_to(modelname2modelpath(target_model)) do |file, line| file.puts line if /^class\s.+\s<\sActiveRecord::Base$/ =~ line single_name = Inflector.singularize(table["tablename"]) plural_name = table["tablename"] file.puts ' # has_one :' + single_name + ' # TODO:CHECK_ME' file.puts ' has_many :' + plural_name end end end end end def tablename2modelname(tablename) Inflector.singularize(tablename).classify end def modelname2modelpath(modelname) "app/models/" + modelname + ".rb" end def text_insert_to(filename) current_model_contents = [] File::open(filename, "r") do |file| current_model_contents = file.readlines end File::open(filename, "w") do |file| current_model_contents.each do |line| yield(file, line) end end end =begin script/generate migration add_indexes_for_all_tables class CreatePosts < ActiveRecord::Migration def self.up create_table :posts do |t| t.string :title t.text :body t.boolean :published t.timestamps end end def self.down drop_table :posts end end =end def add_index_to(table) end def notice(message) puts "* " + message if @options["verbose"] @logfile.puts "* " + message if @options["logging"] and @logfile end def exec_shell_command(command) command << " > /dev/null" unless @options["verbose"] command = "sudo " + command if @options["sudo"] puts '->' + command if @options["verbose"] @logfile.puts '->' + command if @options["logging"] result = `#{command}`.chomp unless @options["emulate"] puts '-->' + result if @options["verbose"] and not result.nil? and not result.empty? @logfile.puts '-->' + result if @options["logging"] and not result.nil? and not result.empty? Sqld4r_options::error_with_show_usage "receive error from command." unless 0 == $? $? end end