00001
00002
00003
00004
00005
00006
00007
00008 #ifndef col_handling_rep_HPP
00009 #define col_handling_rep_HPP
00010
00011 #include "rep_base.hpp"
00012 #include "Report_Params_ui.h"
00013
00018 class formatHandler
00019 {
00020 public:
00021 string ftype;
00022
00023 formatHandler(string ftype):ftype(ftype){;}
00024 virtual string operator()( string in )
00025 {
00026 return in;
00027 }
00028 };
00029
00030 class formatString: public formatHandler
00031 {
00032 public:
00033 formatString():formatHandler("STRING"){;}
00034 virtual string operator()( string in )
00035 {
00036 return in;
00037 }
00038 };
00039
00040 class formatCurrency: public formatHandler
00041 {
00042 public:
00043 formatCurrency():formatHandler("CURRENCY"){;}
00044 virtual string operator()( string in )
00045 {
00046 money mon = atof( in.c_str() );
00047 return mon.format("%n");
00048 }
00049 };
00050 class formatDate: public formatHandler
00051 {
00052 public:
00053 formatDate():formatHandler("DATE"){;}
00054 virtual string operator()( string in )
00055 {
00056 time_date dt;
00057 dt.parse( in.c_str(), "%m-%d-%Y" );
00058
00059 if(!dt.is_good_parse()) dt.parse( in.c_str(), "%Y-%m-%d" );
00060 if(!dt.is_good_parse()) return in;
00061 return dt.format("%m/%d/%Y");
00062 }
00063 };
00064 class formatInteger: public formatHandler
00065 {
00066 public:
00067 formatInteger():formatHandler("INTEGER"){;}
00068 virtual string operator()( string in )
00069 {
00070 size_t sz = in.length()*2;
00071 char * dynStr = new char[sz];
00072 snprintf(dynStr,sz,"%i", atol(in.c_str()));
00073 in = dynStr;
00074 return in;
00075
00076 }
00077 };
00078
00079 class formatDecimal: public formatHandler
00080 {
00081 public:
00082 formatDecimal():formatHandler("DECIMAL"){;}
00083 virtual string operator()( string in )
00084 {
00085 size_t sz = 3+(in.length()*2);
00086 char * dynStr = new char[sz];
00087 snprintf(dynStr,sz,"%0.2f", atof(in.c_str()));
00088 in = dynStr;
00089 return in;
00090 }
00091 };
00092
00094 typedef map< int, class formatHandler* > formatMap;
00095
00102 class colHandler
00103 {
00104 protected:
00105
00106 int m_column;
00107 string m_name;
00108 rep_base & m_repBase;
00109 string m_Tuple_Section;
00110
00111 public:
00112
00113 colHandler( int column, string name, string tuple, rep_base & in):
00114 m_column(column),
00115 m_name(name),
00116 m_repBase(in),
00117 m_Tuple_Section(tuple)
00118 {
00119 ;
00120 }
00121
00122 virtual ~colHandler()
00123 {
00124 ;
00125 }
00126
00127 colHandler( colHandler & in):
00128 m_column(in.m_column),
00129 m_name(in.m_name),
00130 m_repBase(in.m_repBase),
00131 m_Tuple_Section(in.m_Tuple_Section)
00132 {
00133 ;
00134 }
00135
00136 virtual bool operator()( int ev )
00137 {
00138 return false;
00139 }
00140
00141
00142
00143 int column( void ) { return m_column; }
00144
00145 void column( const int in ) { m_column = in; }
00146
00147
00148 string & name( void ) { return m_name; }
00149
00150 void name( const string & in ) { m_name = in; }
00151
00152
00153 rep_base & repBase( void ) { return m_repBase; }
00154
00155
00156 string & Tuple_Section( void ) { return m_Tuple_Section; }
00157
00158 void Tuple_Section( const string & in ) { m_Tuple_Section = in; }
00159 };
00160
00162 typedef map< int, class colHandler* > colHandlerMap;
00163
00164
00172 class col_handling_rep: public rep_base
00173 {
00174
00175 ocString handlerSQL;
00176
00177 public:
00190 enum events { commence_event, prerow_event, field_event, postfield_event, postrow_event, complete_event };
00191
00192 colHandlerMap colHandlers;
00193 formatMap colFormats;
00194 int fieldCount;
00195 int Formatting_Modulus;
00196 int Items_Per_Page;
00197 bool doParamFilter;
00198
00199 col_handling_rep(ostream&sc):rep_base(sc),fieldCount(0),
00200 Formatting_Modulus(0),Items_Per_Page(0),doParamFilter(false)
00201 {
00202 }
00203
00204 string paramFilter( ocString sql, string tag, ocString rep )
00205 {
00206
00207
00208
00209
00210 if( rep.find("|") != string::npos )
00211 {
00212 string tok = rep.parse("|");
00213 int count = 0;
00214 while( tok.length() )
00215 {
00216 ocString tgUniq = tag + ":";
00217 tgUniq.append(++count);
00218
00219 sql = sql.replace(tgUniq,tok.c_str());
00220 tok = rep.parse("|");
00221 }
00222 }
00223 else
00224 {
00225 sql = sql.replaceAll(tag,rep);
00226 }
00227 return sql;
00228 }
00229
00230 string filter( string & sql )
00231 {
00232 string ret = sql;
00233 Session_Obj sess(false);
00234 ocString params = sess.GetData("rep_params");
00235 if( params.length() )
00236 {
00237 ocString tokPair = params.parse("`");
00238 while( tokPair.length() )
00239 {
00240 ocString tag = tokPair.parse("~");
00241 string rep = tokPair.parse("~");
00242 ret = paramFilter( ret, tag, rep );
00243 tokPair = params.parse("`");
00244 }
00245 }
00246 return ret;
00247 }
00248 bool getData( string sql )
00249 {
00250 if( doParamFilter )
00251 {
00252 sql = filter(sql);
00253 }
00254 webIO << "<!-- " << sql << " -->" << endl;
00255 return rep_base::getData(sql);
00256 }
00257
00258 void addColumnHandlers( long long Report_Id )
00259 {
00260 handlerSQL = "select Id, Report_Id, Col, Sort_Pos, Col_Handler, Direction, Format, "
00261 " Tuple_Section, spawnedReport, spawnedTuplePretext, spawnedTuplePosttext, spawningEvent "
00262 " from Report_Conditioning where Report_Id = ";
00263 handlerSQL.append( Report_Id );
00264 for( bool bopen = rs.open(handlerSQL); bopen; bopen=rs.next() )
00265 {
00266 addHandler();
00267 addFormat();
00268 }
00269 rs.close();
00270 }
00271
00272 void addFormat( void )
00273 {
00274 int col = dynamic_cast<longField&>(rs.getField(2)).get();
00275 string Col_Format = rs.getField(6).format();
00276 if(Col_Format=="CURRENCY")
00277 {
00278 colFormats.insert(make_pair(col, new formatCurrency));
00279 }
00280 else if(Col_Format=="DATE")
00281 {
00282 colFormats.insert(make_pair(col, new formatDate));
00283 }
00284 else if(Col_Format=="DECIMAL")
00285 {
00286 colFormats.insert(make_pair(col, new formatDecimal));
00287 }
00288 else if(Col_Format=="INTEGER")
00289 {
00290 colFormats.insert(make_pair(col, new formatInteger));
00291 }
00292 }
00293
00294 string formatField( int iField )
00295 {
00296 string val = rs.getField(iField).format();
00297 formatMap::iterator pos = colFormats.find(iField);
00298 if( pos != colFormats.end() )
00299 {
00300 val = (*(pos->second))(val);
00301 }
00302 return val;
00303 }
00304
00305
00306
00307
00308 string formatValue( int iField, string val )
00309 {
00310 formatMap::iterator pos = colFormats.find(iField);
00311 if( pos != colFormats.end() )
00312 {
00313 val = (*(pos->second))(val);
00314 }
00315 return val;
00316 }
00317
00318
00319 ocString fpart( string key, int iField, bool doReplace = true )
00320 {
00321 string id = key;
00322
00323 formatMap::iterator pos = colFormats.find(iField);
00324 if( pos != colFormats.end() )
00325 {
00326 formatHandler * pFmtHndlr = pos->second;
00327 if( ( pFmtHndlr->ftype == "CURRENCY" ||
00328 pFmtHndlr->ftype == "DECIMAL" ||
00329 pFmtHndlr->ftype == "INTEGER" ) &&
00330 doReplace )
00331 id += "_right";
00332 }
00333 return reportParts.getParagraph(id);
00334 }
00335 void addHandler( void );
00336
00337 void addHandler( colHandler * hndlr )
00338 {
00339 colHandlers.insert( make_pair( hndlr->column(), hndlr ) );
00340 }
00341
00342 virtual ~col_handling_rep()
00343 {
00344 colHandlerMap::iterator pos;
00345 for(pos=colHandlers.begin(); pos!=colHandlers.end(); ++pos)
00346 {
00347 delete pos->second;
00348 }
00349
00350 formatMap::iterator pos2;
00351 for(pos2=colFormats.begin(); pos2!=colFormats.end(); ++pos2)
00352 {
00353 delete pos2->second;
00354 }
00355 }
00356
00357
00358 virtual void sendField( int iField, ocString & td )
00359 {
00360 colHandlerMap::iterator pos = colHandlers.find(iField);
00361
00362 ocString ftd = fpart( "td", iField );
00363
00364 if( pos != colHandlers.end() )
00365 {
00366 if(pos->second->Tuple_Section().length() > 0)
00367 {
00368 ftd = fpart( pos->second->Tuple_Section().c_str(), iField, false );
00369 }
00370
00371 if( (*(pos->second))(field_event) ) return;
00372 }
00373
00374 ftd = ftd.replace( "$data$", formatField(iField).c_str() );
00375 ftd = ftd.replace( "$label$", rs.getField(iField).getName().c_str() );
00376 webIO << ftd;
00378 if( pos != colHandlers.end() ) (*(pos->second))(postfield_event);
00379 webIO.flush();
00380 }
00381 virtual string getHeadCell( int iField, ocString & th )
00382 {
00383 colHandlerMap::iterator pos = colHandlers.find(iField);
00384
00385 ocString lth = th;
00386
00387 if( pos != colHandlers.end() )
00388 {
00389 string sctName = pos->second->Tuple_Section();
00390 if(sctName.length() > 0)
00391 {
00392 string lkup = "lbl_" + sctName;
00393 string que = reportParts.getParagraph(lkup);
00394 if( que.length() )
00395 {
00396 lth = que;
00397 }
00398 }
00399 }
00400 return lth.replace( "$data$", rs.getField(iField).getName().c_str() );
00401 }
00402
00403
00404
00405
00406 virtual void derived_commence_event( void )
00407 {
00408 fieldCount = rs.getFieldCount();
00409 for( int i=0; i < fieldCount; ++i )
00410 {
00411 colHandlerMap::iterator pos = colHandlers.find(i);
00412 if( pos != colHandlers.end() )
00413 {
00414
00415 (*(pos->second))(commence_event);
00416 }
00417 }
00418 }
00419
00420
00421
00422
00423 virtual void derived_prerow_event( void )
00424 {
00425 if(Items_Per_Page)
00426 {
00427 if( more_data && row && row%Items_Per_Page == 0 )
00428 {
00429 webIO << part( "pagebreak" );
00430 }
00431 }
00432 webIO.flush();
00433
00434 for( int i=fieldCount-1; i>=0;--i )
00435 {
00436 colHandlerMap::iterator pos = colHandlers.find(i);
00437 if( pos != colHandlers.end() )
00438 {
00439
00440 (*(pos->second))(prerow_event);
00441 }
00442 }
00443 }
00444
00445
00446 virtual void derived_postrow_event( void )
00447 {
00448 webIO.flush();
00449 for( int i=0; i < fieldCount; ++i )
00450 {
00451 colHandlerMap::iterator pos = colHandlers.find(i);
00452 if( pos != colHandlers.end() )
00453 {
00454
00455 (*(pos->second))(postrow_event);
00456 }
00457 }
00458 }
00459
00460
00461 virtual void derived_complete_event( void )
00462 {
00463 webIO.flush();
00464 int skipped = 0;
00465 bool isRow = false;
00466 int i;
00467
00468
00469
00470 for( i=fieldCount-1; i>=0;--i )
00471 {
00472 colHandlerMap::iterator pos = colHandlers.find(i);
00473 if( pos != colHandlers.end() && pos->second->name() == "GROUP" )
00474 {
00475 (*(pos->second))(complete_event);
00476 }
00477 }
00478
00479 for( i=0; i < fieldCount; ++i )
00480 {
00481 colHandlerMap::iterator pos = colHandlers.find(i);
00482 if( pos != colHandlers.end() && (pos->second->name() == "SUM" || pos->second->name() == "AVG") )
00483 {
00484 if( !isRow )
00485 {
00486 webIO << part("tr") << part("ts").replace("$data$","Totals: ");
00487 isRow=true;
00488 skipped--;
00489 }
00490 if( skipped )
00491 {
00492 for(int j=0;j<skipped;j++)
00493 {
00494 webIO << part("ts").replace("$data$"," ");
00495 }
00496 skipped=0;
00497 }
00498
00499 if(!(*(pos->second))(complete_event))
00500 skipped++;
00501 }
00502 else
00503 {
00504 skipped++;
00505 }
00506 }
00507 for( i=0; i < skipped; i++ )
00508 {
00509 webIO << part("ts").replace("$data$"," ");
00510 }
00511 if( isRow ) webIO << part("end_tr");
00512 }
00513
00514 openRS & getRS()
00515 {
00516 return rs;
00517 }
00518
00519 friend class colHandler;
00520 };
00521
00536 class spawnHandler : public colHandler
00537 {
00538 private:
00539 string spawnedReport;
00540 string spawnedTuplePretext;
00541 string spawnedTuplePosttext;
00542 int spawningEvent;
00543 public:
00544 spawnHandler(int column, string name, string tuple, rep_base & in,
00545 string spawnedReport, string spawnedTuplePretext,
00546 string spawnedTuplePosttext, int spawningEvent)
00547 :colHandler(column,name,tuple,in)
00548 ,spawnedReport(spawnedReport)
00549 ,spawnedTuplePretext(spawnedTuplePretext)
00550 ,spawnedTuplePosttext(spawnedTuplePosttext)
00551 ,spawningEvent(spawningEvent)
00552 {
00553 }
00554 spawnHandler(spawnHandler & in):colHandler(in) {;}
00555 ~spawnHandler()
00556 {
00557 }
00558
00559 virtual bool operator()( int ev )
00560 {
00561 bool bEmission = false;
00562 col_handling_rep & dynRep = dynamic_cast<col_handling_rep&>(m_repBase);
00563 if( ev == spawningEvent )
00564 {
00565 Report_Obj report;
00566 report.key( atoll(spawnedReport.c_str()) );
00567 report.Id = report.key();
00568 if( report.get_data() )
00569 {
00570 string path = "reportTemplates/" + report.getTemplatePath();
00571 ocString sql = report.getCompositeQuery();
00572 columnTagFixup(sql,dynRep.getRS());
00573
00574
00575
00576 col_handling_rep rpt(dynRep.webIO);
00577 rpt.doParamFilter = Report_Parameters_form::hasParamValues;
00578 rpt.Formatting_Modulus = report.Formatting_Modulus;
00579 rpt. Items_Per_Page = report.Items_Per_Page;
00580 rpt.loadTemplates(path);
00581
00582 ocString top = rpt.part("top");
00583 columnTagFixup( top, dynRep.getRS() );
00584 rpt.reportParts.getParagraph("top") = top;
00585
00586 ocString pgbrk = rpt.part("pagebreak");
00587 if( pgbrk.length() )
00588 {
00589 columnTagFixup( pgbrk, dynRep.getRS() );
00590 rpt.reportParts.getParagraph("pagebreak") = pgbrk;
00591 }
00592 rpt.addColumnHandlers( report.Id );
00593
00594 if( rpt.getData(sql) )
00595 {
00596 ocString spawnedTuplePretext=this->spawnedTuplePretext;
00597 ocString spawnedTuplePosttext=this->spawnedTuplePosttext;
00598 columnTagFixup(spawnedTuplePretext,dynRep.getRS());
00599 m_repBase.webIO << spawnedTuplePretext;
00600 rpt.emitTop(report.Name);
00601 rpt.emitHeader();
00602 rpt.emitData();
00603 rpt.emitEnd();
00604 columnTagFixup(spawnedTuplePosttext,dynRep.getRS());
00605 dynRep.webIO << spawnedTuplePosttext;
00606 bEmission = true;
00607 }
00608 else
00609 {
00610 dynRep.webIO << "<!-- No data with " << sql << " -->" << endl;
00611 }
00612 }
00613 }
00614 return bEmission;
00615 }
00616 void columnTagFixup( ocString & tgt, openRS & rs )
00617 {
00618 for( int i =0; i < rs.getFieldCount(); i++ )
00619 {
00620 ocString repTag = "{{";
00621 repTag.append(i);
00622 repTag += "}}";
00623 tgt = tgt.replaceAll(repTag, rs.getField(i).format());
00624 }
00625 }
00626 };
00627 typedef map< string, string > lookups;
00628 typedef map< string, lookups > qryLookups;
00629
00630 class lookupHandler: public colHandler
00631 {
00632 public:
00633
00634 static qryLookups GotIt;
00635
00636 lookups lookup;
00637 string lookupSQL;
00638 lookupHandler( int column, string name, string tuple, rep_base & in, string & sql )
00639 :colHandler(column,name,tuple,in),lookupSQL(sql)
00640 {
00641 }
00642 ~lookupHandler(){;}
00643 lookupHandler(lookupHandler & in):colHandler(in) {;}
00644
00645
00646 virtual bool operator()( int ev )
00647 {
00648 bool bEmission = false;
00649 col_handling_rep & dynRep = dynamic_cast<col_handling_rep&>(m_repBase);
00650 switch( ev )
00651 {
00652 case col_handling_rep::commence_event:
00653 {
00654
00655 qryLookups::iterator findPos = GotIt.find(lookupSQL);
00656 if( findPos == GotIt.end() )
00657 {
00658 quickQuery qry;
00659 openRS & qrs = qry.getData ( lookupSQL );
00660 if( qry.opened )
00661 {
00662 do
00663 {
00664 lookup[qrs.getField(0).format()]=qrs.getField(1).format();
00665 }while(qrs.next());
00666 }
00667 }
00668 else
00669 {
00670 lookup = findPos->second;
00671 }
00672 break;
00673 }
00674 case col_handling_rep::field_event:
00675 {
00676 string id = dynRep.getRS().getField(m_column).format();
00677 string val = lookup[id];
00678 if( val.length() == 0 ) val = "REPORT LOOKUP FAIL:" + id;
00679 ocString tmplt = Tuple_Section();
00680 if(tmplt.length()) tmplt = m_repBase.part( tmplt );
00681 else tmplt = m_repBase.part("td");
00682 m_repBase.webIO << tmplt.replace("$data$",val.c_str() );
00683 bEmission = true;
00684 break;
00685 }
00686 }
00687 return bEmission;
00688 }
00689 };
00690 typedef map< string, double > group_sums;
00691 class sumHandler: public colHandler
00692 {
00693 private:
00694 double sum;
00695
00696
00697 int fieldType;
00698 public:
00699 string lastGroupName;
00700
00701 group_sums sums;
00702
00703 sumHandler( int column, string name, string tuple, rep_base & in )
00704 :colHandler(column,name,tuple,in),sum(0.0),fieldType(-1)
00705 {
00706 }
00707 ~sumHandler(){;}
00708 sumHandler(sumHandler & in):colHandler(in) {;}
00709
00710
00711 virtual bool operator()( int ev, string groupName )
00712 {
00713 bool bEmission = false;
00714 if( ev == col_handling_rep::prerow_event )
00715 {
00716 col_handling_rep & dynRep = dynamic_cast<col_handling_rep&>(m_repBase);
00717 double & val = sums[groupName];
00718 ocString Sum;
00719 Sum.append(val);
00720 Sum = dynRep.formatValue(m_column,Sum);
00721 m_repBase.webIO << m_repBase.part("ts").replace("$data$",Sum.c_str());
00722 val=0.0;
00723 bEmission=true;
00724 }
00725 return bEmission;
00726 }
00727
00728 virtual bool operator()( int ev )
00729 {
00730 bool bEmission = false;
00731 col_handling_rep & dynRep = dynamic_cast<col_handling_rep&>(m_repBase);
00732 switch( ev )
00733 {
00734 case col_handling_rep::commence_event:
00735 sum=0.0;
00736 break;
00737 case col_handling_rep::field_event:
00738 {
00739 double val = atof( dynRep.getRS().getField(m_column).format().c_str() );
00740 if( finite(val) )
00741 {
00742 sum += val;
00743 group_sums::iterator pos;
00744 for( pos=sums.begin(); pos!=sums.end();++pos)
00745 {
00746 pos->second += val;
00747 }
00748 }
00749 break;
00750 }
00751 case col_handling_rep::complete_event:
00752 ocString Sum;
00753 Sum.append(sum);
00754 Sum = dynRep.formatValue(m_column,Sum);
00755 m_repBase.webIO << m_repBase.part("ts").replace("$data$",Sum.c_str());
00756 bEmission=true;
00757 break;
00758 }
00759 return bEmission;
00760 }
00761 };
00762
00763 typedef map< string, int > group_counts;
00764 class avgHandler: public colHandler
00765 {
00766 private:
00767 double sum;
00768 int count;
00769
00770
00771 int fieldType;
00772 public:
00773 string lastGroupName;
00774
00775 group_sums sums;
00776 group_counts counts;
00777
00778 avgHandler( int column, string name, string tuple, rep_base & in )
00779 :colHandler(column,name,tuple,in),sum(0.0),fieldType(-1)
00780 {
00781 }
00782 ~avgHandler(){;}
00783 avgHandler(sumHandler & in):colHandler(in) {;}
00784
00785
00786 virtual bool operator()( int ev, string groupName )
00787 {
00788 bool bEmission = false;
00789 if( ev == col_handling_rep::prerow_event )
00790 {
00791
00792 col_handling_rep & dynRep = dynamic_cast<col_handling_rep&>(m_repBase);
00793 double & val = sums[groupName];
00794 int cnt = counts[groupName];
00795 ocString Sum;
00796 if( cnt )
00797 {
00798 Sum.append(val/cnt);
00799 }
00800 else
00801 {
00802 Sum.append(0);
00803 }
00804 Sum = dynRep.formatValue(m_column,Sum);
00805 m_repBase.webIO << m_repBase.part("ts").replace("$data$",Sum.c_str());
00806 val=0.0;
00807 counts[groupName] = 0;
00808 bEmission=true;
00809 }
00810 return bEmission;
00811 }
00812
00813 virtual bool operator()( int ev )
00814 {
00815 bool bEmission = false;
00816 col_handling_rep & dynRep = dynamic_cast<col_handling_rep&>(m_repBase);
00817 switch( ev )
00818 {
00819 case col_handling_rep::commence_event:
00820 sum=0.0;
00821 count=0;
00822 break;
00823 case col_handling_rep::field_event:
00824 {
00825 double val = atof( dynRep.getRS().getField(m_column).format().c_str() );
00826 if( finite(val) )
00827 {
00828 sum += val;
00829 count++;
00830 group_sums::iterator pos;
00831 for( pos=sums.begin(); pos!=sums.end();++pos)
00832 {
00833 pos->second += val;
00834 counts[pos->first]++;
00835 }
00836 }
00837 break;
00838 }
00839 case col_handling_rep::complete_event:
00840 ocString Sum;
00841 Sum.append(sum/count);
00842 Sum = dynRep.formatValue(m_column,Sum);
00843 m_repBase.webIO << m_repBase.part("ts").replace("$data$",Sum.c_str());
00844 bEmission=true;
00845 break;
00846 }
00847 return bEmission;
00848 }
00849 };
00850
00851 class groupHandler: public colHandler
00852 {
00853 private:
00854 string last_val;
00855 string colName;
00856 int counter;
00857 bool hasSums;
00858 public:
00859 groupHandler( int column, string name, string tuple, rep_base & in )
00860 :colHandler(column,name,tuple,in),counter(0),hasSums(false)
00861 {
00862 }
00863
00864 ~groupHandler(){;}
00865
00866 groupHandler(groupHandler & in):colHandler(in) {;}
00867
00868 bool commence( col_handling_rep & dynRep )
00869 {
00870 last_val="";
00871
00872 colHandlerMap & colHandlers = dynRep.colHandlers;
00873 openRS & rs = dynRep.getRS();
00874 int fieldCount = dynRep.fieldCount;
00875 colName = rs.getField(m_column).getName();
00876 for( int i=0; i < fieldCount; ++i )
00877 {
00878 colHandlerMap::iterator pos = colHandlers.find(i);
00879 if( pos != colHandlers.end() )
00880 {
00881
00882 if( pos->second->name() == "SUM" )
00883 {
00884 sumHandler & dyno = dynamic_cast<sumHandler &>(*(pos->second));
00885 dyno.sums.insert(make_pair(colName,0.0));
00886 dyno.lastGroupName = colName;
00887 hasSums = true;
00888 }
00889
00890 if( pos->second->name() == "AVG" )
00891 {
00892 avgHandler & dyno = dynamic_cast<avgHandler &>(*(pos->second));
00893 dyno.sums.insert(make_pair(colName,0.0));
00894 dyno.counts.insert(make_pair(colName,0));
00895 dyno.lastGroupName = colName;
00896 hasSums = true;
00897 }
00898 }
00899 }
00900 return false;
00901 }
00902
00903 bool pre( col_handling_rep & dynRep, bool atEnd=false )
00904 {
00905 preGroups(dynRep,atEnd);
00906
00907 if( counter && hasSums )
00908 {
00909 m_repBase.webIO << m_repBase.part("tr");
00910 for( int i=0; i < m_column; ++i )
00911 {
00912 m_repBase.webIO << m_repBase.part("ts").replace("$data$"," ");
00913 }
00914 string prompt = last_val;
00915 prompt += " Sub-totals:";
00916 m_repBase.webIO << m_repBase.part("end_tg").replace("$data$",prompt.c_str());
00917 preSums( dynRep );
00918 m_repBase.webIO << m_repBase.part("end_tr");
00919 counter=0;
00920 last_val="";
00921 }
00922 if(atEnd==false && m_column ==0)
00923 {
00924 m_repBase.emitHeader();
00925 }
00926 return true;
00927 }
00928
00929
00930 void preGroups(col_handling_rep & dynRep, bool atEnd=false )
00931 {
00932 int fieldCount = dynRep.fieldCount;
00933 int skipped = 0; int i;
00934 for( i=m_column+1; i < fieldCount; ++i )
00935 {
00936 colHandlerMap::iterator pos = dynRep.colHandlers.find(i);
00937 if( pos != dynRep.colHandlers.end() )
00938 {
00939
00940 if( pos->second->name() == "GROUP" )
00941 {
00942 groupHandler & dyno = dynamic_cast<groupHandler &>(*(pos->second));
00943 dyno.pre(dynRep,atEnd);
00944 return;
00945 }
00946 }
00947 }
00948 }
00949 void preSums(col_handling_rep & dynRep )
00950 {
00951
00952 int fieldCount = dynRep.fieldCount;
00953 int skipped = 0;
00954 int i;
00955 for( i=m_column+1; i < fieldCount; ++i )
00956 {
00957 colHandlerMap::iterator pos = dynRep.colHandlers.find(i);
00958 if( pos != dynRep.colHandlers.end() )
00959 {
00960
00961 if( pos->second->name() == "SUM" )
00962 {
00963 sumHandler & dyno = dynamic_cast<sumHandler &>(*(pos->second));
00964 if(!dyno(col_handling_rep::prerow_event,colName))
00965 {
00966 m_repBase.webIO << m_repBase.part("ts").replace("$data$"," ");
00967 }
00968 }
00969 else if( pos->second->name() == "AVG" )
00970 {
00971 avgHandler & dyno = dynamic_cast<avgHandler &>(*(pos->second));
00972 if(!dyno(col_handling_rep::prerow_event,colName))
00973 {
00974 m_repBase.webIO << m_repBase.part("ts").replace("$data$"," ");
00975 }
00976 }
00977 else
00978 {
00979 m_repBase.webIO << m_repBase.part("ts").replace("$data$"," ");
00980 }
00981 }
00982 else
00983 {
00984 m_repBase.webIO << m_repBase.part("ts").replace("$data$"," ");
00985 }
00986 }
00987
00988 }
00989 virtual bool operator()( int ev )
00990 {
00991 bool bEmission = false;
00992 string val;
00993 col_handling_rep & dynRep = dynamic_cast<col_handling_rep&>(m_repBase);
00994 openRS & rs = dynRep.getRS();
00995 if( rs.isOpen() )
00996 {
00997 val = rs.getField(m_column).format();
00998 }
00999 switch( ev )
01000 {
01001 case col_handling_rep::commence_event:
01002 commence(dynRep);
01003 break;
01004 case col_handling_rep::prerow_event:
01005 if( last_val.length() && val != last_val )
01006 {
01007 bEmission = pre(dynRep);
01008 }
01009 break;
01010
01011 case col_handling_rep::field_event:
01012 {
01013 ocString grpTuple;
01014 colHandlerMap::iterator pos = dynRep.colHandlers.find(m_column);
01015 if( pos != dynRep.colHandlers.end() && pos->second->Tuple_Section().length() > 0)
01016 {
01017 grpTuple = dynRep.part(pos->second->Tuple_Section());
01018 }
01019 counter++;
01020 if( val == last_val )
01021 {
01022
01023
01024 if( !grpTuple.length() )
01025 {
01026 m_repBase.webIO << m_repBase.part("tg").replace("$data$"," ");
01027 }
01028 }
01029 else
01030 {
01031 if( grpTuple.length() )
01032 {
01033 m_repBase.webIO << grpTuple.replace("$data$",val.c_str() );
01034 }
01035 else
01036 {
01037 m_repBase.webIO << m_repBase.part("tg").replace("$data$",val.c_str() );
01038 }
01039 }
01040 bEmission = true;
01041 break;
01042 }
01043 case col_handling_rep::postrow_event:
01044 if( val.length() && val != last_val )
01045 {
01046 last_val = val;
01047 }
01048 break;
01049 case col_handling_rep::complete_event:
01050 bEmission = pre(dynRep,true);
01051 break;
01052 }
01053 return bEmission;
01054 }
01055 };
01056
01057
01058
01059 void col_handling_rep::addHandler( void )
01060 {
01061 int col = dynamic_cast<longField&>(rs.getField(2)).get();
01062 string Col_Handler = rs.getField(4).format();
01063 string Tuple_Section = rs.getField(7).format();
01064 if( Col_Handler == "SUM" )
01065 {
01066 addHandler( new sumHandler ( col, Col_Handler, Tuple_Section, *this ) );
01067 }
01068 else if( Col_Handler == "GROUP" )
01069 {
01070 addHandler( new groupHandler ( col, Col_Handler, Tuple_Section, *this ) );
01071 }
01072 else if( Col_Handler == "AVG" )
01073 {
01074 addHandler( new avgHandler ( col, Col_Handler, Tuple_Section, *this ) );
01075 }
01076 else if( Col_Handler == "SPAWN" )
01077 {
01078 string spawnedReport, spawnedTuplePretext, spawnedTuplePosttext;
01079 int spawningEvent = 0;
01080 spawnedReport = rs.getField("spawnedReport").format();
01081 spawnedTuplePretext = rs.getField("spawnedTuplePretext").format();
01082 spawnedTuplePosttext = rs.getField("spawnedTuplePosttext").format();
01083 string strSpawningEvent = rs.getField("spawningEvent").format();
01084 if( strSpawningEvent.length() ) spawningEvent = atoi(strSpawningEvent.c_str());
01085 addHandler( new spawnHandler( col, Col_Handler, Tuple_Section, *this,
01086 spawnedReport, spawnedTuplePretext, spawnedTuplePosttext, spawningEvent ) );
01087 }
01088 else if( Col_Handler == "LOOKUP" )
01089 {
01090 string spawnedTuplePretext;
01091 spawnedTuplePretext = rs.getField("spawnedTuplePretext").format();
01092 addHandler( new lookupHandler( col, Col_Handler, Tuple_Section, *this,
01093 spawnedTuplePretext ) );
01094 }
01095 else
01096 {
01097 addHandler( new colHandler ( col, Col_Handler, Tuple_Section, *this ) );
01098 }
01099 }
01100
01101
01102
01103
01104
01105
01106 #ifndef COL_HANDLING_REP_IMPL_SUPPRESS
01107 qryLookups lookupHandler::GotIt;
01108 #endif
01109
01110 #endif