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

📄 catalog.cpp

📁 实现一个精简型单用户SQL引擎(DBMS)MiniSQL
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			pFile1 = MemWrite((void*)column1->ConstraintPtr.constraint,sizeof(Constraint_Info),&pFile);		//write
		}
		else{	//if there is not any constraint then set the constraint pointer to null
			((Column_Info*)pFile1.MemAddr())->ConstraintPtr.FileConstraint.Initialize();
			pFile1 = pFile;   //record the last positioin that has been written
		}
		column1 = column1->ColumnPtr.next;		//get next node 
	}
	while(column1 != NULL){		//write the other column information 
		((Column_Info*)pFile2.MemAddr())->ColumnPtr.FileNext = pFile1;	//set the prior column infomation's column pointer to current one
		pFile = MemWrite((void*)column1,sizeof(Column_Info),&pFile1);	//write
		((Column_Info*)pFile1.MemAddr())->ColumnPtr.FileNext.Initialize();	//set column pointer to null
		pFile2 = pFile1;	//save current column infomation
		if(column1->ConstraintPtr.constraint != NULL){		//write constraint info if there is any
			((Column_Info*)pFile1.MemAddr())->ConstraintPtr.FileConstraint = pFile;		//set the constraint pointer of the column
			pFile1 = MemWrite((void*)column1->ConstraintPtr.constraint,sizeof(Constraint_Info),&pFile);		//write
    }
		else{	//if there is not any constraint then set the constraint pointer to null
			((Column_Info*)pFile1.MemAddr())->ConstraintPtr.FileConstraint.Initialize();
			pFile1 = pFile;   //record the last positioin that has been written
		}
		column1 = column1->ColumnPtr.next;		//get next list node 
	}

	//delete list
	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;
}


//---------------------------------------------------------------------------------------------
//select
void HCatalog::Select(TB_Select_Info& info,Condition_Info& index,Select_Rec_Info& record)
{
	//locate current table
    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;

	//if not a select on every column, check whether the demanded column exists
    Column_Info* column;	
	int l=0;    //for RecordLength information for record
	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;
        }
    }

	//check if the selection is based on every attributes of key 
    _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)!
	
	//check if the selection is based on primary key and whether the selection is valid
    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!
        }
		//check if the length is correct if the column is char type 
        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!
			}
		}
	}

	//organize information for index selection
	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;  //for min
	pkey3 = pkey1;    //record position for prior pkey1
	pmaxkey = new Key_Attr;
	pkey2 = pmaxkey;  //for max
	pkey4 = pkey2;    //record position for prior pkey2
	int count = TbInfo->KeyAttrNum;

    //if there is any constraints  
    if(info.ConditionHead != NULL){
      //for every attributes of primary key
      while((column!=NULL) && (count!=0)){
		//if the column is primary key
        if(column->IsPrimary == 1){
			//find the corresponding select condition in command
            for(pcondition = info.ConditionHead; pcondition!=NULL; pcondition=pcondition->next){
			    //organize the information
                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: Unknown type!
					}//end switch
					break;
				}//end if
			}//end for
		
			pkey3 = pkey1;  //record current pkey1
			pkey4 = pkey2;  //record current pkey2
			pkey1->next = new Key_Attr; //form new node and link into list
			pkey1 = pkey1->next;   //pkey1 points to new node
			pkey2->next = new Key_Attr; //form new node and link into list
			pkey2 = pkey2->next;   //pkey2 points to new node
			count--;  //one attribute is finished
		}//end if
		
        //to next column
		column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
	}//end while
  
	pkey3->next = NULL;
	pkey4->next = NULL;
	delete pkey1;
	delete pkey2;

	index.max = pmaxkey;
	index.min = pminkey;
    index.OperType = info.ConditionHead->OperType;
  }//end if
  
  //no constraint
  else{
    index.max = NULL;
    index.min = NULL;
    index.OperType = ALL;
  }
	
	
	//organize information for record
	Select_Cell* cell = new Select_Cell;
	Select_Cell* cell1 = cell;
	record.head = cell;
	pcolumn = info.ColumnHead;
	column = head;
	int len=0;    //for prior length of column
	//if not a selection on every column
    if(strcmp(pcolumn->ColumnName,"*")!=0){
		//organize information
        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;
				}//end if
			}//end for
			pcolumn = pcolumn->next;
			len = 0;
		}//end while
	
		record.ColumnNum = info.ColumnNum;
        record.RecordLength = l;
	}

	//else if a selection based on every column
    else{
        //organize information
		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;
}

//---------------------------------------------------------------------------------------------
//insert
void HCatalog::Insert(TB_Insert_Info& info, Key_Attr& index, Rec_Info& record)
{
	//locate current table
    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;
	//check insert validation
    while (raw != NULL){
		//if not a insertion of all columns
        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++;		//count for primary key
		} 
        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 insertion is not for all column
    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();
		}
	}

	//form information for index insertion
	Key_Attr* key = &index;
	column = head;
	raw = info.head;
	while(count!=0 && column!=NULL){
		//not a insertion on all columns
        if(strcmp(info.head->ColumnName,"*") != 0){
            //if this column is not a primary key, go on loop
            if(column->IsPrimary == 0){   
				column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
				continue;
			}
            //else the column is a attribute of primary key
			for(raw=info.head; raw!=NULL; raw=raw->next){
				//find the corresponding information in command
                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: Unknown type!
					}
					count--;
					break;
				}
			}
		}
		//insertion on all colomn
        else{
			//the column is not a primary key, go on loop
            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: Unknown type!
			}
			count--;
			raw = raw->next;
		}
		if(count!=0){
			key->next = new Key_Attr;
			key = key->next;
		}
		column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
	}

	//form infomation for 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;  //for the prior length
	//if user has given all the values for each column
	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: Unknown type!
			}
			len += column->StoredLength;
			column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
			raw = raw->next;
			if(column != NULL){
				cell->next = new Cell_Info;
				cell = cell->next;
			}

⌨️ 快捷键说明

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