Changeset 19133 for lang/ruby

Show
Ignore:
Timestamp:
09/10/08 20:34:22 (2 months ago)
Author:
authorNari
Message:

imprement category describe function, add test.

Location:
lang/ruby/ymldot
Files:
2 added
4 modified

Legend:

Unmodified
Added
Removed
  • lang/ruby/ymldot/README

    r19115 r19133  
    2727    enumerate column names 
    2828  * foreginkeys 
    29     * belongs_to 
    3029    * has_many 
    3130    * has_one 
     
    3332      same meaning the relation of ActiveRecord. 
    3433      enumerate ref table name. 
     34* category 
     35   * label 
     36     category name set. and set frame. 
     37   * table 
     38     nested table. 
    3539 
    3640== Sample 
  • lang/ruby/ymldot/bin/ymldot

    r19117 r19133  
    11#!/usr/bin/ruby -wKU 
     2$: << File.join(File.dirname(__FILE__), "../lib") 
    23 
    3 require 'lib/ymldot' 
     4require 'ymldot' 
    45require 'optparse' 
    56 
  • lang/ruby/ymldot/lib/ymldot.rb

    r19118 r19133  
    2525end 
    2626 
     27class 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 
     55end 
     56 
    2757 
    2858class Ymldot 
     
    3565    end 
    3666    @file_name = $1 if filepath[/(\w+).yml\z/] 
    37     @entities = {} 
     67    @entity_dict = {} 
     68    @category = [] 
    3869    @one_relations = [] 
    3970    @many_relations = [] 
    40     eval 
     71    eval_yml 
    4172  end 
    4273 
     
    4677digraph #{@file_name} { 
    4778#{add_2_tab(config_to_dot)} 
    48 #{add_2_tab(entities_to_dot)} 
     79#{add_2_tab(entity_dict_to_dot)} 
    4980#{add_2_tab(relations_to_dot)} 
    5081} 
     
    6697  end 
    6798 
    68   def entities_to_dot 
     99  def entity_dict_to_dot 
    69100    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 
    73112    res 
    74113  end 
     
    85124  end 
    86125 
    87   def eval 
     126  def eval_yml 
    88127    @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) } } 
    96132  end 
    97133 
     
    99135    foreignkeys = table["foreignkeys"] 
    100136    tname = table["name"] 
    101     eval_relation_belongs_to(foreignkeys["belongs_to"], tname) if foreignkeys["belongs_to"] 
     137    return unless foreignkeys 
    102138    eval_relation_has_many(foreignkeys["has_many"], tname) if foreignkeys["has_many"] 
    103139    eval_relation_has_one(foreignkeys["has_one"], tname) if foreignkeys["has_one"] 
     
    105141  end 
    106142 
    107   def eval_relation_belongs_to(keys, tname) 
    108     keys.each do |rel| 
    109       @entities[tname].foreignkeys << "#{rel}ID(FK)" 
    110     end 
    111   end 
    112  
    113143  def eval_relation_has_many(keys, tname) 
    114144    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]} 
    116147    end 
    117148  end 
     
    119150  def eval_relation_has_one(keys, tname) 
    120151    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]} 
    122154    end 
    123155  end 
     
    126158    keys.each do |rel| 
    127159      join_tname = "#{rel}_#{tname}" 
    128       return if @entities.has_key? join_tname 
     160      return if @entity_dict.has_key? join_tname 
    129161      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]} 
    135174    end 
    136175  end 
  • lang/ruby/ymldot/spec/ymldot_spec.rb

    r19118 r19133  
    33 
    44class Ymldot 
    5   attr_accessor :node, :entities, :one_relations, :many_relations, :file_name, :config 
     5  attr_accessor :node, :entity_dict, :one_relations, :many_relations, :file_name, :config, :category 
    66end 
    77 
     
    2727  end 
    2828 
    29   it "#entities には正しいEntityクラスが格納されていること" do 
    30     @ymldot.entities["foo"].name.should == "foo" 
    31     @ymldot.entities["foo"].dependent?.should be_true 
    32     @ymldot.entities["foo"].columns.should == ["password", "group_id"] 
    33     @ymldot.entities["foo"].foreignkeys.should == ["hogeID(FK)"] 
    34     @ymldot.entities["hoge"].name.should == "hoge" 
    35     @ymldot.entities["hoge"].dependent?.should be_false 
    36     @ymldot.entities["hoge"].columns.should == ["password", "group_id"] 
    37     @ymldot.entities["hoge"].foreignkeys.should be_empty 
     29  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 
    3838  end 
    3939 
     
    6969  end 
    7070 
    71   it "#entities には正しいEntityクラスが格納されていること" do 
    72     @ymldot.entities["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)"] 
    7373  end 
    7474 
     
    8888  node [fontname="MSUIGOTHIC.ttf"] 
    8989  "one1" [shape=Mrecord, label="{one1|password\lgroup_id\l}"] 
    90   "one1_one2" [shape=Mrecord, label="{one1_one2|one1ID(FK)\lone2ID(FK)\l}"] 
    9190  "one2" [shape=record, label="{one2|password\lgroup_id\l}"] 
     91  "one1_one2" [shape=record, label="{one1_one2|one1ID(FK)\lone2ID(FK)\l}"] 
    9292 
    9393  "one1" -> "one1_one2" [arrowtail=none arrowhead=dot headlabel="n" taillabel="1"] 
     
    104104  end 
    105105 
    106   it "#entities には正しいEntityクラスが格納されていること" do 
    107     @ymldot.entities["one1"].foreignkeys.should == ["one2ID(FK)"] 
     106  it "#entity_dict には正しいEntityクラスが格納されていること" do 
     107    @ymldot.entity_dict["one1"].foreignkeys.should == ["one2ID(FK)"] 
    108108  end 
    109109 
     
    129129  end 
    130130 
    131   it "#entities には正しいEntityクラスが格納されていること" do 
    132     @ymldot.entities["コンテンツ_カテゴリ"].foreignkeys.should == ["コンテンツID(FK)", "カテゴリID(FK)"] 
     131  it "#entity_dict には正しいEntityクラスが格納されていること" do 
     132    @ymldot.entity_dict["コンテンツ_カテゴリ"].foreignkeys.should == ["コンテンツID(FK)", "カテゴリID(FK)"] 
    133133  end 
    134134 
     
    159159  end 
    160160 
    161   it "#entities の'baf'には'bar'へのforeginkeyがあること" do 
    162      @ymldot.entities["baf"].foreignkeys[0].should == "barID(FK)" 
     161  it "#entity_dict の'baf'には'bar'へのforeginkeyがあること" do 
     162     @ymldot.entity_dict["baf"].foreignkeys[0].should == "barID(FK)" 
    163163  end 
    164164end 
     
    169169  end 
    170170 
    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 
     175end 
     176 
     177describe 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' 
     188digraph 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} 
     204EOS 
     205  end 
     206end 
     207 
     208describe 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' 
     215digraph 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} 
     226EOS 
     227  end 
     228end