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

📄 selectexe.c

📁 一个c语言开发的小型的dbms系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (i=0;i<TabMax;i++)
		if (stringcmp(tname,TabDic[i].tab_name)==0)
		{
			j = TabDic[i].row_len;
			break;
		}
	return(j);
}

//从表字典表得到表名
char *	GetTabName(int tid)
{
	int		i;

	for (i=0;i<TabMax;i++)
		if (TabDic[i].tab_id == tid)
			return(TabDic[i].tab_name);

	return(NULL);
}

//从列字典表得到字段id
int		GetColID(char *fname)
{
	int		i,j=0;

	for (i=0;i<ColMax;i++)
		if (stringcmp(fname,ColDic[i].col_name)==0)
		{
			j = ColDic[i].col_id;
			break;
		}
	return(j);
}

//从列字典表得到字段类型
int		GetColType(int fid)
{
	int		i,j;

	for (i=0;i<ColMax;i++)
		if (ColDic[i].col_id == fid)
		{
			j = ColDic[i].col_type;
			break;
		}
	return(j);
}

//从列字典表得到字段所在表的表id
int		GetColTabID(int fid)
{
	int		i,j=0;
	for (i=0;i<ColMax;i++)
		if (ColDic[i].col_id == fid)
		{
			j = ColDic[i].tab_id;
			break;
		}
	return(j);
}

//从列字典表得到字段名
char *	GetColName(int fid)
{
	int		i;

	for (i=0;i<ColMax;i++)
		if (ColDic[i].col_id == fid)
			return(ColDic[i].col_name);

	return(0);
}

//得到字段在Tfield重的位置
int		LocateTField(int fid)
{
	int i;

	for(i=0;i<ColNum;i++)
	{
		if (Tfield[i].col_id == fid) return (i);
	}

	return(0);
}

//返回临时文件名
FILE	*CreateTmpFile(char *tname)
{
	int		i;
	int		TabID;
	char	Tmp[24];
	char	TmpFileName[50]="Data";
	FILE	*tmpp;

	//把表中的字段放到Tfield
	TabID = GetTabID(tname);
	for (i=0;i<ColMax;i++)
	{
		if (ColDic[i].tab_id==TabID) 
		{
			Tfield[ColNum].col_id = ColDic[i].col_id;
			Tfield[ColNum].type = ColDic[i].col_type;
			Tfield[ColNum].length = ColDic[i].col_length;
			ColNum++;

			//write template table dictionary
			TTabDic2.col_num++;
			TTabDic2.row_len += ColDic[i].col_length+1 ;
		}
	}
	
	//创建临时文件
	itoa(TfileNum++,Tmp,10);
	strcat(TmpFileName,Tmp);
	strcat(TmpFileName,".tmp");		//template table name will like "Data0.tmp"

	strcpy(TTabDic2.tab_name,TmpFileName);

	if ((tmpp=fopen(TmpFileName,"wb+"))==NULL)
	{
		printf("Can't open %s file\n",TmpFileName);
		exit(3);
	}

	//写临时文件头:列数、列id
	//fwrite(ColNum,4,1,tmpp);
	for (i=0;i<ColNum;i++)
	{
		//fwrite(Tfield[i].col_id,4,1,tmpp);
	}

	return(tmpp);
}

//单表优化
int	Pretreat(char *tname)
{
	int		i;
	long	BufSize;
	int		BlockNum;
	FILE	*tmpfp;
	char	Buf1[BUFSIZE];
//	char    Buff[10240];
	int		*NextBlock;
	int		*NextAddr;
	int		EndSpace=0;

	//写临时文件
	tmpfp = CreateTmpFile(tname);	//write tmp table head infomation
	//BufSize = GetTabRowLen(tname)*GetTabRowNum(tname);
	BlockNum = GetTabAddr(tname);
	EndSpace = (BUFSIZE-24) % GetTabRowLen(tname);
	do
	{
		fseek(fp,BlockNum*BUFSIZE,0);
		fread(Buf1,BUFSIZE,1,fp);
		NextBlock = (int *)Buf1;
		BlockNum = *NextBlock;
		NextAddr = (int *)(Buf1+4);
		if (*NextBlock != -1) 
		{
			fwrite(Buf1+24,BUFSIZE-24-EndSpace,1,tmpfp);
		}
		else
		{
			fwrite(Buf1+24,(*NextAddr) % BUFSIZE,1,tmpfp);
		}
	}while (*NextBlock != -1);

//	rewind(tmpfp);
//	fread(Buff,BUFSIZE*4,1,tmpfp);
	for (i=0;i<TabMax;i++)
	{
		if (stringcmp(TabDic[i].tab_name,tname)==0) 
		{
			TTabDic2.row_num = TabDic[i].row_num ;
			break;
		}
	}
	TTabDic1 = TTabDic2;

	fclose(tmpfp);
}

