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