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

📄 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;

//找出给定列的位置
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();		    //指向文件的头指针
	
	Table_Info* TableHead;
	TableHead = (Table_Info*)head.MemAddr();	//指向内存的头指针
	
	Column_Info* column;
	column = (Column_Info*)TableHead->KeyPtr.FileKey.MemAddr();		//内存中指向列的信息
	
	while (column != NULL)
	{
		if(strcmp(column->ColumnName,Name) == 0)	
			return column;
		else
			column = (Column_Info*)column->ColumnPtr.FileNext.MemAddr();
	}

	return NULL;
}


//判断列是否存在
bool HCatalog::Exist_Column(char* Name) const
{
	if(Find_Column(Name) == NULL)
		return false;
	else
		return true;
} 


//判断列的类型是否正确
bool HCatalog::Check_Type(Column_Info* column, Column_Type type) const
{
	if(column->ColType == type)
		return true;
	else
		return false;
}


//判断此列是否为主键
bool HCatalog::Check_Key(Column_Info* column) const
{
	if(column->IsPrimary == 1)
		return true;
	else
		return false;
}


//判断约束条件是否成立
bool HCatalog::Check_Value(Column_Info* column,Column_Value* val) const
{
	Column_Type ColType = column->ColType; 
	int integer;
	float fl;
	char* ch;
    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----错误的类型;
	}
	
	//此列上的约束条件
    Constraint_Info* constraint = (Constraint_Info*)column->ConstraintPtr.FileConstraint.MemAddr(); 	
	
	//没有约束
    if(constraint == NULL)
		return true;
    if(ColType == I)    
		switch(constraint->OperType){
			case L:   // <
				if(integer >= constraint->max.IntValue)
					return false;
				break;
			case LE:   // <=
				if(integer > constraint->max.IntValue)
					return false;
				break;
			case B:    // >
				if(integer <= constraint->min.IntValue)
					return false;
				break;
			case BE:   // >=
				if(integer < constraint->min.IntValue)
					return false;
				break;
			case E:    // =
				if(integer != constraint->max.IntValue)
					return false;
				break;
			case NE:   // !=
				if(integer == constraint->max.IntValue)
					return false;
				break;
			case BETWEEN:   // between...and...
				if((integer < constraint->min.IntValue) || (integer > constraint->max.IntValue))
					return false;
				break;
			default:
				throw 1009;			//error code 1009----错误的关系运算符
		}

       else if (ColType == F)
		switch(constraint->OperType){
			case L:   // <
				if(fl >= constraint->max.FloatValue)
					return false;
				break;
			case LE:   // <=
				if(fl > constraint->max.FloatValue)
					return false;
				break;
			case B:     // >
				if(fl <= constraint->min.FloatValue)
					return false;
				break;
			case BE:    // >=
				if(fl < constraint->min.FloatValue)
					return false;
				break;
			case E:     // ==
				if(fl != constraint->max.FloatValue)
					return false;
				break;
			case NE:    // !=
				if(fl == constraint->max.FloatValue)
					return false;
				break;
			case BETWEEN:   // between...and...
				if((fl < constraint->min.FloatValue) || (fl > constraint->max.FloatValue))
					return false;
				break;
			default:
				throw 1009;			//error code 1009----错误的关系运算符
		}

      else{ 
		if(strlen(ch) > column->RequiredLength)
			throw 1013;				//Error1013: 长度不符合
		switch(constraint->OperType){
		case L:   // <
			if(strcmp(ch,constraint->max.CharValue) >= 0)
				return false;
			break;
		case LE:  // <=
			if(strcmp(ch,constraint->max.CharValue) > 0)
				return false;
			break;
		case B:   // >
			if(strcmp(ch,constraint->min.CharValue) <= 0)
				return false;
			break;
		case BE:   // >=
			if(strcmp(ch,constraint->min.CharValue) < 0)
				return false;
			break;
		case E:   // ==
			if(strcmp(ch,constraint->max.CharValue) != 0)
				return false;
			break;
		case NE:  // !=
			if(strcmp(ch,constraint->max.CharValue) == 0)
				return false;
			break;
		case BETWEEN:   // between...and...
			if((strcmp(ch,constraint->min.CharValue) < 0) || (strcmp(ch,constraint->max.CharValue)) > 0)
				return false;
			break;
		default:
			throw 1009;				//error code 1009-----错误的关系运算符
		}
	}
	
	return true;
}

