예제 #1
0
파일: API.cpp 프로젝트: RikuSyaCyo/miniSQL
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;
}
예제 #2
0
파일: API.cpp 프로젝트: jxwufan/MiniSQL
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;
}
예제 #3
0
파일: API.cpp 프로젝트: jxwufan/MiniSQL
bool API::dropIndex(SQLcommand sql)
{
//    printf("---%s\n",sql.indexName.c_str());
    printf("----API::dropIndex----\n");
    CatalogManager catalog;
    catalog.deleteIndex(sql.indexName);
    return 1;
}
예제 #4
0
파일: API.cpp 프로젝트: jxwufan/MiniSQL
bool API::dropTable(SQLcommand sql)
{
//    printf("---%s\n",sql.tableName.c_str());
    
    printf("----API::dropTable----\n");
    CatalogManager catalog;
    catalog.dropTable(sql.tableName);
    return 1;
}
예제 #5
0
파일: API.cpp 프로젝트: RikuSyaCyo/miniSQL
bool CallDropIndex()
{
	if (catalog.hasIndex(iname) == false)
	{
		error_info = "Index not exsists!";
		return false;
	}
	catalog.deleteIndex(iname);
	return true;
}
예제 #6
0
파일: API.cpp 프로젝트: RikuSyaCyo/miniSQL
bool CallDropTable()
{
	
	if (!catalog.findTable(tname))
	{
		error_info = "Table not exsists!";
		return false;
	}
	else{
		return catalog.deleteTable(tname);
	}
	return true;
}
예제 #7
0
파일: API.cpp 프로젝트: jxwufan/MiniSQL
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;
}
예제 #8
0
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;
}
예제 #9
0
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);
}
예제 #10
0
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);
}
예제 #11
0
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;
}
예제 #12
0
파일: API.cpp 프로젝트: RikuSyaCyo/miniSQL
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;
}
예제 #13
0
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;
}
예제 #14
0
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);
}
예제 #15
0
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;
			
	}
}
예제 #16
0
파일: API.cpp 프로젝트: jxwufan/MiniSQL
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;
}
예제 #17
0
파일: API.cpp 프로젝트: jxwufan/MiniSQL
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;
}
예제 #18
0
파일: API.cpp 프로젝트: RikuSyaCyo/miniSQL
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;
}
예제 #19
0
파일: API.cpp 프로젝트: RikuSyaCyo/miniSQL
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;
}
예제 #20
0
파일: MiniSQL.cpp 프로젝트: sshic/MiniSQL
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;
}
예제 #21
0
파일: API.cpp 프로젝트: syz2580/MiniSQL
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;
	}
	
}