数据库实验C++ :创建数据库及数据操作功能实践

部分:创建数据库及数据操作功能实践

(一)实验目的

熟练掌握数据库管理系统中创建数据库、关系模式维护以及数据维护操作的实现技术。

 实验内容

注:以下所有功能的实现,要进行语法和语义检查,并注意维护相应的数据

字典文件

    1、用高级语言建立数据库表。

    (1)设计文件存储结构和存取方法。

    (2)属性的个数任意,属性的类型至少包括整数和字符串。

    (3)把表的相关信息存入数据字典。

  1. 用高级语言为关系表插入元组。

    (1)用VALUES子句为新建立的关系插入元组。

    (2)用VALUES子句在关系模式修改之后按照新的模式插入元组。(选做)

3、用高级语言实现属性的添加和删除功能。(选做)

    (1)为关系表添加属性并维护数据字典。

    (2)为关系表删除属性并维护数据字典。

4、用高级语言实现表中元组的删除和修改功能。

(1)实现删除关系表元组的功能,包括如下两种情况:

    a) 没有WHERE条件,删除关系中的所有元组。

        b) 指定WHERE条件,删除满足条件的元组。

    (2)实现修改关系表元组的功能,包括如下两种情况(选做):

        a) 没有WHERE条件,修改所有元组的指定属性的值。

        b) 指定WHERE条件,修改满足条件的元组的指定属性的值。

5、用高级语言实现表的删除功能。

    (1)删除表并维护数据字典。

6、用高级语言实现显示数据库表的功能,用于对上面的操作结果进行测试。

    (1)实现“SELECT * FROM 表名”。

    (2)显示表的结构和内容。

代码:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <regex>
#include <sstream>
#include <queue>
#include <functional>
#include <regex>
#include <filesystem>
#include<cstdio>

using namespace std;

// 数据表的列的结构体
struct Column {
    string name;            // 列名
    string type;            // 列的数据类型
    bool isPrimaryKey;      // 是否是主键
    bool isNullable;        // 是否可以为空
    bool isUnique;          // 是否唯一
};

// 数据表的结构体
struct Table {
    string name;            // 表名
    vector<Column> columns; // 列的集合
};

// 数据字典,以表名作为键,存储表的元信息
map<string, Table> dataDictionary;

//数据库中各表存储的内容 表名 列名 主键 数据内容
map<string, map<string,map<string , string>>> TableData;

queue<string> out;

// 创建一个映射,将操作符映射到相应的函数对象
map<string, function<bool(int, int)>> operators;

// 函数来查找某一列的数据类型
string findColumnType( string tableName, string columnName) {
    // 遍历dataDictionary
    for (const auto& kvp : dataDictionary) {
        const Table& table = kvp.second;
        cout << "Table Name: " << table.name << endl;
        for (const Column& column : table.columns) {
            cout << "  Data Type: " << column.type << endl;
            if (columnName == column.name) {
                return column.type;
            }
        }
    }
    return "Column not found"; // 或者返回适当的错误值
}

void InitOperators() {

    operators["<"] = less<int>();
    operators[">"] = greater<int>();
    operators["<="] = less_equal<int>();
    operators[">="] = greater_equal<int>();
    operators["="] = equal_to<int>();
    operators["!="] = not_equal_to<int>();
}

void PrintOutTableData() {
    // 遍历表名
    for (const auto& tableEntry : TableData) {
        const string& tableName = tableEntry.first;
        cout << "表名: " << tableName << endl;

        // 遍历列名
        for (const auto& columnEntry : tableEntry.second) {
            const string& columnName = columnEntry.first;
            cout << "  列名: " << columnName << endl;

            // 遍历主键和数据内容
            for (const auto& dataEntry : columnEntry.second) {
                const string& key = dataEntry.first;
                const string& value = dataEntry.second;

                if (key == "主键") {
                    cout << "    主键: " << value << endl;
                }
                else {
                    cout << "    数据内容: " << key << " = " << value << endl;
                }
            }
        }
    }
}


void PrintOutDataDictionary() {
    // 遍历数据字典并输出每个表的信息
    for (const auto& entry : dataDictionary) {
        const string& tableName = entry.first;
        const Table& tableInfo = entry.second;

        cout << "表名: " << tableName << endl;

        // 输出列信息
        for (const Column& column : tableInfo.columns) {
            cout << "列名: " << column.name << endl;
            cout << "数据类型: " << column.type << endl;
            cout << "是否为主键: " << (column.isPrimaryKey ? "Yes" : "No") << endl;
            cout << "是否可为空: " << (column.isNullable ? "Yes" : "No") << endl;
            cout << "是否唯一: " << (column.isUnique ? "Yes" : "No") << endl;
        }
        cout << endl;  // 表信息之间加一个空行
    }
}

//写入数据表
void WriteTable(string tableName) {
    //写入map 主键 列名 数据内容
    map<string, map<string, string>> write;

    PrintOutDataDictionary();

    // 遍历TableData
    for (const auto& tableEntry : TableData) {
        if (tableEntry.first == tableName) {
            const auto& table = tableEntry.second;
            // 遍历表中的列
            for (const auto& columnEntry : table) {
                const auto& column = columnEntry.second;
                const string& columnName = columnEntry.first;

                // 遍历列中的主键和数据内容
                for (const auto& primaryKeyEntry : column) {
                    const string& key = primaryKeyEntry.first;
                    const string& data = primaryKeyEntry.second;
                    write[key][columnName] = data;
                }
            }
        }
    }

    // 打开文件以覆盖写入内容
    ofstream file(tableName + ".txt");

    if (!file.is_open()) {
        cerr << "无法打开文件" << endl;
    }
    // 使用范围循环遍历write map
    for (const auto& entry : write) {
        string key = entry.first;

        // 创建一个临时队列来保存原队列中的元素
        queue<string> tempQueue = out;
        string line;
        // 遍历原队列
        while (!tempQueue.empty()) {
            string frontElement = tempQueue.front(); // 获取队头元素

            if (!write[key][frontElement].empty()) {
                line += write[key][frontElement] + " ";
                cout << frontElement << " " << write[key][frontElement] << endl;
            }
            tempQueue.pop();                        // 弹出队头元素
        }

        file << line << endl;
    }

    // 关闭文件
    file.close();

}

