📄 catalog.cpp
字号:
#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 + -