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

📄 catalog.cpp

📁 设计并实现一个精简型单用户SQL引擎(DBMS)MiniSQL
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		}
		else{	
			((Column_Info*)pFile1.MemAddr())->ConstraintPtr.FileConstraint.Initialize();
			pFile1 = pFile;   //记录上次的写入点 
		}
		column1 = column1->ColumnPtr.next;	
	}
	while(column1 != NULL){		
		((Column_Info*)pFile2.MemAddr())->ColumnPtr.FileNext = pFile1;	
		pFile = MemWrite((void*)column1,sizeof(Column_Info),&pFile1);	
		((Column_Info*)pFile1.MemAddr())->ColumnPtr.FileNext.Initialize();	
		pFile2 = pFile1;	
		if(column1->ConstraintPtr.constraint != NULL){		
			((Column_Info*)pFile1.MemAddr())->ConstraintPtr.FileConstraint = pFile;		
			pFile1 = MemWrite((void*)column1->ConstraintPtr.constraint,sizeof(Constraint_Info),&pFile);		
    }
		else{	
			((Column_Info*)pFile1.MemAddr())->ConstraintPtr.FileConstraint.Initialize();
			pFile1 = pFile;   
		}
		column1 = column1->ColumnPtr.next;	
	}

	//删除列表
	column1 = head;
	column2 = column1->ColumnPtr.next;
	while(column1 != NULL){
		if(column1->ConstraintPtr.constraint != NULL)
			delete column1->ConstraintPtr.constraint;
		delete column1;
		column1 = column2;
		if(column1 != NULL)
			column2 = column1->ColumnPtr.next;
	}
	return;
}

