<s> import re <EOL> import sqlite3 <EOL> import sys <EOL> from os . path import abspath , basename , dirname , join , splitext <EOL> try : <EOL> import pydot <EOL> except ImportError : <EOL> print '''<STR_LIT>''' <EOL> DOT_DEFAULTS = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT:true>' , <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> GRAPH_DEFAULTS = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> NODE_DEFAULTS = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> EDGE_DEFAULTS = { <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> def print_usage ( ) : <EOL> print '''<STR_LIT>''' <EOL> def get_indeces ( string ) : <EOL> paren_index = string . find ( '<STR_LIT:(>' ) <EOL> return ( string . rfind ( '<STR_LIT:U+002C>' , <NUM_LIT:0> , paren_index ) + <NUM_LIT:2> , <EOL> string . find ( '<STR_LIT:)>' , paren_index , len ( string ) ) + <NUM_LIT:1> ) <EOL> def handle_constraint_fields ( string , fields ) : <EOL> if '<STR_LIT:(>' in string : <EOL> start_index , end_index = get_indeces ( string ) <EOL> fields . append ( string [ start_index : end_index ] ) <EOL> string = string [ <NUM_LIT:0> : start_index ] + string [ end_index : ] <EOL> string , fields = handle_constraint_fields ( string , fields ) <EOL> return string , fields <EOL> def split_foreign_keys_and_rest ( string ) : <EOL> fks = [ ] <EOL> string , fields = handle_constraint_fields ( string , [ ] ) <EOL> for token in string . split ( '<STR_LIT:U+002CU+0020>' ) : <EOL> if not token : <EOL> continue <EOL> if token . find ( '<STR_LIT>' ) == - <NUM_LIT:1> : <EOL> l = fields <EOL> else : <EOL> l = fks <EOL> l . append ( token ) <EOL> return { '<STR_LIT>' : fields , '<STR_LIT>' : fks } <EOL> def get_schema ( db_file ) : <EOL> with sqlite3 . connect ( db_file ) as conn : <EOL> c = conn . cursor ( ) <EOL> return [ row [ <NUM_LIT:0> ] for row in c . execute ( "<STR_LIT>" ) ] <EOL> def organize_rows ( sql_lines ) : <EOL> data = { } <EOL> for line in sql_lines : <EOL> if line . startswith ( '<STR_LIT>' ) : <EOL> m = re . match ( '<STR_LIT>' , line ) <EOL> if m : <EOL> data [ m . group ( <NUM_LIT:1> ) ] = split_foreign_keys_and_rest ( m . group ( <NUM_LIT:2> ) ) <EOL> return data <EOL> def populate_nodes_and_clusters ( data , graph ) : <EOL> for table_name , value in data . iteritems ( ) : <EOL> node = pydot . Node ( '<STR_LIT:\n>' . join ( value [ '<STR_LIT>' ] ) ) <EOL> cluster = pydot . Cluster ( table_name , label = table_name ) <EOL> cluster . add_node ( node ) <EOL> graph . add_subgraph ( cluster ) <EOL> data [ table_name ] [ '<STR_LIT>' ] = node <EOL> data [ table_name ] [ '<STR_LIT>' ] = cluster <EOL> def populate_edges ( data , graph ) : <EOL> for table_data in data . itervalues ( ) : <EOL> for fk in table_data [ '<STR_LIT>' ] : <EOL> target = fk . split ( '<STR_LIT>' ) [ <NUM_LIT:1> ] <EOL> target_name = fk . split ( ) [ <NUM_LIT:0> ] <EOL> graph . add_edge ( pydot . Edge ( table_data [ '<STR_LIT>' ] , <EOL> data [ target ] [ '<STR_LIT>' ] , <EOL> label = target_name , <EOL> ltail = table_data [ '<STR_LIT>' ] . get_name ( ) , <EOL> lhead = data [ target ] [ '<STR_LIT>' ] . get_name ( ) ) ) <EOL> def create_graph ( data ) : <EOL> graph = pydot . Dot ( ** DOT_DEFAULTS ) <EOL> graph . set_graph_defaults ( ** GRAPH_DEFAULTS ) <EOL> graph . set_node_defaults ( ** NODE_DEFAULTS ) <EOL> graph . set_edge_defaults ( ** EDGE_DEFAULTS ) <EOL> populate_nodes_and_clusters ( data , graph ) <EOL> populate_edges ( data , graph ) <EOL> return graph <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> if len ( sys . argv ) < <NUM_LIT:2> : <EOL> print_usage ( ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> file_name = sys . argv [ <NUM_LIT:1> ] <EOL> data = organize_rows ( get_schema ( file_name ) ) <EOL> file_name = splitext ( basename ( file_name ) ) [ <NUM_LIT:0> ] <EOL> graph = create_graph ( data ) <EOL> graph . write_png ( '<STR_LIT>' % file_name ) <EOL> print '<STR_LIT>' </s>