//对两个表做连接操作
char *MergeTab(char *tname,char *tname1)
{
	int		i,j;
	int		BlockNum;
	long	Len,Num;
	char	TmpBuf[BUFSIZE];
	char	Buf1[BUFSIZE];
	int		pBuf1;
	char	TmpFileName[50]="Data";
	FILE	*fp1,*fp2;
	int		*NextBlock, EndSpace;

	//open 临时文件1
	if ((fp1=fopen(tname1,"r+"))==NULL)
	{
		printf("Can't open %s file\n",tname1);
		exit(3);
	}
	
	//创建临时文件2
	fp2 = CreateTmpFile(tname);	//write tmp table head infomation

	//做两个表的笛卡尔乘积
	//先从tname取一条纪录,然后与临时表tname1的所有记录连接,输出到tname2
	Len = GetTabRowLen(tname);
	Num = GetTabRowNum(tname);
	TTabDic2.row_num = 0;
	BlockNum = GetTabAddr(tname);
	fseek(fp,BlockNum*BUFSIZE,0);
	fread(Buf1,BUFSIZE,1,fp);
	NextBlock = (int *)Buf1;
	pBuf1 = 24;
	EndSpace = (BUFSIZE-24) % GetTabRowLen(tname);
	for(j=0;j<Num;j++)
	{
		if (pBuf1 > BUFSIZE - EndSpace -24)
		{
			BlockNum = *NextBlock;
			fseek(fp,BlockNum*BUFSIZE,0);
			fread(Buf1,BUFSIZE,1,fp);
			NextBlock = (int *)Buf1;
			pBuf1 = 24;
		}
//		 Buf1+pBuf1
		for(i=0;i<Len;i++)
			TmpBuf[TTabDic1.row_len+i] = Buf1[pBuf1++];
		rewind(fp1);
		for(i=0;i<TTabDic1.row_num;i++)
		{
			fread(TmpBuf,TTabDic1.row_len,1,fp1);
			fwrite(TmpBuf,TTabDic2.row_len,1,fp2);
			TTabDic2.row_num ++;
		}
	}

	TTabDic1 = TTabDic2;

	fclose(fp1);
	fclose(fp2);
	return(TTabDic2.tab_name);
}

//字符串比较
int		stringcmp(const char *s1, const char *s2)
{
	int i=0;
	while (s1[i]!=NULL && s2[i]!=NULL)
	{
		if (s1[i]!=s2[i]) break;
		i++;
	}
	if (s1[i] == s2[i]) 
		return(0);
	else 
		if (s1[i] > s2[i])
			return(1);
		else
			return(-1);
}

