Example #1
0
const Status RelCatalog::createRel(const string & relation, 
				   const int attrCnt,
				   const attrInfo attrList[])
{
  Status status;
  RelDesc rd;
  AttrDesc ad;
  int offset;

  if (relation.empty() || attrCnt < 1)
    return BADCATPARM;

  if (relation.length() >= sizeof rd.relName)
    return NAMETOOLONG;
    
  //check to see if relation already exisits
  status = relCat->getInfo(relation, rd);
  if(status == OK) {
    return RELEXISTS;
  } 
  
  //initializing the RelDesc and adding it to relCat
  memcpy(rd.relName, relation.c_str(),sizeof(rd.relName));
  rd.attrCnt = attrCnt;
  status = relCat->addInfo(rd);
  if (status != OK) return status;
  
  offset = 0;
    
  //copy the attr data into the AttrDesc struct, and add to attrCat
  for(int i = 0; i < attrCnt; i++){
      strcpy(ad.relName, attrList[i].relName);
      strcpy(ad.attrName, attrList[i].attrName);
      ad.attrType = attrList[i].attrType;
      ad.attrLen = attrList[i].attrLen;
      ad.attrOffset = offset;
      status = attrCat->addInfo(ad);
      if(status != OK) return status;
      
      //add offset for next attribute
      offset = (offset + attrList[i].attrLen);
    } 

  //create the heapFile instance to hold tuples for this relation 
  status = createHeapFile(relation);
  
  return status;

}
Example #2
0
const Status RelCatalog::createRel(const string & relation, 
				   const int attrCnt,
				   const attrInfo attrList[])
{
  Status status;
  RelDesc rd;
  int offset = 0;

  if (relation.empty() || attrCnt < 1)
    return BADCATPARM;

  if (relation.length() >= sizeof rd.relName)
    return NAMETOOLONG;

  for (int i = 0; i < attrCnt; i++) {
	  for (int j = i + 1; j < attrCnt; j++) {
		  if (strncmp(attrList[i].attrName, attrList[j].attrName, 32) == 0) {
			  return DUPLATTR;
		  }
	  }
  }
  
  status = getInfo(relation, rd);
  if (status == OK) {
	  return RELEXISTS;
  } else if (status != RELNOTFOUND) {
	  return status;
  }
  rd.attrCnt = attrCnt;
  strncpy(rd.relName,relation.c_str(),min(relation.length(), (size_t) MAXNAME - 1));
  if (RelCatalog::addInfo(rd) != OK) {
	return status;
  }
  for (int i = 0; i < attrCnt; i++) {
	  AttrDesc ad;
	  ad.attrLen = attrList[i].attrLen;
          strncpy(ad.attrName,attrList[i].attrName,32);
	  ad.attrType = attrList[i].attrType;
          ad.attrOffset = offset;
          offset += ad.attrLen;
	  strncpy(ad.relName, attrList[i].relName,32);
	  status = attrCat->addInfo(ad);
	  if (status != OK) {
		  return status;
	  }
  }
  return createHeapFile(relation);
}
Example #3
0
/**
 * FUNCTION: RelCatalog::createRel
 *
 * PURPOSE:  Creates a new relation in current database
 *
 * PARAMETERS:
 *		relation 	(in)		Relation name to be created
 *		attrCnt		(in)		Number of attributes in the relation
 *		attrList	(in)		Information of all the attributes
 *	
 * RETURN VALUES:
 * 		Status	OK 				Relation successfully created.
 *				BADCATPARM 		Relation name is empty
 *				NAMETOOLONG		Relation name too long
 *				RELEXISTS	  	A relation with the same name already exists
 *				FILEEOF 		Reached the end of file while scanning for the record
 *				BUFFEREXCEEDED  All buffer frames are pinned
 *				HASHTBLERROR	Hash table error occurred
 *				PAGENOTPINNED 	Pin count is already 0
 *				HASHNOTFOUND  	Page is not in the buffer pool hash table
 **/
