/*
      _______                          .__ .__   .__   .__                 
      \      \    ____   __ __ _______ |__||  |  |  |  |__|  ____    ____  
      /   |   \ _/ __ \ |  |  \\_  __ \|  ||  |  |  |  |  | /  _ \  /    \ 
     /    |    \\  ___/ |  |  / |  | \/|  ||  |__|  |__|  |(  <_> )|   |  \
     \____|__  / \___  >|____/  |__|   |__||____/|____/|__| \____/ |___|  /
    =========\/======\/=================================================\/==
  v0.01 04/JUL/2007 © Copyright 2007-2007 Scott D. Yelich SOME RIGHTS RESERVED
 .,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.-*~'`^`'~*-,._.,-*~'`^`'~*-,. 


  LICENSE:  Creative Commons Attribution 3.0 License.
  SEE:      http://creativecommons.org/licenses/by/3.0/


  Sun Jul 29 21:33:38 EDT 2007, v0.02 sdy

  This is a *very* simple program written to do a web page
  hit counter using sqlite3.

*/

#include "CounterMulti.h"

CounterMulti::CounterMulti()
{
  _sql3.open("/www/neurillion/p/33/databases/hits.sq3");
}

CounterMulti::~CounterMulti()
{
}

int
CounterMulti::hit(std::string const & page)
{
  int rc;
  int hits=1;
  int last=0;
  int ctime=0;
  int current=0;
  time_t time_now = time(NULL);
  std::stringstream sql_command_ss;
  sql_command_ss.str("");
  sql_command_ss << "select current,time,hits,last from counter_multi_totals where page='" << page << "';";
  rc = _sql3.exec(sql_command_ss.str()); // order by?
  int hsz = _sql3.headers().size();
  //  if it doesn't exist, create it ...
  if (0 == hsz) {
    rc = _sql3.exec("CREATE TABLE counter_multi_totals (page,current,time,hits,last);");
    sql_command_ss << "INSERT INTO counter_multi_totals VALUES('";
    sql_command_ss << page << "'," << hits << "," << time_now << ",";
    sql_command_ss << hits << "," << time_now << ");";
    rc = _sql3.exec(sql_command_ss.str());
  } else {
    //  if _sql3.data().size() ....
    std::stringstream i;
    i << _sql3.data()[0];
    if (! (i>>current)); // throw?
    i.clear();
    i << _sql3.data()[1];
    if (! (i>>ctime)); // throw?
    i.clear();
    i << _sql3.data()[2];
    if (! (i>>hits)); // throw?
    i.clear();
    i << _sql3.data()[3];
    if (! (i>>last)); // throw?

    sql_command_ss.str("");
    sql_command_ss << "UPDATE counter_multi_totals SET current=current+1,";
    sql_command_ss << "time=" << time_now;
    //  the "if" check should really be done inside of SQL ...
    if ( (time_now-current)>MINTIME ) {
      sql_command_ss << ",hits=current+1,last=" << time_now;
    }
    sql_command_ss << " WHERE page='" << page << "';";
    rc = _sql3.exec(sql_command_ss.str());
  }
  return hits;
}

int
CounterMulti::hits(std::string const & page)
{
  int rc;
  int hits=0;
  std::stringstream sql_command_ss;
  sql_command_ss.str("");
  sql_command_ss << "select hits from counter_multi_totals where page='" << page << "';";
  rc = _sql3.exec(sql_command_ss.str()); // order by?
  int hsz = _sql3.headers().size();
  if (0 != hsz) {
    std::istringstream buffer(_sql3.data()[0]);
    if (!(buffer >> hits)); // throw?
  }
  return hits;
}

