TableSet TableSet::schema( Connection * connection ) {
  TableSet s;
  RowSet rows = connection->select_all( "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;" );
  for( RowSet::iterator it = rows.begin(); it != rows.end(); ++it ) {
    string table = it->get_text( "name" );
    s[ table ]   = table_data( connection, table );
  }
  return s;
}
string Table::primary_key(Sqlite3Connection *connection,
    const string &table_name) {
  string row_query = "PRAGMA table_info(\"" + table_name + "\");";
  RowSet rows = connection->select_all(row_query);
  for(RowSet::iterator it = rows.begin(); it != rows.end(); ++it) {
    // cid | name | type    | notnull | dflt_value | pk
    //   0 |  bar | INTEGER |       0 |            |  0
    Type::Type t = it->get_type("pk");
    string tn = type_name[t];
    int is_pk = atoi(it->get_text("pk").c_str());
    if(is_pk != 0) {
      string name = it->get_text("name");
      return name;
    }
  }
  return "";
}
Table TableSet::table_data( Connection * connection,
                            const string &table_name ) {
  stringstream row_query;
  row_query << "PRAGMA table_info( \"" << table_name << "\" );";
  Table td( connection, table_name );
  RowSet rows = td.connection()->select_all( row_query.str() );
  for( RowSet::iterator it = rows.begin();
       it != rows.end();
       ++it ) {
    // cid | name | type    | notnull | dflt_value | pk
    //   0 |  bar | INTEGER |       0 |            |  0
    string name      = it->get_text( "name" );
    string type_name = it->get_text( "type" );
    ActiveRecord::Type type = ActiveRecord::to_type( type_name );
    if( type == ActiveRecord::unknown ) {
      stringstream error;
      error << "Unknown type: " << type_name;
      throw ActiveRecordException( error.str(), __FILE__, __LINE__ );
    }
    td.fields().push_back( Field( name, type ) );
  }
  return td;
}