int CatalogManager::new_table_def(Node* node) { Node *tablePtr = cm_catNodeMgr.newCopyDataNode(node); tablePtr->leftSon = cm_catRoot->leftSon; cm_catRoot->leftSon = tablePtr; ++cm_catRoot->numval; Node *insertPtr = node->leftSon; Node *columnPtr = nullptr; int columnCount = 0; while (insertPtr != nullptr) { columnPtr = cm_catNodeMgr.newCopyDataNode(insertPtr); if (insertPtr->rightSon != nullptr) { columnPtr->rightSon = cm_catNodeMgr.newCopyDataNode(insertPtr->rightSon); } columnPtr->leftSon = tablePtr->rightSon; tablePtr->rightSon = columnPtr; insertPtr = insertPtr->leftSon; ++columnCount; } // build file string tmpStr(node->strval); tmpStr += ".db"; BufferManager* bufmgr = BufferManager::getInstance(); bufmgr->createFile(tmpStr.c_str()); Pager* page = bufmgr->getPager(tmpStr.c_str()); unsigned char* block = bufmgr->newblock(page, BUFFER_FLAG_DIRTY); int* blockData = (int*)(block+16*sizeof(char)); int* blockVarType = blockData + 5; int* blockVarLen = blockVarType + columnCount; strncpy((char*)block, "MINISQL v0.01", 16*sizeof(char)); blockData[0] = 1; blockData[1] = 0; blockData[2] = 0; blockData[3] = sizeof(char)*16+sizeof(int)*(5+2*columnCount); blockData[4] = columnCount; insertPtr = node->leftSon; for (int i = columnCount-1; i >=0 ; --i) { blockVarType[i] = insertPtr->operation; blockVarLen[i] = (insertPtr->operation == VAL_CHAR)? insertPtr->numval: 4; insertPtr = insertPtr->leftSon; } return 0; }
int CatalogManager::new_index_def(char* tableName, char* columnName, char* indexName) { Node *ptr = cm_catRoot->leftSon; Node *tmpPtr = nullptr; string tmpStr(tableName); tmpStr += "_"; tmpStr += columnName; tmpStr += ".idx"; BufferManager* bufmgr = BufferManager::getInstance(); IDXFileHeader idxHeader; strncpy(idxHeader.Header_string, "MINISQL v0.01", 16*sizeof(char)); while (ptr != nullptr) { if (strcmp(tableName, ptr->strval) == 0) { ptr = ptr->rightSon; while (ptr != nullptr) { if (strcmp(columnName, ptr->strval) == 0) { if(ptr->operation == VAL_CHAR){ idxHeader.Type = IDX_TYPE_STRING; idxHeader.Val_size = ptr->numval; } else if(ptr->operation == VAL_FLOAT){ idxHeader.Type = IDX_TYPE_FLOAT; idxHeader.Val_size = sizeof(float); } else if(ptr->operation == VAL_INT){ idxHeader.Type = IDX_TYPE_INT; idxHeader.Val_size = sizeof(int); } idxHeader.N_freepages = 0; idxHeader.Free_list = IDX_FLAG_NONPAGE; idxHeader.Root = IDX_FLAG_NOROOT; idxHeader.Degree = (BLOCK_SIZE - IDX_FILEHEADER_SIZE - IDX_BLOCKHEADER_SIZE) / (idxHeader.Val_size + IDX_LEFTPTR_SIZE); ptr = ptr->rightSon; tmpPtr = cm_catNodeMgr.newEmptyNode(); STRDUP_NEW(tmpPtr->strval, indexName); if (/*ptr!=nullptr && */ptr->rightSon != nullptr) { tmpPtr->rightSon = ptr->rightSon; ptr->rightSon = tmpPtr; return 1; } else { bufmgr->createFile(tmpStr.c_str()); Pager* page = bufmgr->getPager(tmpStr.c_str()); unsigned char* block = bufmgr->newblock(page, BUFFER_FLAG_DIRTY); memcpy(block, &idxHeader, IDX_FILEHEADER_SIZE); ptr->rightSon = tmpPtr; return 0; } } ptr = ptr->leftSon; } } ptr = ptr->leftSon; } exit(-1); }
CatalogManager::CatalogManager() { cm_delegate = this; BufferManager* bufmgr = BufferManager::getInstance(); Pager* pager; if(access("minisql.frm", R_OK)!=0) { bufmgr->createFile("minisql.frm"); cm_catRoot = cm_catNodeMgr.newEmptyNode(); cm_catNodeMgr.setRootNode(cm_catRoot); cm_catRoot->strval = new char[32]; strncpy(cm_catRoot->strval, "MINISQL v0.01", 32*sizeof(char)); } else { cm_catRoot = cm_catNodeMgr.newEmptyNode(); cm_catNodeMgr.setRootNode(cm_catRoot); pager = bufmgr->getPager("minisql.frm"); if(pager->getNPages() == 0) { cm_catRoot->strval = new char[32]; strncpy(cm_catRoot->strval, "MINISQL v0.01", 32*sizeof(char)); } else { // File exists and not empty size_t const_offset = sizeof(int)*6 + sizeof(double); size_t var_offset=0; unsigned char* block0 = bufmgr->getblock(pager, 0, BUFFER_FLAG_NONDIRTY); memcpy((char*)&(cm_catRoot->operation), block0, sizeof(int) ); cm_catRoot->strval = new char[CAT_NAME_MAXSIZE]; memcpy(cm_catRoot->strval, block0+sizeof(int), CAT_NAME_MAXSIZE); memcpy((char*)&(cm_catRoot->numval), block0+2*sizeof(int), sizeof(double)); var_offset = sizeof(int)+sizeof(double)+CAT_NAME_MAXSIZE; // If not empty but corrupted .frm -> Corrupted db -> clean all if(strcmp(cm_catRoot->strval, "MINISQL v0.01")!=0) { system("rm *.db"); system("rm *.frm"); system("rm *.idx"); cm_catNodeMgr.clean(); m_columndef.clean(); bufmgr->createFile("minisql.frm"); cm_catRoot = cm_catNodeMgr.newEmptyNode(); cm_catNodeMgr.setRootNode(cm_catRoot); cm_catRoot->strval = new char[32]; strncpy(cm_catRoot->strval, "MINISQL v0.01", 32*sizeof(char)); } else { BlockPtr bPtr; memcpy(&bPtr, block0+var_offset, sizeof(BlockPtr)); Node* node = cm_catRoot; Node* left = nullptr; unsigned char* block; vector<NodePair> bPtrStack; while(bPtr.lBlock!=CAT_FLAG_NONBLOCK || !bPtrStack.empty()) { while(bPtr.lBlock!=CAT_FLAG_NONBLOCK) { block = bufmgr->getblock(pager, bPtr.lBlock, BUFFER_FLAG_NONDIRTY); var_offset = bPtr.lOffset; left = cm_catNodeMgr.newEmptyNode(); // nodeMap[left] = count++; node->leftSon = left; node = left; left->strval = new char[CAT_NAME_MAXSIZE]; memcpy((char*)&left->operation, block+var_offset, sizeof(int)); var_offset += sizeof(int); memcpy((left->strval), block+var_offset, CAT_NAME_MAXSIZE); var_offset += CAT_NAME_MAXSIZE; memcpy((char*)&left->numval, block+var_offset, sizeof(double)); var_offset += sizeof(double); memcpy(&bPtr, block+var_offset, sizeof(BlockPtr)); bPtrStack.push_back(NodePair(left, bPtr)); } while(bPtr.rBlock == CAT_FLAG_NONBLOCK && !bPtrStack.empty()){ bPtrStack.pop_back(); if(!bPtrStack.empty()){ bPtr = bPtrStack.back().second; node = bPtrStack.back().first; } } if(bPtr.rBlock != CAT_FLAG_NONBLOCK) { bPtrStack.pop_back(); block = bufmgr->getblock(pager, bPtr.rBlock, BUFFER_FLAG_NONDIRTY); var_offset = bPtr.rOffset; left = cm_catNodeMgr.newEmptyNode(); // nodeMap[left] = count++; node->rightSon = left; node = left; left->strval = new char[CAT_NAME_MAXSIZE]; memcpy((char*)&left->operation, block+var_offset, sizeof(int)); var_offset += sizeof(int); memcpy((left->strval), block+var_offset, CAT_NAME_MAXSIZE); var_offset += CAT_NAME_MAXSIZE; memcpy((char*)&left->numval, block+var_offset, sizeof(double)); var_offset += sizeof(double); memcpy(&bPtr, block+var_offset, sizeof(BlockPtr)); bPtrStack.push_back(NodePair(left, bPtr)); } } } } // File exists and not empty } }