//读表
void ReadTable(string tableName) {

    // 打开文件
    ifstream inputFile(tableName + ".txt");

    if (!inputFile) {
        cerr << "无法打开文件" << endl;
    }

    string line;

    // 逐行读取文件
    while (getline(inputFile, line)) {
        istringstream iss(line);
        string word;
        vector<string> words;

        // 使用空格分割行
        while (iss >> word) {
            words.push_back(word);
        }

        vector<string> Data;
        // 处理分割后的单词
        for (const string& data : words) {
            Data.push_back(data);
        }

        //在数据字典中遍历
        auto tableIt = dataDictionary.find(tableName);
        if (tableIt != dataDictionary.end()) {
            const Table& table = tableIt->second;
            size_t i = 0;
            for (const Column& column : table.columns) {
                if (i < Data.size()) {

                    TableData[tableName][column.name][Data[0]] = Data[i];
                    i++;
                    cout << TableData[tableName][column.name][Data[0]] << endl;
                }
                else {
                    break;
                }
            }
        }

    }

    // 关闭文件
    inputFile.close();
}

// 函数以引用方式接受一个字符串,从该字符串中删除所有的单引号
string removeSingleQuotes(string str) {
    size_t pos = str.find('\'');
    while (pos != string::npos) {
        str.erase(pos, 1); // 从字符串中删除一个字符
        pos = str.find('\'', pos); // 继续查找下一个单引号
    }
    return str;
}

//int转化为字符串
string IntToString(int num) {
    string str = to_string(num);
    return str;
}

//字符串转化为int
int StringToInt(string str) {
    int num = stoi(str);
    return num;
}


//创建指定名字的.txt文件
void CreateFile(string filename) {

    // 创建一个输出文件流对象
    ofstream outFile(filename + ".txt");

    if (outFile.is_open()) {
        // 关闭文件
        outFile.close();
    }
}

//判断真假
bool Judge(string str) {
    if (str == "true") {
        return true;
    }
    else {
        return false;
    }
}

//判断真假
string JudgeBack(bool judge) {
    if (judge) return "true";
    else return "false";
}

//提取括号中信息
string extractContentInParentheses(const string& input) {
    size_t startPos = input.find('(');
    size_t endPos = input.find(')', startPos);

    if (startPos != string::npos && endPos != string::npos) {
        return input.substr(startPos + 1, endPos - startPos - 1);
    }
    else {
        return ""; // 如果未找到括号内容
    }
}

//处理数据字典中的表语句
void AddTable(string str) {
    Table newTable;
    // 将新表添加到数据字典中
    dataDictionary[str] = newTable;
}

//处理数据字典中的列语句
void DealColumnString(string TableName , string str) {
    Column newcolumn;
    istringstream ss(str);
    string name;
    string type;
    string primaryKey;
    string nullable;
    string unique;
    ss >> name >> type >> primaryKey >> nullable >> unique;
    out.push(name);
    newcolumn.name = name;
    newcolumn.type = type;
    newcolumn.isPrimaryKey = Judge(primaryKey);
    newcolumn.isNullable = Judge(nullable);
    newcolumn.isUnique = Judge(unique);
    dataDictionary[TableName].columns.push_back(newcolumn);
}

//读取数据字典
void ReadDataDictionary(string line) {
    vector<string> result;
    istringstream read(line);
    string token;
    while (getline(read, token, '/')) {
        result.push_back(token);
    }
    bool first = true;
    string TableName;
    for (const string& str : result) {
        if (first) {
            AddTable ( str );
            TableName = str;
            first = false;
        }
        else {
            DealColumnString ( TableName , str );
        }
    }
}

// 将表的指定列设置为主键
void setColumnAsPrimaryKey(const string& tableName, const string& columnName) {
    // 首先检查表是否存在于数据字典中
    if (dataDictionary.find(tableName) != dataDictionary.end()) {
        Table& table = dataDictionary[tableName];
        for (Column& column : table.columns) {
            if (column.name == columnName) {
                column.isPrimaryKey = true;
                column.isNullable = false;
                column.isUnique = true;
                return;
            }
        }
    }
}

// 找主键
string FindPrimaryKey(const string& tableName) {
    // 首先检查表是否存在于数据字典中
    if (dataDictionary.find(tableName) != dataDictionary.end()) {
        Table& table = dataDictionary[tableName];
        for (Column& column : table.columns) {
            if (column.isPrimaryKey) {
                return column.name;
            }
        }
    }
    return "not found";
}

void fillNULL(string tableNameToModify, string columnNameToChange) {
    for (const auto& tableEntry : TableData) {
        if (tableNameToModify == tableEntry.first) {
            for (const auto& columnEntry : tableEntry.second) {
                string columnName = columnEntry.first;
                if (columnNameToChange == columnName) {
                    for (const auto& rowEntry : columnEntry.second) {
                        string primaryKey = rowEntry.first;
                        TableData[tableNameToModify][columnName][primaryKey] = "NULL";
                    }
                }
            }
        }
    }
    PrintOutTableData();
}

//create table建立数据库表的列属性
void CreateColumn(string tableName,string str) {
    if (str.find("PRIMARY KEY") != string::npos) {
        string primaryKey = extractContentInParentheses(str);
        setColumnAsPrimaryKey(tableName, primaryKey);
    }
    else {
        Column newcolumn;
        istringstream ss(str);
        string name;
        string type;
        ss >> name >> type ;
        newcolumn.name = name;
        newcolumn.type = type;
        newcolumn.isPrimaryKey = false;
        newcolumn.isNullable = true;
        newcolumn.isUnique = false;
        dataDictionary[tableName].columns.push_back(newcolumn);
    }
}

