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

📄 catalog.cpp

📁 实现一个精简型单用户SQL引擎(DBMS)MiniSQL
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <iostream>
#include <stdio.h>

#include "Catalog.h"


extern char CurLocation[256];
extern char CurRelationName[33];
extern _M_Buffer Buffer;
extern unsigned int BTreeNodeSize;

using namespace std;

//------------------------------------------------------------------------------------------
//to find the position of a given name column 
Column_Info* HCatalog::Find_Column(char* Name) const
{
	char temp[289];
	sprintf(temp,"%s%s.dbf",CurLocation,CurRelationName);
	_M_File CurrentTable = Buffer[temp];

	_F_FileAddr head;													
	head = CurrentTable.GetCataPoint();		    //head is a file pointer that points to the first place in catalog
	
	Table_Info* TableHead;
	TableHead = (Table_Info*)head.MemAddr();	//TableHead is a memory pointer that points to the first place in catalog
	
	Column_Info* column;
	column = (Column_Info*)TableHead->KeyPtr.FileKey.MemAddr();		//column is a memory pointer pointing to column information
	
	while (column != NULL)
	{
		if(strcmp(column->ColumnName,Name) == 0)	
			return column;
		else
			column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
	}

	return NULL;
}

//---------------------------------------------------------------------------------------------
//to find whether a column exists
bool HCatalog::Exist_Column(char* Name) const
{
	if(Find_Column(Name) == NULL)
		return false;
	else
		return true;
} 

//---------------------------------------------------------------------------------------------
//to find whether the column type is correct
bool HCatalog::Check_Type(Column_Info* column, Column_Type type) const
{
	if(column->ColType == type)
		return true;
	else
		return false;
}

//----------------------------------------------------------------------------------------------
//to find whether the column is primary key
bool HCatalog::Check_Key(Column_Info* column) const
{
	if(column->IsPrimary == 1)
		return true;
	else
		return false;
}

//----------------------------------------------------------------------------------------------
//to find whether the constraint on the column is fulfilled
bool HCatalog::Check_Value(Column_Info* column,Column_Value* val) const
{
	Column_Type ColType = column->ColType; 
	int integer;
	float fl;
	char* ch;
	
	//identify value in the union
    switch(ColType){
    case I:       //int
	    integer = val->IntValue;
		break;
	case F:       //float
		fl = val->FloatValue;
		break;
	case C:       //char
		ch = val->pCharValue;
		break;
	default:
		throw 1010;				//error code 1010----unknown type;
	}
	
	//constraint on current column
    Constraint_Info* constraint = (Constraint_Info*)column->ConstraintPtr.FileConstraint.MemAddr(); 	
	
	//no constraints
    if(constraint == NULL)
		return true;

    //there is constraint 
	if(ColType == I)    //values is int
		switch(constraint->OperType){
			case L:   //in case <, value >= max
				if(integer >= constraint->max.IntValue)
					return false;
				break;
			case LE:   //case <=, value > max
				if(integer > constraint->max.IntValue)
					return false;
				break;
			case B:    //case >, value <= min
				if(integer <= constraint->min.IntValue)
					return false;
				break;
			case BE:   //case >=, value < min
				if(integer < constraint->min.IntValue)
					return false;
				break;
			case E:    //case =, value != max
				if(integer != constraint->max.IntValue)
					return false;
				break;
			case NE:   //case !=, value == max
				if(integer == constraint->max.IntValue)
					return false;
				break;
			case BETWEEN:   //case between...and..., value < min or value >max
				if((integer < constraint->min.IntValue) || (integer > constraint->max.IntValue))
					return false;
				break;
			default:
				throw 1009;			//error code 1009----unknown relation operator
		}

	//value is float
    else if (ColType == F)
		switch(constraint->OperType){
			case L:   //case >
				if(fl >= constraint->max.FloatValue)
					return false;
				break;
			case LE:   //case >=
				if(fl > constraint->max.FloatValue)
					return false;
				break;
			case B:     //case <
				if(fl <= constraint->min.FloatValue)
					return false;
				break;
			case BE:    //case <=
				if(fl < constraint->min.FloatValue)
					return false;
				break;
			case E:     //case ==
				if(fl != constraint->max.FloatValue)
					return false;
				break;
			case NE:    //case !=
				if(fl == constraint->max.FloatValue)
					return false;
				break;
			case BETWEEN:   //case between...and...
				if((fl < constraint->min.FloatValue) || (fl > constraint->max.FloatValue))
					return false;
				break;
			default:
				throw 1009;			//error code 1009----unknown relation operator
		}

	//value is char
    else{ 
		if(strlen(ch) > column->RequiredLength)
			throw 1013;				//Error1013: Length Invalid for type char!
		switch(constraint->OperType){
		case L:   //case >
			if(strcmp(ch,constraint->max.CharValue) >= 0)
				return false;
			break;
		case LE:  //case >=
			if(strcmp(ch,constraint->max.CharValue) > 0)
				return false;
			break;
		case B:   //case <
			if(strcmp(ch,constraint->min.CharValue) <= 0)
				return false;
			break;
		case BE:   //case <=
			if(strcmp(ch,constraint->min.CharValue) < 0)
				return false;
			break;
		case E:   //case ==
			if(strcmp(ch,constraint->max.CharValue) != 0)
				return false;
			break;
		case NE:  //case !=
			if(strcmp(ch,constraint->max.CharValue) == 0)
				return false;
			break;
		case BETWEEN:   //case between...and...
			if((strcmp(ch,constraint->min.CharValue) < 0) || (strcmp(ch,constraint->max.CharValue)) > 0)
				return false;
			break;
		default:
			throw 1009;				//error code 1009-----unknown relation operation
		}
	}
	
	return true;
}
//---------------------------------------------------------------------------------------------
//to check whether length for char type is valid 
bool HCatalog::Check_Length(Column_Info* column, Column_Value* val) const
{
	if((column->ColType==C) && (strlen(val->pCharValue) > column->RequiredLength))
		return false;
	else 
		return true;
}

