tape_ODBC/ODBCTapeStream.cpp

00001 /*  ODBCTapeStream.cpp
00002  *
00003  *  author: Matt Hauer, matthew.hauer@pnl.gov, 5/30/07 - ***
00004  */
00005 
00006 #include "ODBCTapeStream.h"
00007 
00008 list<tapepair *> ODBCTapeStream::tslist;
00009 ODBCTapeStream::ODBCTapeStream(){
00010     dbconn=0;
00011     Reset();
00012 }
00013 
00014 ODBCTapeStream::ODBCTapeStream(char *fname, char *flags){
00015     dbconn=0;
00016     char host[256], uid[256], pwd[64], objname[1024];
00017     if(sscanf(fname, "%256[^:]:%256[^:]:%64[^:]:%1024[^:]", host, uid, pwd, objname)==4){
00018 //      printf("Four-point open: %s, ***, ***, %s\n", host, objname);
00019         Open(host, objname, uid, pwd, flags);
00020     }
00021     else if(sscanf(fname, "%256[^:]:%1024[^:]", host, objname)==2){
00022 //      printf("Two-point open: %s, %s\n", host, objname);
00023         Open(host, objname, flags);
00024     }
00025 
00026 }
00027 
00028 ODBCTapeStream::ODBCTapeStream(char *servername, char *objectname, char *filemode){
00029     dbconn=0;
00030     Open(servername, objectname, filemode);
00031 }
00032 
00033 ODBCTapeStream::ODBCTapeStream(char *host, char *uid, char *pwd, char *objname, char *flags){
00034     dbconn=0;
00035     Open(host, uid, pwd, objname, flags);
00036 }
00037 
00038 ODBCTapeStream::~ODBCTapeStream(){
00039 //  if(lines) delete lines;
00040 }
00041 
00042 //  for the gamblers. -MH
00043 int ODBCTapeStream::Open(char *servername, char *objname, char *filemode){
00044     return Open(servername, objname, "", "", filemode);
00045 }
00046 
00047 int ODBCTapeStream::Open(char *servername, char *objname, char *uid, char *pwd, char *_mode){
00048     Reset();
00049     static char buffer[256];
00050     memset(buffer, 0, 256);
00051     SetFileMode(_mode);
00052     dbconn=ODBCConnMgr::GetMgr()->ConnectToHost(servername, uid, pwd);
00053     if(0 == dbconn){
00054         state=TSO_DONE;
00055         return 0;
00056     }
00057     strncpy(objectname, objname, 63);
00058     if(filemode[0]=='r'){
00059         sprintf(buffer, "SELECT EVENT_TIME, EVENT_VAL FROM EVENT_TABLE WHERE EVENT_OBJECT_NAME='%s' ORDER BY EVENT_LINE", objname);
00060         try{
00061             PreparedStatement *feeder=dbconn->GetConn()->prepareStatement(buffer, 1, 0);
00062             lines = feeder->executeQuery();
00063             if(lines->last()){
00064                 line_max=lines->getRow();
00065                 lines->first();
00066                 state=TSO_OPEN;
00067                 line_cur=1;
00068                 return line_max;
00069             } //    else empty set
00070             state=TSO_DONE;
00071             return 0;
00072         } catch(SQLException& e) {
00073             cout << "Exception caught: "<<e.getMessage()<<endl;
00074         }
00075         return 2;
00076     }
00077     if(filemode[0]=='w' && filemode[1] != '+'){
00078         try{
00079             //  remove any existing header entry, those are pk'ed
00080             sprintf(buffer, "DELETE FROM HEADER_TABLE WHERE HEADER_OBJECT_NAME='%s';", objectname);
00081             PreparedStatement *feeder = dbconn->GetConn()->prepareStatement(buffer);
00082             //  remove any existing events that might collide later
00083             sprintf(buffer, "DELETE FROM EVENT_TABLE WHERE EVENT_OBJECT_NAME='%s';", objname);
00084             feeder=dbconn->GetConn()->prepareStatement(buffer);
00085             feeder->executeUpdate();
00086             state=TSO_OPEN;
00087             return 1;
00088         } catch(SQLException& e) {
00089             cout << "Exception caught: "<<e.getMessage()<<endl;
00090         }
00091         return 2;
00092     }
00093     //  guess we're not 'r', 'r+', or 'w'
00094     state=TSO_OPEN;
00095     return 1;
00096 }
00097 
00098 char *ODBCTapeStream::ReadLine(){
00099     static char buffer[1024];
00100     return ReadLine(buffer, 1024);
00101 }
00102 
00103 char *ODBCTapeStream::ReadLine(char *buffer, unsigned int size){
00104     memset(buffer, 0, size);    //  prevents returning garbage
00105     if(state != TSO_OPEN) return NULL;
00106     sprintf(buffer, "%s,%s", lines->getString(1).c_str(), lines->getString(2).c_str());//timedate,value
00107     ++line_cur;
00108     if(!lines->next())
00109         state = TSO_DONE;
00110     return buffer;
00111 }
00112 
00113 /*  stubbed 'til we figure out how to store shapes in the DB    */
00114 int ODBCTapeStream::ReadShape(char *objname, float *scale){
00115     //  retreive lines for objectname
00116     //  -build query
00117     //  kinda like "SELECT (min, hour, day, month, wkday, value) IN (shape_table) WHERE (shape_obj_name IS $objectname) SORT (asc, shape_part_num)"
00118     //  -run query
00119     //  -parse results
00120 
00121     /*  nasty stuff from open_shaper here   */
00122 
00123     return 1;   //  success?
00124 }
00125 
00126 /*  catches the abstract TS::Write(char *), even if we need to somehow format
00127  *  our input for the database here, rather than either writing it raw or
00128  *  formating it server-side.
00129  */
00130 int ODBCTapeStream::Write(char *inbuffer){
00131     return 0;
00132 }
00133 
00134 //  writes an event to the object table
00135 int ODBCTapeStream::Write(char *timestamp, char *value){
00136     double event_val=atof(value);       //  assuming fp num
00137     odbc::PreparedStatement *feeder=dbconn->GetConn()->prepareStatement("INSERT INTO OBJECT_TABLE VALUES (?, ?, ?, ?)");
00138     feeder->setString(1, objectname);
00139     feeder->setInt(2, ++line_cur);
00140     feeder->setString(3, timestamp);
00141     feeder->setString(4, value);
00142     int rows=feeder->executeUpdate();
00143     return 0;
00144 }
00145 
00146 //  writes a file header to the header table.
00147 //  char*7 + float*2
00148 void ODBCTapeStream::PrintHeader(char *timestr, char *uname, char *hostname, char *targstr,
00149     char *prop, char *trigger, long interval, long limit){
00150     PreparedStatement *feeder = dbconn->GetConn()->prepareStatement("INSERT INTO HEADER_TABLE VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);");
00151     feeder->setString(1, objectname);
00152     feeder->setString(2, timestr);
00153     feeder->setString(3, uname);
00154     feeder->setString(4, hostname);
00155     feeder->setString(5, targstr);
00156     feeder->setString(6, prop);
00157     feeder->setString(7, trigger);
00158     feeder->setLong(8, interval);
00159     feeder->setLong(9, limit);
00160     int affectedRows=feeder->executeUpdate();
00161 }
00162 
00163 void ODBCTapeStream::Close(){
00164     Reset();
00165 }
00166 
00167 void ODBCTapeStream::HardClose(){   //  handle dc'ed us
00168     //  do non-ODBCConnHandle stuff 'cus we got called from there
00169     line_cur=0;
00170     line_max=0;
00171 //  if(lines) delete [] lines;
00172 }
00173 
00174 int ODBCTapeStream::Rewind(){
00175     line_cur=1;
00176     return 0;
00177 }
00178 
00179 void ODBCTapeStream::Reset(){
00180     memset(objectname, 0, 64);
00181     line_cur=0;
00182     line_max=0;
00183 //  if(lines) delete [] lines;
00184     if(dbconn)
00185         dbconn->DisconnectTape(this);
00186 }
00187 
00188 //
00189 //  STATIC METHODS
00190 //
00191 
00192 TapeStream *ODBCTapeStream::OpenStream(void *my, char *fname, char *flags){
00193     char host[256], uid[256], pwd[64], objname[1024];
00194     tapepair *pair=0;
00195     //  try host:uid:pwd:obj
00196     if(sscanf(fname, "%256[^:]:%256[^:]:%64[^:]:%1024[^:]", host, uid, pwd, objname)==4)
00197         pair=new tapepair(new ODBCTapeStream(host, uid, pwd, objname, flags), my);
00198     //  try raw host:obj
00199     else if(sscanf(fname, "%256[^:]:%1024[^:]", host, objname)==2)
00200         pair=new tapepair(new ODBCTapeStream(host, objname, flags), my);
00201     if(0==pair) return 0;   //  this shouldn't happen ~ bad fname format
00202     tslist.push_back(pair);
00203     return pair->tape;
00204 }
00205 
00206 void ODBCTapeStream::CloseStream(void *my){
00207     list<tapepair *>::iterator itr=tslist.begin();
00208     do{
00209         if((*itr)->name == my){
00210             (*itr)->tape->Close();
00211             delete (*itr)->tape;
00212             tslist.erase(itr);
00213             return;
00214         }
00215         ++itr;
00216     } while(itr != tslist.end());
00217 }
00218 
00219 void ODBCTapeStream::CloseAllStream(){
00220     while(!tslist.empty()){
00221         tslist.back()->tape->Close();
00222         delete tslist.back()->tape;
00223         tslist.pop_back();
00224     }
00225 }
00226 
00227 //  end of ODBCTapeStream.cpp

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy