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

📄 table.h

📁 使用C++编写的数据库管理系统; 拥有自定义数据文件格式
💻 H
📖 第 1 页 / 共 2 页
字号:
int testCondition(FIELDREC test,FIELDREC expect,SYMBOL op);


class Table
{
	Block * tableIndex;
	int totalField;
	int realField;
	int primaryField;
	unsigned long totalRec;
	unsigned long realRec;

public:
	Table(Block * t);
	unsigned long getTotalRec();
	int getRealField();
	void addField(FIELD k);
	void findField(FIELD & k);
	int addRecord(FIELDREC * values);
	void listField();
	void listRecord(FIELD conditionField,SYMBOL op,FIELDREC expect);
	void listRecord(FIELD conditionField,SYMBOL op,FIELDREC expect,FIELDNODE * head);
	FIELDREC getOneFieldRecord(FIELD  k,int index);  //get record  of the field
	int changeKey(char * newKeyName);
	void deleteRecord(int i);
	void deleteRecord(FIELD conditionField,SYMBOL op,FIELDREC expect);
	int deleteField(FIELD f);
	int update(FIELD setField,FIELDREC setValue,FIELD conditionField,SYMBOL op,FIELDREC expect);

	
};


Table::Table(Block * t)
{
	tableIndex=t;
	totalField = tableIndex->read(2,0);
	realField = tableIndex->read(2,2);
	totalRec = tableIndex->read(4,4);
	realRec = tableIndex->read(4,8);
	primaryField = tableIndex->read(2,12);
}

unsigned long Table::getTotalRec()
{
	return totalRec;
}

int Table::getRealField()
{
	return realField;
}

void Table::addField(FIELD k)
{
	unsigned long fieldBlockP;
	Block fieldBlock;
	int base = (totalField%8)*256;

	if(totalField%8==0)
	{
		fieldBlockP = allocateBlock();
		tableIndex->write(fieldBlockP,4,14+totalField/8*4);
		fieldBlock.clear();
		fieldBlock.setPosition(fieldBlockP);
	
	}
	else
	{
		fieldBlockP = tableIndex->read(4,totalField/8*4+14);
		fieldBlock.load(fieldBlockP);
	}

	k.indexBlock = allocateBlock();
	
	fieldBlock.write(1,1,base);
	fieldBlock.write(k.length,2,1+base);
	fieldBlock.write(k.type,1,3+base);
	fieldBlock.write(k.nl,1,4+base);
	fieldBlock.write(k.indexBlock,4,5+base);
	fieldBlock.write(k.key,1,9+base);
	fieldBlock.writeString(k.name,246,10+base);
	fieldBlock.save();
	
	if(totalField!=0&&totalRec!=0)
	{
		unsigned long totalLength = k.length*totalRec;
		int a1=totalLength/BLOCK_SIZE;
		Block recIndex(k.indexBlock);
		
		for(int i=0;i<=a1;i++)
		{
			recIndex.write(allocateBlock(),4,i*4);
		}
		recIndex.save();
	}


	
	totalField++;
	realField++;
	tableIndex->write(totalField,2,0);
	tableIndex->write(realField,2,2);
	tableIndex->save();

	


}

void Table::findField(FIELD & k)
{
	int i,j;
	Block fieldBlock;
	int base;
	char * name = new char [247];

	for(j=0,i=0;i<realField;i++)
	{
		do{
			if(j%8==0)
				fieldBlock.load(tableIndex->read(4,j/8*4+14));
			base = (j%8)*256;
			j++;
		}while(!fieldBlock.read(1,0+base));
		name[0]=0;		
		if(fieldBlock.read(1,0+base))
		{
			fieldBlock.readString(name,246,10+base);
			if(strcmp(name,k.name)==0)
			{
				k.valid=1;
				k.length = fieldBlock.read(2,1+base);
				k.type =(SYMBOL) fieldBlock.read(1,3+base);
				k.nl = (int)fieldBlock.read(1,4+base);
				k.indexBlock = fieldBlock.read(4,5+base);
				k.key = fieldBlock.read(1,9+base);
				return;
			}
		}

	}
	k.valid = 0;  //if not find valid=0
}	


