UFUG2601_project_Fall2024 MiniDB Project

PS:如果读过题了可以跳过题目描述直接到题解部分
链接:UFUG2601_project_Fall2024 MiniDB Project

文章目录

  • 题目
  • 题解
    • 声明
    • 可完成操作
    • 运行逻辑
    • 大致思路
    • 数据存储
      • 数据类型
      • 数据名称
    • 命令输入
      • 文件读入
      • 命令读入
    • 操作
      • 2.1 Create Database and Use Database
      • 2.2 Create Tables
      • 2.3 Drop Tables
      • 2.4 Data Insertion
      • 2.5 Data Query: Basic
      • 2.6 Data Query: "Where" Clause
      • 2.7 Data Query: "Inner Join" Clause
      • 2.8 Data Update
      • 2.9 Data Deletion
    • 代码实现

题目

1
2
3
4
5
6
7
8
9
10
11

12
13
14

题解

声明

解题过程中有部分代码功能上是使用AI(包括ChatGPT以及Kimi.ai生成,但是代码思路及操作实现都是自主完成,没有让AI直接生成大段的完整代码并直接抄写。

可完成操作

Operation

运行逻辑

main
readCommand
readCreate
createDatabase
CREATE DATABASE
readUse
USE DATABASE
readDrop
dropTable
DROP TABLE
readInsert
readValue
dataInsert
INSERT INTO VALUES
readSelect
dataPrint
SELECT FROM
readUpdate
readUpdateWhere
dataUpdate
UPDATE SET WHERE
readDelete
readDeleteWhere
fileOperateAnd
filePrint
DELETE FROM WHERE
readTable
createTable
CREATE TABLE
readSelectWhere
dataOperateAnd
SELECT FROM WHERE with complex conditions
dataOperateOr
readInner
SELECT FROM INNER JOIN ON
fileOperateOr

大致思路

整个程序我都选择在线处理操作,既每个命令输入->操作(->输出)->下一个命令。
read部分在进行各种操作的读入及读入内容的处理,read之前的部分负责实现操作。

数据存储

这个程序一开始难住我的地方就在于数据如何存储,如果带入我们平时常写的代码,题目大概就是让你在既不知道数据类型也不知道数据名称的情况下写代码,那么接下来我们就依次解决一下这两个问题。

数据类型

我们可以定义一个枚举来表示支持的数据类型。

enum class DataType{INTEGER,FLOAT,TEXT
};

后来发现这个完全没用就删了……

数据名称

其实这个问题很好解决,用map函数就好了。

class miniDB{private:map<string,map<string,DataType>> databases;public:void createDatabase(const string& dbName);//......
};

事实上,由于数据库特殊的性质,我们不能将数据存在内存中,因此我们需要创建一个外部文件来储存数据,我选择创建csv文件,所以直接把后续操作直接对文件进行即可。

命令输入

文件读入

首先,我们从题目中明确读入类型是文件读入。这个是个很简单的操作,你可以选择任何顺手的方法,包括文件流之类的,我选择了我比较顺手的freopen

	freopen("input.sql","r",stdin);

命令读入

在这个地方我们需要考虑很多问题,最主要问题都是空格和换行造成的,包括如何判断一部分内容的结束等。比如逗号、分号、大括号和前面或者后面一部分是连在一起的还是分开的。还有,我们既可以选择一边输入一边输出,也可以选择全部输入将命令处理成我们便于操作的方式后再统一操作输出。

在这里我选择了我们自己对代码掌控很强的stringchar混合读入处理的方式。(不想大量码代码的人慎用)(具体代码我放在操作部分了)

//处理一些字符串末尾的空格等
string trimTrailingSpaces(const string& str){size_t end=str.find_last_not_of(" \t\n\r\f\v\0");if(end!=string::npos){return str.substr(0,end+1);}return "";
}void readCommand(){string command;while(cin>>command){if(command=="CREATE"){readCreate();}else if(command=="USE"){readUse();}else if(command=="DROP"){readDrop();}else if(command=="INSERT"){cin>>command;//去除INTOreadInsert();}else if(command=="SELECT"){readSelect();cnt++//输出时有用}else if(command=="UPDATE"){readUpdate();}else if(command=="DELETE"){cin>>command;//去除FROMreadDelete();}}
}

操作

2.1 Create Database and Use Database

即新建文件夹并命名和确定所需要打开文件的位置。

void createDatabase(const string& databaseName){string path=databaseName;mkdir(path.c_str());
}void readCreate(){string type;cin>>type;if(type=="DATABASE"){databaseName="";char c=getchar();string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){s.assign(1,c);databaseName+=s;c=getchar();}databaseName=trimTrailingSpaces(databaseName);createDatabase(databaseName);}else if(type=="TABLE"){tableName="";int i=0;char c=getchar();string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!='('){s.assign(1,c);tableName+=s;c=getchar();}tableName=trimTrailingSpaces(tableName);readTable();}
}void readUse(){string type;cin>>type;databaseName="";char c=getchar();string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){s.assign(1,c);databaseName+=s;c=getchar();}databaseName=trimTrailingSpaces(databaseName);
}

2.2 Create Tables

即新建csv文件。为了方便后续condition的处理,我在csv文件第一行存储了数据类型,第二行存储的列名称。

