bool CallCreateTable() { if(catalog.findTable(table.tname)) { error_info="Table name repeat!"; return false; } else{ TableManager tab = catalog.createTable(table.tname); for (int i = 0; i < table.anum; i++) { const _Attribute& attr=table.a[i]; if (attr.dtype != CHAR) { tab.InsertAttribute(attr.aname,attr.dtype,attr.atype); } else { tab.InsertAttribute(attr.aname,attr.dtype,attr.alen,attr.atype); } } } return true; }
bool API::createIndex(SQLcommand sql) { // printf("---%s %s %s\n",sql.indexName.c_str(), sql.tableName.c_str(), sql.attrName.c_str()); clock_t begin = clock(); printf("----API::createIndex----\n"); CatalogManager catalog; if (catalog.insertIndex(sql.tableName, sql.attrName, sql.indexName)) { //catalog创建成功,调用indexManager的接口真正建索引 if (catalog.indexNum(sql.tableName, sql.attrName) == 1) { Table table(sql.tableName); BPTree *indexTree; int i; auto vec = catalog.tableInformation(sql.tableName); for (i = 0; i < vec.size(); ++i) { if (vec[i].attrName == sql.attrName) break; } if (vec[i].type == AttributeType::INT) { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::INT, vec[i].length); } else if (vec[i].type == AttributeType::FLOAT) { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::FLOAT, vec[i].length); } else { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::CHAR, vec[i].length); } for (auto itr: table.getAll(i)) { indexTree->insertKeyPointerPair(itr.first, itr.second); } delete indexTree; } } printf("Command running time: %f second\n", (double)(clock() - begin) / CLOCKS_PER_SEC); return 1; }
bool API::dropIndex(SQLcommand sql) { // printf("---%s\n",sql.indexName.c_str()); printf("----API::dropIndex----\n"); CatalogManager catalog; catalog.deleteIndex(sql.indexName); return 1; }
bool API::dropTable(SQLcommand sql) { // printf("---%s\n",sql.tableName.c_str()); printf("----API::dropTable----\n"); CatalogManager catalog; catalog.dropTable(sql.tableName); return 1; }
bool CallDropIndex() { if (catalog.hasIndex(iname) == false) { error_info = "Index not exsists!"; return false; } catalog.deleteIndex(iname); return true; }
bool CallDropTable() { if (!catalog.findTable(tname)) { error_info = "Table not exsists!"; return false; } else{ return catalog.deleteTable(tname); } return true; }
bool API::createTable(TableInfo tableInfo) { // printf("@@@%s\n",tableInfo.tableName.c_str()); // printf("---%d\n",tableInfo.attrNum); // printf("===%s\n",tableInfo.attrType[2].c_str()); // printf("~~~%s\n",tableInfo.primaryKey.c_str()); clock_t begin = clock(); printf("----API::createTable----\n"); CatalogManager catalog; catalog.insertTable(tableInfo); printf("Command running time: %f second\n", (double)(clock() - begin) / CLOCKS_PER_SEC); return 1; }
int BufferManager::insertBlock(const std::string &fileName, const std::string& content) { int n = fileName.find(".index", 0); std::string indexName = fileName.substr(0, n); Index* indexPtr = Cat.getIndexPtr(indexName); std::list<Block*>::iterator it; if (indexPtr->emptyBlockOffset.empty() == 1) { it = addBlockInFile(fileName); (*it)->blockOffset = indexPtr->blockNum; (*it)->fileName = fileName; (*it)->isDirty = 1; indexPtr->blockNum++; (*it)->changeContent(0, content); } else { int blockOffset = indexPtr->emptyBlockOffset.back(); indexPtr->emptyBlockOffset.pop_back(); it = readFileBlock(fileName, blockOffset); (*it)->changeContent(0, content); } return (*it)->blockOffset; }
void BufferManager::deleteRecord(const std::string& fileName, int blockOffset, int start)//给recordManager { int n = fileName.find(".table",0); std::string tableName = fileName.substr(0, n); Table* tablePtr = Cat.getTablePtr(tableName); std::string ss = ""; for (int i = 0; i < tablePtr->recordSize; i++) ss += '\0'; std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset); if (start + tablePtr->recordSize>BLOCK_SIZE) { int length1 = BLOCK_SIZE - start; int length2 = tablePtr->recordSize - length1; (*it)->changeContent(start,ss.substr(0,length1)); it = readFileBlock(fileName, blockOffset+1); (*it)->changeContent(0,ss.substr(0,length2)); } else (*it)->changeContent(start, ss); int recordOffset = (blockOffset*BLOCK_SIZE + start) / tablePtr->recordSize; tablePtr->emptyRecordOffset.push_back(recordOffset); }
void BufferManager::readFile(const std::string& fileName) { int blockNum; int n; if ((n = fileName.find(".table", 0)) != std::string::npos) { Table* tablePtr = Cat.getTablePtr(fileName.substr(0,n)); blockNum = tablePtr->blockNum; } if ((n = fileName.find(".index", 0)) != std::string::npos) { Index* indexPtr = Cat.getIndexPtr(fileName.substr(0, n)); blockNum = indexPtr->blockNum; } std::list<Block*>::iterator it; for (int i = 0; i < blockNum; i++) it = readFileBlock(fileName, i); }
std::string BufferManager::getBlock(const std::string& fileName, int blockOffset,int start,int end) { int n = fileName.find(".index", 0); Index *indexPtr = Cat.getIndexPtr(fileName.substr(0, n)); std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset); std::string record = ""; for (int i = start; i < end; i++) record += (*it)->content[i]; return record; }
bool CallCreateIndex() { if (!catalog.findTable(index.tname)) { error_info = "Table not exsists!"; return false; } TableManager tab = catalog.getTable(index.tname); if (tab.hasIndexOn(index.aname) == true) { error_info = "Index exsists!"; return false; } if (tab.isUnique(tab.getAttrIndex(index.aname)) == false) { error_info = "The attribute is not unique!"; return false; } catalog.CreateIndexOn(index.tname,index.aname,index.iname); return true; }
std::string BufferManager::getRecord(const std::string& fileName, int blockOffset, int start) { int n = fileName.find(".table",0); Table* tablePtr = Cat.getTablePtr(fileName.substr(0, n)); std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset); std::string record = ""; if (start + tablePtr->recordSize > BLOCK_SIZE) { int length1 = BLOCK_SIZE - start; int length2 = tablePtr->recordSize - length1; for (int i = 0; i < length1; i++) record += (*it)->content[start + i]; it = readFileBlock(fileName, blockOffset+1); for (int i = 0; i < length2; i++) record += (*it)->content[i]; } else for (int i = 0; i < tablePtr->recordSize; i++) record += (*it)->content[i+start]; return record; }
void BufferManager::deleteBlock(const std::string &fileName, int blockOffset)//给indexManager { int n = fileName.find(".index", 0); std::string indexName = fileName.substr(0, n); std::vector<Index*>::iterator indexPtr = Cat.findIndex(indexName); std::string ss = ""; for (int i = 0; i < BLOCK_SIZE; i++) ss += '\0'; std::list<Block*>::iterator it = findBlockInBuffer(fileName, blockOffset); if (it != fullBuffer.end()) { (*it)->changeContent(0, ss); fullBuffer.push_front((*it)); fullBuffer.erase(it); } else { it = readFileBlock(fileName, blockOffset); (*it)->changeContent(0, ss); } (*indexPtr)->emptyBlockOffset.push_back(blockOffset); }
int BufferManager::insertRecord(const std::string& fileName, const std::string& content) { int n = fileName.find(".table", 0); std::string tableName = fileName.substr(0, fileName.size()-6); Table* tablePtr = Cat.getTablePtr(tableName); std::list<Block*>::iterator it; if (tablePtr->emptyRecordOffset.empty() == 1)//没有空位 { it = addBlockInFile(fileName); (*it)->blockOffset = tablePtr->blockNum; (*it)->fileName = fileName; (*it)->isDirty = 1; tablePtr->blockNum++; (*it)->changeContent(0, content); int recordOffset = ((tablePtr->blockNum - 1)*BLOCK_SIZE )/ tablePtr->recordSize; int num; if (BLOCK_SIZE % tablePtr->recordSize == 0) num = BLOCK_SIZE / tablePtr->recordSize; else num = BLOCK_SIZE / tablePtr->recordSize + 1; for (int i = 1; i < num; i++) tablePtr->emptyRecordOffset.push_back(recordOffset + i); return (*it)->blockOffset << 16; } else//有空位 { int recordOffset = *((tablePtr->emptyRecordOffset).begin()); (tablePtr->emptyRecordOffset).erase((tablePtr->emptyRecordOffset).begin()); int blockOffset = (recordOffset*tablePtr->recordSize) / BLOCK_SIZE; int start = (recordOffset*tablePtr->recordSize) % BLOCK_SIZE; it = readFileBlock(fileName, blockOffset); if (start + tablePtr->recordSize > BLOCK_SIZE)//记录跨block { int length1 = BLOCK_SIZE - start; int length2 = tablePtr->recordSize - length1; (*it)->changeContent(start, content.substr(0, length1)); if (blockOffset + 1 == tablePtr->blockNum)//所跨block的下一个需要生成 { it = addBlockInFile(fileName); (*it)->blockOffset = tablePtr->blockNum; (*it)->fileName = fileName; (*it)->isDirty = 1; tablePtr->blockNum++; (*it)->changeContent(0, content.substr(length1, length2)); int i = recordOffset+1; int size = length2; while (size < BLOCK_SIZE) { tablePtr->emptyRecordOffset.push_back(i); size += tablePtr->recordSize; i++; } } else//所跨block的下一个不需要生成 { it = readFileBlock(fileName,blockOffset+1); (*it)->changeContent(0, content.substr(length1, length2)); } } else//记录不跨block (*it)->changeContent(start, content); return (blockOffset << 16) | start; } }
bool API::deleteRecord(SQLcommand sql) { // printf("---%d\n",sql.condNum); // printf("---%s %s %s\n",sql.condCont[2].attrName.c_str(), sql.condCont[2].op.c_str(), sql.condCont[2].attrValueStr.c_str()); clock_t begin = clock(); printf("----API::deleteRecord----\n"); CatalogManager cm; if (!cm.tableExisted(sql.tableName)) { printf("Table %s doesn't exist! Select failed!\n", sql.tableName.c_str()); return 0; } vector<Attribute> conditionList; conditionList.clear(); vector<string> relationList; relationList.clear(); for (int i = 1; i <= sql.condNum; i++) { bool exist = false; for (auto Attribute: cm.tableInformation(sql.tableName)) { if (Attribute.attrName == sql.condCont[i].attrName) { exist = true; if (sql.condCont[i].attrType == "INT") { if (Attribute.type == AttributeType::CHAR) { printf("In where clause, the argument provided for attribute %s doesn't match its type, delete failed!\n", Attribute.attrName.c_str()); return 0; } else if (Attribute.type == AttributeType::INT) { Attribute.intdata = sql.condCont[i].attrValueInt; } else if (Attribute.type == AttributeType::FLOAT) { Attribute.floatdata = (float)sql.condCont[i].attrValueInt; } } else if (sql.condCont[i].attrType == "FLOAT") { if (Attribute.type != AttributeType::FLOAT) { printf("In where clause, the argument provided for attribute %s doesn't match its type, delete failed!\n", Attribute.attrName.c_str()); return 0; } Attribute.floatdata = sql.condCont[i].attrValueFlo; } else if (sql.condCont[i].attrType == "CHAR") { if (Attribute.type != AttributeType::CHAR) { printf("In where clause, the argument provided for attribute %s doesn't match its type, delete failed!\n", Attribute.attrName.c_str()); return 0; } if (Attribute.length < sql.condCont[i].attrValueStr.length()) { printf("In where clause, the argument provided for attribute %s is too long, delete failed!\n", Attribute.attrName.c_str()); return 0; } memset(Attribute.chardata, 0, Attribute.length); memcpy(Attribute.chardata, sql.condCont[i].attrValueStr.c_str(), sql.condCont[i].attrValueStr.length()); } conditionList.push_back(Attribute); relationList.push_back(sql.condCont[i].op); } } if (!exist) { printf("Attribute named %s doesn't exist! Delete failed!\n", sql.condCont[i].attrName.c_str()); return 0; } } Table table(sql.tableName); vector<PageIndexType> result = table.getAll(); if (sql.condNum != 0) { for (int i = 0; i < conditionList.size(); ++i) { if ((relationList[i] == "=") && (cm.indexNum(sql.tableName, conditionList[i].attrName) > 0)) { BPTree *indexTree; if (conditionList[i].type == AttributeType::INT) { indexTree = new BPTree(sql.tableName, conditionList[i].attrName, BPTreeKeyType::INT, conditionList[i].length); } else if (conditionList[i].type == AttributeType::FLOAT) { indexTree = new BPTree(sql.tableName, conditionList[i].attrName, BPTreeKeyType::FLOAT, conditionList[i].length); } else { indexTree = new BPTree(sql.tableName, conditionList[i].attrName, BPTreeKeyType::CHAR, conditionList[i].length); } auto searchResult = indexTree->searchKeyForPagePointer(conditionList[i]); if (searchResult != UNDEFINEED_PAGE_NUM) { result.clear(); result.push_back(searchResult); break; } delete indexTree; } } for (int i = 0; i < conditionList.size(); ++i) { vector<PageIndexType> nextResult; nextResult.clear(); auto tableInfo = cm.tableInformation(sql.tableName); int attributeIndex; for (attributeIndex = 0; attributeIndex < tableInfo.size(); ++attributeIndex) if (tableInfo[attributeIndex].attrName == conditionList[i].attrName) break; if ((relationList[i] == "=") && (cm.indexNum(sql.tableName, conditionList[i].attrName) > 0)) { BPTree *indexTree; if (conditionList[i].type == AttributeType::INT) { indexTree = new BPTree(sql.tableName, conditionList[i].attrName, BPTreeKeyType::INT, conditionList[i].length); } else if (conditionList[i].type == AttributeType::FLOAT) { indexTree = new BPTree(sql.tableName, conditionList[i].attrName, BPTreeKeyType::FLOAT, conditionList[i].length); } else { indexTree = new BPTree(sql.tableName, conditionList[i].attrName, BPTreeKeyType::CHAR, conditionList[i].length); } auto searchResult = indexTree->searchKeyForPagePointer(conditionList[i]); if (searchResult != UNDEFINEED_PAGE_NUM && find(result.begin(), result.end(), searchResult) != result.end()) nextResult.push_back(searchResult); delete indexTree; } else { for (auto itr: result) { auto currentAttributes = table.getTupleAtPage(itr); bool ok = false; if (relationList[i] == "=") { if (conditionList[i] == currentAttributes[attributeIndex]) ok = true; } else if (relationList[i] == "<>") { if (conditionList[i] != currentAttributes[attributeIndex]) ok = true; } else if (relationList[i] == "<") { if (conditionList[i] > currentAttributes[attributeIndex]) ok = true; } else if (relationList[i] == "<=") { if (conditionList[i] >= currentAttributes[attributeIndex]) ok = true; } else if (relationList[i] == ">") { if (conditionList[i] < currentAttributes[attributeIndex]) ok = true; } else if (relationList[i] == ">=") { if (conditionList[i] <= currentAttributes[attributeIndex]) ok = true; } if (ok) nextResult.push_back(itr); } } result = nextResult; } } if (!result.empty()) { auto tableInfo = cm.tableInformation(sql.tableName); for (auto attribute: cm.tableInformation(sql.tableName)) { if (cm.indexNum(sql.tableName, attribute.attrName) > 0) { int attributeIndex; for (attributeIndex = 0; attributeIndex < tableInfo.size(); ++attributeIndex) if (tableInfo[attributeIndex].attrName == attribute.attrName) break; BPTree *indexTree = nullptr; if (attribute.type == AttributeType::INT) { indexTree = new BPTree(sql.tableName, attribute.attrName, BPTreeKeyType::INT, attribute.length); } else if (attribute.type == AttributeType::FLOAT) { indexTree = new BPTree(sql.tableName, attribute.attrName, BPTreeKeyType::FLOAT, attribute.length); } else if (attribute.type == AttributeType::CHAR){ indexTree = new BPTree(sql.tableName, attribute.attrName, BPTreeKeyType::CHAR, attribute.length); } for (auto itr: result) { indexTree->deleteKey(table.getTupleAtPage(itr)[attributeIndex]); } delete indexTree; } } for (auto itr: result) { table.deleteTuple(itr); } } printf("%lu record deleted\n", result.size()); printf("Command running time: %f second\n", (double)(clock() - begin) / CLOCKS_PER_SEC); return 1; }
bool API::insertRecord(SQLcommand sql) { // printf("%d\n",sql.attrNum); // printf("%f\n",sql.condCont[2].attrValueFlo); clock_t begin = clock(); printf("----API::insertRecord----\n"); /* sql使用方法: sql.tableName为用户想要插入的表名 sql.attrNum为用户输入的数据个数 sql.condCont[1..attrNum]里面为每一个数据的情况,其中有如下参数可以使用 condCont[i].attrType 为 "INT" "FLOAT" "CHAR" 中的一种,要注意当用户输入"INT"时,表的属性是"FLOAT"也是合法的 对应的,根据condCont[i].attrType,以下三个里面会有一个有值,要注意当attrType为"INT"时,attrValueFlo里面也会有一份 condCont[i].attrValueFlo / condCont[i].attrValueInt / condCond[i].attrValueStr */ CatalogManager catalog; if (!catalog.tableExisted(sql.tableName)) { printf("Table %s doesn't exist! Insertion failed!\n", sql.tableName.c_str()); } vector<Attribute> vec=catalog.tableInformation(sql.tableName); int i; if (vec.size()!=sql.attrNum) { printf("Failed to insert record. Wrong number of attributes.\n"); return 0; } for (i=1; i<=sql.attrNum; i++) { if (vec[i-1].type==AttributeType::CHAR) { if (sql.condCont[i].attrType!="CHAR") { printf("Failed to insert record. Wrong type of value.\n"); return 0; } if (sql.condCont[i].attrValueStr.length()>vec[i-1].length) { printf("Failed to insert record. Value is too long.\n"); return 0; } memset(vec[i - 1].chardata, 0, vec[i - 1].length); memcpy(vec[i - 1].chardata, sql.condCont[i].attrValueStr.c_str(), sql.condCont[i].attrValueStr.length()); } else if (vec[i-1].type==AttributeType::FLOAT) { if (sql.condCont[i].attrType=="CHAR") { printf("Failed to insert record. Wrong type of value.\n"); return 0; } if (sql.condCont[i].attrType == "INT") { vec[i - 1].floatdata = (float) sql.condCont[i].attrValueInt; } else { vec[i - 1].floatdata = sql.condCont[i].attrValueFlo; } } else { if (sql.condCont[i].attrType!="INT") { printf("Failed to insert record. Wrong type of value.\n"); return 0; } vec[i - 1].intdata = sql.condCont[i].attrValueInt; } } //现在数量和类型都是对的了,就等插入了 //注意判unique的属性不能和表中已有的重复 //判一个属性是否unique可以调用catalogManager的函数 //bool attrUnique(string, string); 参数:表名、列名 //vec[i].attrName可以读列名 Table table(sql.tableName); for (int i = 0; i < vec.size(); ++i) { if (catalog.attrUnique(sql.tableName, vec[i].attrName)) { if (catalog.indexNum(sql.tableName, vec[i].attrName) > 0) { BPTree *indexTree; if (vec[i].type == AttributeType::INT) { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::INT, vec[i].length); } else if (vec[i].type == AttributeType::FLOAT) { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::FLOAT, vec[i].length); } else { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::CHAR, vec[i].length); } if ((*indexTree).searchKeyForPagePointer(vec[i]) != UNDEFINEED_PAGE_NUM) { printf("Conflict on attribute %s, this attribute should be unique!\n", vec[i].attrName.c_str()); delete indexTree; return 0; } delete indexTree; } else { if (!table.scanEqual(i, vec[i]).empty()) { printf("Conflict on attribute %s, this attribute should be unique!\n", vec[i].attrName.c_str()); return 0; } } } } PageIndexType insertedPage = table.insertTuple(vec); for (int i = 0; i < vec.size(); ++i) { if (catalog.indexNum(sql.tableName, vec[i].attrName) > 0) { BPTree *indexTree; if (vec[i].type == AttributeType::INT) { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::INT, vec[i].length); } else if (vec[i].type == AttributeType::FLOAT) { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::FLOAT, vec[i].length); } else { indexTree = new BPTree(sql.tableName, vec[i].attrName, BPTreeKeyType::CHAR, vec[i].length); } (*indexTree).insertKeyPointerPair(vec[i], insertedPage); delete indexTree; } } printf("Command running time: %f second\n", (double)(clock() - begin) / CLOCKS_PER_SEC); return 1; }
bool CallDelete() { if (!catalog.findTable(table.tname)) { error_info = "Table is not existed!"; return false; } TableManager tab = catalog.getTable(table.tname); for (int k = 0; k < tab.attributeCount(); k++) { table.a[k].aname = tab.getAttriName(k); table.a[k].dtype = tab.getAttributeType(k); } table.anum = tab.attributeCount(); ConditionList temp = new Condition; temp = conditions; while(temp!=NULL) { int flag; flag = 0; for(int i=0; i<table.anum; i++){ if(table.a[i].aname == temp->aname){ flag = 1; if(table.a[i].dtype == 0){ int flag1; string inum ; if(temp->value.find('-') != -1){ if(temp->value.find('-') != 0){ error_info = "Value is illegal !"; return false; } int a1 = temp->value.find('-'); string inum1 = temp->value.substr(0, a1); string inum2 = temp->value.substr(a1+1,temp->value.length()-a1-1 ); inum = inum1+inum2; } else inum = temp->value; for(int j=0; j<inum.length(); j++){ flag1=0; for(int k=0;k<=9;k++){ if((int)(inum.at(j)) == k + '0'){ flag1=1; break; } } if(flag1==0){ error_info = "Value is illegal !"; return false; } } temp->dtype = 0; } string num,fnum; if(table.a[i].dtype == 1){ int flag1; if (temp->value.find('-') != -1){ if (temp->value.find('-') != 0){ error_info = "Value is illegal !"; return false; } int t1 = temp->value.find('-'); string num1 = temp->value.substr(0, t1); string num2 = temp->value.substr(t1 + 1, temp->value.length() - t1 - 1); num = num1+num2; } else num = temp->dtype ; if(num.find('.') != -1){ int t2 = num.find('.'); string num3 = num.substr(0, t2); string num4 = num.substr(t2+1,num.length()-t2-1 ); fnum = num3 + num4; } else fnum = num ; for(int j=0; j<fnum.length(); j++){ flag1 = 0; for(int k=0;k<=9;k++){ if((int)(fnum.at(j)) == k + '0'){ flag1=1; break; } } if(flag1==0){ error_info = "Value is illegal !"; return false; } } temp->dtype = 1; } if(table.a[i].dtype == 2){ if(temp->value.find('\'') != 0){ error_info="Value's format is wrong, lack ' !"; return false; } if(temp->value.rfind('\'') != (temp->value.length()-1)){ error_info="Value's format is wrong , lack ' !"; return false; } temp->value= temp->value.substr(1,temp->value.length()-2); temp->dtype = 2; } } } if(flag == 0){ error_info = "Attribute not exists!"; return false; } temp = temp->next; } int cnt = 0; TupleResults results(tab.strName()); if (conditions==NULL) results=tab.getAllTuples(); else while (conditions != NULL){ TupleResults nowResults(tab.strName()); string str = conditions->value; int type = conditions->dtype; stringstream ss; ss << str; switch (type) { case INT: int number; ss >> number; nowResults = tab.selectTuples(conditions->aname, conditions->cmtype, number); break; case FLOAT: float number_float; ss >> number_float; nowResults = tab.selectTuples(conditions->aname, conditions->cmtype, number_float); break; case CHAR: nowResults = tab.selectTuples(conditions->aname, conditions->cmtype, str); break; default: break; } if (cnt == 0) results = nowResults; else results.And(nowResults); cnt++; conditions = conditions->next; } for (int i = 0; i < results.size(); i++) { TupleManager tuple(results.tableName(), results.getTupleIndexAt(i)); tuple.Delete(); } cout << "Completely delete " << results.size() << " tuples!" << endl; return true; }
bool CallInsert() { if (!catalog.findTable(table.tname)) { error_info="The table is not existed!"; return false; } TableManager tab = catalog.getTable(table.tname); if(tab.attributeCount() != vnum) { error_info="Value lack !"; return false; } for (int k = 0; k < tab.attributeCount(); k++) { table.a[k].dtype = tab.getAttributeType(k); } table.anum = tab.attributeCount(); //下面对values[]进行类型确认 for(int i=0; i<table.anum; i++) { if(table.a[i].dtype == 0){ int flag; string inum ; if(values[i].find('-') != -1){ if(values[i].find('-') != 0){ error_info = "Value is illegal !"; return false; } int a1 = values[i].find('-'); string inum1 = values[i].substr(0, a1); string inum2 = values[i].substr(a1+1,values[i].length()-a1-1 ); inum = inum1+inum2; } else inum = values[i]; for(int j=0; j<inum.length(); j++){ flag=0; for(int k=0;k<=9;k++){ if((int)(inum.at(j)) == k + '0'){ flag=1; break; } } if(flag==0){ error_info = "Value is illegal !"; return false; } } } string num ,fnum; if(table.a[i].dtype == 1) { int flag; if(values[i].find('-') != -1){ if(values[i].find('-') != 0){ error_info = "Value is illegal !"; return false; } int t1 = values[i].find('-'); string num1 = values[i].substr(0, t1); string num2 = values[i].substr(t1+1,values[i].length()-t1-1 ); num = num1+num2; } else num = values[i] ; if(num.find('.') != -1){ int t2 = num.find('.'); string num3 = num.substr(0, t2); string num4 = num.substr(t2+1,values[i].length()-t2-1 ); fnum = num3+num4; } else fnum = num ; for(int j=0; j<fnum.length(); j++){ flag=0; for(int k=0;k<=9;k++){ if((int)(fnum.at(j)) == k + '0'){ flag=1; break; } } if(flag==0){ error_info = "Value is illegal !"; return false; } } } if(table.a[i].dtype == 2){ if(values[i].find('\'') != 0){ error_info="Value's format is wrong, lack ' !"; return false; } if(values[i].rfind('\'') != (values[i].length()-1)){ error_info="Value's format is wrong, lack ' !"; return false; } values[i]= values[i].substr(1,values[i].length()-2); } } int inf; TupleManager tuple = tab.CreateNewTuple(); for (int k = 0; k < tab.attributeCount(); k++) { string str = values[k]; int type = tab.getAttributeType(k); stringstream ss; ss << str; switch (type) { case INT: int number; ss >> number; inf=tuple.InsValue(k,number); break; case FLOAT: float number_float; ss >> number_float; inf=tuple.InsValue(k,number_float); break; case CHAR: inf=tuple.InsValue(k,str); break; default: break; } if (inf != INSERT_SUCCEED) { if (inf == INSERT_FAIL_NOTUNIQUE) { error_info = "The value is not unique."; } else { error_info = "CHAR value is out of length."; } return false; } } return true; }
int main() { //输出揭示信息 cout<<"*******************Welocme to use our MiniSQL**********************"<<endl; int flag=0; //标记读取SQL语句的状态,如果flag=1,则为文件中读,如果flag=0,则为标准IO中读取 ifstream file; //用于输入脚本 while(1) { Interpreter in; //语法解析对象 string s; //如果flag==0,不从文件中读入,从标准IO读入,则输出提示符 if(!flag) { //输入提示信息 cout<<">>"; //以';'作为SQL语句结束的标志,输入一条SQL语句 getline(cin,s,';'); } //如果flag==1, 从文件中读入SQL语句 else { cout<<endl; getline(file,s,';'); //如果读到脚本末尾标记,则退出文件读取状态,设置flag=0; int sss=s.find("$end"); if(sss>=0) { flag=0; file.close(); in.~Interpreter(); continue; } } //对SQL语句进行解析,如果解析失败,则退出可能进入的文件读取状态,重新读入SQL语句 if(!in.interpreter(s)) { flag=0; //判断文件是否打开,如果打开,则将其关闭 if(file.is_open()) file.close(); //析构in对象 in.~Interpreter(); continue; } //对firstKey进行遍历,分类处理 switch(in.firstKey) { //firstKey为create case CREATE: //创建表 if(in.secondKey==TABLE) ap.createTable(in.fileName,in.col,in.type,in.uniq,in.primKey); //创建索引 else if(in.secondKey==INDEX) ap.createIndex(in.fileName,in.tableName,in.colName); else cout<<"Error. Usage: create name"<<endl; break; //firstKey为select case SELECT: //无where条件查寻 if(in.condNum==0) ap.printRecord(in.fileName); //一个where条件查寻 else if(in.condNum==1) ap.printRecord(in.fileName,in.col1,in.condition1,in.operater1); //二个where条件查寻 else ap.printRecord(in.fileName,in.col1,in.condition1,in.operater1, in.col2,in.condition2,in.operater2,in.logic); break; //firstKdy为drop case DROP: //删除表 if(in.secondKey==TABLE) ap.dropTable(in.fileName); //删除索引 else if(in.secondKey==INDEX) ap.dropIndex(in.fileName); else cout<<"Error. Usage: drop table name or index name"<<endl; break; //firstKey为delete case DELETE: //无条件删除所有记录 if(in.condNum==0) ap.deleteValue(in.fileName); //根据一个where条件删除满足条件的记录 else if(in.condNum==1) ap.deleteValue(in.fileName,in.col1,in.condition1,in.operater1); //根据两个where条件删除满足条件的记录 else ap.deleteValue(in.fileName,in.col1,in.condition1,in.operater1, in.col2,in.condition2,in.operater2,in.logic); break; //firstKey为insert case INSERT: ap.insertRecord(in.fileName,in.insertValue); break; //firstKey为quit case QUIT: //将字典信息写回 if(!cm.writeBack()) { cout<<"Error! Fail to write back db.info"<<endl; return 0; } //将数据信息写回文件 if(!bm.flushAll()) { cout<<"Error! Fail to flush all the block into database"<<endl; return 0; } return 1; //firstKey为commit case COMMIT: //将字典信息写回 if(!cm.writeBack()) cout<<"Error! Fail to write back db.info"<<endl; //将数据写回文件 if(!bm.flushAll()) cout<<"Error! Fail to flush all the block into database"<<endl; break; //执行脚本 case EXECFILE: //打开文件,如果失败,则输出错误信息 file.open(in.fileName.c_str()); if(!file.is_open()) { cout<<"Fail to open "<<in.fileName<<endl; break; } //将状态设为从文件输入 flag=1; break; } //析构in实例 in.~Interpreter(); } return 1; }
void Execute() { int i; int j; int k; Table tableinfor; Index indexinfor; string tempKeyValue; int tempPrimaryPosition=-1; int rowCount=0; Data data; switch(parsetree.m_operation) { case CRETAB: parsetree.getTableInfo.attriNum=parsetree.getTableInfo.attributes.size(); catalog.createTable(parsetree.getTableInfo); record.createTable(parsetree.getTableInfo); cout<<"Table "<<parsetree.getTableInfo.name<<" is created successfully"<<endl; break; case TABLEEXISTED: cout<<"CREATE ERROR: Table existed"<<endl; break; case DRPTAB: record.dropTable(parsetree.getTableInfo); for(int i = 0; i < parsetree.getTableInfo.attriNum; i++){//���������е�index��ɾ�� indexinfor = catalog.getIndexInformation(parsetree.getTableInfo.name, i); if(indexinfor.index_name != "") indexm.dropIndex(indexinfor); } catalog.dropTable(parsetree.getTableInfo); cout<<"Table "<<parsetree.getTableInfo.name<<" is dropped successfully"<<endl; break; case INSERT: tableinfor = parsetree.getTableInfo; if(parsetree.PrimaryKeyPosition==-1&&parsetree.UniquePostion==-1){ record.insertValue(tableinfor, parsetree.row); catalog.update(tableinfor); cout<<"Insert successfully"<<endl; break; } if(parsetree.PrimaryKeyPosition!=-1) { data=record.select(tableinfor, parsetree.condition); if(data.rows.size()>0){ cout<<"INSERT ERROR: Primary key redundancy"<<endl; break; } } if(parsetree.UniquePostion!=-1){ data=record.select(tableinfor, parsetree.UniqueCondition); if(data.rows.size()>0){ cout<<"INSERT ERROR: Unique value redundancy"<<endl; break; } } record.insertValue(tableinfor,parsetree.row); catalog.update(tableinfor); cout<<"Insert successfully"<<endl; break; case INSERTERR: cout << "Syntax ERROR: Incorrect usage of \"insert\"." << endl; break; case SELECT_NOWHERE_CAULSE: tableinfor = parsetree.getTableInfo; data=record.select(tableinfor); if(data.rows.size()!=0) ShowResult( data, tableinfor, parsetree.column); else{ cout << "No data is found." << endl; } break; case SELECT_WHERE_CAULSE: tableinfor=parsetree.getTableInfo; if(parsetree.condition.size()==1){ for(int i=0;i<parsetree.getTableInfo.attributes.size();i++){ /*��*/if((parsetree.getTableInfo.attributes[i].isPrimeryKey==true||parsetree.getTableInfo.attributes[i].isUnique==true)&&parsetree.m_colname==parsetree.getTableInfo.attributes[i].name){ tempPrimaryPosition=i; indexinfor=catalog.getIndexInformation(tableinfor.name,i); break; } } if(tempPrimaryPosition==parsetree.condition[0].columnNum&&parsetree.condition[0].op==Eq&&indexinfor.table_name!=""){ tempKeyValue=parsetree.condition[0].value; data= indexm.selectEqual(tableinfor,indexinfor,tempKeyValue); } else{ data=record.select(tableinfor,parsetree.condition); } } else{ data=record.select(tableinfor,parsetree.condition); } if(data.rows.size()!=0) ShowResult( data, tableinfor, parsetree.column); else{ cout << "No data is found." << endl; } break; case DELETE: rowCount = record.deleteValue(parsetree.getTableInfo,parsetree.condition); cout<< rowCount <<" tuples are deleted."<<endl; break; case CREIND: indexinfor = parsetree.getIndexInfo; tableinfor = parsetree.getTableInfo; if(!tableinfor.attributes[indexinfor.column].isPrimeryKey && !tableinfor.attributes[indexinfor.column].isUnique){//����primary key�������Խ�index cout << "Column " << tableinfor.attributes[indexinfor.column].name <<" is not unique."<< endl; break; } catalog.createIndex(indexinfor); indexm.createIndex(tableinfor, indexinfor); catalog.update(indexinfor); cout<<"Index "<< indexinfor.index_name << "is created successfully."<<endl; break; case INDEXERROR: cout<<"ERROR: Index existed."<<endl; break; case DRPIND: indexinfor = catalog.getIndexInformation(parsetree.m_indname); if(indexinfor.index_name == ""){ cout << "ERROR: Index" << parsetree.m_indname << "does not exist!" << endl; } indexm.dropIndex(indexinfor); catalog.dropIndex(parsetree.m_indname); cout<<"The index is dropped successfully"<<endl; break; case CREINDERR: cout << "Syntax ERROR: Incorrect usage of \"create index\" query." << endl; break; case QUIT: cout << "Bye Bye~" << endl; system("pause"); exit(0); break; case EMPTY: cout << "Query Empty." << endl; break; case UNKNOW: cout << "Syntax ERROR: Please check your query." << endl; break; case SELERR: cout << "Syntax ERROR: Incorrect usage of \"select\" query." << endl; break; case CRETABERR: cout << "Syntax ERROR: Incorrect usage of \"create table\" query." << endl; break; case DELETEERR: cout << "Syntax ERROR: Incorrect usage of \"delete from\" query." << endl; break; case DRPTABERR: cout << "Syntax ERROR: Incorrect usage of \"drop table\" query." << endl; break; case DRPINDERR: cout << "Syntax ERROR: Incorrect usage of \"drop index\" query." << endl; break; case VOIDPRI: cout << "ERROR: Invalid primary key." << endl; break; case VOIDUNI: cout << "ERROR: Invalid unique key." << endl; break; case CHARBOUD: cout << "ERROR: Too long query. Only 1~255 charactors is allowed." << endl; break; case NOPRIKEY: cout << "ERROR: Please define a primary key." << endl; break; case TABLEERROR: cout << "ERROR: Table is not existed."<<endl; break; case INDEXEROR: cout << "ERROR: Index is not existed."<<endl; break; case COLUMNERROR: cout << "ERROR: Column is not existed"<<endl; break; case INSERTNUMBERERROR: cout << "ERROR: The amount of the columns is not matched."<<endl; break; } }