- Timestamp:
- 09/10/08 20:34:22 (2 months ago)
- Location:
- lang/ruby/ymldot
- Files:
-
- 2 added
- 4 modified
-
README (modified) (2 diffs)
-
bin/ymldot (modified) (1 diff)
-
lib/ymldot.rb (modified) (9 diffs)
-
spec/test_category.yml (added)
-
spec/test_category_none_table.yml (added)
-
spec/ymldot_spec.rb (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/ruby/ymldot/README
r19115 r19133 27 27 enumerate column names 28 28 * foreginkeys 29 * belongs_to30 29 * has_many 31 30 * has_one … … 33 32 same meaning the relation of ActiveRecord. 34 33 enumerate ref table name. 34 * category 35 * label 36 category name set. and set frame. 37 * table 38 nested table. 35 39 36 40 == Sample -
lang/ruby/ymldot/bin/ymldot
r19117 r19133 1 1 #!/usr/bin/ruby -wKU 2 $: << File.join(File.dirname(__FILE__), "../lib") 2 3 3 require ' lib/ymldot'4 require 'ymldot' 4 5 require 'optparse' 5 6 -
lang/ruby/ymldot/lib/ymldot.rb
r19118 r19133 25 25 end 26 26 27 class Tables 28 def initialize(table_node, label=nil, category=false) 29 @label = label 30 @category = category 31 @table_node = table_node 32 @entity_dict = {} 33 table_node.each {|t| eval_entity(t) } 34 end 35 attr_accessor :entity_dict, :label, :table_node, :category 36 37 def entity_dict_to_dot 38 res = "" 39 s = [] 40 @entity_dict.each_value{|e| s << e } 41 if @category 42 res << "label=#{@label}\n" if @label 43 res << "style=invis\n" unless @label 44 end 45 s.sort{|a, b| a.name <=> b.name}.each{|e| res << e.to_dot << "\n"} 46 res 47 end 48 49 private 50 def eval_entity(table) 51 columns = table["columns"]; columns ||= [] 52 @entity_dict[table["name"]] ||= Entity.new(table["name"], table["dependent"], columns) 53 end 54 55 end 56 27 57 28 58 class Ymldot … … 35 65 end 36 66 @file_name = $1 if filepath[/(\w+).yml\z/] 37 @entities = {} 67 @entity_dict = {} 68 @category = [] 38 69 @one_relations = [] 39 70 @many_relations = [] 40 eval 71 eval_yml 41 72 end 42 73 … … 46 77 digraph #{@file_name} { 47 78 #{add_2_tab(config_to_dot)} 48 #{add_2_tab(entit ies_to_dot)}79 #{add_2_tab(entity_dict_to_dot)} 49 80 #{add_2_tab(relations_to_dot)} 50 81 } … … 66 97 end 67 98 68 def entit ies_to_dot99 def entity_dict_to_dot 69 100 res = "" 70 s = [] 71 @entities.each_value{|e| s << e } 72 s.sort{|a, b| a.name <=> b.name}.each{|e| res << e.to_dot << "\n"} 101 unless @category.empty? 102 @category.each_with_index do |c, i| 103 unless c.category 104 res << c.entity_dict_to_dot 105 else 106 res << "subgraph cluster#{i} {\n" 107 res << add_2_tab(c.entity_dict_to_dot) 108 res << "}\n" 109 end 110 end 111 end 73 112 res 74 113 end … … 85 124 end 86 125 87 def eval 126 def eval_yml 88 127 @config = @node["config"]? @node["config"] : {} 89 @node["tables"].each {|t| eval_entity(t) } 90 @node["tables"].each {|t| eval_relation(t) } 91 end 92 93 def eval_entity(table) 94 columns = table["columns"]; columns ||= [] 95 @entities[table["name"]] ||= Entity.new(table["name"], table["dependent"], columns) 128 @category << Tables.new(@node["tables"]) if @node["tables"] and !@node["tables"].empty? 129 @node["category"].each{|c| @category << Tables.new(c["tables"], c["label"], true)} if @node["category"] 130 @category.each{|c| c.entity_dict.each_pair{|k, v| @entity_dict[k] = v}} 131 @category.each{|c| c.table_node.each{|e| eval_relation(e) } } 96 132 end 97 133 … … 99 135 foreignkeys = table["foreignkeys"] 100 136 tname = table["name"] 101 eval_relation_belongs_to(foreignkeys["belongs_to"], tname) if foreignkeys["belongs_to"]137 return unless foreignkeys 102 138 eval_relation_has_many(foreignkeys["has_many"], tname) if foreignkeys["has_many"] 103 139 eval_relation_has_one(foreignkeys["has_one"], tname) if foreignkeys["has_one"] … … 105 141 end 106 142 107 def eval_relation_belongs_to(keys, tname)108 keys.each do |rel|109 @entities[tname].foreignkeys << "#{rel}ID(FK)"110 end111 end112 113 143 def eval_relation_has_many(keys, tname) 114 144 keys.each do |rel| 115 @many_relations << {:self => @entities[tname], :have => @entities[rel]} 145 @entity_dict[rel].foreignkeys << "#{tname}ID(FK)" 146 @many_relations << {:self => @entity_dict[tname], :have => @entity_dict[rel]} 116 147 end 117 148 end … … 119 150 def eval_relation_has_one(keys, tname) 120 151 keys.each do |rel| 121 @one_relations << {:self => @entities[tname], :have => @entities[rel]} 152 @entity_dict[rel].foreignkeys << "#{tname}ID(FK)" 153 @one_relations << {:self => @entity_dict[tname], :have => @entity_dict[rel]} 122 154 end 123 155 end … … 126 158 keys.each do |rel| 127 159 join_tname = "#{rel}_#{tname}" 128 return if @entit ies.has_key? join_tname160 return if @entity_dict.has_key? join_tname 129 161 join_tname = "#{tname}_#{rel}" 130 @entities[join_tname] ||= Entity.new(join_tname, true) 131 @entities[join_tname].foreignkeys << "#{tname}ID(FK)" 132 @entities[join_tname].foreignkeys << "#{rel}ID(FK)" 133 @many_relations << {:self => @entities[tname], :have => @entities[join_tname]} 134 @many_relations << {:self => @entities[rel], :have => @entities[join_tname]} 162 @entity_dict[join_tname] ||= Entity.new(join_tname, true) 163 @entity_dict[join_tname].foreignkeys << "#{tname}ID(FK)" 164 @entity_dict[join_tname].foreignkeys << "#{rel}ID(FK)" 165 166 # make new category 167 keys = [] 168 keys << "#{tname}ID(FK)" 169 keys << "#{rel}ID(FK)" 170 @category << Tables.new([{"name" => join_tname, "columns" => keys}]) 171 172 @many_relations << {:self => @entity_dict[tname], :have => @entity_dict[join_tname]} 173 @many_relations << {:self => @entity_dict[rel], :have => @entity_dict[join_tname]} 135 174 end 136 175 end -
lang/ruby/ymldot/spec/ymldot_spec.rb
r19118 r19133 3 3 4 4 class Ymldot 5 attr_accessor :node, :entit ies, :one_relations, :many_relations, :file_name, :config5 attr_accessor :node, :entity_dict, :one_relations, :many_relations, :file_name, :config, :category 6 6 end 7 7 … … 27 27 end 28 28 29 it "#entit iesには正しいEntityクラスが格納されていること" do30 @ymldot.entit ies["foo"].name.should == "foo"31 @ymldot.entit ies["foo"].dependent?.should be_true32 @ymldot.entit ies["foo"].columns.should == ["password", "group_id"]33 @ymldot.entit ies["foo"].foreignkeys.should == ["hogeID(FK)"]34 @ymldot.entit ies["hoge"].name.should == "hoge"35 @ymldot.entit ies["hoge"].dependent?.should be_false36 @ymldot.entit ies["hoge"].columns.should == ["password", "group_id"]37 @ymldot.entit ies["hoge"].foreignkeys.should be_empty29 it "#entity_dict には正しいEntityクラスが格納されていること" do 30 @ymldot.entity_dict["foo"].name.should == "foo" 31 @ymldot.entity_dict["foo"].dependent?.should be_true 32 @ymldot.entity_dict["foo"].columns.should == ["password", "group_id"] 33 @ymldot.entity_dict["foo"].foreignkeys.should == ["hogeID(FK)"] 34 @ymldot.entity_dict["hoge"].name.should == "hoge" 35 @ymldot.entity_dict["hoge"].dependent?.should be_false 36 @ymldot.entity_dict["hoge"].columns.should == ["password", "group_id"] 37 @ymldot.entity_dict["hoge"].foreignkeys.should be_empty 38 38 end 39 39 … … 69 69 end 70 70 71 it "#entit iesには正しいEntityクラスが格納されていること" do72 @ymldot.entit ies["one1_one2"].foreignkeys.should == ["one1ID(FK)", "one2ID(FK)"]71 it "#entity_dict には正しいEntityクラスが格納されていること" do 72 @ymldot.entity_dict["one1_one2"].foreignkeys.should == ["one1ID(FK)", "one2ID(FK)"] 73 73 end 74 74 … … 88 88 node [fontname="MSUIGOTHIC.ttf"] 89 89 "one1" [shape=Mrecord, label="{one1|password\lgroup_id\l}"] 90 "one1_one2" [shape=Mrecord, label="{one1_one2|one1ID(FK)\lone2ID(FK)\l}"]91 90 "one2" [shape=record, label="{one2|password\lgroup_id\l}"] 91 "one1_one2" [shape=record, label="{one1_one2|one1ID(FK)\lone2ID(FK)\l}"] 92 92 93 93 "one1" -> "one1_one2" [arrowtail=none arrowhead=dot headlabel="n" taillabel="1"] … … 104 104 end 105 105 106 it "#entit iesには正しいEntityクラスが格納されていること" do107 @ymldot.entit ies["one1"].foreignkeys.should == ["one2ID(FK)"]106 it "#entity_dict には正しいEntityクラスが格納されていること" do 107 @ymldot.entity_dict["one1"].foreignkeys.should == ["one2ID(FK)"] 108 108 end 109 109 … … 129 129 end 130 130 131 it "#entit iesには正しいEntityクラスが格納されていること" do132 @ymldot.entit ies["コンテンツ_カテゴリ"].foreignkeys.should == ["コンテンツID(FK)", "カテゴリID(FK)"]131 it "#entity_dict には正しいEntityクラスが格納されていること" do 132 @ymldot.entity_dict["コンテンツ_カテゴリ"].foreignkeys.should == ["コンテンツID(FK)", "カテゴリID(FK)"] 133 133 end 134 134 … … 159 159 end 160 160 161 it "#entit iesの'baf'には'bar'へのforeginkeyがあること" do162 @ymldot.entit ies["baf"].foreignkeys[0].should == "barID(FK)"161 it "#entity_dict の'baf'には'bar'へのforeginkeyがあること" do 162 @ymldot.entity_dict["baf"].foreignkeys[0].should == "barID(FK)" 163 163 end 164 164 end … … 169 169 end 170 170 171 it "#entities['foo'].columnsは空の配列であること" do 172 puts @ymldot.node.inspect 173 @ymldot.entities["foo"].columns.should == [] 174 @ymldot.entities["hoge"].columns.should be_empty 175 end 176 end 171 it "#entity_dict['foo'].columnsは空の配列であること" do 172 @ymldot.entity_dict["foo"].columns.should == [] 173 @ymldot.entity_dict["hoge"].columns.should be_empty 174 end 175 end 176 177 describe Ymldot, "で読み込んだ.ymlにてカテゴリわけがしてがあった場合" do 178 before do 179 @ymldot = Ymldot.new("test_category.yml") 180 end 181 182 it "#category[1].labelはhogeであること" do 183 @ymldot.category[1].label.should == "hoge" 184 end 185 186 it "出力されるdotが正しいこと" do 187 @ymldot.dot_generate.should == <<'EOS' 188 digraph test_category { 189 graph[overlap=false, splines=true] 190 191 "bar" [shape=record, label="{bar|fooID(FK)\lbazID(FK)\lfuge\l}"] 192 "foo" [shape=record, label="{foo|hoge\l}"] 193 subgraph cluster1 { 194 label=hoge 195 "baf" [shape=record, label="{baf|bazID(FK)\lbuge\l}"] 196 "baz" [shape=record, label="{baz|gage\l}"] 197 } 198 199 "baz" -> "baf" [arrowtail=none arrowhead=dot headlabel="n" taillabel="1"] 200 "baz" -> "bar" [arrowtail=none arrowhead=dot headlabel="n" taillabel="1"] 201 "foo" -> "bar" [arrowtail=none arrowhead=dot headlabel="n" taillabel="1"] 202 203 } 204 EOS 205 end 206 end 207 208 describe Ymldot, "で読み込んだ.ymlにてカテゴリわけがしてあり、かつ、tableが定義されていない場合" do 209 before do 210 @ymldot = Ymldot.new("test_category_none_table.yml") 211 end 212 213 it "出力されるdotが正しいこと" do 214 @ymldot.dot_generate.should == <<'EOS' 215 digraph test_category_none_table { 216 graph[overlap=false, splines=true] 217 218 subgraph cluster0 { 219 label=hoge 220 "baf" [shape=record, label="{baf|buge\l}"] 221 "baz" [shape=record, label="{baz|gage\l}"] 222 } 223 224 225 } 226 EOS 227 end 228 end
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)