void createTable(const string& databaseName,const string& tableName,const vector<pair<string,string>>& columns){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;ofstream file(filePath);for(size_t i=0;i<columns.size();++i){file<<columns[i].second;if(i<columns.size()-1){file<<",";}}file<<endl;for(size_t i=0;i<columns.size();++i){file<<columns[i].first;if(i<columns.size()-1){file<<",";}}file<<endl;file.close();
}void readTable(){vector<pair<string,string>> parsedColumns;char c;string s;while(c!=')'){string columnName="";string typeName="";string name="";int i=0;c=getchar();while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=','&&c!=')'){if(c!='\t'&&c!='\n'&&c!='\r'&&c!='\f'&&c!='\v'){s.assign(1,c);columnName+=s;++i;}c=getchar();}i--;int j=0;while(columnName[i--]==' ');while(columnName[i-j]!=' '){j++;}typeName.assign(columnName.substr(i-j+1,j+1));name.assign(columnName.substr(0,i-j));parsedColumns.emplace_back(name,typeName);if(c!=')'){c=getchar();}}while(c!=';'){c=getchar();}createTable(databaseName,tableName,parsedColumns);
}

2.3 Drop Tables

即删除csv文件。

void dropTable(const string& databaseName,const string& tableName){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;remove(filePath.c_str());
}void readDrop(){string type;cin>>type;tableName="";char c=getchar();string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'||c=='\0'){c=getchar();}while(c!=';'){s.assign(1,c);tableName+=s;c=getchar();}tableName=trimTrailingSpaces(tableName);dropTable(databaseName,tableName);
}

2.4 Data Insertion

即向csv文件中添加数据。

void dataInsert(const string& databaseName,const string& tableName,const vector<string>& values){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;ofstream file(filePath,ios::out|ios::app);for(size_t i=0;i<values.size();++i){file<<values[i];if(i<values.size()-1){file<<",";}}file<<endl;file.close();
}void readValue(){vector<string> values;char c;string s;while(c!=')'){string value="";int i=0;c=getchar();while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'||c=='\0'){c=getchar();}while(c!=','&&c!=')'){if(c!='\t'&&c!='\n'&&c!='\r'&&c!='\f'&&c!='\v'&&c!=0){s.assign(1,c);value+=s;++i;}c=getchar();}value=trimTrailingSpaces(value);values.emplace_back(value);}while(c!=';'){c=getchar();}dataInsert(databaseName,tableName,values);
}void readInsert(){char c;string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}tableName="";string name="";int i=0;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'||c=='\0'){c=getchar();}while(c!='('){if(c!='\t'&&c!='\n'&&c!='\r'&&c!='\f'&&c!='\v'){s.assign(1,c);tableName+=s;i++;}c=getchar();}i--;while(tableName[i--]==' ');while(tableName[i--]!=' ');name.assign(tableName.substr(0,i+1));tableName.assign(name);readValue();
}

2.5 Data Query: Basic

即输出数据。其实要先从csv文件中读入数据筛选后输出。这里要注意输出格式(有无,---)和输出位置(output.txt)。

vector<vector<string>> readCSV(const string& databaseName,const string& tableName){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;vector<vector<string>> data;ifstream file(filePath);string line;while(getline(file,line)){vector<string> row;stringstream lineStream(line);string cell;while(getline(lineStream,cell,',')){row.push_back(cell);}data.push_back(row);}file.close();return data;
}void dataPrint(const vector<vector<string>>& data){string filePath="output.txt";ofstream file(filePath,ios::out|ios::app);if(cnt){file<<"---"<<endl;}for(const auto& row:data){file<<row[0];for(int i=1;i<row.size();++i){file<<","<<row[i];}file<<endl;}file.close();
}void readSelect(){string columns;string s;vector<string> column;cin>>s;while(s!="FROM"){columns+=s;cin>>s;}int len=columns.length();for(int i=0,j=0;i<len;){s="";while(columns[i]!=','&&i<len){++i;}s.assign(columns.substr(j,i-j));j=++i;column.emplace_back(s);}char c;c=getchar();columns="";//临时储存字符串 tableName="";while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){s.assign(1,c);if(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){if(columns==" WHERE"){readSelectWhere(column);return;}else if(columns==" INNER"){readInner(column);return;}s=" ";tableName+=columns;columns="";}columns+=s;c=getchar();}tableName+=columns;auto data=readCSV(databaseName,tableName);vector<vector<string>> result;if(column[0]=="*"){for(int i=1;i<data.size();++i){result.emplace_back(data[i]);}dataPrint(result);return;}vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& columnName:column){if(columnName==data[1][i]){w.emplace_back(i);break;}}}for(size_t i=1;i<data.size();++i){vector<string> row;for(const auto& j:w){row.emplace_back(data[i][j]);}result.emplace_back(row);}dataPrint(result);
}

2.6 Data Query: “Where” Clause

同上。

