表のツリーを書く

まともに動くかな?


追記
一応、動いた。管理者で動かしたら、動かないかも…


#!/usr/bin/env ruby
require "dbi"

class Table
attr_reader :name, :parent, :children

def initialize(name=nil)
@name = name
@children =
end

def set_parent(parent)
@parent = parent
parent.add_child(self)
end

def add_child(child)
@children << child
end

def to_s(tabs=, branch="", strbuf="")
put_row(@name, tabs, branch, strbuf)
@children.each_with_index {|child, i|
last = (i+1 >= @children.size)
tabs.push(last ? " " : "│")
branch = last ? "└" : "├"
child.to_s(tabs, branch, strbuf)
tabs.pop
}
return strbuf
end

private
def put_row(name, tabs, branch, strbuf)
head = tabs.clone
head.pop unless head.empty?
head << branch
strbuf << head.join + name + "\n"
end
end

class FKTree
def initialize
@root = Table.new("/")
@tables = {"/"=>@root}
end

def add(r_table, table)
parent = r_table ? get_table(r_table) : @root
child = get_table(table)
parent.add_child(child)
end

def to_s
return @root.to_s
end

private
def get_table(name)
return @tables[name] if @tables.has_key?(name)
table = Table.new(name)
@tables[name] = table
return table
end
end

sql =<<EOS
SELECT A.TABLE_NAME, C.TABLE_NAME R_TABLE_NAME
FROM USER_TABLES A, USER_CONSTRAINTS B, USER_CONSTRAINTS C
WHERE A.TABLE_NAME = B.TABLE_NAME(+)
AND B.CONSTRAINT_TYPE(+) ='R'
AND B.R_CONSTRAINT_NAME = C.CONSTRAINT_NAME(+)
EOS

fktree = FKTree.new

DBI.connect("DBI:OCI8:oracle", "scott", "tiger") {|dbh|
dbh.select_all(sql) {|row|
fktree.add(row["R_TABLE_NAME"], row["TABLE_NAME"])
}
}

puts fktree