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