void dataOperateAnd(const vector<string>& columns,const vector<string>& columnName,const vector<int>& op,const vector<string>& values){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;vector<int> wc;vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& column:columnName){if(column==data[1][i]){w.emplace_back(i);break;}}}result.emplace_back(columns);for(int i=0;i<data[1].size();++i){for(const auto& column:columns){if(column==data[1][i]){wc.emplace_back(i);break;}}}for(int i=2;i<data.size();++i){bool suit=1;for(int j=0;j<op.size();++j){if(data[0][w[j]]=="INTEGER"){int value1=stoi(data[i][w[j]]);int value2=stoi(values[j]);if(op[j]==1){if(value1!=value2){suit=0;break;}}else if(op[j]==2){if(value1==value2){suit=0;break;}}else if(op[j]==3){if(value1>=value2){suit=0;break;}}else{if(value1<=value2){suit=0;break;}}}else if(data[0][w[j]]=="FLOAT"){float value1=stof(data[i][w[j]]);float value2=stof(values[j]);if(op[j]==1){if(value1!=value2){suit=0;break;}}else if(op[j]==2){if(value1==value2){suit=0;break;}}else if(op[j]==3){if(value1>=value2){suit=0;break;}}else{if(value1<=value2){suit=0;break;}}}else{if(op[j]==1){if(data[i][w[j]]!=values[j]){suit=0;break;}}else if(op[j]==2){if(data[i][w[j]]==values[j]){suit=0;break;}}}}if(suit){vector<string> row;for(int j=0;j<wc.size();++j){row.emplace_back(data[i][wc[j]]);}result.emplace_back(row);}}dataPrint(result);
}void dataOperateOr(const vector<string>& columns,const vector<string>& columnName,const vector<int>& op,const vector<string>& values){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;vector<int> wc;vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& column:columnName){if(column==data[1][i]){w.emplace_back(i);break;}}}result.emplace_back(columns);for(int i=0;i<data[1].size();++i){for(const auto& column:columns){if(column==data[1][i]){wc.emplace_back(i);break;}}}for(int i=2;i<data.size();++i){bool suit=0;for(int j=0;j<op.size();++j){if(data[0][w[j]]=="INTEGER"){int value1=stoi(data[i][w[j]]);int value2=stoi(values[j]);if(op[j]==1){if(value1==value2){suit=1;break;}}else if(op[j]==2){if(value1!=value2){suit=1;break;}}else if(op[j]==3){if(value1<value2){suit=1;break;}}else{if(value1>value2){suit=1;break;}}}else if(data[0][w[j]]=="FLOAT"){float value1=stof(data[i][w[j]]);float value2=stof(values[j]);if(op[j]==1){if(value1==value2){suit=1;break;}}else if(op[j]==2){if(value1!=value2){suit=1;break;}}else if(op[j]==3){if(value1<value2){suit=1;break;}}else{if(value1>value2){suit=1;break;}}}else{if(op[j]==1){if(data[i][w[j]]==values[j]){suit=1;break;}}else if(op[j]==2){if(data[i][w[j]]!=values[j]){suit=1;break;}}}}if(suit){vector<string> row;for(int j=0;j<wc.size();++j){row.emplace_back(data[i][wc[j]]);}result.emplace_back(row);}}dataPrint(result);
}void readSelectWhere(vector<string> column){char c=getchar();vector<string> columnName;vector<int> op;//1= 2!= 3> 4<vector<string> value;string s,str="",strin="";//临时存放 bool a;//1and 0orwhile(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){str="";while(c!='='&&c!='!'&&c!='<'&&c!='>'){if(c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=' ';}s.assign(1,c);str+=s;c=getchar();}//读入columnName str=trimTrailingSpaces(str);columnName.emplace_back(str);if(c=='='){op.emplace_back(1);}else if(c=='!'){op.emplace_back(2);c=getchar();}else if(c=='<'){op.emplace_back(3);}else{op.emplace_back(4);}//读入op c=getchar();while(c==' '){c=getchar();}str="";while(c!=';'){if(c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=' ';}s.assign(1,c);str+=s;if(c==' '){if(str=="AND "){a=1;break;}else if(str=="OR "){a=0;break;}strin+=str;str="";}if(c==';'){break;}c=getchar();} strin+=str;value.emplace_back(trimTrailingSpaces(strin));if(c==';'){break;}c=getchar();}if(a){dataOperateAnd(column,columnName,op,value);}else{dataOperateOr(column,columnName,op,value);}
}

2.7 Data Query: “Inner Join” Clause

未完成。

void readInner(vector<string> column){}

2.8 Data Update

未完成。

void readUpdateWhere(){}void readUpdate(){}

2.9 Data Deletion

即清空数据。我用的是重新输出数据类型和列名称覆盖原文件的方式。