int Table::addRecord(FIELDREC * values)
{
	int i,j;
	int base;
	FIELD * fields = new FIELD[realField];
	Block fieldBlock;


	for(j=0, i=0;i<realField;i++)     //read out all fields
	{
		do{
			if(j%8==0)
				fieldBlock.load(tableIndex->read(4,j/8*4+14));
			base = (j%8)*256;
			j++;
		}while(!fieldBlock.read(1,0+base));
		
		fields[i].name = new char[247];
		fields[i].valid =1;
		fields[i].length = fieldBlock.read(2,1+base);
		fields[i].type=(SYMBOL) fieldBlock.read(1,3+base);
		fields[i].nl= fieldBlock.read(1,4+base);
		fields[i].indexBlock= fieldBlock.read(4,5+base);
		fields[i].key = fieldBlock.read(1,9+base);
		fieldBlock.readString(fields[i].name,246,10+base);

	}

	int typeFlag;
	for(i=0;i<realField;i++)   //type and null check
	{
		if(fields[i].nl==0&&values[i].value==0)  //can not empty but values not exits
		{
			cout<<"Field "<<fields[i].name<<" can't null!"<<endl;
			return 1;  //report error
		}
		typeFlag = 0;
		if(values[i].type = NUM)
		{
			switch(fields[i].type)
			{
			case BYTE:
				if(atoi(values[i].value)>255||atoi(values[i].value)<0)
					typeFlag=1;
				break;
			case INT:
				if(atoi(values[i].value)<-32768||atoi(values[i].value)>32767)
					typeFlag=1;
				break;
			//case LONG:
			}
			values[i].type = fields[i].type;
		}
		else
		{
			if(values[i].type!=NL&&values[i].type!=fields[i].type)
				typeFlag=1;
		}
		if(typeFlag)
		{
			cout<<"Field "<<fields[i].name<<" type dismatch!"<<endl;
			return 1;
		}			
		if(fields[i].key)  //if primary key,value must be unique
		{
			FIELDREC fr1,fr2;					
					
			for(j=0;j<(long)totalRec;j++)
			{
				fr2=getOneFieldRecord(fields[0],j);
				if(atoi(fr2.value))
				{
					fr1=getOneFieldRecord(fields[i],j);
					if(!strcmp(fr1.value,values[i].value))												
						return 2;
				}
			}
		}
			
	}

	//if no error ,write to database
	Block indexBlock,recBlock;
	unsigned long nextIndexBlockP,nextRecBlockP;
	int a1,a2,b1,b2;
	unsigned char * ucWord =new unsigned char[1024];
	
	for(i=0;i<realField;i++)
	{
		indexBlock.load(fields[i].indexBlock);
		if(totalRec ==0)
		{
			indexBlock.write(allocateBlock(),4,0);
			indexBlock.save();
		}
		a1=(fields[i].length*totalRec)/BLOCK_SIZE;
		a2=(fields[i].length*totalRec)%BLOCK_SIZE;
		b1=a1/(BLOCK_SIZE/4-1);
		b2=a1%(BLOCK_SIZE/4-1);
		for(j=0;j<b1;j++)
			indexBlock.load(indexBlock.read(4,BLOCK_SIZE-4));
		recBlock.load(indexBlock.read(4,b2*4));			
	
		getUcWord(ucWord,fields[i].length,values[i]);

		for(j=0;j<fields[i].length;j++)
		{
			if(a2==BLOCK_SIZE)  //last block is full
			{
				recBlock.save();
				b2++;			
				if(b2==BLOCK_SIZE/4-1)
				{
					nextIndexBlockP=allocateBlock();
					indexBlock.write(nextIndexBlockP,4,BLOCK_SIZE-4);
					indexBlock.save();
					indexBlock.clear();
					indexBlock.setPosition(nextIndexBlockP);
					b2=0;
				}
				nextRecBlockP = allocateBlock();
				indexBlock.write(nextRecBlockP,4,b2*4);
				indexBlock.save();
				recBlock.clear();
				recBlock.setPosition(nextRecBlockP);
				a2=0;
			}
			recBlock.write(ucWord[j],1,a2);
			a2++;
		}
		recBlock.save();
		
	}
	//write finish , modify table imformation
	totalRec++;
	realRec++;
		
	tableIndex->write(totalRec,4,4);
	tableIndex->write(realRec,4,8);
	tableIndex->save();
	return 0;
}