//create table建立数据库表
void CreateTable(string sql) {
    // 创建一个正则表达式模式来匹配CREATE TABLE语句
    regex pattern(R"((CREATE TABLE) ([A-Za-z_][A-Za-z0-9_]*) \(([^;]*)\);)");

    // 在输入字符串中搜索匹配项
    smatch match;
    string createTable;
    string tableName;
    string columnInfo;
    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "CREATE TABLE"
        // match[2] 包含表名
        // match[3] 包含列信息
        createTable = match[1];
        tableName = match[2];
        columnInfo = match[3];
    }
    else {
        cout << "未能成功匹配!" << endl;
    }
    AddTable(tableName);
    vector<string> result;
    istringstream read(columnInfo);
    string token;
    while (getline(read, token, ',')) {
        result.push_back(token);
    }
    for (const string& str : result) {
        CreateColumn(tableName, str);
    }
    CreateFile(tableName);
}


//从文件读取数据字典
void InitDataDictionary() {
    // 打开文件以进行读取
    ifstream inputFile("dataDictionary.txt");

    if (!inputFile.is_open()) {
        // 如果文件不存在,创建一个新文件
        ofstream outputFile("dataDictionary.txt");
        if (outputFile.is_open()) {
            cout << "数据库不存在,已创建数据库" << endl;
            // 可以在这里写入新文件的内容
            outputFile << "这是一个新创建的数据库。\n";
            outputFile.close();
        }
        else {
            cerr << "无法创建数据库'" << endl;
        }
    }
    else {
        string line;
        while (getline(inputFile, line)) {
            // 处理数据字典文件中的内容
            ReadDataDictionary(line);
        }
        inputFile.close();
    }
}


//写入数据
void WriteDataDictionary() {
    // 打开文件并设置文件模式为输出和覆盖
    ofstream outputFile( "DataDictionary.txt", ios::out | ios::trunc);
    if (!outputFile.is_open()) {
        cerr << "无法打开文件 " << "DataDictionary.txt" << endl;
    }

    // 遍历每个表的信息
    for (const auto& entry : dataDictionary) {
        const string& tableName = entry.first;
        const Table& tableInfo = entry.second;
        string write;
        write = tableName;

        // 遍历列信息
        for (const Column& column : tableInfo.columns) {
            write += "/" + column.name + " " + column.type + " " + (column.isPrimaryKey ? "true" : "false") + " " + (column.isNullable ? "true" : "false") + " " + (column.isUnique ? "true" : "false");

        }
        outputFile << write << endl;
    }
    // 关闭文件
    outputFile.close();
}

// 有列名列表的INSERT INTO语句
void InsertIntoWithColumns(string sql) {
    // 创建一个正则表达式模式来匹配INSERT INTO语句
    regex pattern(R"((INSERT INTO) ([A-Za-z_][A-Za-z0-9_]*) \(([^)]*)\) VALUES \(([^)]*)\);)");

    string insertInto;
    string tableName;
    string columnNames;
    string values;

    // 在输入字符串中搜索匹配项
    smatch match;
    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "INSERT INTO"
        // match[2] 包含表名
        // match[3] 包含列名列表
        // match[4] 包含值列表
        insertInto = match[1];
        tableName = match[2];
        columnNames = match[3];
        values = removeSingleQuotes(match[4]);
        cout << tableName << endl << columnNames << endl << values << endl;
    }
    else {
        cout << "No match found." << endl;
    }

    vector<string> valueresult;
    istringstream valueread(values);
    string valuetoken;

    while (getline(valueread, valuetoken, ',')) {
        valueresult.push_back(valuetoken);
    }

    vector<string> columnresult;
    istringstream columnread(columnNames);
    string columntoken;

    while (getline(columnread, columntoken, ',')) {
        columnresult.push_back(columntoken);
    }

    // 打开文件并设置文件模式为输出和追加
    ofstream outputFile(tableName + ".txt", ios::out | ios::app);

    if (!outputFile.is_open()) {
        cerr << "无法打开文件 " << tableName + ".txt" << endl;
    }

    for (size_t i = 0; i < columnresult.size(); i++) {
        string ColumnName = removeSingleQuotes(columnresult[i]);
        string Value = removeSingleQuotes(valueresult[i]);
        //在数据字典中查找该表是否有该列
        auto tableIt = dataDictionary.find(tableName);
        if (tableIt != dataDictionary.end()) {
            const Table& table = tableIt->second;
            for (const Column& column : table.columns) {
                if (column.name == ColumnName) {
                    // 找到列名

                    TableData[tableName][ColumnName][FindPrimaryKey(tableName)] = Value;

                }
            }
        }
    }

    string line;

    for (const string& str : columnresult) {
        string Str = TableData[tableName][str][FindPrimaryKey(tableName)];
        if (Str.empty()) {
            Str = "NULL" ;
            line += Str + " ";
        }
        else {
            line += Str + " ";
        }
    }

    // 逐行写入文件(这次将不覆盖以前的内容)
    outputFile << line << endl;

    // 关闭文件
    outputFile.close();
}