void filePrint(const string& databaseName,const string& tableName,const vector<vector<string>>& data){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;ofstream file(filePath);for(size_t i=0;i<data.size();++i){for(size_t j=0;j<data[i].size();++j){file<<data[i][j];if(j<data[i].size()-1){file<<",";}}file<<endl;}file.close();
}void fileOperateAnd(const vector<string>& columnName,const vector<int>& op,const vector<string>& values){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& column:columnName){if(column==data[1][i]){w.emplace_back(i);break;}}}result.emplace_back(data[0]);result.emplace_back(data[1]);for(int i=2;i<data.size();++i){bool suit=1;for(int j=0;j<op.size();++j){if(data[0][w[j]]=="INTEGER"){int value1=stoi(data[i][w[j]]);int value2=stoi(values[j]);if(op[j]==1){if(value1!=value2){suit=0;break;}}else if(op[j]==2){if(value1==value2){suit=0;break;}}else if(op[j]==3){if(value1>=value2){suit=0;break;}}else{if(value1<=value2){suit=0;break;}}}else if(data[0][w[j]]=="FLOAT"){float value1=stof(data[i][w[j]]);float value2=stof(values[j]);if(op[j]==1){if(value1!=value2){suit=0;break;}}else if(op[j]==2){if(value1==value2){suit=0;break;}}else if(op[j]==3){if(value1>=value2){suit=0;break;}}else{if(value1<=value2){suit=0;break;}}}else{if(op[j]==1){if(data[i][w[j]]!=values[j]){suit=0;break;}}else if(op[j]==2){if(data[i][w[j]]==values[j]){suit=0;break;}}}}if(suit){result.emplace_back(data[i]);}}filePrint(databaseName,tableName,result);
}void fileOperateOr(const vector<string>& columnName,const vector<int>& op,const vector<string>& values){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& column:columnName){if(column==data[1][i]){w.emplace_back(i);break;}}}result.emplace_back(data[0]);result.emplace_back(data[1]);for(int i=2;i<data.size();++i){bool suit=0;for(int j=0;j<op.size();++j){if(data[0][w[j]]=="INTEGER"){int value1=stoi(data[i][w[j]]);int value2=stoi(values[j]);if(op[j]==1){if(value1==value2){suit=1;break;}}else if(op[j]==2){if(value1!=value2){suit=1;break;}}else if(op[j]==3){if(value1<value2){suit=1;break;}}else{if(value1>value2){suit=1;break;}}}else if(data[0][w[j]]=="FLOAT"){float value1=stof(data[i][w[j]]);float value2=stof(values[j]);if(op[j]==1){if(value1==value2){suit=1;break;}}else if(op[j]==2){if(value1!=value2){suit=1;break;}}else if(op[j]==3){if(value1<value2){suit=1;break;}}else{if(value1>value2){suit=1;break;}}}else{if(op[j]==1){if(data[i][w[j]]==values[j]){suit=1;break;}}else if(op[j]==2){if(data[i][w[j]]!=values[j]){suit=1;break;}}}}if(suit){result.emplace_back(data[i]);}}filePrint(databaseName,tableName,result);
}void readDeleteWhere(){char c=getchar();vector<string> columnName;vector<int> op;//1= 2!= 3> 4<vector<string> value;string s,str="",strin="";//临时存放 bool a;//1and 0orwhile(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){str="";while(c!='='&&c!='!'&&c!='<'&&c!='>'){if(c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=' ';}s.assign(1,c);str+=s;c=getchar();
//			cout<<1<<endl;}//读入columnName str=trimTrailingSpaces(str);columnName.emplace_back(str);if(c=='='){op.emplace_back(1);}else if(c=='!'){op.emplace_back(2);c=getchar();}else if(c=='<'){op.emplace_back(3);}else{op.emplace_back(4);}//读入op c=getchar();while(c==' '){c=getchar();}str="";while(c!=';'){if(c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=' ';}s.assign(1,c);str+=s;if(c==' '){if(str=="AND "){a=1;break;}else if(str=="OR "){a=0;break;}strin+=str;str="";}if(c==';'){break;}c=getchar();} strin+=str;value.emplace_back(trimTrailingSpaces(strin));if(c==';'){break;}c=getchar();}if(a){fileOperateAnd(columnName,op,value);}else{fileOperateOr(columnName,op,value);}
}void readDelete(){char c=getchar();string s,str;tableName="";while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){s.assign(1,c);if(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){if(str==" WHERE"){break;}s=" ";tableName+=str;str="";}str+=s;c=getchar();}tableName=trimTrailingSpaces(tableName);if(c==';'){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;result.emplace_back(data[0]);result.emplace_back(data[1]);filePrint(databaseName,tableName,result);return;}readDeleteWhere();
}

代码实现

以下是最终未完成的完整版代码。