//检查char的长度是否合法
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;
}


//检查键是否合法
bool HCatalog::Check_Key_Validation(Column_Type ColType, Column_Value* max, Column_Value* min) const
{
  switch(ColType){
  case I:  
    if(max->IntValue < min->IntValue)
      return false;
    else 
      return true;
  case F:   
    if(max->FloatValue < min->FloatValue)
      return false;
    else 
      return true;
  case C:   
    if(strcmp(max->pCharValue,min->pCharValue) < 0)
      return false;
    else
      return true;
  default:
    throw 1010;   //Error1010: 错误的数据类型
  }
}


//表的信息
TTable_Info::TTable_Info()
{
	KeyPtr.FileKey.Initialize();
	KeyPtr.Key = NULL;			
	strcpy(TableName,"");
	TotalColumn = 0;
	RecordLength = 0;
	KeyAttrNum = 0;
}


//生成链表节点
Column_Info* HCatalog::Form_ListNode(Create_Column* ptr,int id) const
{
	Column_Info* pcolumn = new Column_Info;		
	Constraint_Info* constraint;
	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;		
	else if (ptr->IsNull == true)
		pcolumn->IsNull = 1;
	else if (ptr->IsNull == false)
		pcolumn->IsNull = 0;
	switch(pcolumn->ColType){
	case I:   
		pcolumn->RequiredLength = sizeof(int);
		pcolumn->StoredLength = pcolumn->RequiredLength;
		break;
	case F:   
		pcolumn->RequiredLength = sizeof(float);
		pcolumn->StoredLength = pcolumn->RequiredLength;
		break;
	case C:   
		pcolumn->RequiredLength = ptr->length;
		pcolumn->StoredLength = pcolumn->RequiredLength+1;
		break;
	default:
		throw 1010;				//error 1010: 错误的数据类型
	}
		
	//是否有约束
	bool flag=false;	
	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){	//有约束,连接入节点
		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	//没约束,指针设为空
		pcolumn->ConstraintPtr.constraint = NULL;

	return pcolumn;
}


//创建
void HCatalog::Create(TB_Create_Info& info, char* KeyInfo)
{
	Create_Column* ptr;
	ptr = info.head;
	Table_Info TableNode;
	strcpy(TableNode.TableName,info.TableName);
	TableNode.TotalColumn = info.TotalColumn;
	
	Column_Info* column1;
	Column_Info* head;
	Column_Info* column2;
	int count=0;		//主键数
	int	length=0;		//记录长度
	int j=0;
    int keylen=0;
	for(int i=0 ;ptr!=NULL ;ptr=ptr->next,i++){
		column1 = this->Form_ListNode(ptr,i);   
		length += column1->StoredLength;        
		if(column1->IsPrimary == 1){
			count++;      
			keylen += column1->StoredLength;  
            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");
		}
		if(i == 0)
			head = column1;	
		else
			column2->ColumnPtr.next = column1;		
		column2 = column1;		
	}
    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;

    //定位到当前表
	char temp[289];
	sprintf(temp,"%s%s.dbf",CurLocation,CurRelationName);
	_M_File CurrentTable = Buffer[temp];

	//写入文件
	_F_FileAddr pFile,pFile1,pFile2;
	
	pFile = CurrentTable.GetCataPoint();	
	
	pFile1 = MemWrite((void*)&TableNode,sizeof(Table_Info),&pFile);	
	
	column1 = head;
	
	if(column1 != NULL){		
		((Table_Info*)pFile.MemAddr())->KeyPtr.FileKey = 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);	

⌨️ 快捷键说明

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