BadgerDB
/afs/cs.wisc.edu/u/n/w/nwilliam/private/workspace/Quut/src/utility.cpp
00001 
00008 #include <cstdio>
00009 #include <string>
00010 #include <cstring>
00011 #include <fcntl.h>
00012 #include "catalog.h"
00013 #include "utility.h"
00014 #include "index.h"
00015 #include "buffer.h"
00016 #include "exceptions/end_of_file_exception.h"
00017 #include "exceptions/bad_param_exception.h"
00018 #include "exceptions/file_open_exception.h"
00019 
00020 #define MAX(a,b) ((a) > (b) ? (a) : (b))
00021 #define MIN(a,b) ((a) < (b) ? (a) : (b))
00022 
00023 extern badgerdb::RelCatalog *relCat;    // pointer to the relation catalogs 
00024 extern badgerdb::AttrCatalog *attrCat;  // pointer to the attribute catalogs
00025 extern badgerdb::BufMgr *bufMgr;  // pointer to the attribute catalogs
00026 
00027 namespace badgerdb
00028 {
00029   // Compute widths of columns in attribute array.
00030   //
00031 
00032   void Utilities::UT_computeWidth(int attrCnt, AttrDesc attrs[], int *&attrWidth)
00033   {
00034     attrWidth = new int [attrCnt];
00035 
00036     for(int i = 0; i < attrCnt; i++)
00037       {
00038   int namelen = strlen(attrs[i].attrName);
00039   switch(attrs[i].attrType)
00040     {
00041     case INTEGER:
00042     case DOUBLE:
00043       // For ints and doubles print at most 7 characters.
00044       attrWidth[i] = MIN(MAX(namelen, 5), 7);
00045 
00046       // To print numbers using a longer format, comment out the previous line
00047       // and uncomment the next line.
00048       // attrWidth[i] = MAX(namelen, 5);
00049       break;
00050     case STRING:
00051       // For strings print at most 15 characters. 
00052       // BUG: The MAX implies that if the length of the attribute name is greater 
00053       //      than the type of the attribute, the subsequent print may print out garbage
00054       //      values
00055       attrWidth[i] = MIN(MAX(namelen, attrs[i].attrLen), 15);
00056 
00057       // To print the entire string, comment out the previous line
00058       // and uncomment the next line.
00059       // attrWidth[i] = MAX(namelen, attrs[i].attrLen);
00060       break;
00061     }
00062       }
00063   }
00064 
00065 
00066   //
00067   // Prints values of attributes stored in buffer pointed to
00068   // by recPtr. The desired width of columns is in attrWidth.
00069   //
00070 
00071   void UT_printRec(int attrCnt, AttrDesc attrs[], int *attrWidth, const std::string &rec)
00072   {
00073     for(int i = 0; i < attrCnt; i++)
00074       {
00075   char *attr = (char *)rec.c_str() + attrs[i].attrOffset;
00076   switch(attrs[i].attrType)
00077     {
00078     case INTEGER:
00079       int tempi;
00080       memcpy(&tempi, attr, sizeof(int));
00081       printf("%-*d  ", attrWidth[i], tempi);
00082       break;
00083     case DOUBLE:
00084       double tempf;
00085       memcpy(&tempf, attr, sizeof(double));
00086       printf("%-*.2f  ", attrWidth[i], tempf);
00087       break;
00088     default:
00089       printf("%-*.*s  ", attrWidth[i], attrWidth[i], attr);
00090       break;
00091     }
00092       }
00093 
00094     printf("\n");
00095   }
00096 
00097 
00098   void Utilities::Print(const std::string &relation)
00099   {
00100     RelDesc rd;
00101     AttrDesc *attrs;
00102     int attrCnt;
00103 
00104     if(relation.empty())
00105       std::string relation = RELCATNAME;
00106 
00107     relCat->getInfo(relation, rd);
00108 
00109     // get attribute data
00110     attrCat->getRelInfo(rd.relName, attrCnt, attrs);
00111 
00112     // compute width of output columns
00113     int *attrWidth;
00114     UT_computeWidth(attrCnt, attrs, attrWidth);
00115 
00116     // open data file
00117     FileScan filescan(rd.relName, bufMgr);
00118 
00119     for(int i = 0; i < attrCnt; i++)
00120       {
00121   printf("%-*.*s%c ", attrWidth[i], attrWidth[i], attrs[i].attrName, (attrs[i].indexed ? '*' : ' '));
00122       }
00123     printf("\n");
00124 
00125     for(int i = 0; i < attrCnt; i++) {
00126       for(int j = 0; j < attrWidth[i]; j++)
00127   putchar('-');
00128       printf("  ");
00129     }
00130     printf("\n");
00131 
00132     RecordId rid;
00133 
00134     int records = 0;
00135     while(1)
00136       {
00137   try
00138     {
00139       filescan.scanNext(rid);
00140       std::string recordStr = filescan.getRecord();
00141       UT_printRec(attrCnt, attrs, attrWidth, recordStr);
00142       records++;
00143     }
00144   catch(EndOfFileException &e)
00145     {
00146       break;
00147     }
00148       }
00149 
00150     std::cout << std::endl << "Number of records: " << records << std::endl;
00151 
00152     delete [] attrWidth;
00153     delete [] attrs;
00154   }
00155 
00156   void Utilities::Load(const std::string &relation, const std::string &fileName)
00157   {
00158     RelDesc rd;
00159     AttrDesc *attrs;
00160     int attrCnt;
00161 
00162     if(relation.empty() || fileName.empty() || relation == std::string(RELCATNAME) || relation == std::string(ATTRCATNAME))
00163       throw BadParamException();
00164 
00165     // open Unix data file
00166     int fd;
00167     if((fd = open(fileName.c_str(), O_RDONLY, 0)) < 0)
00168       throw FileOpenException(fileName);
00169 
00170     // get relation data
00171     relCat->getInfo(relation, rd);
00172 
00173     // get attribute data
00174 
00175     attrCat->getRelInfo(rd.relName, attrCnt, attrs);
00176 
00177     // open data file
00178     FileScan fscan(std::string(rd.relName), bufMgr);
00179 
00180     int records = 0;
00181 
00182     Index **index = new Index * [attrCnt];
00183 
00184     //compute width of tuple and open index files, if any
00185 
00186     int width = 0;
00187     int i;
00188 
00189     for(i = 0; i < attrCnt; i++)
00190       {
00191   width += attrs[i].attrLen;
00192   index[i] = NULL;
00193   if (attrs[i].indexed)
00194     {
00195       index[i] = new Index(std::string(rd.relName), attrs[i].attrOffset, attrs[i].attrLen,  (Datatype)attrs[i].attrType, NONUNIQUE, bufMgr);
00196     }
00197       }
00198 
00199     // Now start reading "width" bytes from the unix file (fd). The bytes that you
00200     // read are in the same format as the record used by Minirel. You now need to
00201     // insert this record into the heapfile (hfile) corresponding to this relation 
00202     // and also insert entries for this record in "each" index. You can insert 
00203     // entries into the index using the index[i]->insesrtEntry(...) command. Note,
00204     // you will need to provide to this method, the key of the entry being inserted.
00205     // Use the record and the index information from the catalog to locate the 
00206     // key that you need to pass to insertEntry.
00207 
00208     // Solution Starts
00209     // create a record for constructing the tuple
00210 
00211     char *record = new char [width];
00212 
00213     int nbytes;
00214     std::string rec;
00215 
00216     while((nbytes = read(fd, record, width)) == width)
00217       {
00218   RecordId rid;
00219   rec.assign(record, width);
00220 
00221   fscan.insertRecord(rec, rid);
00222 
00223   for(i = 0; i < attrCnt; i++)
00224     {
00225       if (index[i])
00226         {
00227     index[i]->insertEntry(record + attrs[i].attrOffset, rid);
00228         }
00229     }
00230   records++;
00231       }
00232 
00233     std::cout << "Number of records inserted: " << records << std::endl;
00234 
00235     if(close(fd) < 0)
00236       throw FileOpenException(fileName);
00237 
00238     for(i = 0; i < attrCnt; i++)
00239       {
00240   if(index[i])
00241     delete index[i];
00242       }
00243 
00244     delete []index;
00245 
00246     delete [] record;
00247     delete [] attrs;
00248   }
00249 
00250 
00251   void Utilities::Quit()
00252   {
00253     // close relcat and attrcat
00254 
00255     delete ::relCat;
00256     delete ::attrCat;
00257 
00258     // delete bufMgr to flush out all dirty pages
00259 
00260     delete ::bufMgr;
00261 
00262     exit(1);
00263   }
00264    
00265   void Helpers::printAttrInfo(const attrInfo *attr){
00266     if(attr!=NULL){
00267       std::cout<<"\nPrinting attrInfo\n";
00268       std::cout<<"\n\tRelname:"<<attr->relName<<"\n";
00269       std::cout<<"\n\tattrName:"<<attr->attrName<<"\n";
00270       std::cout<<"\n\tattrType:"<<attr->attrType<<"\n";
00271       if(attr->attrValue)
00272   std::cout<<"\n\tValue:"<< (attr->attrValue)<<"\n";
00273       else
00274   std::cout<<"\n\tValue is NULL\n";
00275     }
00276     else{
00277       std::cout<<"\nATTR is NULL\n";
00278     }
00279   }
00280   void Helpers::printAttrDesc(const AttrDesc *attrDesc){
00281     if(attrDesc!=NULL){
00282       std::cout<<"\nPrinting attrDesc\n";
00283       if(attrDesc->attrName)
00284   std::cout<<"\n\tAttrName:"<<attrDesc->attrName<<"\n";
00285       else
00286   std::cout<<"\n\tAttrName is NULL\n";
00287       std::cout<<"\n\tattrType:"<<Datatype(attrDesc->attrType)<<"\n";
00288       std::cout<<"\n\tattrLen:"<<attrDesc->attrLen<<"\n";
00289      
00290     }
00291     else{
00292       std::cout<<"\nATTRDESC is NULL\n";
00293     }
00294   }
00295 
00296   void Helpers::printAttrCat(std::string attributeName){
00297     print("ATTR CAT INFO");
00298     AttrDesc *outAttrDesc = new AttrDesc[6];
00299     int six = 6;
00300     attrCat->getRelInfo(attributeName,six,outAttrDesc);
00301     int i;
00302     for(i=0; i< 6; i++){
00303       print(outAttrDesc[i].relName);
00304       print(outAttrDesc[i].attrName);
00305       print(outAttrDesc[i].attrOffset);
00306       print(outAttrDesc[i].attrType);
00307       print(outAttrDesc[i].attrLen);
00308       print(outAttrDesc[i].indexed);
00309     }
00310     delete[] outAttrDesc;
00311   }
00312   std::string Helpers::charArrToStr(char charArr[]){
00313     std::string returnString;
00314     int i = 0;
00315     while(charArr[i] != 0){
00316       returnString += charArr[i];
00317       i++;
00318     }
00319     return returnString;
00320   }
00321 
00322 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends