SelectedCols.cc

00001 // File:  SelectedCols.cc
00002 
00003 // --8<--8<--8<--8<--
00004 //
00005 // Copyright (C) 2006 Smithsonian Astrophysical Observatory
00006 //
00007 // This file is part of rdbstats
00008 //
00009 // rdbstats is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 //
00014 // rdbstats is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the 
00021 //       Free Software Foundation, Inc. 
00022 //       51 Franklin Street, Fifth Floor
00023 //       Boston, MA  02110-1301, USA
00024 //
00025 // -->8-->8-->8-->8--
00026 
00027 #include <iterator>
00028 
00029 #include "SelectedCols.h"
00030 
00031 SelectedCols::SelectedCols( const vector< string >& cols, RDB& rdbtable,
00032                             clo::parser& clo ) throw( Exception ) {
00033 
00034 #ifdef TRACEFCT
00035   TraceFct tf( "SelectedCols( const vector< string >&, RDB&, "
00036                "clo::parser& ) throw( Exception )" );
00037 #endif
00038 
00039   try {
00040 
00041     const clo::options& options = clo.get_options();
00042 
00043     for ( int ii = 0; ii < cols.size( ); ii++ )
00044       if ( true == is_column_numeric( cols[ ii ], rdbtable, options ) )
00045         selected_cols.push_back( cols[ ii ] );
00046 
00047   } catch ( Exception& e ) {
00048 
00049     throw;
00050 
00051   }
00052 
00053 }
00054 
00055 SelectedCols::SelectedCols( RDB& rdbtable, clo::parser& clo ) 
00056  throw( Exception ) {
00057 
00058 #ifdef TRACEFCT
00059   TraceFct tf( "SelectedCols( RDB&, clo::parser& ) throw( Exception )" );
00060 #endif
00061 
00062   try {
00063 
00064     const clo::options& options = clo.get_options();
00065 
00066     // --group a -- group b
00067     vector< string > groupies;
00068     vector< string >::const_iterator current_group( options.group.begin( ) ),
00069       end_group( options.group.end( ) );
00070     for ( ; current_group != end_group; ++current_group ) {
00071       // --group a,b,c may have been entered, so must parse entry.
00072       suplib::tok( groupies, *current_group, "," );
00073     }
00074 
00075     //
00076     // Loop through all rdb column and select the numeric columns only.
00077     //
00078     size_t num = rdbtable.nColumns( );
00079 
00080     for ( size_t ii = 0; ii < num; ii++ ) {
00081 
00082       string name = rdbtable.getColumn( ii )->getName( );
00083 
00084       if ( true == is_column_numeric( name, rdbtable, options ) &&
00085            false == is_groupie( name, groupies ) )
00086         selected_cols.push_back( name );
00087 
00088     }
00089 
00090   } catch ( RDBErr& rdbe ) {
00091 
00092     throw Exception( rdbe );
00093 
00094   } catch ( Exception& e ) {
00095 
00096     throw;
00097 
00098   }
00099 
00100 }
00101 
00102 bool SelectedCols::is_column_numeric( const string& colname,
00103                                       RDB& rdbtable ) throw( Exception ) {
00104 
00105 #ifdef TRACEFCT
00106   TraceFct tf( "SelectedCols::is_column_numeric( const string&, "
00107                "RDB& ) throw( Exception )" );
00108 #endif
00109 
00110   try {
00111 
00112     RDBColumn::Type mytype = rdbtable.getColumn( colname )->getType( );
00113 
00114     if ( RDBColumn::NUMERIC == mytype )
00115       return true;
00116     else
00117       return false;
00118 
00119   } catch ( RDBErr& rdbe ) {
00120 
00121     throw Exception( rdbe );
00122 
00123   } catch ( Exception& e ) {
00124 
00125     throw;
00126 
00127   }
00128 
00129 }
00130 
00131 bool SelectedCols::is_column_numeric( const string& colname,
00132                                       RDB& rdbtable,
00133                                       const clo::options& options )
00134   throw ( Exception ) {
00135 
00136 #ifdef TRACEFCT
00137   TraceFct tf( "SelectedCols::is_column_numeric( const string&, "rr
00138                "RDB&, const clo::options& ) throw( Exception )" );
00139 #endif
00140 
00141   try {
00142 
00143     bool is_numeric( false );
00144 
00145     RDBColumn::Type mytype = rdbtable.getColumn( colname )->getType( );
00146 
00147     if ( RDBColumn::NUMERIC == mytype )
00148       is_numeric = true;
00149 
00150     vector< string >::const_iterator
00151       current_override( options.override.begin( ) ),
00152       end_override( options.override.end( ) );
00153 
00154     for ( ; current_override != end_override; ++current_override ) {
00155 
00156       string str( *current_override );
00157 
00158       //
00159       // The user has requested that a column is to change type.
00160       //
00161       vector< string > container;
00162 
00163       suplib::tok( container, str, "," );
00164 
00165       if ( 0 == colname.compare( container[ 0 ] ) ) {
00166 
00167         switch( container.size( ) ) {
00168 
00169         case 1:
00170 
00171           //
00172           // The definition is unspecified so set to
00173           // the opposite of the current definition.
00174           //
00175           toggle_column_definition( colname, rdbtable );
00176           return is_column_numeric( colname, rdbtable );
00177 
00178         case 2:
00179 
00180           //
00181           // Set the column definition to the user specified value.
00182           //
00183           rdbtable.getColumn( colname )->setDef( container[ 1 ] );
00184           return is_column_numeric( colname, rdbtable );
00185 
00186         default:
00187 
00188           throw Exception( "Too many options for column " + colname );
00189 
00190         }
00191 
00192       }
00193 
00194     }
00195 
00196     return is_numeric;
00197 
00198   } catch ( RDBErr& rdbe ) {
00199 
00200     throw Exception( rdbe );
00201       
00202   } catch ( Exception& e ) {
00203 
00204     throw;
00205 
00206   } 
00207 
00208 }
00209 
00210 bool SelectedCols::is_groupie( const string& name,
00211                                const vector<string>& groupies ) {
00212 
00213   vector< string >::const_iterator current_group( groupies.begin( ) ),
00214       end_group( groupies.end( ) );
00215   for ( ; current_group != end_group; ++current_group )
00216     if ( 0 == name.compare( *current_group ) )
00217       return true;
00218 
00219   return false;
00220 
00221 }
00222 
00223 void SelectedCols::print( ostream& os ) const {
00224 
00225 #ifdef TRACEFCT
00226   TraceFct tf( "SelectedCols::print( ostream& ) const " );
00227 #endif
00228 
00229   copy( selected_cols.begin( ), selected_cols.end( ),
00230         ostream_iterator< string >( os, " " ) );
00231 
00232 }
00233 
00234 void SelectedCols::toggle_column_definition( const string& colname,
00235                                              RDB& rdbtable )
00236   const throw ( Exception ) {
00237 
00238 #ifdef TRACEFCT
00239   TraceFct tf( "SelectedCols::toggle_column_definition( const string&, "
00240                "RDB& ) throw( Exception )" );
00241 #endif
00242 
00243   try {
00244 
00245     RDBColumn::Type mytype = rdbtable.getColumn( colname )->getType( );
00246     if ( RDBColumn::NUMERIC == mytype )
00247       rdbtable.getColumn( colname )->setDef( "S" );
00248     else
00249       rdbtable.getColumn( colname )->setDef( "N" );
00250 
00251   } catch ( RDBErr& rdbe ) {
00252 
00253     throw Exception( rdbe );
00254 
00255   }
00256 
00257 }
00258