//minidb
#include<bits/stdc++.h>
#include<sys/stat.h>
using namespace std;
string databaseName;
string tableName;
int cnt;string trimTrailingSpaces(const string& str){size_t end=str.find_last_not_of(" \t\n\r\f\v\0");if(end!=string::npos){return str.substr(0,end+1);}return "";
}vector<vector<string>> readCSV(const string& databaseName,const string& tableName){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;vector<vector<string>> data;ifstream file(filePath);string line;while(getline(file,line)){vector<string> row;stringstream lineStream(line);string cell;while(getline(lineStream,cell,',')){row.push_back(cell);}data.push_back(row);}file.close();return data;
}void createDatabase(const string& databaseName){string path=databaseName;mkdir(path.c_str());
}void createTable(const string& databaseName,const string& tableName,const vector<pair<string,string>>& columns){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;ofstream file(filePath);for(size_t i=0;i<columns.size();++i){file<<columns[i].second;if(i<columns.size()-1){file<<",";}}file<<endl;for(size_t i=0;i<columns.size();++i){file<<columns[i].first;if(i<columns.size()-1){file<<",";}}file<<endl;file.close();
}void dropTable(const string& databaseName,const string& tableName){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;remove(filePath.c_str());
}void dataInsert(const string& databaseName,const string& tableName,const vector<string>& values){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;ofstream file(filePath,ios::out|ios::app);for(size_t i=0;i<values.size();++i){file<<values[i];if(i<values.size()-1){file<<",";}}file<<endl;file.close();
}void dataPrint(const vector<vector<string>>& data){string filePath="output.txt";ofstream file(filePath,ios::out|ios::app);if(cnt){file<<"---"<<endl;}for(const auto& row:data){file<<row[0];for(int i=1;i<row.size();++i){file<<","<<row[i];}file<<endl;}file.close();
}void dataOperateAnd(const vector<string>& columns,const vector<string>& columnName,const vector<int>& op,const vector<string>& values){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;vector<int> wc;vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& column:columnName){if(column==data[1][i]){w.emplace_back(i);break;}}}result.emplace_back(columns);for(int i=0;i<data[1].size();++i){for(const auto& column:columns){if(column==data[1][i]){wc.emplace_back(i);break;}}}for(int i=2;i<data.size();++i){bool suit=1;for(int j=0;j<op.size();++j){if(data[0][w[j]]=="INTEGER"){int value1=stoi(data[i][w[j]]);int value2=stoi(values[j]);if(op[j]==1){if(value1!=value2){suit=0;break;}}else if(op[j]==2){if(value1==value2){suit=0;break;}}else if(op[j]==3){if(value1>=value2){suit=0;break;}}else{if(value1<=value2){suit=0;break;}}}else if(data[0][w[j]]=="FLOAT"){float value1=stof(data[i][w[j]]);float value2=stof(values[j]);if(op[j]==1){if(value1!=value2){suit=0;break;}}else if(op[j]==2){if(value1==value2){suit=0;break;}}else if(op[j]==3){if(value1>=value2){suit=0;break;}}else{if(value1<=value2){suit=0;break;}}}else{if(op[j]==1){if(data[i][w[j]]!=values[j]){suit=0;break;}}else if(op[j]==2){if(data[i][w[j]]==values[j]){suit=0;break;}}}}if(suit){vector<string> row;for(int j=0;j<wc.size();++j){row.emplace_back(data[i][wc[j]]);}result.emplace_back(row);}}dataPrint(result);
}void dataOperateOr(const vector<string>& columns,const vector<string>& columnName,const vector<int>& op,const vector<string>& values){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;vector<int> wc;vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& column:columnName){if(column==data[1][i]){w.emplace_back(i);break;}}}result.emplace_back(columns);for(int i=0;i<data[1].size();++i){for(const auto& column:columns){if(column==data[1][i]){wc.emplace_back(i);break;}}}for(int i=2;i<data.size();++i){bool suit=0;for(int j=0;j<op.size();++j){if(data[0][w[j]]=="INTEGER"){int value1=stoi(data[i][w[j]]);int value2=stoi(values[j]);if(op[j]==1){if(value1==value2){suit=1;break;}}else if(op[j]==2){if(value1!=value2){suit=1;break;}}else if(op[j]==3){if(value1<value2){suit=1;break;}}else{if(value1>value2){suit=1;break;}}}else if(data[0][w[j]]=="FLOAT"){float value1=stof(data[i][w[j]]);float value2=stof(values[j]);if(op[j]==1){if(value1==value2){suit=1;break;}}else if(op[j]==2){if(value1!=value2){suit=1;break;}}else if(op[j]==3){if(value1<value2){suit=1;break;}}else{if(value1>value2){suit=1;break;}}}else{if(op[j]==1){if(data[i][w[j]]==values[j]){suit=1;break;}}else if(op[j]==2){if(data[i][w[j]]!=values[j]){suit=1;break;}}}}if(suit){vector<string> row;for(int j=0;j<wc.size();++j){row.emplace_back(data[i][wc[j]]);}result.emplace_back(row);}}dataPrint(result);
}void filePrint(const string& databaseName,const string& tableName,const vector<vector<string>>& data){string a="/";string b=".csv";string filePath=databaseName+a+tableName+b;ofstream file(filePath);for(size_t i=0;i<data.size();++i){for(size_t j=0;j<data[i].size();++j){file<<data[i][j];if(j<data[i].size()-1){file<<",";}}file<<endl;}file.close();
}void fileOperateAnd(const vector<string>& columnName,const vector<int>& op,const vector<string>& values){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& column:columnName){if(column==data[1][i]){w.emplace_back(i);break;}}}result.emplace_back(data[0]);result.emplace_back(data[1]);for(int i=2;i<data.size();++i){bool suit=1;for(int j=0;j<op.size();++j){if(data[0][w[j]]=="INTEGER"){int value1=stoi(data[i][w[j]]);int value2=stoi(values[j]);if(op[j]==1){if(value1!=value2){suit=0;break;}}else if(op[j]==2){if(value1==value2){suit=0;break;}}else if(op[j]==3){if(value1>=value2){suit=0;break;}}else{if(value1<=value2){suit=0;break;}}}else if(data[0][w[j]]=="FLOAT"){float value1=stof(data[i][w[j]]);float value2=stof(values[j]);if(op[j]==1){if(value1!=value2){suit=0;break;}}else if(op[j]==2){if(value1==value2){suit=0;break;}}else if(op[j]==3){if(value1>=value2){suit=0;break;}}else{if(value1<=value2){suit=0;break;}}}else{if(op[j]==1){if(data[i][w[j]]!=values[j]){suit=0;break;}}else if(op[j]==2){if(data[i][w[j]]==values[j]){suit=0;break;}}}}if(suit){result.emplace_back(data[i]);}}filePrint(databaseName,tableName,result);
}void fileOperateOr(const vector<string>& columnName,const vector<int>& op,const vector<string>& values){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& column:columnName){if(column==data[1][i]){w.emplace_back(i);break;}}}result.emplace_back(data[0]);result.emplace_back(data[1]);for(int i=2;i<data.size();++i){bool suit=0;for(int j=0;j<op.size();++j){if(data[0][w[j]]=="INTEGER"){int value1=stoi(data[i][w[j]]);int value2=stoi(values[j]);if(op[j]==1){if(value1==value2){suit=1;break;}}else if(op[j]==2){if(value1!=value2){suit=1;break;}}else if(op[j]==3){if(value1<value2){suit=1;break;}}else{if(value1>value2){suit=1;break;}}}else if(data[0][w[j]]=="FLOAT"){float value1=stof(data[i][w[j]]);float value2=stof(values[j]);if(op[j]==1){if(value1==value2){suit=1;break;}}else if(op[j]==2){if(value1!=value2){suit=1;break;}}else if(op[j]==3){if(value1<value2){suit=1;break;}}else{if(value1>value2){suit=1;break;}}}else{if(op[j]==1){if(data[i][w[j]]==values[j]){suit=1;break;}}else if(op[j]==2){if(data[i][w[j]]!=values[j]){suit=1;break;}}}}if(suit){result.emplace_back(data[i]);}}filePrint(databaseName,tableName,result);
}//read
void readTable(){vector<pair<string,string>> parsedColumns;char c;string s;while(c!=')'){string columnName="";string typeName="";string name="";int i=0;c=getchar();while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=','&&c!=')'){if(c!='\t'&&c!='\n'&&c!='\r'&&c!='\f'&&c!='\v'){s.assign(1,c);columnName+=s;++i;}c=getchar();}i--;int j=0;while(columnName[i--]==' ');while(columnName[i-j]!=' '){j++;}typeName.assign(columnName.substr(i-j+1,j+1));name.assign(columnName.substr(0,i-j));parsedColumns.emplace_back(name,typeName);if(c!=')'){c=getchar();}}while(c!=';'){c=getchar();}createTable(databaseName,tableName,parsedColumns);
}void readCreate(){string type;cin>>type;if(type=="DATABASE"){databaseName="";char c=getchar();string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){s.assign(1,c);databaseName+=s;c=getchar();}databaseName=trimTrailingSpaces(databaseName);createDatabase(databaseName);}else if(type=="TABLE"){tableName="";int i=0;char c=getchar();string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!='('){s.assign(1,c);tableName+=s;c=getchar();}tableName=trimTrailingSpaces(tableName);readTable();}
}void readUse(){string type;cin>>type;databaseName="";char c=getchar();string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){s.assign(1,c);databaseName+=s;c=getchar();}databaseName=trimTrailingSpaces(databaseName);
}void readDrop(){string type;cin>>type;tableName="";char c=getchar();string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'||c=='\0'){c=getchar();}while(c!=';'){s.assign(1,c);tableName+=s;c=getchar();}tableName=trimTrailingSpaces(tableName);dropTable(databaseName,tableName);
}void readValue(){vector<string> values;char c;string s;while(c!=')'){string value="";int i=0;c=getchar();while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'||c=='\0'){c=getchar();}while(c!=','&&c!=')'){if(c!='\t'&&c!='\n'&&c!='\r'&&c!='\f'&&c!='\v'&&c!=0){s.assign(1,c);value+=s;++i;}c=getchar();}value=trimTrailingSpaces(value);values.emplace_back(value);}while(c!=';'){c=getchar();}dataInsert(databaseName,tableName,values);
}void readInsert(){char c;string s;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}tableName="";string name="";int i=0;while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'||c=='\0'){c=getchar();}while(c!='('){if(c!='\t'&&c!='\n'&&c!='\r'&&c!='\f'&&c!='\v'){s.assign(1,c);tableName+=s;i++;}c=getchar();}i--;while(tableName[i--]==' ');while(tableName[i--]!=' ');name.assign(tableName.substr(0,i+1));tableName.assign(name);readValue();
}void readSelectWhere(vector<string> column){char c=getchar();vector<string> columnName;vector<int> op;//1= 2!= 3> 4<vector<string> value;string s,str="",strin="";//临时存放 bool a;//1and 0orwhile(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){str="";while(c!='='&&c!='!'&&c!='<'&&c!='>'){if(c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=' ';}s.assign(1,c);str+=s;c=getchar();}//读入columnName str=trimTrailingSpaces(str);columnName.emplace_back(str);if(c=='='){op.emplace_back(1);}else if(c=='!'){op.emplace_back(2);c=getchar();}else if(c=='<'){op.emplace_back(3);}else{op.emplace_back(4);}//读入op c=getchar();while(c==' '){c=getchar();}str="";while(c!=';'){if(c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=' ';}s.assign(1,c);str+=s;if(c==' '){if(str=="AND "){a=1;break;}else if(str=="OR "){a=0;break;}strin+=str;str="";}if(c==';'){break;}c=getchar();} strin+=str;value.emplace_back(trimTrailingSpaces(strin));if(c==';'){break;}c=getchar();}if(a){dataOperateAnd(column,columnName,op,value);}else{dataOperateOr(column,columnName,op,value);}
}void readInner(vector<string> column){}void readSelect(){string columns;string s;vector<string> column;cin>>s;while(s!="FROM"){columns+=s;cin>>s;}int len=columns.length();for(int i=0,j=0;i<len;){s="";while(columns[i]!=','&&i<len){++i;}s.assign(columns.substr(j,i-j));j=++i;column.emplace_back(s);}char c;c=getchar();columns="";//临时储存字符串 tableName="";while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){s.assign(1,c);if(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){if(columns==" WHERE"){readSelectWhere(column);return;}else if(columns==" INNER"){readInner(column);return;}s=" ";tableName+=columns;columns="";}columns+=s;c=getchar();}tableName+=columns;auto data=readCSV(databaseName,tableName);vector<vector<string>> result;if(column[0]=="*"){for(int i=1;i<data.size();++i){result.emplace_back(data[i]);}dataPrint(result);return;}vector<int> w;for(int i=0;i<data[1].size();++i){for(const auto& columnName:column){if(columnName==data[1][i]){w.emplace_back(i);break;}}}for(size_t i=1;i<data.size();++i){vector<string> row;for(const auto& j:w){row.emplace_back(data[i][j]);}result.emplace_back(row);}dataPrint(result);
}void readUpdateWhere(){}void readUpdate(){}void readDeleteWhere(){char c=getchar();vector<string> columnName;vector<int> op;//1= 2!= 3> 4<vector<string> value;string s,str="",strin="";//临时存放 bool a;//1and 0orwhile(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){str="";while(c!='='&&c!='!'&&c!='<'&&c!='>'){if(c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=' ';}s.assign(1,c);str+=s;c=getchar();
//			cout<<1<<endl;}//读入columnName str=trimTrailingSpaces(str);columnName.emplace_back(str);if(c=='='){op.emplace_back(1);}else if(c=='!'){op.emplace_back(2);c=getchar();}else if(c=='<'){op.emplace_back(3);}else{op.emplace_back(4);}//读入op c=getchar();while(c==' '){c=getchar();}str="";while(c!=';'){if(c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=' ';}s.assign(1,c);str+=s;if(c==' '){if(str=="AND "){a=1;break;}else if(str=="OR "){a=0;break;}strin+=str;str="";}if(c==';'){break;}c=getchar();} strin+=str;value.emplace_back(trimTrailingSpaces(strin));if(c==';'){break;}c=getchar();}if(a){fileOperateAnd(columnName,op,value);}else{fileOperateOr(columnName,op,value);}
}void readDelete(){char c=getchar();string s,str;tableName="";while(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){c=getchar();}while(c!=';'){s.assign(1,c);if(c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f'||c=='\v'){if(str==" WHERE"){break;}s=" ";tableName+=str;str="";}str+=s;c=getchar();}tableName=trimTrailingSpaces(tableName);if(c==';'){auto data=readCSV(databaseName,tableName);vector<vector<string>> result;result.emplace_back(data[0]);result.emplace_back(data[1]);filePrint(databaseName,tableName,result);return;}readDeleteWhere();
}void readCommand(){string command;while(cin>>command){if(command=="CREATE"){readCreate();}else if(command=="USE"){readUse();}else if(command=="DROP"){readDrop();}else if(command=="INSERT"){cin>>command;readInsert();}else if(command=="SELECT"){readSelect();++cnt;}else if(command=="UPDATE"){readUpdate();}else if(command=="DELETE"){cin>>command;readDelete();}}
}int main(){freopen("input.sql","r",stdin);readCommand();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/487749.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

this version of the Java Runtime only recognizes class file versions up to 52.0

问题描述 Exception in thread "main" java.lang.UnsupportedClassVersionError: com/xxx/Main has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versi…

Tr0ll: 1 Vulnhub靶机渗透笔记

Tr0ll: 1 本博客提供的所有信息仅供学习和研究目的&#xff0c;旨在提高读者的网络安全意识和技术能力。请在合法合规的前提下使用本文中提供的任何技术、方法或工具。如果您选择使用本博客中的任何信息进行非法活动&#xff0c;您将独自承担全部法律责任。本博客明确表示不支…

CAP定理

2.1 CAP 定理的由来与证明 CAP 定理是计算机科学界的“铁律”&#xff0c;最早由 Eric Brewer 提出&#xff0c;后来被正式证明&#xff1a; 分布式系统里&#xff0c;一致性&#xff08;C&#xff09;、可用性&#xff08;A&#xff09;、分区容错性&#xff08;P&#xff09…

【flutter】webview下载文件方法集锦

说明&#xff1a;android的webview是不支持下载的&#xff01;&#xff01;&#xff01; 所以我们需要监听下载接口 然后手动执行下载操作&#xff0c;分为三种类型 直接打开浏览器下载&#xff08;最简单&#xff09;&#xff0c;但是一些下载接口需要cookie信息时不能满足 …

Java版-图论-最短路-Floyd算法

实现描述 网络延迟时间示例 根据上面提示&#xff0c;可以计算出&#xff0c;最大有100个点&#xff0c;最大耗时为100*wi,即最大的耗时为10000&#xff0c;任何耗时计算出来超过这个值可以理解为不可达了&#xff1b;从而得出实现代码里面的&#xff1a; int maxTime 10005…

SQL注入基础入门篇 注入思路及常见的SQL注入类型总结

目录 前言一、了解mysql数据库1、了解sql增删改查2、了解sql查询 二、sql注入基础三、学习sql注入漏洞1、union注入1、判断数字型注入还是字符型型注入&#xff1a;2、判断闭合方式&#xff08;字符型注入&#xff09;&#xff1a;3、判断回显位4、查询库名&#xff0c;表名&am…

基于Spring Boot库存管理系统

文末获取源码和万字论文&#xff0c;制作不易&#xff0c;感谢点赞支持。 基于Spring Boot库存管理系统 当下&#xff0c;如果还依然使用纸质文档来记录并且管理相关信息&#xff0c;可能会出现很多问题&#xff0c;比如原始文件的丢失&#xff0c;因为采用纸质文档&#xff0c…

JSSIP的使用及问题(webRTC,WebSockets)

简介 项目中有一个需要拨打电话的功能&#xff0c;要求实时的进行音频接听&#xff0c;并且可以在电话接听或者挂断等情况下做出相应的操作。jssip作为一个强大的实现实时通信的javascript库&#xff0c;这不门当户对了嘛。 jssip&#xff08;官网&#xff1a; JsSIP - the J…

【Cadence32】PCB多层板电源、地平面层创建心得➕CM约束管理器Analyze分析显示设置➕“DP”报错DRC

【转载】Cadence Design Entry HDL 使用教程 【Cadence01】Cadence PCB Edit相对延迟与绝对延迟的显示问题 【Cadence02】Allegro引脚焊盘Pin设置为透明 【Cadence03】cadence不小心删掉钢网层怎么办&#xff1f; 【Cadence04】一般情况下Allegro PCB设计时的约束规则设置&a…

Java阶段三06

第3章-第6节 一、知识点 理解MVC三层模型、理解什么是SpringMVC、理解SpringMVC的工作流程、了解springMVC和Struts2的区别、学会使用SpringMVC封装不同请求、接收参数 二、目标 理解MVC三层模型 理解什么是SpringMVC 理解SpringMVC的工作流程 学会使用SpringMVC封装请求…

C/C++流星雨

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C/C…

Vmware Vcenter7.0证书web续期发生错误

1. 故障描述 vSphere Client 版本 7.0.2.00200 vCenter _MACHINE_CERT快到期了&#xff0c;通过web界面更新证书失败 第一步先这样&#xff0c;重新续订一下证书 续订发生错误 2. 解决办法 2.1. 前提工作 登陆ssh到vcenter&#xff0c;重新生成证书 先关掉HA&#xff…

【合作原创】使用Termux搭建可以使用的生产力环境(五)

前言 在上一篇【合作原创】使用Termux搭建可以使用的生产力环境&#xff08;四&#xff09;-CSDN博客我们讲到了如何让proot-distro中的Debian声音驱动正常&#xff0c;将我们的系统备份后&#xff0c;通过VNC客户端连接到VNC服务器&#xff0c;这一篇我们来讲一下xfce桌面的美…

uniapp -- 实现页面滚动触底加载数据

效果 首选,是在pages.json配置开启下拉刷新 {"path": "pages/my/document/officialDocument","style": {"navigationStyle":</

Python之爬虫入门--示例(2)

一、Requests库安装 可以使用命令提示符指令直接安装requests库使用 pip install requests 二、爬取JSON数据 &#xff08;1&#xff09;、点击网络 &#xff08;2&#xff09;、刷新网页 &#xff08;3&#xff09;、这里有一些数据类型&#xff0c;选择全部 &#xff08…

OLLAMA+FASTGPT+M3E 大模型本地化部署手记

目录 1.安装ollama 0.5.1 2.下载大模型 qwen2.5 3b 3.开启WSL 4.更新wsl 5.安装ubuntu 6.docker下载 6.1 修改docker镜像源 6.2 开启WSL integration 7.安装fastgpt 7.1 创建fastgpt文件夹 7.2 下载fastgpt配置文件 8.启动容器 9.M3E下载 9.1 下载运行命令 9.2…

Linux网络基础知识————网络编程

计算机网络的体系结构 网络采用分而治之的方法设计&#xff0c;将网络的功能划分为不同的模块&#xff0c;以分层的形式有机结合在一起 每层实现不同的功能&#xff0c;其内部实现的方法对外部其他层次来说是透明的&#xff0c;每层向上一层提供服务&#xff0c;使用下一层提供…

【数据库】选择题+填空+简答

1.关于冗余数据的叙述中&#xff0c;不正确的是&#xff08;&#xff09; A.冗余的存在容易破坏数据库的完整新 B.冗余的存在给数据库的维护增加困难 C.不应该在数据库中存储任何冗余数据 D.冗余数据是指由基本数据导出的数据 C 2.最终用户使用的数据视图称为&#xff08;&…

unity3d—demo(实现给出图集名字和图片名字生成对应的图片)

目录 实现给出图集名字和图片名字生成对应的图片&#xff1a; 代码示例&#xff1a; dic: 键 是图集名称 值是一个字典 该字典键是图片名称 值是图片&#xff0c;结构如图&#xff1a; 测试代码&#xff1a; 结果&#xff1a; SpriteRenderer 讲解&#xff1a; Resour…

jmeter 提取数据写入文件

BeanShell PostProcessor FileWriter file new FileWriter("E:\\IOT\\cui家庭中心\\v3.8.0\\123.txt",true); BufferedWriter out new BufferedWriter(file); out.write(vars.get("localKey")"\n"); log.info("到这里了吗"); out.c…