⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sm_manager.cpp

📁 斯坦福大学数据库实现的代码,非常好的.可以了解数据库系统的实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					if (ret < 1) { break; }					//printf ("int = %d\n", j);					T.SetValue (i, &j);					break;				case TYPE_FLOAT:					float f;					ret = fscanf (ifp, " %f ", &f);					if (ret < 1) { break; }					//printf ("float = %f\n", f);					T.SetValue (i, &f);					break;				case TYPE_STRING:					char s[MAXSTRINGLEN+1];					memset (s, 0, MAXSTRINGLEN+1);					ret = fscanf (ifp, " '%[^'\n]' ", s);					if (ret < 1) { break; }					//printf ("string = %s\n", s);					T.SetValue (i, s);					break;			}			/* Check if an error occured */			/* If we reached end of file exit the loop */			if (ret == -1 && i==0) { 				break; 			}			/* If we encountered an error, clean up and return */			else if (ret < 1) {			  	fprintf (stderr, "*** Error reading attribute ***");				fprintf (stderr, " %s at line %d ***\n", info[i].attrName, lineNum);				fprintf (stderr, "Saving the %d tuples read so far..\n", lineNum-1);				/* Save records read so far */				fileHandle.ForceAllPages ();				/* Free up memory */				free (info);				fclose (ifp);				/* Close file */				rmm.CloseFile (fileHandle);				/* Return error */				return SM_BADINPUT;			}		}		/* Exit loop if an error has occured */		if (ret < 1) {			break;		}		/* Get the tuple's contents */		T.GetData (pData);		/* Insert record */		RID rid;		rc = fileHandle.InsertRec (pData, rid);		if (rc != SUCCESS) { 			free (info);			fclose (ifp);			return rc; 		}		/* free up memory now (after inserting record) */		free (pData); pData = NULL;		/* Increment line number */		lineNum++;	}	/* Close the input file */	fclose (ifp);	/* Free allocated memory */	free (info);	/* Flush dirty pages to disk */	rc = fileHandle.ForceAllPages ();	if (rc != SUCCESS) { return rc; }	/* Close the file handle */	rc = rmm.CloseFile (fileHandle);	if (rc != SUCCESS) { return rc; }	printf ("%d tuples read\n", lineNum-1);	/* Successfully loaded data into the file */	return SUCCESS;}RC SM_Manager::Help () { 	/* Check if we are not connected to a database */	if (!bOpen) { return SM_DBCLOSED; }	printf ("Tables in this database:\n");	return Print (relName_relcat);}RC SM_Manager::Help (const char *relName) { 	/* Check if we are not connected to a database */	if (!bOpen) { return SM_DBCLOSED; }	DataAttrInfo *info;	int attrCount;	RC rc;	/* Determine the structure of the relation */	rc = GetDataAttrInfo (relName, info, attrCount);	if (rc != SUCCESS) { return rc; }	printf ("Help for %s:\n", relName);	/* Print the tuple header */	PrintTupleHeader (dataAttrInfo_attrcat, 5);	/* Print out the structure */	for (int i = 0; i < attrCount; i++) {		SM_Tuple T (dataAttrInfo_attrcat, 5, 				info[i].relName, 				info[i].attrName,				info[i].offset,				info[i].attrType,				info[i].attrLength);		T.PrintData ();	}		/* Free up memory allocated to info */	free (info);	/* Successfully printed help */	return SUCCESS;}RC SM_Manager::CrossProduct (const char *rel1, const char *rel2) {	/* Check if we are not connected to a database */	if (!bOpen) { return SM_DBCLOSED; }	const char *relName_outer = rel1;	const char *relName_inner = rel2;	RC rc;	RM_FileHandle fileHandle_outer, fileHandle_inner;	/* Get a handle to the outer relation */	rc = rmm.OpenFile (relName_outer, fileHandle_outer);	if (rc != SUCCESS) { return rc; }	/* Get a handle to the inner relation */	rc = rmm.OpenFile (relName_inner, fileHandle_inner);	if (rc != SUCCESS) { return rc; }	RM_FileScan fileScan_outer, fileScan_inner;	/* Open a file scan on the outer relation */	rc = fileScan_outer.OpenScan (fileHandle_outer, 			TYPE_STRING, MAXNAME, 0, /* <-- Doesn't matter what						    these 3 values are						    because the scan is						    based on NO_OP */			NO_OP, NULL, NO_HINT);	if (rc != SUCCESS) { return rc; }	/* Open a file scan on the inner relation */	rc = fileScan_inner.OpenScan (fileHandle_inner, 			TYPE_STRING, MAXNAME, 0, /* <-- Doesn't matter what						    these 3 values are						    because the scan is						    based on NO_OP */			NO_OP, NULL, NO_HINT);	if (rc != SUCCESS) { return rc; }	/* Determine the attributes present in each relation */	DataAttrInfo *info_outer, *info_inner;	int attrCount_outer, attrCount_inner;	/* Get attribute information for the outer relation */	rc = GetDataAttrInfo (relName_outer, info_outer, attrCount_outer);	if (rc != SUCCESS) { return rc; }	/* Get attribute information for the inner relation */	rc = GetDataAttrInfo (relName_inner, info_inner, attrCount_inner);	if (rc != SUCCESS) { 		free (info_outer);		return rc; 	}	RM_Record rec_outer, rec_inner;	char *pData;	int  nRecords = 0; /* # of records in cross-product */	/* Do the cross product */	while (fileScan_outer.FetchPages() == SUCCESS) {		while (fileScan_inner.FetchPages() == SUCCESS) {			while (fileScan_outer.GetNextRecInMem(rec_outer) == SUCCESS) {				/* Build an SM_Tuple object from the outer record */				rec_outer.GetData (pData);				SM_Tuple T_outer (info_outer, attrCount_outer, pData);				while (fileScan_inner.GetNextRecInMem(rec_inner) == SUCCESS) {					/* Build an SM_Tuple object from the inner record */					rec_inner.GetData (pData);					SM_Tuple T_inner (info_inner, attrCount_inner, pData);					/* Combine the two tuples */					SM_Tuple T = T_outer + T_inner;					/* Print the tuple */					T.PrintData ();					/* Increment count */					nRecords++;				}				fileScan_inner.JumpToFirstRecInMem();			}			fileScan_outer.JumpToFirstRecInMem();		}		/* Re-open a file scan on the inner relation */		fileScan_inner.CloseScan();		rc = fileScan_inner.OpenScan (fileHandle_inner, TYPE_STRING, 				MAXNAME, 0, NO_OP, NULL, NO_HINT);		if (rc != SUCCESS) { 			free (info_outer); free (info_inner);			return rc; 		}	}	/* Print # of records in the cross-product */	printf ("%d records in cross-product\n", nRecords);	/* Free up attribute information for the inner relation */	free (info_inner);	/* Free up attribute information for the outer relation */	free (info_outer);	/* Close the inner file scan */	rc = fileScan_inner.CloseScan ();	if (rc != SUCCESS) { return rc; }	/* Close the outer file scan */	rc = fileScan_outer.CloseScan ();	if (rc != SUCCESS) { return rc; }	/* Close the inner file handle */	rc = rmm.CloseFile (fileHandle_inner);	if (rc != SUCCESS) { return rc; }	/* Close the outer file handle */	rc = rmm.CloseFile (fileHandle_outer);	if (rc != SUCCESS) { return rc; }		/* Successfully joined relations */	return SUCCESS;}RC SM_Manager::EquiJoin (const char *rel1, const char *rel2,			 const int *attrList1, const int *attrList2,			 int condCount) {	/* Check if we are not connected to a database */	if (!bOpen) { return SM_DBCLOSED; }	/*	   // Uncomment these lines	const char *relName_outer = rel1;	const char *relName_inner = rel2;	const int  *attrList_outer = attrList1;	const int  *attrList_inner = attrList2;	*/	/* ---- Write your equi-join code here ---- */	/* Successfully joined relations */	return SUCCESS;}RC SM_Manager::EquiJoin_Opt (const char *rel1, const char *rel2,			 const int *attrList1, const int *attrList2,			 int condCount) {	/* Check if we are not connected to a database */	if (!bOpen) { return SM_DBCLOSED; }	/*	   // Uncomment these lines	const char *relName_outer = rel1;	const char *relName_inner = rel2;	const int  *attrList_outer = attrList1;	const int  *attrList_inner = attrList2;	*/	/* ---- Write your optimized equi-join code here ---- */	/* Successfully joined relations */	return SUCCESS;}RC SM_Manager::Print (const char *relName) { 	/* Check if we are not connected to a database */	if (!bOpen) { return SM_DBCLOSED; }	/* Step 1 */	RC rc;	/* Determine the structure of the relation */	DataAttrInfo *info;	int attrCount;	rc = GetDataAttrInfo (relName, info, attrCount);	if (rc != SUCCESS) { return rc; }	/* Step 2 */	/* Scan the relation and print its tuples */	RM_FileHandle fileHandle;	/* Get a handle to the file first */	rc = rmm.OpenFile (relName, fileHandle);	if (rc != SUCCESS) { 		free (info);		return rc; 	}	RM_FileScan fileScan;	/* Open a file scan using the file handle */	rc = fileScan.OpenScan (fileHandle, 			TYPE_STRING, MAXNAME, 0, /* <-- Doesn't matter what						    these values are						    because the scan is						    based on NO_OP */			NO_OP, NULL, NO_HINT);	if (rc != SUCCESS) { 		free (info);		return rc; 	}	/* Print the tuple header */	PrintTupleHeader (info, attrCount);	RM_Record rec;	/* Get each record from the file */	while (fileScan.GetNextRec(rec) == SUCCESS) {		char *pData;		/* Get the record's contents (data) */		rc = rec.GetData (pData);		/* Clean up before returning from an error */		if (rc != SUCCESS) {			free (info);			fileScan.CloseScan ();			return rc;		}		/* Create a tuple from the record */		SM_Tuple T (info, attrCount, pData);		/* Print the tuple to the standard output */		T.PrintData ();	}	/* Free up relation structure information */	free (info);	/* Close the scan */	rc = fileScan.CloseScan ();	if (rc != SUCCESS) { return rc; }	/* Print info about relation */	int nRecords, nPages;	rc = fileHandle.GetNumRecords(nRecords);	if (rc != SUCCESS) { return rc; }	rc = fileHandle.GetNumPages(nPages);	if (rc != SUCCESS) { return rc; }	fprintf (stdout, "%d tuples occupying %d pages\n", nRecords, nPages);	/* Close the file handle */	rc = rmm.CloseFile (fileHandle);	if (rc != SUCCESS) { return rc; }	/* Successfully printed relation */	return SUCCESS;}RC SM_Manager::GetDataAttrInfo (const char *relName, DataAttrInfo *&info,		int &attrCount) const {	/* Pad relName because we are going to use it in a file scan. */	char rName[MAXNAME+1];	memset (rName, 0, MAXNAME+1);	strcpy (rName, relName);	/* Step 1 */	/* Use the relation catalog to verify that the relation exists */	RM_FileScan fileScan;	RM_Record rec;	RC rc;	/* Open a scan on relcat */	rc = fileScan.OpenScan (fileHandle_relcat, 			/* dataAttrInfo_relcat[0] corresponds to attribute relName 			   of relation relcat */				dataAttrInfo_relcat[0].attrType,				dataAttrInfo_relcat[0].attrLength,				dataAttrInfo_relcat[0].offset,				EQ_OP, rName, NO_HINT);	/* If there are no records corresponding to this relation, flag an	 * error */	if (fileScan.GetNextRec(rec) != SUCCESS) {		fileScan.CloseScan ();		return SM_RELNOTFOUND;	}	/* Close the scan */	rc = fileScan.CloseScan ();	if (rc != SUCCESS) { return rc; }	/* Step 2 */	/* We now know that the relation exists. Use the attribute catalog 	   to determine the structure of the relation. */	/* Open a scan on attrcat */	rc = fileScan.OpenScan (fileHandle_attrcat, 			/* dataAttrInfo_attrcat[0] corresponds to attribute relName 			   of relation attrcat */				dataAttrInfo_attrcat[0].attrType,				dataAttrInfo_attrcat[0].attrLength,				dataAttrInfo_attrcat[0].offset,				EQ_OP, rName, NO_HINT);	/* initialise attrCount and info */	attrCount = 0; info = NULL;	/* get the structure of each attribute */	while (fileScan.GetNextRec(rec) == SUCCESS) {		char *pData;		/* Get the content's of the record */		rec.GetData (pData);		/* Build a tuple from the retrieved record */		SM_Tuple T (dataAttrInfo_attrcat, 5, pData);		/* Retrieve the name,type,offset,length of each attribute */		DataAttrInfo d;			strcpy (d.relName, rName);			T.GetValue(1, d.attrName); 			T.GetValue(2, &d.offset);			T.GetValue(3, &d.attrType);			T.GetValue(4, &d.attrLength);		/* Increase size of structure by 1 */		attrCount++;		info = (DataAttrInfo *) realloc (info,				attrCount*sizeof(DataAttrInfo));		/* Copy structure information into info */		info[attrCount-1] = d;	}	/* Close the scan */	rc = fileScan.CloseScan ();	if (rc != SUCCESS) { return rc; }	return SUCCESS;}void SM_Manager::PrintTupleHeader (const DataAttrInfo *info, 					int attrCount) const {	/* Print out the attribute names */	for (int i = 0; i < attrCount; i++) {		if (info[i].attrType == TYPE_STRING) {			printf ("%-*s|", info[i].attrLength,					info[i].attrName);		}		else {			printf ("%*s|", 10,					info[i].attrName);		}	}	printf ("\n");	for (int i = 0; i < attrCount; i++) {		int d;		switch (info[i].attrType) {			case TYPE_INT:			case TYPE_FLOAT:  d = 10; break;			case TYPE_STRING: d = info[i].attrLength; break;		}		for (int j = 0; j < d; j++) {			putchar ('-');		}		putchar ('+');	}	printf ("\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -