BadgerDB
|
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 }