示例#1
0
/*
 * This function is used to update a Record,
 * updating on a deleted page is not possible
 */
RC updateRecord (RM_TableData *rel, Record *record)
{
	//Find the data to be updated
	if(record->id.page > 0 && record->id.page <=  totalPages)
	{
		BM_PageHandle *page = MAKE_PAGE_HANDLE();

		int pageNum, slotNum;

		// Setting record id and slot number
		pageNum = record->id.page;
		slotNum = record->id.slot;

		//Compare if the record is a deleted Record,
		//return update not possible for deleted records (EC 401)

		if(strncmp(record->data, "DELETED_RECORD", 14) == 0)
			return RC_RM_UPDATE_NOT_POSSIBLE_ON_DELETED_RECORD;

		//Take the serailized updated record data
		char *record_str = serializeRecord(record, rel->schema);

		//pin page
		pinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page, record->id.page);

		//set the new fields, or the entire modified page
		memset(page->data, '\0', strlen(page->data));
		sprintf(page->data, "%s", record_str);

		//free the temp data
		free(record_str);

		//mark the page as dirty
		markDirty(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		//unpin the page, after use
		unpinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		//force write onto the page, as it is modified page now
		forcePage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		//printf("record data in update: %s\n", page->data);

		free(page);		//free page, avoid leaks
		return RC_OK;
	}
	else
	{
		return RC_RM_NO_MORE_TUPLES;	//return the data to be modfied not found
	}

	return RC_OK;
}
void pageOperations(recordTableInfo *table, int pageNum, int slot,
		RM_TableData *rel, Record *record) {
	BM_PageHandle *pageHandle=NULL;
	pageHandle = getBuffPageHandle();
	char *strRecord,*tempData;
	strRecord = serializeRecord(record, rel->schema);
	if(pinPage(table->bufferManager, pageHandle, pageNum)==RC_OK)
			strncpy(pageHandle->data + (slot * table->slotSize), strRecord,
			strlen(strRecord));

	markDirty(table->bufferManager, pageHandle);
	unpinPage(table->bufferManager, pageHandle);
	if(forcePage(table->bufferManager, pageHandle)==RC_OK)
		record->id.tombS = false;
	table->numOfRecords = table->numOfRecords + 1;
	tableInfoDetailsToFileData(rel->name, tempData, table);
		free(pageHandle);
		free(strRecord);
}
char *
serializeTableContent(RM_TableData *rel) {
	int i;
	VarString *result;
	RM_ScanHandle *sc = (RM_ScanHandle *) malloc(sizeof(RM_ScanHandle));
	Record *r = (Record *) malloc(sizeof(Record));
	MAKE_VARSTRING(result);

	for (i = 0; i < rel->schema->numAttr; i++)
		APPEND(result, "%s%s", (i != 0) ? ", " : "", rel->schema->attrNames[i]);

	startScan(rel, sc, NULL);

	while (next(sc, r) != RC_RM_NO_MORE_TUPLES) {
		APPEND_STRING(result, serializeRecord(r, rel->schema));
		APPEND_STRING(result, "\n");
	}
	closeScan(sc);

	RETURN_STRING(result);
}
void testScansTwo (void)
{
  RM_TableData *table = (RM_TableData *) malloc(sizeof(RM_TableData));
  TestRecord inserts[] = { 
    {1, "aaaa", 3}, 
    {2, "bbbb", 2},
    {3, "cccc", 1},
    {4, "dddd", 3},
    {5, "eeee", 5},
    {6, "ffff", 1},
    {7, "gggg", 3},
    {8, "hhhh", 3},
    {9, "iiii", 2},
    {10, "jjjj", 5},
  };
  bool foundScan[] = {
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE
  };
  int numInserts = 10, i;
  Record *r;
  RID *rids;
  Schema *schema;
  RM_ScanHandle *sc = (RM_ScanHandle *) malloc(sizeof(RM_ScanHandle));
  Expr *sel, *left, *right, *first, *se;
  int rc;

  testName = "test creating a new table and inserting tuples";
  schema = testSchema();
  rids = (RID *) malloc(sizeof(RID) * numInserts);
  
  TEST_CHECK(initRecordManager(NULL));
  TEST_CHECK(createTable("test_table_r",schema));
  TEST_CHECK(openTable(table, "test_table_r"));
  
  // insert rows into table
  for(i = 0; i < numInserts; i++)
  {
    r = fromTestRecord(schema, inserts[i]);
    TEST_CHECK(insertRecord(table,r)); 
    rids[i] = r->id;
  }

  TEST_CHECK(closeTable(table));
  TEST_CHECK(openTable(table, "test_table_r"));

  // Select 1 record with INT in condition a=2.
  MAKE_CONS(left, stringToValue("i2"));
  MAKE_ATTRREF(right, 0);
  MAKE_BINOP_EXPR(sel, left, right, OP_COMP_EQUAL);
  createRecord(&r, schema);
  TEST_CHECK(startScan(table, sc, sel));
  while((rc = next(sc, r)) == RC_OK)
  {
     ASSERT_EQUALS_RECORDS(fromTestRecord(schema, inserts[1]), r, schema, "compare records");
  }
  if (rc != RC_NO_TUPLES)
    TEST_CHECK(rc);
  TEST_CHECK(closeScan(sc));
  
  // Select 1 record with STRING in condition b='ffff'.
  MAKE_CONS(left, stringToValue("sffff"));
  MAKE_ATTRREF(right, 1);
  MAKE_BINOP_EXPR(sel, left, right, OP_COMP_EQUAL);
  createRecord(&r, schema);
  TEST_CHECK(startScan(table, sc, sel));
  while((rc = next(sc, r)) == RC_OK)
  {
     ASSERT_EQUALS_RECORDS(fromTestRecord(schema, inserts[5]), r, schema, "compare records");
     serializeRecord(r, schema);
  }
  if (rc != RC_NO_TUPLES)
    TEST_CHECK(rc);
  TEST_CHECK(closeScan(sc));
  
  // Select all records, with condition being false
  MAKE_CONS(left, stringToValue("i4"));
  MAKE_ATTRREF(right, 2);
  MAKE_BINOP_EXPR(first, right, left, OP_COMP_SMALLER);
  MAKE_UNOP_EXPR(se, first, OP_BOOL_NOT);
  TEST_CHECK(startScan(table, sc, se));
    while((rc = next(sc, r)) == RC_OK)
    {
     serializeRecord(r, schema);
     for(i = 0; i < numInserts; i++)
     {
       if (memcmp(fromTestRecord(schema, inserts[i])->data,r->data,getRecordSize(schema)) == 0)
	     foundScan[i] = TRUE;
     }
    }
  if (rc != RC_NO_TUPLES)
    TEST_CHECK(rc);
  TEST_CHECK(closeScan(sc));
  
  ASSERT_TRUE(!foundScan[0], "not greater than four");
  ASSERT_TRUE(foundScan[4], "greater than four");
  ASSERT_TRUE(foundScan[9], "greater than four");

  // clean up
  TEST_CHECK(closeTable(table));
  TEST_CHECK(deleteTable("test_table_r"));
  TEST_CHECK(shutdownRecordManager());

  freeRecord(r);
  free(table);
  free(sc);
  freeExpr(sel);
  TEST_DONE();
}
示例#5
0
/*
 * This function is used to insert a new Record into the table
 * while inserting, the record Manager assigns a RID to the record
 * and update the "record" parameter too
 */
