00001 #ifndef LIST_BASE_HPP
00002 #define LIST_BASE_HPP
00003
00004 #include <iostream>
00005 #include <iomanip>
00006 #include "ocTypes.h"
00007 #include "ocString.h"
00008 #include "read_base.hpp"
00009 #include "cgiClass.h"
00010 #include "cgiTemplates.h"
00011 #include "Session.hpp"
00012
00013 #define DEBUGOUT
00014
00015 class list_base: public read_base
00016 {
00017 protected:
00018 cgiTemplates listTemplate;
00019 cgiScript & webIO;
00020 ocString td;
00022 Session_Obj & session;
00024 string sessionName;
00025 public:
00026 bool opened;
00028 ocString editLink;
00030 int hotCol;
00032 int skipCol;
00034 string addedCriteria;
00035
00036
00037
00038 string cookiePrefix;
00039 string filter, sort, direction;
00040 int listPg, itemsPerPg, recCount, colCount, pgCount, dsetCount;
00041
00042
00043 void setPage( cgiInput & args )
00044 {
00045 listPg = atol(session.GetData(sessionName+"lPg").c_str());
00046 if (args.count("Pg") )
00047 {
00048 listPg = (atol(args["Pg"].c_str())-1);
00049 }
00050 else if(args.count("navigate") )
00051 {
00052 if( args["navigate"] == "prev" ) listPg--;
00053 if( args["navigate"] == "next" ) listPg++;
00054 }
00055 if( listPg < 0 ) listPg = 0;
00056
00057 }
00058 string limitClause( void )
00059 {
00060 ocString limit;
00061 int rowStart = listPg * itemsPerPg;
00062 limit = " limit ";
00063 if( db.getProvider() == MySQL )
00064 {
00065 limit.append(rowStart);
00066 limit += ", ";
00067 limit.append(itemsPerPg);
00068 }
00069 else if( db.getProvider() == PostGresQL )
00070 {
00071 limit.append(itemsPerPg);
00072 limit += " offset ";
00073 limit.append(rowStart);
00074 }
00075 return limit;
00076 }
00077 void setSort( cgiInput & args )
00078 {
00079 direction = session.GetData(sessionName+"lDir");
00080 sort = session.GetData(sessionName+"lSort");
00081
00082 if (args.count("sort") )
00083 {
00084 if( sort == args["sort"].c_str() )
00085 {
00086
00087 direction = direction=="desc"?"asc":"desc";
00088 session.SetData(sessionName+"lDir",direction.c_str());
00089 }
00090 sort = args["sort"].c_str();
00091 session.SetData(sessionName+"lSort",sort.c_str());
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100 void reset( cgiInput & args )
00101 {
00102 if( args.count("init") )
00103 reset();
00104 }
00105 void reset( void )
00106 {
00107
00108 session.SetData(sessionName+"lFilter","");
00109 session.SetData(sessionName+"lDir","");
00110 session.SetData(sessionName+"lSort","");
00111 session.SetData(sessionName+"lPg","");
00112 }
00113
00114
00115
00116
00117
00118
00119
00120 void setFilter( cgiInput & args )
00121 {
00122 if( webIO.RequestMethod().upper() == "GET" )
00123 {
00124 filter = session.GetData(sessionName+"lFilter");
00125 }
00126 if( args.count("filter") )
00127 {
00128 filter = args["filter"].c_str();
00129 session.SetData(sessionName+"lFilter",filter.c_str());
00130 }
00131 else if( sessionName.length() > 0 )
00132 {
00133 filter = session.GetData(sessionName+"lFilter");
00134 }
00135 }
00136
00137
00138
00139
00140 list_base(cgiScript&sc,Session_Obj & session,string sessionName=""):read_base(),webIO(sc),opened(false),hotCol(0),skipCol(-1)
00141 ,listPg(0), itemsPerPg(20), recCount(0), colCount(0)
00142 ,pgCount(0), dsetCount(0),session(session),sessionName(sessionName)
00143 {
00144 cgiInput & args = sc.ClientArguments();
00145 reset( args );
00146
00147 setSort( args );
00148
00149 setFilter( args );
00150
00151 setPage( args );
00152
00153 }
00154
00155 virtual ~list_base()
00156 {
00157 session.Synch();
00158 }
00159
00160
00161 bool loadListTemplates( string path )
00162 {
00163 return listTemplate.load(path.c_str());
00164 }
00165
00166 list_base & copyListTemplates( const cgiTemplates & in )
00167 {
00168 listTemplate = in;
00169 return * this;
00170 }
00171
00172 bool getData( string sql )
00173 {
00174 opened = rs.open(sql);
00175 if( opened ) recCount = rs.getRecordCount();
00176 return opened;
00177 }
00178
00179 string whereClause( ocString & filterTemplate )
00180 {
00181 string sql = "";
00182 if( filter.length() )
00183 {
00184 ocString filterParts = filter;
00185 filterParts = filterParts.replaceAll("|", "");
00186 if( filterParts.length() )
00187 {
00188 filterParts = filter;
00189 filterTemplate.parseInit();
00190 ocString filterParts = filter;
00191 string filterPart = filterParts.parse("|");
00192 ocString filterTemp = filterTemplate.parse("|");
00193 do
00194 {
00195 bool valSet = filterPart.length() > 0;
00196 if( valSet )
00197 {
00198 sql += ( sql.length() ) ? " and " : " where ";
00199 sql += filterTemp.replace("$filter$", filterPart.c_str() );
00200 }
00201 filterTemp = filterTemplate.parse("|");
00202 filterPart = filterParts.parse("|");
00203
00204 } while( !(filterTemplate.endOfParse() && filterTemp.length()==0) );
00205 }
00206 }
00207 if( addedCriteria.length() )
00208 {
00209 sql += ( sql.length() ) ? " and " : " where ";
00210 sql += addedCriteria;
00211 }
00212 return sql;
00213 }
00214
00215 void maxPageFixup( void )
00216 {
00217 pgCount = (recCount/itemsPerPg)+1;
00218 if( listPg >= pgCount ) listPg = pgCount-1;
00219 ocString Pg;
00220 Pg.append(listPg);
00221 session.SetData(sessionName+"lPg",Pg.c_str());
00222 }
00223 bool getFilteredData( string rows,
00224 string table,
00225 ocString filterTemplate,
00226 string defaultSort = "",
00227 string groupBy = "",
00228 string countTable = "" )
00229 {
00230 string sql = "select count(*) from ";
00231 sql += countTable.length()?countTable:table;
00232 sql += whereClause( filterTemplate );
00233 #ifdef DEBUGOUT
00234 webIO << "<!--" << sql << "-->";
00235 #endif
00236 opened = rs.open(sql);
00237 if( opened )
00238 {
00239 recCount = atol(rs.getField(0).format().c_str());
00240 maxPageFixup();
00241 rs.close();
00242 }
00243 sql = "select ";
00244 sql += rows;
00245 sql += " from ";
00246 sql += table;
00247 sql += whereClause( filterTemplate );
00248 if( groupBy.length() )
00249 {
00250 sql += " group by ";
00251 sql += groupBy;
00252 }
00253 if( sort.length() )
00254 {
00255 sql += " order by ";
00256 sql += sort;
00257 sql += " ";
00258 sql += direction;
00259 }
00260 else if ( defaultSort.length() )
00261 {
00262 sql += " order by ";
00263 sql += defaultSort;
00264 }
00265 sql += limitClause();
00266 #ifdef DEBUGOUT
00267 webIO << "<!--" << sql << "-->";
00268 #endif
00269 opened = rs.open(sql);
00270 if( opened )
00271 {
00272 dsetCount = rs.getRecordCount();
00273 }
00274 return opened;
00275 }
00276 list_base & emitFilter( string program, string label )
00277 {
00278 string value;
00279 if( webIO.ClientArguments().count("filter") )
00280 {
00281 value = webIO.ClientArguments()["filter"].c_str();
00282 }
00283 ocString filterform = listTemplate.getParagraph("list_filter");
00284 if( program.find("?") != string::npos )
00285 {
00286 filterform = filterform.replace("?","&");
00287 }
00288 webIO << filterform.replaceAll( "$location", program.c_str())
00289 .replaceAll("$label",label.c_str())
00290 .replace("$value", value.c_str() );
00291 }
00292 string filtersValue( int idx )
00293 {
00294 string val;
00295 if( webIO.ClientArguments().count("filter") )
00296 {
00297 ocString values = webIO.ClientArguments()["filter"].c_str();
00298 for( int i = 0;
00299 (i <= idx) && ! (values.endOfParse() && values.length()==0);
00300 i++ )
00301 {
00302 val = values.parse("|");
00303 }
00304 }
00305 return val;
00306 }
00307 list_base & emitFilters( string program, ocString labels )
00308 {
00309 ocString values = this->filter;
00310 ocString fstart = listTemplate.getParagraph("multi_filter_start");
00311 ocString fitem = listTemplate.getParagraph("multi_filter_item");
00312 ocString fend = listTemplate.getParagraph("multi_filter_end");
00313
00314 if( program.find("?") != string::npos )
00315 {
00316 fstart = fstart.replace("?","&");
00317 }
00318 webIO << fstart.replaceAll( "$location", program.c_str());
00319 ocString label = labels.parse("|");
00320 ocString nlabel = label.parse("::");
00321 string typeSection = label.parse("::");
00322 string value = values.parse("|");
00323 do
00324 {
00325 if(typeSection.length())
00326 {
00327 ocString fAltItem = listTemplate.getParagraph(typeSection);
00328 if( fAltItem.length() )
00329 webIO << fAltItem.replaceAll("$label",nlabel.c_str()).replace("$value", value.c_str() );
00330 else
00331 webIO << "<!-- NO [" << typeSection << "] found -->" ;
00332 }
00333 else
00334 {
00335 webIO << fitem.replaceAll("$label",label.c_str()).replace("$value", value.c_str() );
00336 }
00337 value = values.parse("|");
00338 label = labels.parse("|");
00339 nlabel = label.parse("::");
00340 typeSection = label.parse("::");
00341 } while ( ! (labels.endOfParse() && label.length()==0) );
00342 webIO << fend.replaceAll( "$location", program.c_str());
00343 }
00344
00345 list_base & emitHeadings( string pipedelimited )
00346 {
00347 ocString headings(pipedelimited);
00348 string list_begin = listTemplate.getParagraph("list_begin");
00349 string tr = listTemplate.getParagraph("tr");
00350 ocString th = listTemplate.getParagraph("th");
00351 string end_tr = listTemplate.getParagraph("end_tr");
00352 webIO << list_begin << tr;
00353 while( ! headings.endOfParse() )
00354 {
00355 colCount++;
00356 string heading = headings.parse("|");
00357 webIO << th.replace( "$data$", heading.c_str() );
00358 }
00359 webIO << end_tr;
00360 return * this;
00361 }
00362 list_base & emitNavigation( string program )
00363 {
00364 ocString numcols, curPage, numPages,datasetCount,recordCount;
00365 numcols.append(colCount);
00366 curPage.append(listPg+1);
00367 numPages.append(pgCount);
00368 datasetCount.append(dsetCount);
00369 recordCount.append(recCount);
00370
00371 ocString nav = listTemplate.getParagraph("list_nav");
00372 nav = nav.replaceAll("$cols",numcols.c_str())
00373 .replaceAll("$location",program.c_str())
00374 .replace("$Page",curPage.c_str())
00375 .replace("$total$",numPages.c_str())
00376 .replace("$dsetCount", datasetCount.c_str())
00377 .replace("$recCount", recordCount.c_str());
00378 webIO << nav;
00379 return * this;
00380 }
00381
00382 list_base & emitEnd( void )
00383 {
00384 ocString list_end = listTemplate.getParagraph("list_end");
00385 ocString lPg;
00386 lPg.append(listPg);
00387 webIO << list_end.replace("$lpg",lPg.c_str());
00388 return * this;
00389 }
00390
00391 void setColFormat( string fmt, int pos )
00392 {
00393 if( pos < rs.getFieldCount() )
00394 {
00395 rs.getField(pos).setFormatMask(fmt);
00396 }
00397 }
00398
00399 list_base & emitData( void )
00400 {
00401 bool more_data = opened;
00402 string tr = listTemplate.getParagraph("tr");
00403 td = listTemplate.getParagraph("td");
00404 string end_tr = listTemplate.getParagraph("end_tr");
00405 int fieldCount;
00406 if( opened ) fieldCount = rs.getFieldCount();
00407 derived_commence_event();
00408 while( more_data )
00409 {
00410 if( derived_predata_event() )
00411 {
00412 webIO << tr;
00413 for( int i=0; i < fieldCount; ++i )
00414 {
00415 if( i != skipCol )
00416 {
00417 if( i == hotCol || hotCol == -2 )
00418 {
00419 sendHotField(i, td );
00420 }
00421 else
00422 {
00423 sendField(i, td );
00424 }
00425 }
00426 }
00427 webIO << end_tr;
00428 }
00429 derived_data_event();
00430 more_data = rs.next();
00431 }
00432 dsetCount = rs.getRecordCount();
00433 derived_complete_event();
00434 return * this;
00435 }
00436
00437
00438 virtual void sendField( int iField, ocString & td )
00439 {
00440 webIO << td.replace( "$data$", rs.getField(iField).format().c_str() );
00441 }
00442
00443
00444 virtual void sendHotField( int iField, ocString & td )
00445 {
00446 webIO << td.replace( "$data$",
00447 editLink.replaceAll( "$key$",rs.getField(0).format().c_str())
00448 .replaceAll( "$col$",rs.getField(iField).format().c_str()).c_str());
00449 }
00450
00451
00452
00453 virtual void derived_commence_event( void ){;}
00454 virtual bool derived_predata_event( void ){ return true; }
00455 virtual void derived_data_event( void ){;}
00456 virtual void derived_complete_event( void ){;}
00457 };
00458
00459 #endif