/******************************************************************************
								处理where子句
	采用后序扁历的方法,用S[]栈存储节点(指针),Tval[]存储计算的结果,Tmp[]来标示
左右子女是否已处理过。sp为S[]和Tmp[]的指针,tp为Tval[]的指针。
*******************************************************************************/
int dCondition()
{
	struct	_conditions		*S[CONNUM];
	struct	_fval			Tval[CONNUM];
	int		sp=0,tp=-1,Tmp[CONNUM];
	int		i;


	//没有条件
	if (Tdelete.cons == NULL) return(1);

	//有条件: 后续遍历
	S[sp]=Tdelete.cons;
	Tmp[sp] = 2;

	while (sp>=0) 
	{
		if (Tmp[sp] == 2)		//未处理节点,左子女进栈
		{
			Tmp[sp] = 1;
			S[sp+1] = S[sp]->left ;
			sp++;
			if (S[sp]->left == NULL) 
				Tmp[sp] = 0;
			else
				Tmp[sp] =2;
			continue;
		}
		else if (Tmp[sp] == 1)	//右子女进栈
		{
			Tmp[sp] = 0;
			S[sp+1] = S[sp]->right ;
			sp++;
			if (S[sp]->left == NULL) 
				Tmp[sp] = 0;
			else
				Tmp[sp] =2;
			continue;
		}
		else					//处理节点
		{
			/*	先判断comp_op操作符: 'a'(表示AND)、'o'(表示OR)、d'='、'<'、'>'等
				如果是叶节点则判断type:'3'表示子段、'1'表示字符串值、'0'表示整型值*/
			switch (S[sp]->comp_op)
			{
				case	'a':
				{
					tp--;
					if ((Tval[tp].iVal !=0) && (Tval[tp+1].iVal !=0))
						Tval[tp].iVal = 1;
					else
						Tval[tp].iVal =0;
					Tval[tp].type = 1;
					break;
				}
				case	'o':
				{
					tp--;
					if ((Tval[tp].iVal !=0) || (Tval[tp+1].iVal !=0))
						Tval[tp].iVal = 1;
					else
						Tval[tp].iVal =0;
					Tval[tp].type = 1;
					break;
				}
				case	'=':
				{
					tp--;
					if (Tval[tp].type != Tval[tp+1].type) printf("Error:'=' 类型不符!\n");
					switch (Tval[tp].type)
					{
						case	1:
							{
								if (stringcmp(Tval[tp].szVal,Tval[tp+1].szVal) == 0)
									Tval[tp].iVal = 1;
								else
									Tval[tp].iVal =0;
								break;
							}
						case	0:
							{
								if (Tval[tp].iVal == Tval[tp+1].iVal )
									Tval[tp].iVal = 1;
								else
									Tval[tp].iVal =0;
								break;
							}
						default: break;
					}
					Tval[tp].type = 1;
					break;
				}
				case	'>':
				{
					tp--;
					if (Tval[tp].type != Tval[tp+1].type) printf("Error:'>' 类型不符!\n");
					switch (Tval[tp].type)
					{
						case	1:
							{
								if (stringcmp(Tval[tp].szVal,Tval[tp+1].szVal) > 0)
									Tval[tp].iVal = 1;
								else
									Tval[tp].iVal =0;
								break;
							}
						case	0:
							{
								if (Tval[tp].iVal > Tval[tp+1].iVal )
									Tval[tp].iVal = 1;
								else
									Tval[tp].iVal =0;
								break;
							}
						default: break;
					}
					Tval[tp].type = 1;
					break;
				}
				case	'<':
				{
					tp--;
					if (Tval[tp].type != Tval[tp+1].type) printf("Error:'<' 类型不符!\n");
					switch (Tval[tp].type)
					{
						case	1:
							{
								if (stringcmp(Tval[tp].szVal,Tval[tp+1].szVal) < 0)
									Tval[tp].iVal = 1;
								else
									Tval[tp].iVal =0;
								break;
							}
						case	0:
							{
								if (Tval[tp].iVal < Tval[tp+1].iVal )
									Tval[tp].iVal = 1;
								else
									Tval[tp].iVal =0;
								break;
							}
						default: break;
					}
					Tval[tp].type = 1;
					break;
				}
				default:	//叶节点,把值保存下来,入Tval[]
				{
					tp++;
					switch (S[sp]->type)
					{
						case	'2':	//field:把子段名称换成相应的值
						{
							i = GetColID(S[sp]->value);
							i = LocateTField(i);
							if (GetColType(GetColID(S[sp]->value))==1)
							{
								Tval[tp].type = 1;
								strcpy(Tval[tp].szVal,Tfield[i].charval);
//								Tval[tp].szVal = Tfield[i].charval;
							}
							else
							{
								Tval[tp].type = 0;
								Tval[tp].iVal = Tfield[i].intval;
							}
							break;
						}
						case	'1':	//string
						{
							Tval[tp].type =1;
							strcpy(Tval[tp].szVal,S[sp]->value); 
							break;
						}
						case	'0':	//int
						{
							Tval[tp].type =0;
							Tval[tp].iVal = S[sp]->intval ;
							break;
						}
						default: break;
					}
				}
			}
			sp--;	//出栈
		}
	}

	return(Tval[0].iVal);
}