// 没有列名列表的INSERT INTO语句
void InsertIntoWithoutColumns(string sql) {

    // 创建一个正则表达式模式来匹配INSERT INTO语句
    regex pattern(R"((INSERT INTO) ([A-Za-z_][A-Za-z0-9_]*) (?:\([^)]*\) )?VALUES \(([^)]*)\);)");

    string insertInto;
    string tableName;
    string columnNames;
    string values;

    // 在输入字符串中搜索匹配项
    smatch match;
    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "INSERT INTO"
        // match[2] 包含表名
        // match[3] 包含值列表
        insertInto = match[1];
        tableName = match[2];
        values = match[3];
    }
    else {
        cout << "No match found." << endl;
    }

    vector<string> result;
    istringstream read(values);
    string token;

    while (getline(read, token, ',')) {
        result.push_back(token);
    }

    // 打开文件并设置文件模式为输出和追加
    ofstream outputFile(tableName + ".txt", ios::out | ios::app);

    if (!outputFile.is_open()) {
        cerr << "无法打开文件 " << tableName + ".txt" << endl;
    }

    string line;

    for (const string& str : result) {
        string Str = removeSingleQuotes(str);
        line += Str + " ";
    }

    // 逐行写入文件(这次将不覆盖以前的内容)
    outputFile << line << endl;

    // 关闭文件
    outputFile.close();

}


//InsertInto为关系表插入元组
void InsertInto( string sql) {
    // 创建一个正则表达式模式来匹配INSERT INTO语句
    regex patternWithColumns(R"((INSERT INTO) ([A-Za-z_][A-Za-z0-9_]*) \(([^)]*)\) VALUES \(([^)]*)\);)");
    regex patternWithoutColumns(R"((INSERT INTO) ([A-Za-z_][A-Za-z0-9_]*) VALUES \(([^)]*)\);)");

    // 在输入字符串中搜索匹配项
    smatch matchWithColumns;
    smatch matchWithoutColumns;

    if (regex_search(sql, matchWithColumns, patternWithColumns)) {
        // 匹配到有列名列表的INSERT INTO语句
        InsertIntoWithColumns(sql);
    }
    else if (regex_search(sql, matchWithoutColumns, patternWithoutColumns)) {
        // 匹配到没有列名列表的INSERT INTO语句
        InsertIntoWithoutColumns(sql);
    }
    else {
        cout << "No match found." << endl;
    }
}

void Create(string tableName,string str) {
    Column newcolumn;
    istringstream ss(str);
    string name;
    string type;
    ss >> name >> type;
    newcolumn.name = name;
    newcolumn.type = type;
    newcolumn.isPrimaryKey = false;
    newcolumn.isNullable = true;
    newcolumn.isUnique = false;
    dataDictionary[tableName].columns.push_back(newcolumn);
    out.push(name);
    cout << name << endl;
    fillNULL(tableName, name);
}

//AlterADD添加属性
void AlterADD(string sql) {

    // 创建一个正则表达式模式来匹配ALTER TABLE语句
    regex pattern(R"((ALTER TABLE) ([A-Za-z_][A-Za-z0-9_]*) ADD \(([^;]*)\);)");

    // 在输入字符串中搜索匹配项
    smatch match;
    string alterTable;
    string tableName;
    string columnInfo;

    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "ALTER TABLE"
        // match[2] 包含表名
        // match[3] 包含要添加的列信息
        alterTable = match[1];
        tableName = match[2];
        columnInfo = match[3];
    }
    else {
        cout << "No match found." << endl;
    }

    ReadTable(tableName);

    Create(tableName, columnInfo);

    WriteTable(tableName);
}



// 函数:从数据表中删除指定列
void deleteColumnFromTable(string tableName, string columnName) {
    if (dataDictionary.find(tableName) != dataDictionary.end()) {
        Table& table = dataDictionary[tableName];

        auto it = find_if(table.columns.begin(), table.columns.end(),
            [columnName](const Column& col) {
                return col.name == columnName;
            });

        if (it != table.columns.end()) {
            table.columns.erase(it);
            cout << "Column '" << columnName << "' deleted from table '" << tableName << "'." << endl;
        }
        else {
            cout << "Column '" << columnName << "' not found in table '" << tableName << "'." << endl;
        }
    }
    else {
        cout << "Table '" << tableName << "' not found." << endl;
    }
}




//删除列元祖
void DeleteColumn(string tableName,string columnName) {
    ReadTable(tableName);

    //在TableData中删除
    auto tableIt = TableData.find(tableName);
    if (tableIt != TableData.end()) {
        auto columnIt = tableIt->second.find(columnName);
        if (columnIt != tableIt->second.end()) {
            tableIt->second.erase(columnIt);
            cout << "整列已删除" << endl;
        }
    }

    //在数据字典中删除
    deleteColumnFromTable(tableName, columnName);

    //重新写入文件
    WriteTable(tableName);
}

//AlterDROP删除属性
void AlterDROP(string sql) {

    // 创建一个正则表达式模式来匹配ALTER TABLE语句中的DROP操作
    regex pattern(R"((ALTER TABLE) ([A-Za-z_][A-Za-z0-9_]*) (DROP) ([A-Za-z_][A-Za-z0-9_]*);)");

    // 在输入字符串中搜索匹配项
    smatch match;
    string alterTable;
    string tableName;
    string operation;
    string columnName;

    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "ALTER TABLE"
        // match[2] 包含表名
        // match[3] 包含 "DROP"
        // match[4] 包含要删除的列名
        alterTable = match[1];
        tableName = match[2];
        operation = match[3];
        columnName = match[4];
    }
    else {
        cout << "No match found." << endl;
    }
    if (FindPrimaryKey(tableName) != columnName) {
        DeleteColumn(tableName, columnName);
    }
    else {
        cout << "主键不可删除!" << endl;
    }
}

void AlterTable(string sql) {
    if (sql.find("ADD") != string::npos) {
        AlterADD(sql);
    }
    else if (sql.find("DROP") != string::npos) {
        AlterDROP(sql);
    }
}