//选择
void HCatalog::Select(TB_Select_Info& info,Condition_Info& index,Select_Rec_Info& record)
{

    char temp[289];
	sprintf(temp,"%s%s.dbf",CurLocation,CurRelationName);
	_M_File CurrentTable = Buffer[temp];

	Select_Column* pcolumn = info.ColumnHead;
	Select_Condition* pcondition = info.ConditionHead;

	//检查约束条件列是否存在
    Column_Info* column;	
	int l=0;   
	if(strcmp(pcolumn->ColumnName,"*") != 0){
        for(; pcolumn!=NULL; pcolumn=pcolumn->next){
			if(!this->Exist_Column(pcolumn->ColumnName))
				throw 1008;				//Error1008: Column demanded has not existed yet!  
            column = this->Find_Column(pcolumn->ColumnName);
            l += column->StoredLength;
        }
    }
    _F_FileAddr pFile = CurrentTable.GetCataPoint();
	Table_Info* TbInfo = (Table_Info*)pFile.MemAddr();
    if((info.ConditionNum!=0) && (TbInfo->KeyAttrNum!=info.ConditionNum))
		throw 1019;		//Error1019: Information Inadequate for selection(Every attribute should be included)!
	for(; pcondition!=NULL; pcondition=pcondition->next){
		column = this->Find_Column(pcondition->PrimaryKey); //find the demanded column
		if(column == NULL)
			throw 1007;				//Error1007: Primary Key demanded has not existed yet!
		if(!this->Check_Key(column))
			throw 1011;				//Error1011: Not a select based on primary key!
		if(!this->Check_Type(column,pcondition->ColType))
			throw 1012;				//Error1012: Type mismatch!
        if(pcondition->OperType == BETWEEN){
            if(!Check_Key_Validation(pcondition->ColType,&(pcondition->max),&(pcondition->min)))
                throw 1020;       //Error1020: Result is null!
        }
        if(pcondition->ColType == C){	
			switch(pcondition->OperType){
			case L:
			case LE:
				if(!Check_Length(column,&(pcondition->max)))
					throw 1013;		//Error1013: Length Invalid for type char!
				else 
					break;
			case B:
			case BE:
				if(!Check_Length(column,&(pcondition->min)))
					throw 1013;		//Error1013: Length Invalid for type char!
				else
					break;
			case BETWEEN:
			case E:
			case NE:
					if(!Check_Length(column,&(pcondition->max)) || !Check_Length(column,&(pcondition->min)))
					throw 1013;		//Error1013: Length Invalid for type char!
					else 
						break;
			default:
				throw 1009;			//Error1009: Unknown relation operator!
			}
		}
	}
	Column_Info* head;
	head = (Column_Info*)TbInfo->KeyPtr.FileKey.MemAddr();
	column = head;
	pKey_Attr pkey1,pkey2,pminkey,pmaxkey,pkey3,pkey4;
	pminkey = new Key_Attr;
	pkey1 = pminkey;  
	pkey3 = pkey1;    
	pmaxkey = new Key_Attr;
	pkey2 = pmaxkey; 
	pkey4 = pkey2;    
	int count = TbInfo->KeyAttrNum;
    if(info.ConditionHead != NULL){
      while((column!=NULL) && (count!=0)){
        if(column->IsPrimary == 1){
			//找寻选择条件
            for(pcondition = info.ConditionHead; pcondition!=NULL; pcondition=pcondition->next){
                if(strcmp(pcondition->PrimaryKey,column->ColumnName)==0){		 
					switch (pcondition->ColType){
					case I:
						pkey1->value.IntValue = pcondition->min.IntValue;
						pkey2->value.IntValue = pcondition->max.IntValue;
						break;
					case F:
						pkey1->value.FloatValue = pcondition->min.FloatValue;
						pkey2->value.FloatValue = pcondition->max.FloatValue;
						break;
					case C:
						pkey1->value.pCharValue = pcondition->min.pCharValue;
						pkey2->value.pCharValue = pcondition->max.pCharValue;
						break;
					default:
						throw 1010;				//Error1010: 错误的数据类型
					}
					break;
				}
			}
		
			pkey3 = pkey1;  
			pkey4 = pkey2;  
			pkey1->next = new Key_Attr; 
			pkey1 = pkey1->next;   
			pkey2->next = new Key_Attr; 
			pkey2 = pkey2->next;   
			count--;  
		}
		
		column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
	}
  
	pkey3->next = NULL;
	pkey4->next = NULL;
	delete pkey1;
	delete pkey2;

	index.max = pmaxkey;
	index.min = pminkey;
    index.OperType = info.ConditionHead->OperType;
  }
  
  else{
    index.max = NULL;
    index.min = NULL;
    index.OperType = ALL;
  }
	
	
	//为record准备的数据
	Select_Cell* cell = new Select_Cell;
	Select_Cell* cell1 = cell;
	record.head = cell;
	pcolumn = info.ColumnHead;
	column = head;
	int len=0;    
    if(strcmp(pcolumn->ColumnName,"*")!=0){
        while(pcolumn != NULL){
			for(column = head; column!=NULL; len+=column->StoredLength,column=(Column_Info*)column->ColumnPtr.FileNext.MemAddr()){
				if(strcmp(pcolumn->ColumnName,column->ColumnName)==0){
					strcpy(cell->ColumnName,column->ColumnName);
					cell->ColType = column->ColType;
					cell->ColLength = column->StoredLength;
					cell->PriorLength = len;
					if(pcolumn->next != NULL){
						cell1 = cell;
						cell->next = new Select_Cell;
						cell = cell->next;
					}
					break;
				}
			}
			pcolumn = pcolumn->next;
			len = 0;
		}
	
		record.ColumnNum = info.ColumnNum;
        record.RecordLength = l;
	}
    else{
		while(column!=NULL){
			strcpy(cell->ColumnName,column->ColumnName);
			cell->ColType = column->ColType;
			cell->ColLength = column->StoredLength;
			cell->PriorLength = len;
			len += column->StoredLength;
			column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
			if(column!=NULL){
				cell->next = new Select_Cell;
				cell = cell->next;
			}
		}
		record.ColumnNum = TbInfo->TotalColumn;
        record.RecordLength = TbInfo->RecordLength;
	}
	
	return;
}