//--------------------------------------------------------------------------------------------
//to check whether value of key in selection is valid
bool HCatalog::Check_Key_Validation(Column_Type ColType, Column_Value* max, Column_Value* min) const
{
  //if max < min, then invalid
  switch(ColType){
  case I:   //case int
    if(max->IntValue < min->IntValue)
      return false;
    else 
      return true;
  case F:   //case float
    if(max->FloatValue < min->FloatValue)
      return false;
    else 
      return true;
  case C:   //case char
    if(strcmp(max->pCharValue,min->pCharValue) < 0)
      return false;
    else
      return true;
  default:
    throw 1020;   //Error1020: Unknown type!
  }
}


//----------------------------------------------------------------------------------------------
//*********************************************************************************************
//----------------------------------------------------------------------------------------------

//Constructor for Table_Info
TTable_Info::TTable_Info()
{
	KeyPtr.FileKey.Initialize();
	KeyPtr.Key = NULL;			
	strcpy(TableName,"");
	TotalColumn = 0;
	RecordLength = 0;
	KeyAttrNum = 0;
}

//-------------------------------------------------------------------------------------
//form a node for the list of catalog
Column_Info* HCatalog::Form_ListNode(Create_Column* ptr,int id) const
{
	Column_Info* pcolumn = new Column_Info;		//create a new node
	Constraint_Info* constraint;
	
    //write infomation into node
	pcolumn->ID = id;
	strcpy(pcolumn->ColumnName,ptr->ColumnName);
	pcolumn->ColType = ptr->ColType;
	pcolumn->IsPrimary = ptr->IsPrimary;
	pcolumn->ColumnPtr.next = NULL;
	if(ptr->IsPrimary == true)
		pcolumn->IsNull = 0;		//primary can not be null
	else if (ptr->IsNull == true)
		pcolumn->IsNull = 1;
	else if (ptr->IsNull == false)
		pcolumn->IsNull = 0;
	
	//calculate required length(RequiredLength) and real length(StoredLength), for type char real length = required length + 1
    switch(pcolumn->ColType){
	case I:   //RequiredLength = StoredLength
		pcolumn->RequiredLength = sizeof(int);
		pcolumn->StoredLength = pcolumn->RequiredLength;
		break;
	case F:   //RequiredLength = StoredLength
		pcolumn->RequiredLength = sizeof(float);
		pcolumn->StoredLength = pcolumn->RequiredLength;
		break;
	case C:   //RequiredLength + 1 = StoredLength
		pcolumn->RequiredLength = ptr->length;
		pcolumn->StoredLength = pcolumn->RequiredLength+1;
		break;
	default:
		throw 1010;				//error 1010: unknown type
	}
		
	//to check if there is no constraint on the column,say,min > max
	bool flag=false;	//false--no constraint; true--otherwise
	if((ptr->ColType==I) && (ptr->min.IntValue<=ptr->max.IntValue))
		flag=true;
	else if((ptr->ColType==F) && (ptr->min.FloatValue<=ptr->max.FloatValue))
		flag=true;
	else if((ptr->ColType==C) && (strcmp(ptr->min.pCharValue,ptr->max.pCharValue)<=0))
		flag=true;

	if(flag){	//if there is constraint,write infomation into and link it to column node
		constraint = new Constraint_Info;
		constraint->OperType = ptr->OperType;
		switch(pcolumn->ColType){
		case I:
			constraint->min.IntValue = ptr->min.IntValue;
			constraint->max.IntValue = ptr->max.IntValue;
			break;
		case F:
			constraint->min.FloatValue = ptr->min.FloatValue;
			constraint->max.FloatValue = ptr->max.FloatValue;
			break;
		case C:
			strcpy(constraint->min.CharValue, ptr->min.pCharValue);
			strcpy(constraint->max.CharValue, ptr->max.pCharValue);
			break;
		}
		pcolumn->ConstraintPtr.constraint = constraint;
	}
	else	//no constraint, set the pointer to null
		pcolumn->ConstraintPtr.constraint = NULL;

	return pcolumn;
}