void del(_deletestruct_type *ds)	//用来检测delete语句的语法树是否正确
{
	int		i,j,k;
	int		RecordLen;
	int		BlockNum;
	int		RecInBlock,offset;
	int		TabID;
	int		*NextAddr,*NextBlock;
	int		DelFlag=0;
	long	lfp;
	int		ConsRecNum;
	int		RecordNum;
	int		ddd;
	
	fp = NULL;			//数据文件指针
	TfileNum=0;			//临时文件的数量
	TabNum=0;			//涉及的表的数量
	RecNum=0;			//临时表的记录数
	ColNum=0;			//涉及的表的列数
	TabMax = 0;
	ColMax = 0;
	for (i=0;i<BUFSIZE;i++) Buf[i]=0;
    for (i=0;i<TABNUM;i++)	strcpy(TabName[i],"");//涉及的表的名称

	read_dic(TabDic,&TabMax,ColDic,&ColMax);
    Tdelete = *ds;

	//open data file
	if ((fp=fopen("DATABASE","rb+"))==NULL)
	{

		printf("Can't open data file\n");
		exit(1);
	}

	//把表中的字段放到Tfield
	TabID = GetTabID(Tdelete.table);
	for (i=0;i<ColMax;i++)
	{
		if (ColDic[i].tab_id==TabID) 
		{
			Tfield[ColNum].col_id = ColDic[i].col_id;
			Tfield[ColNum].type = ColDic[i].col_type;
			Tfield[ColNum].length = ColDic[i].col_length;
			Tfield[ColNum].charval = ColDic[i].col_name;
			ColNum++;
			//write template table dictionary
		}
	}


	//删除字段
	BlockNum = GetTabAddr(Tdelete.table);
	RecInBlock = (int)((BUFSIZE-24)/GetTabRowLen(Tdelete.table));
	offset = 24;
	RecordNum = GetTabRowNum(Tdelete.table);
	ConsRecNum =0;
	do
	{
		lfp = BlockNum*BUFSIZE;
		fseek(fp,BlockNum*BUFSIZE,0);
		fread(Buf,24,1,fp);
		lfp += 24;
		NextBlock = (int *)Buf;
		ddd = BlockNum;
		BlockNum = *NextBlock;
		NextAddr = (int *)(Buf+4);
		if (BlockNum != -1) 
			k = RecInBlock;
		else
			k = (int)(((*NextAddr)% BUFSIZE-24)/GetTabRowLen(Tdelete.table));
		for(i=0;i<k;i++)
		{	
			//fp1 = fp2;
			ConsRecNum++;
			fread(Buf,GetTabRowLen(Tdelete.table),1,fp);
			lfp += GetTabRowLen(Tdelete.table);
			ReadARecord(Buf,Tfield);
			offset+=GetTabRowLen(Tdelete.table);
			if (dCondition()==1) 
			{
				//MoveEnd2Current
				for (j=0;j<TabMax;j++)
					if (strcmp(Tdelete.table,TabDic[j].tab_name)==0)
						break;
				fclose(fp);
				get_last(TabDic[j],Buf);
					//open data file
				TabDic[j].row_num--;
				DelFlag ++;
				if (ConsRecNum >= RecordNum) break;

				if ((fp=fopen("DATABASE","rb+"))==NULL)
				{

					printf("Can't open data file\n");
					exit(1);
				}
				lfp -= GetTabRowLen(Tdelete.table);
				fseek(fp,lfp,0);
				fwrite(Buf,GetTabRowLen(Tdelete.table),1,fp);
				fseek(fp,lfp,0);
				i--;
				
				//if (i==k) BlockNum = ddd;
			}//end if condition
		}
	}while (BlockNum != -1);

	printf("%d records deleted\n",DelFlag);//delete record	
	fclose(fp);
}
 

⌨️ 快捷键说明

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