const Status RelCatalog::createRel(const string & relation, 
				   const int attrCnt,
				   const attrInfo attrList[])
{
  Status status;
  RelDesc rd;
  AttrDesc ad;

  if (relation.empty() || attrCnt < 1)
    return BADCATPARM;

  if (relation.length() >= sizeof rd.relName)
    return NAMETOOLONG;

	status = relCat->getInfo(relation, rd);
	if(status == OK)
	{
		return RELEXISTS;
	}
	else
	{
		// Adding a tuple in "relcat" table
		strcpy(rd.relName, relation.c_str());
		rd.attrCnt = attrCnt;
		status = addInfo(rd);
		
		// Adding appropriate tuples in the "attrcat" table
		int offset = 0;
		for(int i = 0; i< attrCnt; i++)
		{
			strcpy(ad.relName, attrList[i].relName);
			strcpy(ad.attrName, attrList[i].attrName);
			ad.attrOffset = offset;//(i == 0) ? 0 : MAXNAME; 
			ad.attrType = attrList[i].attrType; 
			ad.attrLen = attrList[i].attrLen;
			offset += ad.attrLen;
			
			status = attrCat->addInfo(ad);
			if(status != OK) break;
		}
	}
	// Creating HeapFile for the relation
	status = createHeapFile(relation.c_str());

	return status;
}
Example #4
0
int main(int argc, char **argv)
{
    cout << "Testing the relation interface" << endl << endl;
    
    // DB db;
    Error error;
    HeapFile* file1;
    HeapFileScan *scan1, *scan2;
    
    InsertFileScan *iScan;
    Status status;
    RID newRid;
	int deleted;
    
    typedef struct {
        int i;
        float f;
        char s[64];
    } RECORD;
    
    RECORD 	rec1;
    RECORD rec2;              // retrieved recs are unaligned!!
    int           rec1Len;
    Record        dbrec2;
    RID		  rec2Rid;
    
    bufMgr = new BufMgr(101);
    
    int i,j;
    int num = 10120;
    Record dbrec1;
    RID*  ridArray;
    
    
    ridArray = new RID[num];
    
    // destroy any old copies of "dummy.02"
    status = destroyHeapFile("dummy.02");
    // ignore the error return
    
    status = createHeapFile("dummy.02");
    if (status != OK) 
    {
		cerr << "got err0r status return from  createHeapFile" << endl;
    	error.print(status);
    }
    
    // initialize all of rec1.s to keep purify happy
    memset(rec1.s, ' ', sizeof(rec1.s));
    
    cout << endl;
    cout << "insert " << num << " records into dummy.02" << endl;
    cout << endl;
    
    cout << "Start an insert scan which will have the side effect of opening dummy.02 " << endl;
    iScan = new InsertFileScan("dummy.02", status);
    for(i = 0; i < num; i++) {
        sprintf(rec1.s, "This is record %05d", i);
        rec1.i = i;
        rec1.f = i;
        
        dbrec1.data = &rec1;
        dbrec1.length = sizeof(RECORD);
        status = iScan->insertRecord(dbrec1, newRid);
        
		// stash away rid and key of the record
		ridArray[i] = newRid;
		//printf("next rid (%d.%d)\n",ridArray[i].pageNo, ridArray[i].slotNo);
        
        if (status != OK) 
        {
            cout << "got err0r status return from insertrecord" << endl;
            cout << "inserted " << i << "records into file dummy1 before error " 
            << endl;
            error.print(status);
            exit(1);
        }
    }
    
    delete iScan; // delete the scan, closing the file at the same time
    file1 = NULL;
    
    cout << "inserted " << num << " records into file dummy.02 successfully" << endl;
    cout << endl;
    
    cout << endl;
    cout << "pull 11th record from file dummy.02 using file->getRecord() " << endl;
    file1 = new HeapFile("dummy.02", status); // open the file
    if (status != OK) error.print(status);
    else 
    {
		// get every record
		for (i=0;i<num;i=i+11)
		{
			// reconstruct record for comparison purposes
    	    sprintf(rec1.s, "This is record %05d", i);
    	    rec1.i = i;
    	    rec1.f = i;
            
			// now read the record
			//printf("getting record (%d.%d)\n",ridArray[i].pageNo, ridArray[i].slotNo);
			status = file1->getRecord(ridArray[i], dbrec2);
    	    if (status != OK) error.print(status);
            
			// compare with what we should get back
			if (memcmp(&rec1, dbrec2.data, sizeof(RECORD)) != 0)
                cout << "err0r reading record " << i << " back" << endl;
		}
		cout << "getRecord() tests passed successfully" << endl;
    }
    delete file1;
    
    // scan the file sequentially checking that each record was stored properly
    cout << "scan file dummy.02 " << endl;
    scan1 = new HeapFileScan("dummy.02", status);
    if (status != OK) error.print(status);
    else 
    {
		scan1->startScan(0, 0, STRING, NULL, EQ);
		i = 0; 
		while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
		{
			// reconstruct record i
			sprintf(rec1.s, "This is record %05d", i);
    	    rec1.i = i;
    	    rec1.f = i;
    	    status = scan1->getRecord(dbrec2);
    	    if (status != OK) break;
			if (memcmp(&rec1, dbrec2.data, sizeof(RECORD)) != 0)
                cout << "err0r reading record " << i << " back" << endl;
    	    i++;
		}
		if (status != FILEEOF) error.print(status);
		cout << "scan file1 saw " << i << " records " << endl;
		if (i != num)
            cout << "Err0r.   scan should have returned " << num << " records!"
            << endl;
    }
    // delete scan object
    scan1->endScan();
    delete scan1;
    scan1 = NULL;
    
    
	// scan the file sequentially checking that each record was stored properly
    cout << endl << "scan file dummy.02 " << endl;
    scan1 = new HeapFileScan("dummy.02", status);
    if (status != OK) error.print(status);
    else 
    {
		scan1->startScan(0, 0, STRING, NULL, EQ);
		i = 0; 
		while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
		{
			// reconstruct record i
			sprintf(rec1.s, "This is record %05d", i);
    	    rec1.i = i;
    	    rec1.f = i;
    	    status = scan1->getRecord(dbrec2);
    	    if (status != OK) break;
			if (memcmp(&rec1, dbrec2.data, sizeof(RECORD)) != 0)
                cout << "err0r reading record " << i << " back" << endl;
    	    i++;
		}
		if (status != FILEEOF) error.print(status);
		cout << "scan file1 saw " << i << " records " << endl;
		if (i != num)
            cout << "Err0r.   scan should have returned " << num << " records!"
            << endl;
    }
    // delete scan object
    scan1->endScan();
    delete scan1;
    scan1 = NULL;
	
    
    // pull every 7th record from the file directly w/o opening a scan
    // by using the file->getRecord() method
    cout << endl;
    cout << "pull every 7th record from file dummy.02 using file->getRecord() " << endl;
    file1 = new HeapFile("dummy.02", status); // open the file
    if (status != OK) error.print(status);
    else 
    {
		// get every 7th record
		for (i=0;i<num;i=i+7)
		{
			// reconstruct record for comparison purposes
    	    sprintf(rec1.s, "This is record %05d", i);
    	    rec1.i = i;
    	    rec1.f = i;
            
			// now read the record
			//printf("getting record (%d.%d)\n",ridArray[i].pageNo, ridArray[i].slotNo);
			status = file1->getRecord(ridArray[i], dbrec2);
    	    if (status != OK) error.print(status);
            
			// compare with what we should get back
			if (memcmp(&rec1, dbrec2.data, sizeof(RECORD)) != 0)
                cout << "err0r reading record " << i << " back" << endl;
		}
		cout << "getRecord() tests passed successfully" << endl;
    }
    delete file1; // close the file
    delete [] ridArray;
    
    
	// next scan the file deleting all the odd records
    cout << endl;
    cout << "scan file deleting all records whose i field is odd" << endl;
    
    scan1 = new HeapFileScan("dummy.02", status);
    if (status != OK) error.print(status);
    else 
    {
        scan1->startScan(0, 0, STRING, NULL, EQ);
		i = 0;
		deleted = 0;
		while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
		{
			// cout << "processing record " << i << i << endl;
			if (status != OK) error.print(status);
			if ((i % 2) != 0)
			{
				// printf("deleting record %d with rid(%d.%d)\n",i,rec2Rid. pageNo, rec2Rid.slotNo);
				status = scan1->deleteRecord(); 
				deleted++;
				if ((status != OK)  && ( status != NORECORDS))
				{
                    cout << "err0r status return from deleteRecord" << endl;
                    error.print(status);
				}
			}
			i++;
		}
		if (status != FILEEOF) error.print(status);
		cout << "deleted " << deleted << " records" << endl;
		if (deleted != num / 2)
            cout << "Err0r.   should have deleted " << num / 2 << " records!" << endl;
		scan1->endScan();
    }
    delete scan1;
    scan1 = NULL;
    
    
    cout << endl;
    cout << "scan file, counting number of remaining records" << endl;
    
    scan1 = new HeapFileScan("dummy.02", status);
    if (status != OK) error.print(status);
    else 
    {
        i = 0;
        scan1->startScan(0, 0, STRING, NULL, EQ);
        while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
        {
            if ( i > 0 ) // don't delete the first one
            {
                status = scan1->deleteRecord();
                if ((status != OK) && ( status != NORECORDS))
                {
                    cout << "err0r status return from deleteRecord" << endl;
                    error.print(status);
                }
            }
            i++;
        }
        // subtract first record
        i--;
        
        if (status != FILEEOF) error.print(status);
        scan1->endScan(); 
        delete scan1;
        scan1 = NULL;
        
        scan1 = new HeapFileScan("dummy.02", status);
        scan1->startScan(0, 0, STRING, NULL, EQ);
        
        // delete the rest (should only be one)
        while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
        {
            status = scan1->deleteRecord();
            if ((status != OK) && ( status != NORECORDS))
            {
                cout << "err0r status return from deleteRecord" << endl;
                error.print(status);
            }
            i++;
        }
        
        scan1->endScan();
        delete scan1;
        
        cout << "scan saw " << i << " records " << endl;
        if (i != (num+1) / 2)
            cout << "Err0r.   scan should have returned " << (num+1) / 2
            << " records!" << endl;
    }
	
    
    
    
    status = destroyHeapFile("dummy.02");
    if (status != OK) 
    {
        cerr << "got err0r status return from  destroyHeapFile" << endl;
    	error.print(status);
    }
    status = createHeapFile("dummy.03");
    if (status != OK) 
    {
        cerr << "got err0r status return from  createHeapFile" << endl;
    	error.print(status);
    }
    iScan = new InsertFileScan("dummy.03", status);
    if (status != OK) 
    {
        cout << "got err0r status return from new insertFileScan call" << endl;
    	error.print(status);
    }
    
    cout << endl;
    cout << "insert " << num << " variable-size records into dummy.03" << endl;
    int smallest, largest;
    for(i = 0; i < num; i++) {
        rec1Len = 2 + rand() % (sizeof(rec1.s)-2);    // includes NULL!!
        //cout << "record length is " << rec1Len << endl;
        memset((void *)rec1.s, 32 + rec1Len, rec1Len - 1);
        rec1.s[rec1Len-1] = 0;
        rec1Len += sizeof(rec1.i) + sizeof(rec1.f);
        rec1.i = i;
        rec1.f = rec1Len;
        dbrec1.data = &rec1;
        dbrec1.length = rec1Len;
        
        status = iScan->insertRecord(dbrec1, newRid);
        if (status != OK) 
        {
            cout << "got err0r status return from insertrecord" << endl;
            error.print(status);
        }
        if (i == 0 || rec1Len < smallest) smallest = rec1Len;
        if (i == 0 || rec1Len > largest) largest = rec1Len;
    }
    cout << "inserted " << num << " variable sized records successfully into dummy.03" << endl;
    cout << "smallest record was " << smallest << " bytes, largest was "
    << largest << " bytes" << endl;
    
    delete iScan;
    file1 = NULL;
    
    cout << endl << "scan dummy.03 using the predicate < num/2 " << endl;
    j = num/2;
    scan1 = new HeapFileScan("dummy.03", status);
    if (status != OK) error.print(status);
    else 
    {
        scan1->startScan(0, sizeof(int), INTEGER, (char*)&j, LT);
        i = 0;
        
        while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
        {
            status = scan1->getRecord(dbrec2);
            if (status != OK) break;
            memcpy(&rec2, dbrec2.data, dbrec2.length);
            if (rec2.i >= j || rec2.f != dbrec2.length || rec2.s[0] != 32+dbrec2.length-8)
                cout << "err0r reading record " << i << " back" << endl;
            i++;
        }
        if (status != FILEEOF)
            error.print(status);
        cout << "scan of dummy.03 saw " << i << " records " << endl;
        if (i != num / 2)
            cout << "Err0r.   scan should have returned " << num / 2
            << " records!" << endl;
    }
    
    scan1->endScan();
    delete scan1;
    scan1 = NULL;
    
    
    //================================================
    
    cout << endl;
    cout << "Next attempt two concurrent scans on dummy.03 " << endl;
    int Ioffset = (int)((char*)&rec1.i - (char*)&rec1);
    int Ivalue = num/2;
    int Foffset = (int)((char*)&rec1.f - (char*)&rec1);
    float Fvalue = 0;
    
    scan1 = new HeapFileScan("dummy.03", status);
    if (status != OK) error.print(status);
    status = scan1->startScan(Ioffset, sizeof(int), INTEGER,
                              (char*)&Ivalue, LT);
    if (status != OK) error.print(status);
    
    scan2 = new HeapFileScan("dummy.03", status);
    if (status != OK) error.print(status);
    status = scan2->startScan(Foffset, sizeof(float), FLOAT,
                              (char*)&Fvalue, GTE);
    if (status != OK) error.print(status);
    else 
    {
        int count = 0;
        for(i = 0; i < num; i++)
        {
            status = scan1->scanNext(rec2Rid);
            if (status == OK) count++;
            else if (status != FILEEOF) error.print(status);
            status = scan2->scanNext(rec2Rid);
            if (status == OK) count++;
            else if (status != FILEEOF) error.print(status);
        }
        cout << "scan file1 saw " << count << " records " << endl;
        if (count != num/2 + num)
            cout << "Err0r.   scan should have returned " << num/2 + num
            << " records!" << endl;
        if (scan1->scanNext(rec2Rid) != FILEEOF)
            cout << "Err0r.   scan past end of file did not return FILEEOF!" << endl;
        if (scan2->scanNext(rec2Rid) != FILEEOF)
            cout << "Err0r.   scan past end of file did not return FILEEOF!" << endl;
    }
    delete scan1;
    delete scan2;
    scan1 = scan2 = NULL;
	
    cout << endl;
    cout << "Destroy dummy.03" << endl;
    if ((status = destroyHeapFile("dummy.03")) != OK) {
        cout << "got err0r status return from destroy file" << endl;
        error.print(status);
    }
    
    status = createHeapFile("dummy.04");
    if (status != OK) 
    {
        cerr << "got err0r status return from  createHeapFile" << endl;
    	error.print(status);
    }
    
    iScan = new InsertFileScan("dummy.04", status);
    if (status != OK) 
    {
        cerr << "got err0r status return from new insertFileScan" << endl;
    	error.print(status);
    }
    cout << "inserting " << num << " records into dummy1" << endl;
    for(i = 0; i < num; i++) {
        sprintf(rec1.s, "This is record %05d", i);
        rec1.i = i;
        rec1.f = i;
        
        dbrec1.data = &rec1;
        dbrec1.length = sizeof(RECORD);
        status = iScan->insertRecord(dbrec1, newRid);
        if (status != OK) 
        {
            cout << "got err0r status return from insertrecord" << endl;
            error.print(status);
        }
    }
    delete iScan;
    file1 = NULL;
	
	
    
    //bufMgr->clearBufStats();
    int numDeletes = 0;
    cout << endl;
    cout << "now scan dummy.04, deleting records with keys between 1000 and 2000" << endl;
    
    scan1 = new HeapFileScan("dummy.04", status);
    if (status != OK) error.print(status);
    status = scan1->startScan(0, 0, STRING, NULL, EQ);
    if (status != OK) error.print(status);
    else 
    {
        i = 0;
        while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
        {
            // reconstruct record i
    	    sprintf(rec1.s, "This is record %05d", i);
    	    rec1.i = i;
    	    rec1.f = i;
    	    status = scan1->getRecord(dbrec2);
    	    if (status != OK) break;
            if (memcmp(&rec1, dbrec2.data, sizeof(RECORD)) != 0)
                cout << "err0r reading record " << i << " back" << endl;
            
            if ((i > 1000) && ( i <= 2000))
            {
                status = scan1->deleteRecord();
                if ((status != OK) && ( status != NORECORDS))
                {
                    cout << "err0r status return from deleteRecord" << endl;
                    error.print(status);
                }
                else numDeletes++;
            }
    	    i++;
        }
        if (status != FILEEOF) error.print(status);
        cout << "scan file1 saw " << i << " records " << endl;
        if (i != num)
            cout << "Err0r. scan should have returned " << (int) num 
            << " records!!" << endl;
        cout << "number of records deleted by scan " << numDeletes << endl;
        if (numDeletes != 1000)
            cout << "Err0r. Should have deleted 1000 records!!!" << endl;
    }
    cout << endl;
    delete scan1;
	
    
    
    // rescan.  should see 1000 fewer records
    
    scan1 = new HeapFileScan("dummy.04", status);
    if (status != OK) error.print(status);
    scan1->startScan(0, 0, STRING, NULL, EQ);
    i = 0;
    while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
    {
        i++;
    }
    cout << "should have seen 1000 fewer records after deletions" << endl;
    cout << "saw " << i << "records" << endl;
    delete scan1;
	
    
    // perform filtered scan #1
    scan1 = new HeapFileScan("dummy.04", status);
    if (status != OK) error.print(status);
    
    int filterVal1 = num * 3 / 4;
    cout << endl << "Filtered scan matching i field GTE than " << filterVal1 << endl;
    status = scan1->startScan(0, sizeof(int), INTEGER, (char *) &filterVal1, GTE);
    if (status != OK) 
    {
        cerr << "got err0r status return from startScan" << endl;
    	error.print(status);
    }
    else
    {
        // do scan
        i = 0;
        while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
        {
            // reconstruct record i
            status = scan1->getRecord(dbrec2);
            if (status != OK) break;
            // verify that the scan predicate was actually met
            RECORD *currRec = (RECORD *) dbrec2.data;
            if (! (currRec->i >= filterVal1))
            {
                cerr << "Err0r.   filtered scan returned record that doesn't satisfy predicate "
                << "i val is " << currRec->i << endl;
                exit(1);
            }
            
            i++;
        }
        if (status != FILEEOF) error.print(status);
        cout << "scan file1 saw " << i << " records " << endl;
        if (i != num/4)
            cout << "Err0r.   scan should have returned " << num/4 << " records!"
            << " returned "<< i <<endl;
    }
    
    delete scan1;
	
    // perform filtered scan #2
    scan1 = new HeapFileScan("dummy.04", status);
    if (status != OK) error.print(status);
    // perform filtered scan #2
    float filterVal2 = num * 9 / 10;
    cout << endl << "Filtered scan matching f field GT than " << filterVal2 << endl;
    status = scan1->startScan(sizeof(int), sizeof(float), FLOAT, (char *) &filterVal2, GT);
    if (status != OK) 
    {
        cerr << "got err0r status return from startScan" << endl;
    	error.print(status);
    }
    else
    {
        // do scan
        i = 0;
        while ((status = scan1->scanNext(rec2Rid)) != FILEEOF)
        {
            // reconstruct record i
            status = scan1->getRecord(dbrec2);
            if (status != OK) break;
            // verify that the scan predicate was actually met
            RECORD *currRec = (RECORD *) dbrec2.data;
            if (! (currRec->f > filterVal2))
            {
                cerr << "Err0r.   filtered scan returned record that doesn't satisfy predicate "
                << "f val is " << currRec->f << endl;
                exit(1);
            }
            //            cout << "scan return: " << currRec->f << endl;
            i++;
        }
        if (status != FILEEOF) error.print(status);
        cout << "scan file1 saw " << i << " records " << endl;
        if (i != num/10-1)
            cout << "Err0r.   filtered scan 2 should have returned " << num/10-1 << " records!"
            << endl;
    }
    delete scan1;
	
	
    // open up the heapFile
    file1 = new HeapFile("dummy.04", status);
    if (status != OK) 
    {
        cerr << "got err0r status return from new HeapFile" << endl;
    	error.print(status);
    }
    delete file1;
    
    
    // cout << "BUFSTATS:" << bufMgr->getBufStats() << endl;
    // bufMgr->clearBufStats();
    
    scan1 = new HeapFileScan("dummy.04", status);
    if (status != OK) error.print(status);
    status = scan1->startScan(0, 20, INTEGER, "Hi" , EQ);
    if ( status == BADSCANPARM)
    {
        cout << endl << "passed BADSCANPARAM test" << endl;
    }
    else
    {
        cout << "should have returned BADSCANPARM, actually returned: " << endl;
        error.print(status);
    }
    
    // add insert for bigger than pagesized record
    iScan = new InsertFileScan("dummy.04", status);
    if (status != OK) error.print(status);
    char bigdata[8192];
    sprintf(bigdata, "big record");
    dbrec1.data = (void *) &bigdata;
    dbrec1.length = 8192;
    status = iScan->insertRecord(dbrec1, rec2Rid);
    if ((status == INVALIDRECLEN) || (status == NOSPACE))
    {
        cout << endl << "passed large record insert test" << endl;
    }
    else
    {
        cout << "got err0r status return from insert record " << endl;
        error.print(status);
        cout << "expected INVALIDRECLEN or NOSPACE" << endl;
    }
    delete iScan;
    
    delete scan1;
    
    // MORE ERROR HANDLING TESTS HERE
    
    // get rid of the file
    if ((status = destroyHeapFile("dummy.04")) != OK) {
        cout << endl << "got err0r status return from destroy file" << endl;
        error.print(status);
    }
    delete bufMgr;
    
    cout << endl << "Done testing." << endl;
    return 1;
    
}
Example #5
0
const Status RelCatalog::createRel(const string & relation, 
				   const int attrCnt,
				   const attrInfo attrList[])
{
  Status status;
  RelDesc rd;
  AttrDesc ad;

  if (relation.empty() || attrCnt < 1)
    return BADCATPARM;

  if (relation.length() >= sizeof rd.relName)
    return NAMETOOLONG;

  // make sure the relation doesn't already exist

  status = getInfo(relation, rd);
  if (status == OK)
    return RELEXISTS;
  if (status != RELNOTFOUND)
    return status;

  // make sure there are no duplicate attribute names

  unsigned int tupleWidth = attrList[0].attrLen;

  if (attrCnt > 1) {
    for(int i = 1; i < attrCnt; i++) {
      tupleWidth += attrList[i].attrLen;
      for(int j = 0; j < i; j++)
	if (strcmp(attrList[i].attrName, attrList[j].attrName) == 0)
	  return DUPLATTR;
    }
  }
  
  if (tupleWidth > PAGESIZE)            // should be more strict
    return ATTRTOOLONG;

  cout << "Creating relation " << relation << endl;

  // insert information about relation

  strcpy(rd.relName, relation.c_str());
  rd.attrCnt = attrCnt;
  if ((status = addInfo(rd)) != OK)
    return status;

  // insert information about attributes

  strcpy(ad.relName, relation.c_str());
  int offset = 0;
  for(int i = 0; i < attrCnt; i++) {
    if (strlen(attrList[i].attrName) >= sizeof ad.attrName)
      return NAMETOOLONG;
    strcpy(ad.attrName, attrList[i].attrName);
    ad.attrOffset = offset;
    ad.attrType = attrList[i].attrType;
    ad.attrLen = attrList[i].attrLen;
    if ((status = attrCat->addInfo(ad)) != OK)
    {
	cout << "got error return"  << status << endl;
      return status;
    }
    offset += ad.attrLen;
  }

  // now create the actual heapfile to hold the relation
  status = createHeapFile (relation);
  if (status != OK) return status;
  return OK;
}
int main(int argc, char *argv[])
{
  if (argc < 2) {
    cerr << "Usage: " << argv[0] << " dbname" << endl;
    return 1;
  }

  // create database subdirectory and chdir there

  if (mkdir(argv[1], S_IRUSR | S_IWUSR | S_IXUSR
	             | S_IRGRP | S_IWGRP | S_IXGRP) < 0) {
    perror("mkdir");
    exit(1);
  }


  if (chdir(argv[1]) < 0) {
    perror("chdir");
    exit(1);
  }

  // create buffer manager
  
  bufMgr = new BufMgr(100);
  

  Status status;
  // create heapfiles to hold the relcat and attribute catalogs
  status = createHeapFile("relcat");
  if (status != OK) {
    error.print(status);
    exit(1);
  }
  status = createHeapFile("attrcat");
  if (status != OK) {
    error.print(status);
    exit(1);
  }

  // open relation and attribute catalogs
  relCat = new RelCatalog(status);
  if (status == OK)
    attrCat = new AttrCatalog(status);
  if (status != OK) {
    error.print(status);
    exit(1);
  }

  // add tuples describing relcat and attrcat to relation catalog
  // and attribute catalog

  RelDesc rd;
  AttrDesc ad;

  strcpy(rd.relName, RELCATNAME);
  rd.attrCnt = 2;
  CALL(relCat->addInfo(rd));

  strcpy(ad.relName, RELCATNAME);
  strcpy(ad.attrName, "relName");
  ad.attrOffset = 0;
  ad.attrType = (int)STRING;
  ad.attrLen = sizeof rd.relName;
  CALL(attrCat->addInfo(ad));

  strcpy(ad.attrName, "attrCnt");
  ad.attrOffset += sizeof rd.relName;
  ad.attrType = (int)INTEGER;
  ad.attrLen = sizeof rd.attrCnt;
  CALL(attrCat->addInfo(ad));

  strcpy(rd.relName, ATTRCATNAME);
  rd.attrCnt = 5;
  CALL(relCat->addInfo(rd))

  strcpy(ad.relName, ATTRCATNAME);
  strcpy(ad.attrName, "relName");
  ad.attrOffset = 0;
  ad.attrType = (int)STRING;
  ad.attrLen = sizeof ad.relName;
  CALL(attrCat->addInfo(ad));

  strcpy(ad.attrName, "attrName");
  ad.attrOffset += sizeof ad.relName;
  ad.attrType = (int)STRING;
  ad.attrLen = sizeof ad.attrName;
  CALL(attrCat->addInfo(ad));

  strcpy(ad.attrName, "attrOffset");
  ad.attrOffset += sizeof ad.attrName;
  ad.attrType = (int)INTEGER;
  ad.attrLen = sizeof ad.attrOffset;
  CALL(attrCat->addInfo(ad));

  strcpy(ad.attrName, "attrType");
  ad.attrOffset += sizeof ad.attrOffset;
  ad.attrType = (int)INTEGER;
  ad.attrLen = sizeof ad.attrType;
  CALL(attrCat->addInfo(ad));

  strcpy(ad.attrName, "attrLen");
  ad.attrOffset += sizeof ad.attrType;
  ad.attrType = (int)INTEGER;
  ad.attrLen = sizeof ad.attrLen;
  CALL(attrCat->addInfo(ad));

  delete relCat;
  delete attrCat;

  delete bufMgr;

  cout << "Database " << argv[1] << " created" << endl;

  return 0;
}