//插入
void HCatalog::Insert(TB_Insert_Info& info, Key_Attr& index, Rec_Info& record)
{
    char temp[289];
	sprintf(temp,"%s%s.dbf",CurLocation,CurRelationName);
	_M_File CurrentTable = Buffer[temp];

	Insert_Column *raw;
	raw = info.head;

	Column_Info* column = NULL;
	Column_Info* head;
	Table_Info* table;
	table = (Table_Info*)CurrentTable.GetCataPoint().MemAddr();
	head = (Column_Info*)table->KeyPtr.FileKey.MemAddr();
	int count=0;
	//检查插入的信息
    while (raw != NULL){
        if(strcmp(raw->ColumnName,"*") != 0){
			if(!Exist_Column(raw->ColumnName))
				throw 1008;		//Error1008: Column demanded has not existed yet!
			column = this->Find_Column(raw->ColumnName);
			if(Check_Key(column))
				count++;	
		} 
        else{
			if(column == NULL)
				column = head;
			else
				column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
			}
		if(!Check_Type(column,raw->ColType))
			throw 1012;		//Error1012: Type mismatch!
		if(!Check_Length(column,&(raw->value)))
			throw 1013;		//Error1013: Length Invalid for type char!
		if(!Check_Value(column,&(raw->value)))
			throw 1014;		//Error1014: Invalid Value!
		raw = raw->next;
	}

	raw = info.head;
	if(strcmp(raw->ColumnName,"*") != 0){
		if(count != table->KeyAttrNum)
			throw 1015;		//Error1015: Value of Primary Key can not be null!
	}
	else{
		if(info.ColumnNum != table->TotalColumn)
			throw 1016;		//Error1016: Inadequate value for every column! 
		count = table->KeyAttrNum;
	}
	
	column = head;
    if(strcmp(info.head->ColumnName,"*") != 0){
		while(column != NULL){
			if(column->IsNull == 0){
				for(raw=info.head; raw!=NULL; raw=raw->next)
					if(strcmp(raw->ColumnName,column->ColumnName) == 0)
						break;
				if(raw == NULL)
					throw 1017;		//Error1017: No value for some not null column!
			}
			column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
		}
	}

	//为index insertion 的信息
	Key_Attr* key = &index;
	column = head;
	raw = info.head;
	while(count!=0 && column!=NULL){
        if(strcmp(info.head->ColumnName,"*") != 0){
            if(column->IsPrimary == 0){   
				column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
				continue;
			}
			for(raw=info.head; raw!=NULL; raw=raw->next){
                if(strcmp(raw->ColumnName,column->ColumnName)==0){
					switch(column->ColType){
					case I:
						key->value.IntValue = raw->value.IntValue;
						break;
					case F:
						key->value.FloatValue = raw->value.FloatValue;
						break;
					case C:
						key->value.pCharValue = raw->value.pCharValue;
						break;
					default:
						throw 1010;		//Error1010: 错误的数据类型
					}
					count--;
					break;
				}
			}
		}
		//i插入所有列
        else{
            if(column->IsPrimary == 0){
				raw = raw->next;
				column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
				continue;
			}
			switch(column->ColType){
			case I:
				key->value.IntValue = raw->value.IntValue;
				break;
			case F:
				key->value.FloatValue = raw->value.FloatValue;
				break;
			case C:
				key->value.pCharValue = raw->value.pCharValue;
				break;
			default:
				throw 1010;		//Error1010: 错误的数据类型
			}
			count--;
			raw = raw->next;
		}
		if(count!=0){
			key->next = new Key_Attr;
			key = key->next;
		}
		column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
	}

	//为 record insert的信息
	Cell_Info* cell = new Cell_Info;
	record.ColNum = table->TotalColumn;
	record.head = cell;
    record.RecordLength = table->RecordLength;
	column = head;
	raw = info.head;
	int len=0;  
	if(strcmp(info.head->ColumnName,"*") == 0){
		while(column != NULL){
			cell->ColLength = column->StoredLength;
			cell->ColType = column->ColType;
			cell->PriorLength = len;
			switch(column->ColType){
			case I:
				cell->value.IntValue = raw->value.IntValue;
				break;
			case F:
				cell->value.FloatValue = raw->value.FloatValue;
				break;
			case C:
				cell->value.pCharValue = raw->value.pCharValue;
				break;
			default:
				throw 1010;		//Error1010: 错误的数据类型
			}
			len += column->StoredLength;
			column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
			raw = raw->next;
			if(column != NULL){
				cell->next = new Cell_Info;
				cell = cell->next;
			}
		}
	}
	
	else{
		column = head;
		len = 0;
		while(column!=NULL){
			raw = info.head;
			while(raw != NULL){

⌨️ 快捷键说明

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