// 遍历嵌套的map并打印内容
void TraverseNestedMap() {
    for (const auto& entry : TableData) {
        std::cout << "Outer Key: " << entry.first << std::endl;

        const std::map<std::string, std::map<std::string, std::string>>& innerMap = entry.second;

        for (const auto& innerEntry : innerMap) {
            std::cout << "  Inner Key: " << innerEntry.first << std::endl;

            const std::map<std::string, std::string>& subInnerMap = innerEntry.second;

            for (const auto& subInnerEntry : subInnerMap) {
                std::cout << "    Sub Inner Key: " << subInnerEntry.first << " - Value: " << subInnerEntry.second << std::endl;
            }
        }
    }
}

// 删除特定行的函数
void DeleteTableRow(string tableName, string primaryKey) {
    TraverseNestedMap();
    // 遍历TableData中的每个表格
    for (auto& table : TableData) {
        // 遍历当前表格中的每一列
        for (auto& column : table.second) {
            // 检查当前列中是否包含指定的主键
            auto primaryKeyIt = column.second.find(primaryKey);
            if (primaryKeyIt != column.second.end()) {
                // 如果找到主键,从列中删除它
                column.second.erase(primaryKey);

                // 输出成功删除主键的信息,包括表格、列和主键的标识
                cout << "成功删除了行 " << table.first << " - " << column.first << " - " << primaryKey << endl;
            }
        }
    }
    TraverseNestedMap();
}

void DeleteFindWhereDouble(string tableName, string condition) {

    // 创建一个正则表达式模式来匹配AND或OR操作符
    regex pattern0(R"(([^ ]+) (AND|OR) ([^ ]+))");
    string firstString;
    string operation;
    string secondString;

    // 在输入字符串中搜索匹配项
    smatch match0;
    if (std::regex_search(condition, match0, pattern0)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含第一个字符串
        // match[2] 包含AND或OR操作符
        // match[3] 包含第二个字符串
        firstString = match0[1];
        operation = match0[2];
        secondString = match0[3];
    }
    else {
        cout << "No match found." << endl;
    }

    // 解析条件字符串
    string op1,op2;
    regex pattern(R"((\w+)\s*(=|>|<|>=|<=)\s*['"]?(\w+)['"]?)");
    smatch match1, match2;
    string leftOperand1, leftOperand2;
    string rightOperand1, rightOperand2;
    queue<string> keyToDelete1, keyToDelete2;
    if (regex_search(firstString, match1, pattern)) {
        leftOperand1 = match1[1];
        op1 = match1[2];
        rightOperand1 = match1[3];
        // 遍历TableData
        for (const auto& tableEntry : TableData) {
            if (tableEntry.first == tableName) {
                const auto& table = tableEntry.second;
                // 遍历表中的列
                for (const auto& columnEntry : table) {
                    const auto& column = columnEntry.second;
                    const string& columnName = columnEntry.first;
                    if (columnName == leftOperand1) {
                        // 遍历列中的主键和数据内容
                        for (const auto& primaryKeyEntry : column) {
                            const string& key = primaryKeyEntry.first;
                            const string& data = primaryKeyEntry.second;
                            if (findColumnType(tableName, leftOperand1) == "INT") {

                                // 将字符串转换为整数
                                int leftValue = stoi(data);
                                int rightValue = stoi(rightOperand1);

                                // 使用条件映射执行比较
                                bool result = operators[op1](leftValue, rightValue);

                                if (result) {
                                    keyToDelete1.push(key);

                                }
                            }
                            else {
                                if (data == rightOperand1) {
                                    keyToDelete1.push(key);

                                }
                            }
                        }
                    }
                }
            }
        }

    }
    else {
        cout << "No match found." << endl;
    }
    if (regex_search(secondString, match2, pattern)) {
        leftOperand2 = match2[1];
        op2 = match2[2];
        rightOperand2 = match2[3];
        // 遍历TableData
        for (const auto& tableEntry : TableData) {
            if (tableEntry.first == tableName) {
                const auto& table = tableEntry.second;
                // 遍历表中的列
                for (const auto& columnEntry : table) {
                    const auto& column = columnEntry.second;
                    const string& columnName = columnEntry.first;
                    if (columnName == leftOperand2) {
                        // 遍历列中的主键和数据内容
                        for (const auto& primaryKeyEntry : column) {
                            const string& key = primaryKeyEntry.first;
                            const string& data = primaryKeyEntry.second;
                            if (findColumnType(tableName, leftOperand2) == "INT") {

                                // 将字符串转换为整数
                                int leftValue = stoi(data);
                                int rightValue = stoi(rightOperand1);

                                // 使用条件映射执行比较
                                bool result = operators[op2](leftValue, rightValue);

                                if (result) {
                                    keyToDelete2.push(key);

                                }
                            }
                            else {
                                if (data == rightOperand2) {
                                    keyToDelete2.push(key);

                                }
                            }
                        }
                    }
                }
            }
        }

        if (operation == "OR") {
            // 遍历队列
            while (!keyToDelete1.empty()) {
                string frontElement = keyToDelete1.front(); // 获取队头元素
                DeleteTableRow(tableName, frontElement);
                keyToDelete1.pop();                      // 弹出队头元素
            }
            // 遍历队列
            while (!keyToDelete2.empty()) {
                string frontElement = keyToDelete2.front(); // 获取队头元素
                DeleteTableRow(tableName, frontElement);
                keyToDelete2.pop();                      // 弹出队头元素
            }
        }
        else if (operation == "AND") {
            while (!keyToDelete1.empty()) {
                string frontElement1 = keyToDelete1.front(); // 获取队头元素
                queue<string> key2 = keyToDelete2;
                while (!key2.empty()) {
                    string frontElement2 = key2.front(); // 获取队头元素
                    if (frontElement1 == frontElement2) {
                        DeleteTableRow(tableName, frontElement1);
                    }
                    key2.pop();                      // 弹出队头元素
                }
                keyToDelete1.pop();                      // 弹出队头元素
            }
        }
    }
    else {
        cout << "No match found." << endl;
    }
}

void DeleteFindWhere(string tableName, string condition) {

    // 解析条件字符串
    string op;
    regex pattern(R"((\w+)\s*(=|>|<|>=|<=)\s*['"]?(\w+)['"]?)");
    smatch match;
    string leftOperand;
    string rightOperand;

    if (regex_search(condition, match, pattern)) {
        leftOperand = match[1];
        op = match[2];
        rightOperand = removeSingleQuotes( match[3]);
        queue<string> keyToDelete;
        // 遍历TableData

        for (const auto& tableEntry : TableData) {
            if (tableEntry.first == tableName) {
                const auto& table = tableEntry.second;
                // 遍历表中的列
                for (const auto& columnEntry : table) {
                    const auto& column = columnEntry.second;
                    string columnName = columnEntry.first;
                    if (columnName == leftOperand) {
                        // 遍历列中的主键和数据内容
                        for (const auto& primaryKeyEntry : column) {
                            string key = primaryKeyEntry.first;
                            string data = primaryKeyEntry.second;
                            if (findColumnType(tableName, leftOperand) == "INT") {

                                // 将字符串转换为整数
                                int leftValue = stoi(data);
                                int rightValue = stoi(rightOperand);

                                // 使用条件映射执行比较
                                bool result = operators[op](leftValue, rightValue);

                                if (result) {
                                    keyToDelete.push(key);
                                }
                            }
                            else  {
                                if (data == rightOperand) {
                                    keyToDelete.push(key);
                                }
                            }
                        }
                    }
                }
            }
        }
        // 遍历队列
        while (!keyToDelete.empty()) {
            string frontElement = keyToDelete.front(); // 获取队头元素
            DeleteTableRow(tableName, frontElement);
            keyToDelete.pop();                      // 弹出队头元素
        }

    }
    else {
        cout << "No match found." << endl;
    }

}

//分析删除条件
void DeleteWhere(string tableName, string Where) {
    ReadTable(tableName);
    if (Where.find("AND") != string::npos|| Where.find("OR") != string::npos) {
        DeleteFindWhereDouble(tableName, Where);
    }
    else {
        DeleteFindWhere(tableName, Where);
    }

    WriteTable(tableName);
}

//DeleteFrom语句删除
void DeleteFrom(string sql) {
    // 创建一个正则表达式模式来匹配DELETE语句
    regex pattern(R"((DELETE FROM) ([A-Za-z_][A-Za-z0-9_]*) (?:WHERE (.*))?;)");

    // 在输入字符串中搜索匹配项
    smatch match;
    string deleteFrom;
    string tableName;
    string whereCondition;

    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "DELETE FROM"
        // match[2] 包含表名
        // match[3] 包含可选的WHERE条件
        deleteFrom = match[1];
        tableName = match[2];
        whereCondition = match[3];

        //判断是否有where
        if (!whereCondition.empty()) {
            DeleteWhere(tableName,whereCondition);
        }
        else {
            WriteTable(tableName);
        }
    }
    else {
        cout << "No match found." << endl;
    }
}

//删除表
void DropTable(string sql) {
    // 创建一个正则表达式模式来匹配DROP TABLE语句
    regex pattern(R"(DROP TABLE ([A-Za-z_][A-Za-z0-9_]*);)");

    // 在输入字符串中搜索匹配项
    smatch match;
    string tableName;
    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含表名
        tableName = match[1];
    }
    else {
        cout << "No match found." << endl;
    }

    // 查找要删除的表是否存在
    auto it = dataDictionary.find(tableName);

    if (it != dataDictionary.end()) {
        // 表存在,删除它
        dataDictionary.erase(it);
        cout << "表 " << tableName << " 已被删除。" << endl;
    }
    else {
        // 表不存在
        cout << "表 " << tableName << " 不存在,无法删除。" << endl;
    }

    string Filename = tableName + ".txt"; // 要删除的文件名

    const char* filename = Filename.c_str();

    if (remove(filename) == 0) {
        cout << "文件 " << filename << " 已经被删除" << endl;
    }
    else {
        cout << "无法删除文件 " << filename << endl;
    }
}