void Table::listField()
{
	Block fieldBlock;
	FIELD k;
	char fieldname[247];
	int i,j,base;
	cout<<setw(15)<<"Name"
			<<setw(8)<<"type"
			<<setw(8)<<"Length"
			<<setw(6)<<"Null"
			<<setw(6)<<"KEY"
			<<setw(12)<<"IndexBlock"<<endl;
	cout<<setfill('-')<<setw(15)<<" "
			<<setw(8)<<" "
			<<setw(8)<<" "
			<<setw(6)<<" "
			<<setw(6)<<" "
			<<setw(12)<<" "<<setfill(' ')<<endl;
	for(j=0, i=0;i<realField;i++)     
	{
		do{
			if(j%8==0)
				fieldBlock.load(tableIndex->read(4,j/8*4+14));
			base = (j%8)*256;
			j++;
		}while(!fieldBlock.read(1,0+base));
		
		k.name = fieldname;
		k.name[0]=0;
		k.valid =1;
		k.length = fieldBlock.read(2,1+base);
		k.type=(SYMBOL) fieldBlock.read(1,3+base);
		k.nl= fieldBlock.read(1,4+base);
		k.indexBlock= fieldBlock.read(4,5+base);
		k.key = fieldBlock.read(1,9+base);
		fieldBlock.readString(k.name,246,10+base);

		cout<<setw(15)<<k.name<<setw(8);
		outType(k.type);
		if (k.type==CHAR)
			cout<<setw(8)<<k.length-1;
		else
			cout<<setw(8)<<k.length;
		cout<<setw(6)<<k.nl
			<<setw(6)<<k.key
			<<setw(12)<<k.indexBlock<<endl;

	}
}

 FIELDREC Table::getOneFieldRecord(FIELD  k,int index)
{
	int a1,a2,b1,b2,j;
	Block indexBlock,recBlock;
	unsigned char * ucWord =new unsigned char[1024];
	unsigned long nextIndexBlockP,nextRecBlockP;
	FIELDREC kr;
	kr.type = k.type;
	kr.value = new char[256];
	indexBlock.load(k.indexBlock);
	a1=(k.length*index)/BLOCK_SIZE;
	a2=(k.length*index)%BLOCK_SIZE;
	b1=a1/(BLOCK_SIZE/4-1);
	b2=a1%(BLOCK_SIZE/4-1);
	for(j=0;j<b1;j++)
			indexBlock.load(indexBlock.read(4,BLOCK_SIZE-4));
	recBlock.load(indexBlock.read(4,b2*4));	
	
	for(j=0;j<k.length;j++)
		{
			if(a2==BLOCK_SIZE)  //last block is full
			{
				
				b2++;			
				if(b2==BLOCK_SIZE/4-1)
				{
					nextIndexBlockP=indexBlock.read(4,BLOCK_SIZE-4);					
					indexBlock.load(nextIndexBlockP);
					b2=0;
				}
				nextRecBlockP = indexBlock.read(4,b2*4);
				recBlock.load(nextRecBlockP);				
				a2=0;
			}
			ucWord[j]=(unsigned char)recBlock.read(1,a2);

			a2++;
		}
	getFieldRec(ucWord,k.length,kr);
	return kr;
}

 int Table::changeKey(char * newKeyName)
 {
	 int i,j,base,flag=0;
	 FIELD readField;
	 Block fieldBlock;

	 readField.name = new char[246];

	for(j=0, i=0;i<realField;i++)     
	{
		do{
			if(j%8==0)		
				fieldBlock.load(tableIndex->read(4,j/8*4+14));
							
			base = (j%8)*256;
			j++;
		}while(!fieldBlock.read(1,0+base));
				
		readField.key = fieldBlock.read(1,9+base);
		if(readField.key)
		{
			fieldBlock.write((int)0,1,9+base);
			fieldBlock.save();
		}

⌨️ 快捷键说明

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