//-----------------------------------------------------------------------------------------
//create
void HCatalog::Create(TB_Create_Info& info, char* KeyInfo)
{
	Create_Column* ptr;
	ptr = info.head;
	
	//form the first node about the table information 
	Table_Info TableNode;
	strcpy(TableNode.TableName,info.TableName);
	TableNode.TotalColumn = info.TotalColumn;
	
	Column_Info* column1;
	Column_Info* head;
	Column_Info* column2;
	
	//form a list about infomation on every column 
	int count=0;		//the number of Attributes of primary key
	int	length=0;		//total length of record
	int j=0;
    int keylen=0;
	for(int i=0 ;ptr!=NULL ;ptr=ptr->next,i++){
		column1 = this->Form_ListNode(ptr,i);   //form a node
		length += column1->StoredLength;        //increase the length
		//form necessary infomation needed by index
		if(column1->IsPrimary == 1){
			count++;      //increase count for attrbutes of primary key
			keylen += column1->StoredLength;
            //organize information for index creation
            if(column1->ColType == C)
				j += sprintf(KeyInfo+j,"c%d",column1->RequiredLength);
			else if(column1->ColType == F)
				j += sprintf(KeyInfo+j,"f");
			else 
				j += sprintf(KeyInfo+j,"i");
		}//end if
		if(i == 0)
			head = column1;		//save the first node of list 
		else
			column2->ColumnPtr.next = column1;		//link current node to the prior node
		column2 = column1;		//save current node 
	}//end for
    if(( BTreeNodeSize - 2*sizeof(_F_FileAddr) - sizeof(bool) - sizeof(int) ) 
                       / ( sizeof(_F_FileAddr) + keylen) < 4)
                       throw 1034;      //Error 1034: Primary Key is too long!
	TableNode.KeyPtr.Key = head;
	TableNode.KeyAttrNum = count;
	TableNode.RecordLength = length;

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

	//write the list into file
	_F_FileAddr pFile,pFile1,pFile2;
	
	pFile = CurrentTable.GetCataPoint();		//pFile--the first place that the list could be written
	
	pFile1 = MemWrite((void*)&TableNode,sizeof(Table_Info),&pFile);	//write _M_File Information into file
	
	column1 = head;
	//write all column infomation and its constraint into file 
	if(column1 != NULL){		//write the first column infomation into file
		((Table_Info*)pFile.MemAddr())->KeyPtr.FileKey = pFile1;	//move the file pointer to next available place
		pFile = MemWrite((void*)column1,sizeof(Column_Info),&pFile1);	//write
		((Column_Info*)pFile1.MemAddr())->ColumnPtr.FileNext.Initialize();	//set the next pointer to null
		pFile2 = pFile1;	//save current column pointer
		if(column1->ConstraintPtr.constraint != NULL){		//write the corresponding constraint infomation if any
			((Column_Info*)pFile1.MemAddr())->ConstraintPtr.FileConstraint = pFile;		//set the constraint pointer of the column

⌨️ 快捷键说明

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