void ShowTable(string sql) {
    // 创建一个正则表达式模式来匹配SELECT语句
    regex pattern(R"((SELECT \*) FROM ([A-Za-z_][A-Za-z0-9_]*);)");


    string selectFrom;
    string tableName;
    // 在输入字符串中搜索匹配项
    smatch match;
    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "SELECT *"
        // match[2] 包含表名
        selectFrom = match[1];
        tableName = match[2];

    }
    else {
        cout << "No match found." << endl;
    }
    ReadTable(tableName);
    TraverseNestedMap();
}

void ChangeWithoutWHERE(string tableName,string propertyName, string propertyValue) {

    for (const auto& tableEntry : TableData) {
        if (tableName == tableEntry.first) {
            for (const auto& columnEntry : tableEntry.second) {
                string columnName = columnEntry.first;
                if (propertyName == columnName) {
                    for (const auto& rowEntry : columnEntry.second) {
                        string primaryKey = rowEntry.first;
                        TableData[tableName][columnName][primaryKey] = propertyValue;
                    }
                }
            }
        }
    }
}

void UpdataWithoutWHERE(string sql) {
    // 创建一个正则表达式模式来匹配UPDATE语句
    regex pattern(R"((UPDATE) ([A-Za-z_][A-Za-z0-9_]*) SET ([A-Za-z_][A-Za-z0-9_]*)=([^;]*);)");

    // 在输入字符串中搜索匹配项
    smatch match;
    string update;
    string tableName;
    string columnName;
    string updatedValue;

    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "UPDATE"
        // match[2] 包含表名
        // match[3] 包含列名
        // match[4] 包含更新的值
        update = match[1];
        tableName = match[2];
        columnName = match[3];
        updatedValue = removeSingleQuotes(match[4]);
    }
    else {
        cout << "No match found." << std::endl;
    }
    cout << tableName << endl;
    ReadTable(tableName);
    ChangeWithoutWHERE(tableName, columnName, updatedValue);
    WriteTable(tableName);
}