RC insertRecord (RM_TableData *rel, Record *record)
{
	//Create a record variable
	Record *r = (Record *)malloc(sizeof(Record));

	RID rid;
	rid.page = 1;
	rid.slot = 0;

	//Find the next place of insertion of a record
	while(rid.page > 0 && rid.page < totalPages)
	{
		rid.page = rid.page + 1;
		rid.slot = 0;

		/*getRecord(rel, rid, r); //obtaining the record from the table
		//checking for soft delete record in the table space for insertion
		if(strncmp(r->data, "DELETED_RECORD", 14) == 0)
			break;*/
	}


	r = NULL;
	free(r); //free the memory of r which was just a temporary allocation

	//mark the page as free page
	((RM_RecordMgmt *)rel->mgmtData)->freePages[0] = rid.page;

	//create a page handle
	BM_PageHandle *page = MAKE_PAGE_HANDLE();

	//assign the record, its RID and slot number
	record->id.page = ((RM_RecordMgmt *)rel->mgmtData)->freePages[0];
	record->id.slot = 0;

	//Serialize the Record to be inserted
	char * serializedRecord = serializeRecord(record, rel->schema);

	//Pin the record page, to mark that it is in use
	pinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page, ((RM_RecordMgmt *)rel->mgmtData)->freePages[0]);

	//insert the new record data, into the Table i.e. Pages of the PageFile
	memset(page->data, '\0', strlen(page->data));
	sprintf(page->data, "%s", serializedRecord);

	//mark the page as Dirty Page, as now there is a new record entry on that page
	markDirty(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

	//Unpin the page as now it has been used
	unpinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

	//Force Page to push entire data onto the page
	forcePage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

	//printf("record data: %s\n", page->data);

	free(page);		//free page, avoid memory leaks

	((RM_RecordMgmt *)rel->mgmtData)->freePages[0] += 1;

	totalPages++;
	return RC_OK;
}