void ChangeWithWHEREdouble(string tableName, string condition,string columnToSet, string valueToSet) {
    // 创建一个正则表达式模式来匹配AND或OR操作符
    regex pattern0(R"(([^ ]+) (AND|OR) ([^ ]+))");
    string firstString;
    string operation;
    string secondString;

    // 在输入字符串中搜索匹配项
    smatch match0;
    if (regex_search(condition, match0, pattern0)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含第一个字符串
        // match[2] 包含AND或OR操作符
        // match[3] 包含第二个字符串
        firstString = match0[1];
        operation = match0[2];
        secondString = match0[3];
        cout << firstString << endl << secondString << endl;
    }
    else {
        cout << "No match found." << endl;
    }

    // 解析条件字符串
    string op1, op2;
    regex pattern(R"((\w+)\s*(=|>|<|>=|<=)\s*['"]?(\w+)['"]?)");
    smatch match1, match2;
    string leftOperand1, leftOperand2;
    string rightOperand1, rightOperand2;
    queue<string> keyToChange1, keyToChange2;
    if (regex_search(firstString, match1, pattern)) {
        leftOperand1 = match1[1];
        op1 = match1[2];
        rightOperand1 = match1[3];
        // 遍历TableData
        for (const auto& tableEntry : TableData) {

            if (tableEntry.first == tableName) {

                const auto& table = tableEntry.second;
                // 遍历表中的列
                for (const auto& columnEntry : table) {
                    const auto& column = columnEntry.second;
                    const string& columnName = columnEntry.first;
                    if (columnName == leftOperand1) {
                        // 遍历列中的主键和数据内容
                        for (const auto& primaryKeyEntry : column) {
                            const string& key = primaryKeyEntry.first;
                            const string& data = primaryKeyEntry.second;
                            if (findColumnType(tableName, leftOperand1) == "INT") {

                                // 将字符串转换为整数
                                int leftValue = stoi(data);
                                int rightValue = stoi(rightOperand1);
                                // 使用条件映射执行比较
                                bool result = operators[op1](leftValue, rightValue);

                                if (result) {
                                    keyToChange1.push(key);

                                }
                            }
                            else {
                                if (data == rightOperand1) {
                                    keyToChange1.push(key);

                                }
                            }
                        }
                    }
                }
            }
        }

    }
    else {
        cout << "No match found." << endl;
    }

    if (regex_search(secondString, match2, pattern)) {
        leftOperand2 = match2[1];
        op2 = match2[2];
        rightOperand2 = match2[3];
        // 遍历TableData
        for (const auto& tableEntry : TableData) {
            if (tableEntry.first == tableName) {
                const auto& table = tableEntry.second;
                // 遍历表中的列
                for (const auto& columnEntry : table) {
                    const auto& column = columnEntry.second;
                    const string& columnName = columnEntry.first;
                    if (columnName == leftOperand2) {
                        // 遍历列中的主键和数据内容
                        for (const auto& primaryKeyEntry : column) {
                            const string& key = primaryKeyEntry.first;
                            const string& data = primaryKeyEntry.second;
                            if (findColumnType(tableName, leftOperand2) == "INT") {

                                // 将字符串转换为整数
                                int leftValue = stoi(data);
                                int rightValue = stoi(rightOperand1);

                                // 使用条件映射执行比较
                                bool result = operators[op2](leftValue, rightValue);

                                if (result) {
                                    keyToChange2.push(key);

                                }
                            }
                            else {
                                if (data == rightOperand2) {
                                    keyToChange2.push(key);

                                }
                            }
                        }
                    }
                }
            }
        }

        if (operation == "OR") {

            // 遍历队列
            while (!keyToChange1.empty()) {
                string frontElement = keyToChange1.front(); // 获取队头元素
                TableData[tableName][columnToSet][frontElement] = valueToSet;
                cout << TableData[tableName][columnToSet][frontElement] << endl;
                keyToChange1.pop();                      // 弹出队头元素
            }
            // 遍历队列
            while (!keyToChange2.empty()) {
                string frontElement = keyToChange2.front(); // 获取队头元素
                TableData[tableName][columnToSet][frontElement] = valueToSet;
                keyToChange2.pop();                      // 弹出队头元素
            }
        }
        else if (operation == "AND") {
            while (!keyToChange1.empty()) {
                string frontElement1 = keyToChange1.front(); // 获取队头元素
                queue<string> key2 = keyToChange2;
                while (!key2.empty()) {
                    string frontElement2 = key2.front(); // 获取队头元素
                    if (frontElement1 == frontElement2) {
                        TableData[tableName][columnToSet][frontElement1] = valueToSet;
                    }
                    key2.pop();                      // 弹出队头元素
                }
                keyToChange1.pop();                      // 弹出队头元素
            }
        }
    }
    else {
        cout << "No match found." << endl;
    }
}

void ChangeWithWHEREsingle(string tableName, string condition, string columnToSet, string valueToSet) {
    // 解析条件字符串
    string op;
    regex pattern(R"((\w+)\s*(=|>|<|>=|<=)\s*['"]?(\w+)['"]?)");
    smatch match;
    string leftOperand;
    string rightOperand;

    if (regex_search(condition, match, pattern)) {
        leftOperand = match[1];
        op = match[2];
        rightOperand = match[3];
        queue<string> keyToChange;
        // 遍历TableData

        for (const auto& tableEntry : TableData) {
            if (tableEntry.first == tableName) {
                const auto& table = tableEntry.second;
                // 遍历表中的列
                for (const auto& columnEntry : table) {
                    const auto& column = columnEntry.second;
                    const string& columnName = columnEntry.first;
                    if (columnName == leftOperand) {
                        // 遍历列中的主键和数据内容
                        for (const auto& primaryKeyEntry : column) {
                            const string& key = primaryKeyEntry.first;
                            const string& data = primaryKeyEntry.second;

                            if (findColumnType(tableName, leftOperand) == "INT") {
                                cout << op << endl;
                                // 将字符串转换为整数
                                int leftValue = stoi(data);
                                int rightValue = stoi(rightOperand);

                                // 使用条件映射执行比较
                                bool result = operators[op](leftValue, rightValue);

                                if (result) {
                                    keyToChange.push(key);
                                }
                            }
                            else {
                                if (data == rightOperand) {
                                    keyToChange.push(key);

                                }
                            }
                        }
                    }
                }
            }
        }
        // 遍历队列
        while (!keyToChange.empty()) {
            string frontElement = keyToChange.front(); // 获取队头元素
            TableData[tableName][columnToSet][frontElement] = valueToSet;
            keyToChange.pop();                      // 弹出队头元素
        }

    }
    else {
        cout << "No match found." << endl;
    }
}

void UpdataWithWHEREsingle(string tableName, string setValues, string whereClause) {
    // 创建一个正则表达式模式来匹配等号左侧和右侧的字符串
    regex pattern(R"(([^=]+)=([^=]+))");


    // 在输入字符串中搜索匹配项
    smatch match;
    string column = match[1];
    string value = match[2];
    if (regex_search(setValues, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含等号左侧的字符串
        // match[2] 包含等号右侧的字符串
        column = match[1];
        value = removeSingleQuotes(match[2]);
    }
    else {
        cout << "No match found." << endl;
    }

    ChangeWithWHEREsingle(tableName, whereClause, column, value);
}

void UpdataWithWHEREdouble(string tableName, string setValues, string whereClause){
    // 创建一个正则表达式模式来匹配等号左侧和右侧的字符串
    regex pattern(R"(([^=]+)=([^=]+))");

    // 在输入字符串中搜索匹配项
    smatch match;
    string column = match[1];
    string value = match[2];
    if (regex_search(setValues, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含等号左侧的字符串
        // match[2] 包含等号右侧的字符串
        column = match[1];
        value = removeSingleQuotes(match[2]);
    }
    else {
        cout << "No match found." << endl;
    }

    ChangeWithWHEREdouble(tableName, whereClause, column, value);


}

void UpdataWithWHERE(string sql) {
    // 创建一个正则表达式模式来匹配UPDATE语句
    regex pattern(R"((UPDATE) ([A-Za-z_][A-Za-z0-9_]*).*SET (.*)\s*WHERE (.*);)");

    // 在输入字符串中搜索匹配项
    smatch match;
    string update;
    string tableName;
    string setValues;
    string whereClause;
    if (regex_search(sql, match, pattern)) {
        // match[0] 包含整个匹配的字符串
        // match[1] 包含 "UPDATE"
        // match[2] 包含表名
        // match[3] 包含列值设置
        // match[4] 包含更新条件
        update = match[1];
        tableName = match[2];
        setValues = match[3];
        whereClause = match[4];
    }
    else {
        cout << "No match found." << endl;
    }
    ReadTable(tableName);

    if (sql.find("AND") != string::npos || sql.find("OR") != string::npos) {
        UpdataWithWHEREdouble(tableName, setValues, whereClause);
    }
    else {
        UpdataWithWHEREsingle(tableName, setValues, whereClause);
    }
    WriteTable(tableName);
}

void Updata(string sql) {

    if (sql.find("WHERE") != string::npos) {
        UpdataWithWHERE(sql);
    }
    else {
        UpdataWithoutWHERE(sql);
    }
}

int main()
{
    locale::global(locale(""));
    InitDataDictionary();
    PrintOutDataDictionary();
    InitOperators();
    out = queue<string>(); // 清空队列
    while (true) {
        InitDataDictionary();
        string sql;
        cout << "请输入SQL语句:" << endl;
        getline(cin, sql);
        if (sql.find("CREATE TABLE") != string::npos) {
            CreateTable(sql);
        }
        else if ( sql.find("INSERT INTO") != string::npos) {
            InsertInto(sql);
        }
        else if (sql.find("ALTER TABLE") != string::npos) {
            AlterTable(sql);
        }
        else if (sql.find("DELETE FROM") != string::npos) {
            DeleteFrom(sql);
        }
        else if (sql.find("UPDATE") != string::npos) {
            Updata(sql);
        }
        else if (sql.find("DROP TABLE") != string::npos) {
            DropTable(sql);
        }
        else if (sql.find("SELECT * FROM") != string::npos) {
            ShowTable(sql);
        }

        // 清空队列
        out = queue<string>();

        //写入数据字典
        WriteDataDictionary();

        // 清空数据
        TableData.clear();
    }
}

/*

CREATE TABLE stu (sid CHAR(6),sname VARCHAR(20),age INT,gender VARCHAR(10),PRIMARY KEY(sid));
CREATE TABLE MyTable (column1 INT, column2 VARCHAR(255));

ALTER TABLE stu ADD (classname INT);
INSERT INTO stu VALUES ('s_1002','liSi',32,'male',4);
INSERT INTO stu (sid,sname,age,gender,classname) VALUES ('s_2003','JOE',23,'female',3);
ALTER TABLE stu DROP classname;

DELETE FROM stu WHERE sid='s_2003' ;
DELETE FROM stu WHERE age=23 ;
DELETE FROM stu WHERE sname='JOE' OR age=32 ;
DELETE FROM stu WHERE age>23 AND age<40 ;
DELETE FROM stu WHERE sid='s_2003' AND age=23 ;

UPDATE stu SET sname='zhangSanSan' WHERE sid='s_1002';
UPDATE stu SET age=18;
UPDATE stu SET age=18 WHERE age>23 AND age<40;

SELECT * FROM stu;

DELETE FROM stu ;

DROP TABLE stu;
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值