├── gui ├── README.md └── ColaSqlGui │ ├── Colasql.ico │ ├── Colasql.icon │ ├── resource │ ├── images │ │ ├── logo.png │ │ ├── table.jpg │ │ ├── Colasql.png │ │ ├── database.jpg │ │ ├── create │ │ │ ├── ok-1.png │ │ │ ├── ok-2.png │ │ │ ├── cancel-1.png │ │ │ ├── cancel-2.png │ │ │ ├── createindex-bg.png │ │ │ └── createrecord-bg.png │ │ ├── main │ │ │ ├── main-bg.png │ │ │ ├── BIGGERONE.png │ │ │ ├── huitui-1.png │ │ │ ├── huitui-2.png │ │ │ ├── tijiao-1.png │ │ │ └── tijiao-2.png │ │ ├── add_table │ │ │ ├── tj-1.png │ │ │ ├── tj-2.png │ │ │ ├── add-bg.png │ │ │ ├── comp-1.png │ │ │ ├── comp-2.png │ │ │ ├── cancel-1.png │ │ │ └── cancel-2.png │ │ ├── login │ │ │ ├── login-bg.png │ │ │ ├── btn-login-1.png │ │ │ ├── btn-login-2.png │ │ │ ├── btn-register-1.png │ │ │ └── btn-register-2.png │ │ └── register │ │ │ ├── back-1.png │ │ │ ├── back-2.png │ │ │ ├── reg-1.png │ │ │ ├── reg-2.png │ │ │ └── register-bg.png │ ├── font │ │ ├── FiraCode-Regular-1.ttf │ │ └── SmileySans-Oblique.ttf │ └── res.qrc │ ├── src │ ├── main.cpp │ ├── ui_login.cpp │ ├── columndialog.cpp │ ├── createindex.cpp │ ├── createrecord.cpp │ ├── ui_register.cpp │ └── createtable.cpp │ ├── include │ ├── ui_register.h │ ├── ui_login.h │ ├── qtbstreambuf.h │ ├── columndialog.h │ ├── createindex.h │ ├── createrecord.h │ ├── createtable.h │ └── mainwindow.h │ ├── .gitignore │ ├── ui │ ├── createindex.ui │ ├── createrecord.ui │ ├── ui_login.ui │ ├── ui_register.ui │ ├── createtable.ui │ ├── mainwindow.ui │ ├── mainwindow - 副本.ui │ └── secondarywindow.ui │ └── ColaSqlGui.pro ├── cmd ├── README.md ├── include │ ├── header_template.h │ ├── command_processor.h │ └── my_parser.h ├── main.cpp ├── Build.ps1 ├── student.colasql ├── indexSimplified.colasql ├── test │ ├── CREATE TABLE 测试语句.txt │ └── 测试语句.md ├── index.colasql ├── CMakeLists.txt └── src │ └── command_processor.cpp ├── document ├── pictures │ ├── logo.png │ ├── pic1.png │ ├── pic2.png │ ├── pic3.png │ ├── Github.png │ ├── CodeCounter.png │ └── ProjectConstruction.png ├── FinalDemonstration.pdf ├── sql test.md ├── FinalDemonstration.md └── FinalDocument.md ├── core ├── src │ ├── constraint │ │ ├── unique_constraint.cpp │ │ ├── primary_key_constraint.cpp │ │ ├── not_null_constraint.cpp │ │ ├── default_constraint.cpp │ │ ├── CMakeLists.txt │ │ ├── constraint.cpp │ │ ├── foreign_key_constraint.cpp │ │ ├── foreign_refered_constraint.cpp │ │ └── constraint_test.cpp.txt │ ├── index │ │ ├── index.cpp │ │ └── fhqtreapindex.cpp │ └── user.cpp ├── include │ ├── constraint │ │ ├── all_constraints.h │ │ ├── unique_constraint.h │ │ ├── not_null_constraint.h │ │ ├── primary_key_constraint.h │ │ ├── default_constraint.h │ │ ├── constraint.h │ │ ├── foreign_refered_constraint.h │ │ └── foreign_key_constraint.h │ ├── colasqltool.h │ ├── user.h │ ├── constants.h │ ├── index │ │ ├── fhqtreapindex.h │ │ └── index.h │ ├── database.h │ ├── table.h │ └── dataprocessor.h ├── CMakeLists.txt ├── README.md └── main.cpp ├── file ├── README.md └── include │ └── filemanager.h ├── LICENSE.txt ├── .gitignore └── README.md /gui/README.md: -------------------------------------------------------------------------------- 1 | # GUI 2 | * GUI模块 3 | * 使用C++ & Qt实现 4 | -------------------------------------------------------------------------------- /cmd/README.md: -------------------------------------------------------------------------------- 1 | # Co1aSQL Command 2 | * 命令行(SQL语法解释)模块 3 | * 使用C++实现 4 | -------------------------------------------------------------------------------- /document/pictures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/document/pictures/logo.png -------------------------------------------------------------------------------- /document/pictures/pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/document/pictures/pic1.png -------------------------------------------------------------------------------- /document/pictures/pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/document/pictures/pic2.png -------------------------------------------------------------------------------- /document/pictures/pic3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/document/pictures/pic3.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/Colasql.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/Colasql.ico -------------------------------------------------------------------------------- /gui/ColaSqlGui/Colasql.icon: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/Colasql.icon -------------------------------------------------------------------------------- /document/pictures/Github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/document/pictures/Github.png -------------------------------------------------------------------------------- /document/FinalDemonstration.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/document/FinalDemonstration.pdf -------------------------------------------------------------------------------- /document/pictures/CodeCounter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/document/pictures/CodeCounter.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/logo.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/table.jpg -------------------------------------------------------------------------------- /document/pictures/ProjectConstruction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/document/pictures/ProjectConstruction.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/Colasql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/Colasql.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/database.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/database.jpg -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/create/ok-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/create/ok-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/create/ok-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/create/ok-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/main/main-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/main/main-bg.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/add_table/tj-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/add_table/tj-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/add_table/tj-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/add_table/tj-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/create/cancel-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/create/cancel-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/create/cancel-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/create/cancel-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/login/login-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/login/login-bg.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/main/BIGGERONE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/main/BIGGERONE.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/main/huitui-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/main/huitui-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/main/huitui-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/main/huitui-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/main/tijiao-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/main/tijiao-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/main/tijiao-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/main/tijiao-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/register/back-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/register/back-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/register/back-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/register/back-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/register/reg-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/register/reg-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/register/reg-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/register/reg-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/font/FiraCode-Regular-1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/font/FiraCode-Regular-1.ttf -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/font/SmileySans-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/font/SmileySans-Oblique.ttf -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/add_table/add-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/add_table/add-bg.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/add_table/comp-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/add_table/comp-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/add_table/comp-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/add_table/comp-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/login/btn-login-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/login/btn-login-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/login/btn-login-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/login/btn-login-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/add_table/cancel-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/add_table/cancel-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/add_table/cancel-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/add_table/cancel-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/login/btn-register-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/login/btn-register-1.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/login/btn-register-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/login/btn-register-2.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/register/register-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/register/register-bg.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/create/createindex-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/create/createindex-bg.png -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/images/create/createrecord-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/HEAD/gui/ColaSqlGui/resource/images/create/createrecord-bg.png -------------------------------------------------------------------------------- /cmd/include/header_template.h: -------------------------------------------------------------------------------- 1 | #ifndef __HEADER_H__ 2 | #define __HEADER_H__ 3 | 4 | namespace Co1aSQL_CMD { 5 | 6 | 7 | 8 | 9 | 10 | } // Co1aSQL_CMD 11 | 12 | #endif // __HEADER_H__ -------------------------------------------------------------------------------- /core/src/constraint/unique_constraint.cpp: -------------------------------------------------------------------------------- 1 | #include "unique_constraint.h" 2 | 3 | UniqueConstraint::UniqueConstraint(const std::string& fieldName, const std::string& constraintName): Constraint(fieldName, constraintName) { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "mainwindow.h" 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | MainWindow w; 9 | // w.show(); 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /core/src/constraint/primary_key_constraint.cpp: -------------------------------------------------------------------------------- 1 | #include "primary_key_constraint.h" 2 | 3 | PrimaryKeyConstraint::PrimaryKeyConstraint(const std::string& fieldName, const std::string& constraintName): 4 | Constraint(fieldName, constraintName) { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /core/src/constraint/not_null_constraint.cpp: -------------------------------------------------------------------------------- 1 | #include "not_null_constraint.h" 2 | 3 | NotNullConstraint::NotNullConstraint(const std::string& fieldName, 4 | const std::string& constraintName): 5 | Constraint(fieldName, constraintName) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /core/include/constraint/all_constraints.h: -------------------------------------------------------------------------------- 1 | 2 | // 本文件包含了所有Constraint子类,只需要引用本头文件即可 3 | 4 | #include "constraint.h" 5 | 6 | #include "primary_key_constraint.h" 7 | #include "foreign_key_constraint.h" 8 | #include "foreign_refered_constraint.h" 9 | #include "unique_constraint.h" 10 | #include "not_null_constraint.h" 11 | #include "default_constraint.h" -------------------------------------------------------------------------------- /core/include/constraint/unique_constraint.h: -------------------------------------------------------------------------------- 1 | #ifndef __UNIQUE_CONSTRAINT_H__ 2 | #define __UNIQUE_CONSTRAINT_H__ 3 | 4 | #include 5 | 6 | #include "constraint.h" 7 | 8 | // 非空 9 | class UniqueConstraint: public Constraint { 10 | public: 11 | UniqueConstraint(const std::string& fieldName, const std::string& constraintName); 12 | }; 13 | 14 | #endif // __UNIQUE_CONSTRAINT_H__ 15 | -------------------------------------------------------------------------------- /core/include/constraint/not_null_constraint.h: -------------------------------------------------------------------------------- 1 | #ifndef __NOT_NULL_CONSTRAINT_H__ 2 | #define __NOT_NULL_CONSTRAINT_H__ 3 | 4 | #include 5 | 6 | #include "constraint.h" 7 | 8 | // 非空 9 | class NotNullConstraint: public Constraint { 10 | public: 11 | NotNullConstraint(const std::string& fieldName, const std::string& constraintName); 12 | }; 13 | 14 | #endif // __NOT_NULL_CONSTRAINT_H__ 15 | -------------------------------------------------------------------------------- /core/include/constraint/primary_key_constraint.h: -------------------------------------------------------------------------------- 1 | #ifndef __PRIMARY_KEY_CONSTRAINT_H__ 2 | #define __PRIMARY_KEY_CONSTRAINT_H__ 3 | 4 | #include 5 | 6 | #include "constraint.h" 7 | 8 | // 主键:非空 且 唯一 9 | class PrimaryKeyConstraint: public Constraint { 10 | public: 11 | PrimaryKeyConstraint(const std::string& fieldName, const std::string& constraintName); 12 | }; 13 | 14 | #endif // __PRIMARY_KEY_CONSTRAINT_H__ 15 | -------------------------------------------------------------------------------- /cmd/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "command_processor.h" 5 | 6 | int main(int argc, char** argv) { 7 | 8 | if(argc <= 2) { 9 | std::cout << "Please enter account name and password after \"colasql\"" << std::endl; 10 | return 0; 11 | } 12 | 13 | ColaSQLCommand::CommandProcessor::GetInstance().Start(std::string(argv[1]), std::string(argv[2])); 14 | 15 | return 0; 16 | } -------------------------------------------------------------------------------- /core/src/constraint/default_constraint.cpp: -------------------------------------------------------------------------------- 1 | #include "default_constraint.h" 2 | 3 | DefaultConstraint::DefaultConstraint(const std::string& fieldName, const std::string& constraintName, std::any value): 4 | Constraint(fieldName, constraintName), _value(value) { 5 | } 6 | 7 | std::any DefaultConstraint::GetValue() const { 8 | return _value; 9 | } 10 | 11 | void DefaultConstraint::SetValue(std::any value) { 12 | _value = value; 13 | } 14 | -------------------------------------------------------------------------------- /cmd/Build.ps1: -------------------------------------------------------------------------------- 1 | # Remove-Item "./build" -Recurse 2 | New-Item -Path "./build" -ItemType Directory 3 | Set-Location "./build" 4 | # cmake .. 5 | # cmake -DCMAKE_CXX_COMPILER="C:/Program Files/mingw-w64/mingw64/bin/g++.exe" -DCMAKE_C_COMPILER="C:/Program Files/mingw-w64/mingw64/bin/gcc.exe" -G "MinGW Makefiles" .. 6 | cmake -DCMAKE_CXX_COMPILER="C:/Program Files/mingw64/bin/g++.exe" -DCMAKE_C_COMPILER="C:/Program Files/mingw64/bin/gcc.exe" -G "MinGW Makefiles" .. 7 | mingw32-make 8 | Set-Location ".." -------------------------------------------------------------------------------- /core/src/index/index.cpp: -------------------------------------------------------------------------------- 1 | #include "index/index.h" 2 | 3 | Index::Index(const std::vector>& records, 4 | const std::vector>& fields, 5 | const std::unordered_map& field_map, 6 | const std::vector& compare_key) { 7 | _state = 1; 8 | } 9 | 10 | Index::~Index() { 11 | } 12 | 13 | const std::vector& Index::getCompareKey() const { 14 | return _compare_key; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /core/src/constraint/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is to test constraints 2 | 3 | cmake_minimum_required(VERSION 3.10) 4 | 5 | project(colasql_constraint_test) 6 | 7 | # 将src文件夹下所有文件添加至SOURCE_src 8 | aux_source_directory(./ SOURCE_src) 9 | 10 | add_executable( 11 | colasql_constraint_test 12 | ${SOURCE_src} 13 | ) 14 | 15 | target_include_directories( 16 | colasql_constraint_test 17 | PRIVATE 18 | ${PROJECT_SOURCE_DIR}/../../include/constraint 19 | ) 20 | 21 | target_compile_features( 22 | colasql_constraint_test 23 | PRIVATE 24 | cxx_std_17 25 | ) -------------------------------------------------------------------------------- /core/include/constraint/default_constraint.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEFAULT_CONSTRAINT_H__ 2 | #define __DEFAULT_CONSTRAINT_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "constraint.h" 8 | 9 | // 主键:非空 且 唯一 10 | class DefaultConstraint: public Constraint { 11 | 12 | public: 13 | DefaultConstraint(const std::string& fieldName, const std::string& constraintName, std::any value); 14 | 15 | std::any GetValue() const; 16 | 17 | void SetValue(std::any value); 18 | 19 | private: 20 | std::any _value; 21 | 22 | }; 23 | 24 | #endif // __DEFAULT_CONSTRAINT_H__ 25 | -------------------------------------------------------------------------------- /file/README.md: -------------------------------------------------------------------------------- 1 | # File 2 | 3 | * 文件管理系统 4 | * 单例 5 | * 使用C++实现 6 | 7 | 8 | 9 | 10 | ## 1. 接口 11 | 12 | ```C++ 13 | int CreateUser(const User& user); 14 | int CreateDatabaseDirectory(const DataBase& database); 15 | int CreateTableFile(const Table& table); 16 | 17 | int ReadUser(User& user); 18 | int ReadUsers(std::vector& users); 19 | int ReadDatabase(Database& database); 20 | int ReadDatabases(std::vector& databases); 21 | 22 | int WriteUser(User user); 23 | int WriteUsers(std::vector users); 24 | int WriteDatabase(Database& database); 25 | int WriteDatabases(std::vector databases); 26 | 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /cmd/student.colasql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE bjtu; 2 | 3 | USE bjtu; 4 | 5 | CREATE TABLE student 6 | Sno int 7 | Sname string 8 | Ssex string 9 | Sbirthday string 10 | Totalcredit int 11 | 12 | Constraint c10 Primary key Sno 13 | Constraint c11 Not Null Sname 14 | Constraint c12 Unique Sbirthday 15 | Constraint c13 Default Totalcredit 0 16 | ; 17 | 18 | INSERT INTO student Sno Sname Ssex Sbirthday 19 | VALUES 21301114 YXH_XianYu Male 2002-10-12; 20 | INSERT INTO student Sno Sname Ssex Sbirthday 21 | VALUES 21301113 YLW Male Unknown; 22 | INSERT INTO student Sno Sname Ssex Sbirthday Totalcredit 23 | VALUES 1 ShirahaneSuoh Female 2002-03-16 163; 24 | -------------------------------------------------------------------------------- /core/include/constraint/constraint.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONSTRAINT_H__ 2 | #define __CONSTRAINT_H__ 3 | 4 | #include 5 | 6 | class Constraint { 7 | 8 | public: 9 | Constraint(const std::string& fieldName, const std::string& constraintName); 10 | 11 | std::string GetFieldName() const; 12 | 13 | void SetFieldName(const std::string& fieldName); 14 | 15 | std::string GetConstraintName() const; 16 | 17 | void SetConstraintName(const std::string& constraintName); 18 | 19 | virtual void Polymorphic(); 20 | 21 | private: 22 | std::string _fieldName; 23 | 24 | std::string _constraintName; 25 | 26 | }; 27 | 28 | #endif // __CONSTRAINT_H__ 29 | -------------------------------------------------------------------------------- /core/src/constraint/constraint.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "constraint.h" 3 | 4 | Constraint::Constraint(const std::string& fieldName, const std::string& constraintName): 5 | _fieldName(fieldName), _constraintName(constraintName) { 6 | } 7 | 8 | std::string Constraint::GetFieldName() const { 9 | return _fieldName; 10 | } 11 | 12 | void Constraint::SetFieldName(const std::string& fieldName) { 13 | _fieldName = fieldName; 14 | } 15 | 16 | std::string Constraint::GetConstraintName() const { 17 | return _constraintName; 18 | } 19 | 20 | void Constraint::SetConstraintName(const std::string& constraintName) { 21 | _constraintName = constraintName; 22 | } 23 | 24 | void Constraint::Polymorphic() { 25 | // make class Constraint a polymorphic class. 26 | } 27 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/include/ui_register.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_REGISTER_H 2 | #define UI_REGISTER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dataprocessor.h" 9 | 10 | namespace Ui 11 | { 12 | class ui_register; 13 | } 14 | 15 | class ui_register : public QMainWindow 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit ui_register(QWidget* parent = nullptr); 21 | ~ui_register(); 22 | 23 | signals: 24 | void back(); 25 | 26 | private slots: 27 | void on_pushButton_back_clicked(); 28 | 29 | void on_pushButton_regist_clicked(); 30 | 31 | private: 32 | Ui::ui_register* ui; 33 | QString user_name; 34 | QString user_pwd1; 35 | QString user_pwd2; 36 | 37 | void clear(); 38 | }; 39 | 40 | #endif // UI_REGISTER_H 41 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/include/ui_login.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_LOGIN_H 2 | #define UI_LOGIN_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "dataprocessor.h" 11 | 12 | namespace Ui 13 | { 14 | class ui_login; 15 | } 16 | 17 | class ui_login : public QMainWindow 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | explicit ui_login(QWidget* parent = nullptr); 23 | ~ui_login(); 24 | 25 | signals: 26 | void login(); 27 | 28 | private slots: 29 | void on_pushButton_login_clicked(); 30 | 31 | void on_pushButton_regist_clicked(); 32 | 33 | private: 34 | Ui::ui_login* ui; 35 | ui_register* ui_regist; 36 | QString user_name; 37 | QString user_pwd; 38 | void clear(); 39 | }; 40 | 41 | #endif // UI_LOGIN_H 42 | -------------------------------------------------------------------------------- /cmd/indexSimplified.colasql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE indexDatabase; 2 | USE indexDatabase; 3 | CREATE TABLE X 4 | A int, 5 | B int, 6 | C int, 7 | ; 8 | CREATE TABLE Y 9 | B int, 10 | C int, 11 | D int, 12 | ; 13 | 14 | INSERT INTO X A B C VALUES 1 1 1; 15 | INSERT INTO X A B C VALUES 1 1 2; 16 | INSERT INTO X A B C VALUES 1 2 1; 17 | INSERT INTO X A B C VALUES 1 2 2; 18 | 19 | INSERT INTO X A B C VALUES 2 1 1; 20 | INSERT INTO X A B C VALUES 2 1 2; 21 | INSERT INTO X A B C VALUES 2 2 1; 22 | INSERT INTO X A B C VALUES 2 2 2; 23 | 24 | INSERT INTO Y B C D VALUES 1 1 1; 25 | INSERT INTO Y B C D VALUES 1 1 2; 26 | INSERT INTO Y B C D VALUES 1 2 1; 27 | INSERT INTO Y B C D VALUES 1 2 2; 28 | 29 | INSERT INTO Y B C D VALUES 2 1 1; 30 | INSERT INTO Y B C D VALUES 2 1 2; 31 | INSERT INTO Y B C D VALUES 2 2 1; 32 | INSERT INTO Y B C D VALUES 2 2 2; 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /cmd/test/CREATE TABLE 测试语句.txt: -------------------------------------------------------------------------------- 1 | CREATE TABLE student 2 | Sno int 3 | Sname string 4 | Ssex string 5 | Sbirthday string 6 | Totalcredit int 7 | ; 8 | 9 | CREATE TABLE student 10 | Sno int 11 | Sname string 12 | Ssex string 13 | Sbirthday string 14 | Totalcredit int 15 | 16 | Constraint Primary key Sno 17 | Constraint Not Null Sname 18 | Constraint Unique Sbirthday 19 | Constraint Default Totalcredit 0 20 | ; 21 | 22 | // ----- error test ----- 23 | 24 | CREATE TABLE student 25 | Sno int 26 | Sno float 27 | ; 28 | 29 | CREATE TABLE student 30 | Sno int 31 | Sno1 float 32 | 33 | constraint primary sno 34 | ; 35 | 36 | CREATE TABLE student 37 | Sno int 38 | Sno1 float 39 | 40 | constraint primary key sn1 41 | ; 42 | 43 | CREATE TABLE student 44 | Sno int 45 | Sno1 float 46 | 47 | constraint foreign key Sno reference Sno 48 | ; 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/include/qtbstreambuf.h: -------------------------------------------------------------------------------- 1 | #ifndef QTBSTREAMBUF_H 2 | #define QTBSTREAMBUF_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class QTextEditStreamBuf : public std::streambuf 9 | { 10 | public: 11 | QTextEditStreamBuf(QTextEdit* edit) 12 | : m_Edit(edit) {} 13 | 14 | protected: 15 | virtual std::streamsize xsputn(const char* s, std::streamsize n) override 16 | { 17 | QString text = QString::fromUtf8(s, static_cast(n)); 18 | m_Edit->append(text); 19 | return n; 20 | } 21 | 22 | virtual int_type overflow(int_type v) override 23 | { 24 | if (v != traits_type::eof()) 25 | { 26 | char ch = static_cast(v); 27 | xsputn(&ch, 1); 28 | } 29 | return v; 30 | } 31 | 32 | private: 33 | QTextEdit* m_Edit; 34 | }; 35 | 36 | #endif // QTBSTREAMBUF_H 37 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/include/columndialog.h: -------------------------------------------------------------------------------- 1 | #ifndef COLUMNDIALOG_H 2 | #define COLUMNDIALOG_H 3 | // 自定义对话框窗口类 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | class ColumnDialog : public QDialog 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit ColumnDialog(QWidget* parent = nullptr); 18 | 19 | // 声明三个QLineEdit指针成员变量 20 | QLineEdit* lineEdit1; 21 | QLineEdit* lineEdit2; 22 | QLineEdit* lineEdit3; 23 | QLineEdit* lineEdit4; 24 | QComboBox* comboBox; 25 | QStringList getValues(); 26 | 27 | private: 28 | // 声明两个按钮的指针成员变量 29 | QPushButton* okButton; 30 | QPushButton* cancelButton; 31 | 32 | private slots: 33 | // 声明确认按钮的槽函数 34 | void acceptValues(); 35 | }; 36 | 37 | #endif // COLUMNDIALOG_H 38 | -------------------------------------------------------------------------------- /core/include/constraint/foreign_refered_constraint.h: -------------------------------------------------------------------------------- 1 | #ifndef __FOREIGN_REFERED_CONSTRAINT_H__ 2 | #define __FOREIGN_REFERED_CONSTRAINT_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "constraint.h" 8 | 9 | // 主键:非空 且 唯一 10 | class ForeignReferedConstraint: public Constraint { 11 | 12 | public: 13 | ForeignReferedConstraint(const std::string& fieldName, const std::string& constraintName, const std::string& referenceTableName, const std::string& referenceFieldName); 14 | 15 | std::string GetReferenceTableName() const; 16 | 17 | void SetReferenceTableName(const std::string& referenceTableName); 18 | 19 | std::string GetReferenceFieldName() const; 20 | 21 | void SetReferenceFieldName(const std::string& referenceFieldName); 22 | 23 | private: 24 | std::string _referenceTableName; 25 | std::string _referenceFieldName; 26 | 27 | }; 28 | 29 | #endif // __FOREIGN_KEY_CONSTRAINT_H__ 30 | -------------------------------------------------------------------------------- /core/include/constraint/foreign_key_constraint.h: -------------------------------------------------------------------------------- 1 | #ifndef __FOREIGN_KEY_CONSTRAINT_H__ 2 | #define __FOREIGN_KEY_CONSTRAINT_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "constraint.h" 8 | 9 | // 主键:非空 且 唯一 10 | class ForeignKeyConstraint: public Constraint { 11 | 12 | public: 13 | ForeignKeyConstraint(const std::string& fieldName, 14 | const std::string& constraintName, 15 | const std::string& referenceTableName, 16 | const std::string& referenceFieldName); 17 | 18 | std::string GetReferenceTableName() const; 19 | 20 | void SetReferenceTableName(const std::string& referenceTableName); 21 | 22 | std::string GetReferenceFieldName() const; 23 | 24 | void SetReferenceFieldName(const std::string& referenceFieldName); 25 | 26 | private: 27 | std::string _referenceTableName; 28 | std::string _referenceFieldName; 29 | 30 | }; 31 | 32 | #endif // __FOREIGN_KEY_CONSTRAINT_H__ 33 | -------------------------------------------------------------------------------- /core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | project(colasql) 4 | 5 | # For ccls config 6 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 7 | set(CMAKE_CXX_STANDARD 17) # A ccls bug, you need to use old syntax to enable ccls 8 | 9 | # 将src文件夹下所有文件添加至SOURCE_src 10 | aux_source_directory(./src SOURCE_SRC) 11 | aux_source_directory(./src/constraint SOURCE_CONSTRANIT_SRC) 12 | aux_source_directory(./src/index SOURCE_INDEX_SRC) 13 | aux_source_directory(./../file/src/ SOURCE_FILE) 14 | 15 | # cpp 16 | add_executable( 17 | colasql 18 | 19 | # main 20 | main.cpp 21 | 22 | # core 23 | ${SOURCE_SRC} 24 | ${SOURCE_CONSTRANIT_SRC} 25 | ${SOURCE_INDEX_SRC} 26 | 27 | # file 28 | ${SOURCE_FILE} 29 | ) 30 | 31 | # h (directory) 32 | target_include_directories( 33 | colasql 34 | PRIVATE 35 | ${PROJECT_SOURCE_DIR}/include/. 36 | ${PROJECT_SOURCE_DIR}/include/constraint/. 37 | ${PROJECT_SOURCE_DIR}/../file/include/. 38 | ) 39 | 40 | target_compile_features( 41 | colasql 42 | PRIVATE 43 | cxx_std_17 44 | ) 45 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | qrc_*.cpp 31 | Thumbs.db 32 | *.res 33 | *.rc 34 | /.qmake.cache 35 | /.qmake.stash 36 | 37 | # qtcreator generated files 38 | *.pro.user* 39 | 40 | # xemacs temporary files 41 | *.flc 42 | 43 | # Vim temporary files 44 | .*.swp 45 | 46 | # Visual Studio generated files 47 | *.ib_pdb_index 48 | *.idb 49 | *.ilk 50 | *.pdb 51 | *.sln 52 | *.suo 53 | *.vcproj 54 | *vcproj.*.*.user 55 | *.ncb 56 | *.sdf 57 | *.opensdf 58 | *.vcxproj 59 | *vcxproj.* 60 | 61 | # MinGW generated files 62 | *.Debug 63 | *.Release 64 | 65 | # Python byte code 66 | *.pyc 67 | 68 | # Binaries 69 | # -------- 70 | *.dll 71 | *.exe 72 | 73 | -------------------------------------------------------------------------------- /core/src/constraint/foreign_key_constraint.cpp: -------------------------------------------------------------------------------- 1 | #include "foreign_key_constraint.h" 2 | 3 | ForeignKeyConstraint::ForeignKeyConstraint(const std::string& fieldName, 4 | const std::string& constraintName, 5 | const std::string& referenceTableName, 6 | const std::string& referenceFieldName): 7 | Constraint(fieldName, constraintName), _referenceTableName(referenceTableName), _referenceFieldName(referenceFieldName) { 8 | } 9 | 10 | std::string ForeignKeyConstraint::GetReferenceTableName() const { 11 | return _referenceTableName; 12 | } 13 | 14 | void ForeignKeyConstraint::SetReferenceTableName(const std::string& referenceTableName) { 15 | _referenceTableName = referenceTableName; 16 | } 17 | 18 | std::string ForeignKeyConstraint::GetReferenceFieldName() const { 19 | return _referenceFieldName; 20 | } 21 | 22 | void ForeignKeyConstraint::SetReferenceFieldName(const std::string& referenceFieldName) { 23 | _referenceFieldName = referenceFieldName; 24 | } 25 | -------------------------------------------------------------------------------- /cmd/index.colasql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE indexDatabase; 2 | USE indexDatabase; 3 | CREATE TABLE X 4 | A int, 5 | B int, 6 | C int, 7 | ; 8 | CREATE TABLE Y 9 | B int, 10 | C int, 11 | D int, 12 | ; 13 | 14 | INSERT INTO X A B C VALUES 1 1 1; 15 | INSERT INTO X A B C VALUES 1 1 2; 16 | INSERT INTO X A B C VALUES 1 2 1; 17 | INSERT INTO X A B C VALUES 1 2 2; 18 | 19 | INSERT INTO X A B C VALUES 2 1 1; 20 | INSERT INTO X A B C VALUES 2 1 2; 21 | INSERT INTO X A B C VALUES 2 2 1; 22 | INSERT INTO X A B C VALUES 2 2 2; 23 | 24 | INSERT INTO Y B C D VALUES 1 1 1; 25 | INSERT INTO Y B C D VALUES 1 1 2; 26 | INSERT INTO Y B C D VALUES 1 2 1; 27 | INSERT INTO Y B C D VALUES 1 2 2; 28 | 29 | INSERT INTO Y B C D VALUES 2 1 1; 30 | INSERT INTO Y B C D VALUES 2 1 2; 31 | INSERT INTO Y B C D VALUES 2 2 1; 32 | INSERT INTO Y B C D VALUES 2 2 2; 33 | 34 | SELECT * FROM X; 35 | SELECT * FROM Y; 36 | 37 | CREATE INDEX ON X A; 38 | 39 | SELECT * FROM X WHERE A = 1; 40 | 41 | SELECT * FROM X WHERE B = 1; 42 | 43 | SELECT * FROM X WHERE A = 1 C = 1; 44 | 45 | SELECT * FROM X WHERE A = 1 B = 2; 46 | 47 | 48 | -------------------------------------------------------------------------------- /file/include/filemanager.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEMANAGER_H 2 | #define FILEMANAGER_H 3 | 4 | #include 5 | 6 | #include "database.h" 7 | #include "user.h" 8 | #include "constants.h" 9 | 10 | class FileManager { 11 | private: 12 | FileManager(); 13 | 14 | public : 15 | static FileManager& GetInstance(); 16 | 17 | public : 18 | // ----- Write ----- 19 | 20 | int ClearData(); 21 | 22 | int WriteDatabasesFile(const std::vector& databases); 23 | 24 | int WriteTablesFile(const std::string& databaseName, const std::vector& tables); 25 | 26 | int WriteUsersFile(const std::vector& users); 27 | 28 | int WriteLogFile(const std::string& databaseName, const std::string& log); 29 | 30 | // ----- Read ----- 31 | 32 | int ReadDatabasesFile(std::vector& databases); 33 | 34 | int ReadTablesFile(const std::string& databaseName, std::vector
& tables); 35 | 36 | int ReadUsersFile(std::vector& users); 37 | 38 | int ReadLogFile(const std::string& databaseName, std::string& log); 39 | }; 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /document/sql test.md: -------------------------------------------------------------------------------- 1 | ```sql 2 | create database drj; 3 | use drj; 4 | create table student(sno string,sname string, age int, address string) constraint c1 primary key sno; 5 | create table course(cno string, cname string) constraint c2 primary key cno; 6 | create table sc(sno string, cno string, grade int) constraint c3 foreign key sno references student sno constraint c4 foreign key cno references course cno; 7 | 8 | insert into student values(21301032, drj, 20, beijing); 9 | insert into student values(21301114, yxh, 200, beijing); 10 | insert into student values(21301011, gyf, 123, nanjing); 11 | 12 | insert into course values(1, eat); 13 | insert into course values(2, sleep); 14 | insert into course values(3, study); 15 | 16 | insert into sc values(21301032, 1, 100); 17 | 18 | delete from student where sno = 21301032;//违反约束 19 | 20 | insert into sc values(21301032, 1, 90); 21 | insert into sc values(21301032, 3, 91); 22 | insert into sc values(21301114, 1, 50); 23 | 24 | insert into sc values(21301013, 1, 67);//违反约束 25 | 26 | select * from student natural join course natural join sc order by grade; 27 | 28 | 29 | 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 YXH_XianYu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /core/src/constraint/foreign_refered_constraint.cpp: -------------------------------------------------------------------------------- 1 | #include "foreign_refered_constraint.h" 2 | 3 | ForeignReferedConstraint::ForeignReferedConstraint(const std::string& fieldName, 4 | const std::string& constraintName, 5 | const std::string& referenceTableName, 6 | const std::string& referenceFieldName): 7 | Constraint(fieldName, constraintName), _referenceTableName(referenceTableName), _referenceFieldName(referenceFieldName) { 8 | } 9 | 10 | std::string ForeignReferedConstraint::GetReferenceTableName() const { 11 | return _referenceTableName; 12 | } 13 | 14 | void ForeignReferedConstraint::SetReferenceTableName(const std::string& referenceTableName) { 15 | _referenceTableName = referenceTableName; 16 | } 17 | 18 | std::string ForeignReferedConstraint::GetReferenceFieldName() const { 19 | return _referenceFieldName; 20 | } 21 | 22 | void ForeignReferedConstraint::SetReferenceFieldName(const std::string& referenceFieldName) { 23 | _referenceFieldName = referenceFieldName; 24 | } 25 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/include/createindex.h: -------------------------------------------------------------------------------- 1 | #ifndef CREATEINDEX_H 2 | #define CREATEINDEX_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "command_processor.h" 13 | #include "dataprocessor.h" 14 | 15 | namespace Ui 16 | { 17 | class createindex; 18 | } 19 | 20 | class createindex : public QMainWindow 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit createindex(std::vector> return_records, 26 | const QString& tbName, QWidget* parent = nullptr); 27 | ~createindex(); 28 | 29 | private: 30 | void display_table(std::vector>& return_records); 31 | QString anyToQString(const std::any& value); 32 | 33 | signals: 34 | void create_index_signal(QString); 35 | 36 | private slots: 37 | void on_btn_cancel_clicked(); 38 | 39 | void on_btn_finish_clicked(); 40 | 41 | private: 42 | Ui::createindex* ui; 43 | std::vector> records; 44 | QString table; 45 | }; 46 | 47 | #endif // CREATEINDEX_H 48 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/include/createrecord.h: -------------------------------------------------------------------------------- 1 | #ifndef CREATERECORD_H 2 | #define CREATERECORD_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "command_processor.h" 13 | #include "dataprocessor.h" 14 | 15 | namespace Ui 16 | { 17 | class createrecord; 18 | } 19 | 20 | class createrecord : public QMainWindow 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit createrecord(std::vector> return_records, 26 | const QString& tbName, QWidget* parent = nullptr); 27 | ~createrecord(); 28 | 29 | private: 30 | void display_table(std::vector>& return_records); 31 | QString anyToQString(const std::any& value); 32 | 33 | signals: 34 | void create_record_signal(QString); 35 | 36 | private slots: 37 | void on_btn_cancel_clicked(); 38 | 39 | void on_btn_finish_clicked(); 40 | 41 | private: 42 | Ui::createrecord* ui; 43 | std::vector> records; 44 | QString table; 45 | }; 46 | 47 | #endif // CREATERECORD_H 48 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/include/createtable.h: -------------------------------------------------------------------------------- 1 | #ifndef CREATETABLE_H 2 | #define CREATETABLE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Ui 12 | { 13 | class createtable; 14 | } 15 | 16 | class createtable : public QMainWindow 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit createtable(QWidget* parent = nullptr); 22 | ~createtable(); 23 | 24 | signals: 25 | void create_table_signal(QString, QString); 26 | 27 | private slots: 28 | void on_cancel_table_clicked(); 29 | 30 | void on_add_col_clicked(); 31 | 32 | void on_finished_table_clicked(); 33 | 34 | private: 35 | Ui::createtable* ui; 36 | QStandardItemModel* model; 37 | QString database_name; 38 | QString table_name; 39 | std::vector> not_nulls; 40 | std::vector> primes; 41 | std::vector> uniques; 42 | std::vector> foreigns; 43 | std::vector> record; 44 | }; 45 | 46 | #endif // CREATETABLE_H 47 | -------------------------------------------------------------------------------- /cmd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | project(colasql) 4 | 5 | # For ccls config 6 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 7 | set(CMAKE_CXX_STANDARD 17) 8 | 9 | # 将src文件夹下所有文件添加至SOURCE_src 10 | aux_source_directory(./src/ SOURCE_SRC) 11 | aux_source_directory(./../core/src/ SOURCE_CORE) 12 | aux_source_directory(./../core/src/constraint/ SOURCE_CONSTRAINT) 13 | aux_source_directory(./../core/src/index/ SOURCE_INDEX) 14 | aux_source_directory(./../file/src/ SOURCE_FILE) 15 | 16 | 17 | add_executable( 18 | colasql 19 | 20 | main.cpp 21 | 22 | # cmd 23 | ${SOURCE_SRC} 24 | 25 | # core 26 | ${SOURCE_CORE} 27 | 28 | # core/constraints 29 | ${SOURCE_CONSTRAINT} 30 | 31 | # core/indexes 32 | ${SOURCE_INDEX} 33 | 34 | # file 35 | ${SOURCE_FILE} 36 | ) 37 | 38 | target_include_directories( 39 | colasql 40 | PRIVATE 41 | ${PROJECT_SOURCE_DIR}/include/. 42 | ${PROJECT_SOURCE_DIR}/../core/include/. 43 | ${PROJECT_SOURCE_DIR}/../core/include/constraint/. 44 | ${PROJECT_SOURCE_DIR}/../core/include/index/. 45 | ${PROJECT_SOURCE_DIR}/../file/include/. 46 | ) 47 | 48 | target_compile_features( 49 | colasql 50 | PRIVATE 51 | cxx_std_17 52 | ) 53 | -------------------------------------------------------------------------------- /cmd/include/command_processor.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMAND_PROCESSORT_H__ 2 | #define __COMMAND_PROCESSORT_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "dataprocessor.h" 11 | 12 | #include "my_parser.h" 13 | 14 | namespace ColaSQLCommand { 15 | 16 | // 命令行处理 17 | class CommandProcessor { 18 | private: 19 | // Parser 20 | Parser _parser; 21 | 22 | public: 23 | /** 24 | * 获取单例 25 | */ 26 | static CommandProcessor& GetInstance(); 27 | 28 | /** 29 | * Start CLI 30 | */ 31 | void Start(const std::string& accountName, const std::string& password); 32 | 33 | // 本函数不包含登入!请务必先登入再调用本函数 34 | std::string Run(std::string input); 35 | 36 | /** 37 | * ComplexSelect (output result as vector instead of stdout) 38 | */ 39 | std::string ComplexSelect(std::string input, std::vector>& result); 40 | 41 | /** 42 | * Run a script 43 | */ 44 | std::string RunScript(std::string path); 45 | 46 | private: 47 | /** 48 | * 输入序列 49 | */ 50 | std::vector seq; 51 | 52 | /** 53 | * 私有化构造函数 54 | */ 55 | CommandProcessor(); 56 | 57 | /** 58 | * 返回Prompt() 59 | */ 60 | std::string GetPrompt(); 61 | 62 | /** 63 | * 序列化 64 | */ 65 | int Tokenize(std::string input, std::vector& result); 66 | 67 | /** 68 | * 预处理 69 | */ 70 | int Preprocess(std::string& str); 71 | }; 72 | 73 | } // ColaSQLCommand 74 | 75 | #endif // __COMMAND_PROCESSORT_H__ 76 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/resource/res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | font/SmileySans-Oblique.ttf 4 | images/login/btn-login-1.png 5 | images/login/btn-login-2.png 6 | images/login/btn-register-1.png 7 | images/login/btn-register-2.png 8 | images/login/login-bg.png 9 | images/register/back-1.png 10 | images/register/back-2.png 11 | images/register/reg-1.png 12 | images/register/reg-2.png 13 | images/register/register-bg.png 14 | images/main/huitui-1.png 15 | images/main/huitui-2.png 16 | images/main/main-bg.png 17 | images/main/tijiao-1.png 18 | images/main/tijiao-2.png 19 | images/add_table/add-bg.png 20 | images/add_table/cancel-1.png 21 | images/add_table/cancel-2.png 22 | images/add_table/comp-1.png 23 | images/add_table/comp-2.png 24 | images/add_table/tj-1.png 25 | images/add_table/tj-2.png 26 | images/Colasql.png 27 | images/database.jpg 28 | images/table.jpg 29 | images/create/cancel-1.png 30 | images/create/cancel-2.png 31 | images/create/createindex-bg.png 32 | images/create/createrecord-bg.png 33 | images/create/ok-1.png 34 | images/create/ok-2.png 35 | font/FiraCode-Regular-1.ttf 36 | images/main/BIGGERONE.png 37 | 38 | 39 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/src/ui_login.cpp: -------------------------------------------------------------------------------- 1 | #include "ui_login.h" 2 | 3 | #include "ui_ui_login.h" 4 | 5 | ui_login::ui_login(QWidget* parent) : QMainWindow(parent), ui(new Ui::ui_login) 6 | { 7 | ui->setupUi(this); 8 | ui_regist = new ui_register; 9 | setWindowTitle("Login"); 10 | QIcon icon = QIcon(":/images/Colasql.png"); 11 | this->setWindowIcon(icon); 12 | ui->lineEdit_password->setEchoMode(QLineEdit::Password); 13 | ui->lineEdit_account->setStyleSheet( 14 | "background:transparent;border-width:0;border-style:outset"); 15 | ui->lineEdit_password->setStyleSheet( 16 | "background:transparent;border-width:0;border-style:outset"); 17 | 18 | int font_Id = 19 | QFontDatabase::addApplicationFont(":/font/FiraCode-Regular-1.ttf"); 20 | QStringList font_list = QFontDatabase::applicationFontFamilies(font_Id); 21 | if (!font_list.isEmpty()) 22 | { 23 | QFont f; 24 | f.setFamily(font_list[0]); 25 | f.setPointSize(9); 26 | ui->lineEdit_account->setFont(f); 27 | } 28 | 29 | connect(ui_regist, SIGNAL(back()), this, SLOT(show())); 30 | } 31 | 32 | ui_login::~ui_login() { delete ui; } 33 | 34 | void ui_login::clear() 35 | { 36 | ui->lineEdit_account->setText(""); 37 | ui->lineEdit_password->setText(""); 38 | } 39 | 40 | void ui_login::on_pushButton_login_clicked() 41 | { 42 | user_name = ui->lineEdit_account->text(); 43 | user_pwd = ui->lineEdit_password->text(); 44 | int ret = DataProcessor::GetInstance().Login(user_name.toStdString(), 45 | user_pwd.toStdString()); 46 | if (!ret) 47 | { 48 | emit login(); 49 | this->close(); 50 | } 51 | else if (ret == kUserNameNotFound) 52 | { 53 | QMessageBox::warning(this, "错误", "用户不存在"); 54 | clear(); 55 | } 56 | else 57 | { 58 | QMessageBox::warning(this, "错误", "用户名或密码错误"); 59 | // ui->lineEdit_account->setText(""); 60 | ui->lineEdit_password->setText(""); 61 | } 62 | } 63 | 64 | void ui_login::on_pushButton_regist_clicked() 65 | { 66 | ui_regist->show(); 67 | clear(); 68 | this->hide(); 69 | } 70 | -------------------------------------------------------------------------------- /core/include/colasqltool.h: -------------------------------------------------------------------------------- 1 | /** 2 | * author: drj 3 | * 工具类。 4 | * 含有对any类型进行操作的接口、输出表信息的接口、数据结构转换的接口、对其它数据结构转换成表结构的接口等等。 5 | */ 6 | #ifndef __COLASQLTOOL_H__ 7 | #define __COLASQLTOOL_H__ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "all_constraints.h" 15 | #include "constants.h" 16 | 17 | class ColasqlTool { 18 | public: 19 | 20 | // 输入一个表示类型的string,输出一个该类型的any(值随机) 21 | static std::any GetAnyByType(const std::string& type); 22 | 23 | // 输入一个表示类型的string 和 表示any数值的string,输出一个该类型的any 24 | static std::any GetAnyByTypeAndValue(const std::string& type, const std::string& value); 25 | 26 | // 输入一个表示类型的any 和 表示any数值的string,输出一个该类型的any 27 | static std::any GetAnyByTypeAndValue(const std::any& type, const std::string& value); 28 | 29 | // 输入一个any,以string形式输出该any的值 30 | static std::string AnyToString(const std::any& any); 31 | 32 | // 用stdout输出fields内的信息 33 | static void OutputFields(const std::vector>& fields); 34 | 35 | //输入两个any,比较它们的大小 36 | static int CompareAny(const std::any& any1, const std::any& any2); 37 | 38 | // 用stdout输出constraints内的信息 39 | static void OutputConstraints(const std::vector constraints); 40 | 41 | // 输出选择结果 42 | static std::string OutputSelectResult(const std::vector> result); 43 | 44 | //把string 转换成表结构, head为表头, 默认为空 45 | static std::vector> ChangeStringsToRecords(std::vector strings, std::string head); 46 | 47 | //把表描述信息转换成表结构 48 | static std::vector> ChangeDescriptionToRecords(const std::vector>& fields, 49 | const std::vector&constraints); 50 | 51 | // 把约束条件vector转换成字符串(用于文件输出) 52 | static std::string ConstraintsToString(const std::vector& constraints); 53 | 54 | // 把字符串转换成约束条件vector 55 | // static std::vector StringToConstraints(const std::string& str); 56 | }; 57 | 58 | class ColasqlException { 59 | 60 | }; 61 | class ColasqlNull { 62 | 63 | }; 64 | #endif // __COLASQLTOOL_H__ 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/c++,windows,cmake,qt 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=c++,windows,cmake,qt 3 | 4 | ### Path ### 5 | # Added by. YXHXianYu 6 | # ccls 7 | .ccls-cache/ 8 | cmd/.ccls-cache/ 9 | core/.ccls-cache/ 10 | file/.ccls-cache/ 11 | 12 | # Vscode 13 | .vscode/ 14 | # VSCodeCounter 15 | .VSCodeCounter/ 16 | 17 | # Cmd 18 | cmd/build/ 19 | cmd/data/ 20 | 21 | # Core 22 | core/build/ 23 | 24 | # Gui 25 | gui/build*/ 26 | gui/ColaSqlGui/build/ 27 | gui/ColaSqlGui/data/ 28 | 29 | 30 | ### C++ ### 31 | # Prerequisites 32 | *.d 33 | 34 | # Compiled Object files 35 | *.slo 36 | *.lo 37 | *.o 38 | *.obj 39 | 40 | # Precompiled Headers 41 | *.gch 42 | *.pch 43 | 44 | # Compiled Dynamic libraries 45 | *.so 46 | *.dylib 47 | *.dll 48 | 49 | # Fortran module files 50 | *.mod 51 | *.smod 52 | 53 | # Compiled Static libraries 54 | *.lai 55 | *.la 56 | *.a 57 | *.lib 58 | 59 | # Executables 60 | *.exe 61 | *.out 62 | *.app 63 | 64 | ### CMake ### 65 | CMakeLists.txt.user 66 | CMakeCache.txt 67 | CMakeFiles 68 | CMakeScripts 69 | Testing 70 | Makefile 71 | cmake_install.cmake 72 | install_manifest.txt 73 | compile_commands.json 74 | CTestTestfile.cmake 75 | _deps 76 | 77 | ### CMake Patch ### 78 | # External projects 79 | *-prefix/ 80 | 81 | ### Qt ### 82 | # C++ objects and libs 83 | *.so.* 84 | 85 | # Qt-es 86 | object_script.*.Release 87 | object_script.*.Debug 88 | *_plugin_import.cpp 89 | *.qmake.cache 90 | *.qmake.stash 91 | *.pro.user 92 | *.pro.user.* 93 | *.qbs.user 94 | *.qbs.user.* 95 | *.moc 96 | moc_*.cpp 97 | moc_*.h 98 | qrc_*.cpp 99 | *.qmlc 100 | *.jsc 101 | Makefile* 102 | *build-* 103 | *.qm 104 | *.prl 105 | 106 | # Qt unit tests 107 | target_wrapper.* 108 | 109 | # QtCreator 110 | *.autosave 111 | 112 | # QtCreator Qml 113 | *.qmlproject.user 114 | *.qmlproject.user.* 115 | 116 | # QtCreator CMake 117 | CMakeLists.txt.user* 118 | 119 | # QtCreator 4.8< compilation database 120 | 121 | # QtCreator local machine specific files for imported projects 122 | *creator.user* 123 | 124 | *_qmlcache.qrc 125 | 126 | # End of https://www.toptal.com/developers/gitignore/api/c++,windows,cmake,qt 127 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/ui/createindex.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | createindex 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | 15 | 400 16 | 300 17 | 18 | 19 | 20 | 21 | 400 22 | 300 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | #centralwidget{border-image: url(:/images/create/createindex-bg.png)} 31 | 32 | 33 | 34 | 35 | 162 36 | 239 37 | 77 38 | 29 39 | 40 | 41 | 42 | QPushButton#btn_cancel{border-image: url(:/images/create/cancel-1.png)} 43 | QPushButton::pressed#btn_cancel{border-image: url(:/images/create/cancel-2.png)} 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 13 53 | 13 54 | 373 55 | 179 56 | 57 | 58 | 59 | 60 | 61 | 62 | 162 63 | 202 64 | 77 65 | 29 66 | 67 | 68 | 69 | QPushButton#btn_finish{border-image: url(:/images/create/ok-1.png)} 70 | QPushButton::pressed#btn_finish{border-image: url(:/images/create/ok-2.png)} 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/ui/createrecord.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | createrecord 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | 15 | 400 16 | 300 17 | 18 | 19 | 20 | 21 | 400 22 | 300 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | #centralwidget{border-image: url(:/images/create/createrecord-bg.png)} 31 | 32 | 33 | 34 | 35 | 13 36 | 13 37 | 373 38 | 179 39 | 40 | 41 | 42 | 43 | 44 | 45 | 162 46 | 202 47 | 77 48 | 29 49 | 50 | 51 | 52 | QPushButton#btn_finish{border-image: url(:/images/create/ok-1.png)} 53 | QPushButton::pressed#btn_finish{border-image: url(:/images/create/ok-2.png)} 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 162 63 | 239 64 | 77 65 | 29 66 | 67 | 68 | 69 | QPushButton#btn_cancel{border-image: url(:/images/create/cancel-1.png)} 70 | QPushButton::pressed#btn_cancel{border-image: url(:/images/create/cancel-2.png)} 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /cmd/test/测试语句.md: -------------------------------------------------------------------------------- 1 | # Co1aSQL Command模块 测试 2 | 3 | 4 | USE bjtu; 5 | CREATE TABLE X 6 | A int 7 | B int 8 | C int 9 | ; 10 | INSERT INTO X VALUES 1 1 1; 11 | INSERT INTO X VALUES 1 1 2; 12 | INSERT INTO X VALUES 1 2 1; 13 | INSERT INTO X VALUES 1 2 2; 14 | 15 | 16 | INSERT INTO X VALUES 2 1 1; 17 | INSERT INTO X VALUES 2 1 2; 18 | INSERT INTO X VALUES 2 2 1; 19 | INSERT INTO X VALUES 2 2 2; 20 | 21 | CREATE INDEX ON test A B; 22 | SELECT * FROM test WHERE A = 1 B = 2; 23 | 24 | 25 | CREATE USER yxh_xianyu 20021012; 26 | GRANT USER yxh_xianyu bjtu select; 27 | LOGIN yxh_xianyu 20021012; 28 | USE bjtu; 29 | SELECT * FROM student; 30 | LOGIN admin 123456; 31 | REVOKE USER yxh_xianyu bjtu select; 32 | LOGIN yxh_xianyu 20021012; 33 | SELECT * FROM student; 34 | 35 | 36 | ```sql 37 | CREATE DATABASE bjtu; 38 | 39 | USE bjtu; 40 | 41 | CREATE TABLE student 42 | Sno int 43 | Sname string 44 | Ssex string 45 | Sbirthday string 46 | Totalcredit int 47 | 48 | Constraint c1 Primary key Sno 49 | Constraint c2 Not Null Sname 50 | Constraint c3 Unique Sbirthday 51 | Constraint c4 Default Totalcredit 0 52 | ; 53 | 54 | INSERT INTO student Sno Sname Ssex Sbirthday 55 | VALUES 21301114 YXH_XianYu Male 2002-10-12; 56 | INSERT INTO student Sno Sname Ssex Sbirthday 57 | VALUES 21301113 YLW Male Unknown; 58 | INSERT INTO student Sno Sname Ssex Sbirthday Totalcredit 59 | VALUES 1 ShirahaneSuoh Female 2002-03-16 163; 60 | 61 | SELECT * FROM student; 62 | SELECT Sno Sname Ssex FROM student WHERE Sno = 21301114; 63 | SELECT * FROM student ORDER BY Sno Sname Ssex; 64 | 65 | SELECT Sno Sname Ssex Sbirthday Totalcredit 66 | FROM student NATURAL JOIN sc NATURAL JOIN teaching NATURAL JOIN course 67 | WHERE Sno = 1 Sname = YXH_XianYu Ssex = Female 68 | ORDER BY Totalcredit Sno Sname Ssex; 69 | 70 | SELECT Sno Sname Ssex Sbirthday Totalcredit 71 | FROM student NATURAL JOIN sc NATURAL JOIN teaching NATURAL JOIN course 72 | WHERE Sno = 1 Sname = ShirahaneSuoh Ssex = Female 73 | ORDER BY Totalcredit Sno Sname Ssex; 74 | ``` 75 | 76 | ```sql 77 | SHOW DATABASES; 78 | USE bjtu; 79 | SHOW TABLES; 80 | DESC TABLE student; 81 | 82 | ALTER TABLE student ADD Createby string; 83 | DESC TABLE student; 84 | ALTER TABLE student MODIFY Createby int; 85 | DESC TABLE student; 86 | ALTER TABLE student DROP Createby; 87 | DESC TABLE student; 88 | 89 | SELECT * FROM student; 90 | UPDATE student SET Ssex = female; 91 | SELECT * FROM student; 92 | ``` 93 | 94 | -------------------------------------------------------------------------------- /core/include/user.h: -------------------------------------------------------------------------------- 1 | /** 2 | * author: drj 3 | * 用户类。存储了用户名、权限等。 4 | * 提供了检查权限、授予权限、收回权限等权限相关的接口。 5 | * 用户登录时需在此类检查用户名和密码是否匹配。 6 | */ 7 | #ifndef __USER_H__ 8 | #define __USER_H__ 9 | 10 | #include 11 | #include 12 | #include 13 | #include"constants.h" 14 | 15 | enum authority_number { 16 | //表级权限 17 | SELECT, 18 | DELETE, 19 | INSERT, 20 | UPDATE, 21 | INDEX, 22 | ALTER, 23 | //数据库级权限 24 | CREATE, 25 | DROP, 26 | }; 27 | struct priviledge { 28 | std::string database_name; 29 | std::string table_name; 30 | authority_number number; 31 | //数据库级权限,table_name = "" 32 | }; 33 | 34 | class User { 35 | public: 36 | 37 | private: 38 | 39 | std::vector authorities; 40 | std::string user_name; 41 | std::string user_password; 42 | 43 | public: 44 | User(std::string user_name, std::string user_password, std::vector authorities); 45 | User(std::string user_name, std::string user_password); 46 | //验证密码 47 | int Identify(std::string password); 48 | //获取用户名 49 | std::string GetUserName() const ; 50 | //获取密码 51 | std::string GetUserPassword() const ; 52 | //查询数据库级权限 53 | int CheckAuthority(std::string database_name, authority_number number) const; 54 | //查询表级权限 55 | int CheckAuthority(std::string database_name, std::string table_name, authority_number number) const; 56 | //添加数据库级权限 57 | int GrantAuthority(std::string database_name, authority_number number) ; 58 | //添加表级权限 59 | int GrantAuthority(std::string database_name, std::string table_name, authority_number number) ; 60 | //删除数据库级权限 61 | int RevokeAuthority(std::string database_name, authority_number number) ; 62 | //删除表级权限 63 | int RevokeAuthority(std::string database_name, std::string table_name, authority_number number) ; 64 | int GrantAllTableAuthorities(std::string database_name, std::string table_name); 65 | int GrantAllDatabaseAuthorities(std::string database_name); 66 | int RevokeAllTableAuthorities(std::string database_name, std::string table_name); 67 | int RevokeAllDatabaseAuthorities(std::string database_name); 68 | int RevokeAllDatabaseAndTableAuthorities(std::string database_name); 69 | int CheckDatabaseInAuthorities(std::string database_name); 70 | int CheckTableInAuthorities(std::string database_name, std::string table_name); 71 | //获取权限 72 | std::vector GetAuthorities() const ; 73 | 74 | }; 75 | 76 | #endif // __USER_H__ 77 | -------------------------------------------------------------------------------- /core/include/constants.h: -------------------------------------------------------------------------------- 1 | /** 2 | * author: drj 3 | * 常量类,存储了所有常量,包括错误代码常量、数据比较结果常量等等。 4 | */ 5 | 6 | #ifndef CONSTANTS_H 7 | #define CONSTANTS_H 8 | 9 | const int kSuccess = 0; 10 | const int kUserNameExisted = 1; 11 | const int kUserNameNotFound = 2; 12 | const int kUserPasswordError = 3; 13 | const int kUserNotLogin = 4; 14 | const int kDatabaseNotFound = 5; 15 | const int kDatabaseExisted = 6; 16 | const int kTableNameExisted = 7; 17 | const int kConstraintConflict = 8; 18 | 19 | 20 | const int kFieldNotFound = 9; 21 | const int kDataTypeWrong = 10; 22 | const int kEqualConditon = 11; 23 | const int kLargerConditon = 12; 24 | const int kLessCondition = 13; 25 | const int kLargerEqualCondition = 14; 26 | const int kLessEqualConditon = 15; 27 | const int kNotEqualConditon =16; 28 | 29 | const int kTableNotFound = 17; 30 | const int kConditionsNotSatisfied = 18; 31 | const int kNotSameType = 19; 32 | const int kLarger = 1; 33 | const int kEqual = 0; 34 | const int kLess = -1; 35 | 36 | const int kIdentifiedFail = 24; 37 | const int kDatabaseNotUse = 25; 38 | 39 | const int kErrorCurrentUser = 26; 40 | const int kErrorCurrentDatabase = 27; 41 | const int kSizeNotProper = 28; 42 | 43 | const int kInsufficientAuthority = 29; 44 | const int kAuthorityNotFound = 30; 45 | const int kAuthorityExisted = 31; 46 | const int kConstraintNotNullConflict = 32; 47 | const int kConstraintUniqueConflict = 33; 48 | const int kConstraintPrimaryKeyConflict = 34; 49 | const int kConstraintForeignKeyConflict = 35; 50 | const int kImpossibleSituation = 36; 51 | const int kBeingRefered = 37; 52 | const int kConstraintDefaultConflict = 38; 53 | const int kAuthorityNotProper = 39; 54 | const int kReferenceTableNotFound = 40; 55 | const int kFieldExisted = 41; 56 | const int kPrimaryKeyExcessive = 42; 57 | const int kConstraintNameExisted = 43; 58 | const int kConstraintNotFound = 44; 59 | 60 | const int kPrimaryKeyEmpty = 45; 61 | const int kPrimaryKeyRepeated = 46; 62 | const int kNotNullEmpty = 47; 63 | const int kUniqueRepeated = 48; 64 | const int kFieldValueNotFound = 49; 65 | 66 | // ===== About Index ===== 67 | const int kUnknownIndex = 100; 68 | const int kFHQTreapIndex = 101; 69 | 70 | const int kFailedConditionRelationNotSupport = 110; 71 | const int kFailedConditionDuplicate = 111; 72 | const int kFailedIndexCouldnotSpeedup = 112; 73 | const int kFailedIndexNotBuild = 113; 74 | 75 | 76 | // ===== About Constraints ===== 77 | const int kPrimaryKey = 150; 78 | const int kForeignKey = 151; 79 | const int kForeignRefered = 152; 80 | const int kUnique = 153; 81 | const int kNotNull = 154; 82 | const int kDefault = 155; 83 | 84 | // ===== File ===== 85 | const int kClearDataFailed = 170; 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /core/include/index/fhqtreapindex.h: -------------------------------------------------------------------------------- 1 | #ifndef __FHQTREAPINDEX_H__ 2 | #define __FHQTREAPINDEX_H__ 3 | 4 | #include 5 | 6 | /** 7 | * 索引基类 8 | */ 9 | class FHQTreapIndex: public Index { 10 | public: 11 | /** 12 | * Construct an Index 13 | * compare_key is the keys of Index 14 | */ 15 | FHQTreapIndex(const std::vector>& records, 16 | const std::vector>& fields, 17 | const std::unordered_map& field_map, 18 | const std::vector& compare_key); 19 | 20 | /** 21 | * Destructor an Index 22 | */ 23 | virtual ~FHQTreapIndex(); 24 | 25 | /** 26 | * build an index (rebuild) 27 | */ 28 | virtual int build(const std::vector>& records, 29 | const std::vector>& fields, 30 | const std::unordered_map& field_map, 31 | const std::vector& compare_key); 32 | 33 | /** 34 | * query on index 35 | * @return if return value isn't zero, then result is invalid! 36 | */ 37 | virtual int query(const std::vector>& conditions, 38 | std::vector& result_indexes); 39 | 40 | private: 41 | // ===== FHQ Treap Core ===== 42 | 43 | struct Node { 44 | int c[2], siz, pos, va; 45 | }; 46 | 47 | std::vector t; 48 | int rt, tot; 49 | 50 | // basic operations 51 | void reset(); 52 | 53 | void pushup(int x); 54 | int newNode(int va); 55 | 56 | void splits(int x, int siz, int &l, int &r); 57 | void splitv(int x, int va, int &l, int &r, bool nullIsLess = true); // 将与va相等的值归类至L 58 | void splitv(int x, const std::unordered_map& va, int &l, int &r, bool nullIsLess = true); // 将与va相等的值归类至L 59 | void splitvR(int x, int va, int &l, int &r, bool nullIsLess = true); // 将与va相等的值归类至R 60 | void splitvR(int x, const std::unordered_map& va, int &l, int &r, bool nullIsLess = true);// 将与va相等的值归类至R 61 | int merge(int l, int r); 62 | 63 | void output(int x, std::vector& result); // 将以x为根的子树的所有va存入result 64 | 65 | // operations 66 | void insert(int va); 67 | void erase(int va); 68 | int getRank(int va); 69 | int getNumber(int siz); 70 | int getLower(int va); 71 | int getUpper(int va); 72 | }; 73 | 74 | #endif // __FHQTREAPINDEX_H__ 75 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/ui/ui_login.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ui_login 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | 15 | 400 16 | 300 17 | 18 | 19 | 20 | 21 | 400 22 | 300 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | #centralwidget{border-image: url(:/images/login/login-bg.png)} 31 | 32 | 33 | 34 | 35 | 36 | 162 37 | 202 38 | 77 39 | 29 40 | 41 | 42 | 43 | QPushButton#pushButton_login{border-image: url(:/images/login/btn-login-1.png)} 44 | QPushButton::pressed#pushButton_login{border-image: url(:/images/login/btn-login-2.png)} 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 162 54 | 238 55 | 77 56 | 29 57 | 58 | 59 | 60 | QPushButton#pushButton_regist{border-image: url(:/images/login/btn-register-1.png)} 61 | QPushButton::pressed#pushButton_regist{border-image: url(:/images/login/btn-register-2.png)} 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 180 72 | 121 73 | 100 74 | 26 75 | 76 | 77 | 78 | 79 | 80 | 81 | 180 82 | 157 83 | 100 84 | 26 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/src/columndialog.cpp: -------------------------------------------------------------------------------- 1 | #include "columndialog.h" 2 | 3 | ColumnDialog::ColumnDialog(QWidget* parent) : QDialog(parent) 4 | { 5 | lineEdit4 = new QLineEdit(this); 6 | lineEdit1 = new QLineEdit(this); 7 | lineEdit2 = new QLineEdit(this); 8 | int font_Id = 9 | QFontDatabase::addApplicationFont(":/font/FiraCode-Regular-1.ttf"); 10 | QStringList font_list = QFontDatabase::applicationFontFamilies(font_Id); 11 | if (!font_list.isEmpty()) 12 | { 13 | QFont f; 14 | f.setFamily(font_list[0]); 15 | f.setPointSize(9); 16 | lineEdit1->setFont(f); 17 | lineEdit2->setFont(f); 18 | lineEdit4->setFont(f); 19 | } 20 | // 创建三个QLineEdit输入框,并将它们添加到布局中 21 | QVBoxLayout* layout = new QVBoxLayout(this); 22 | QHBoxLayout* hLayout = new QHBoxLayout(); 23 | QLabel* label = new QLabel("插入数据库:", this); 24 | hLayout->addWidget(label); 25 | hLayout->addWidget(lineEdit4); 26 | layout->addLayout(hLayout); 27 | 28 | QHBoxLayout* hLayout1 = new QHBoxLayout(); 29 | QLabel* label1 = new QLabel("插入表:", this); 30 | hLayout1->addWidget(label1); 31 | hLayout1->addWidget(lineEdit1); 32 | layout->addLayout(hLayout1); 33 | 34 | QHBoxLayout* hLayout2 = new QHBoxLayout(); 35 | QLabel* label2 = new QLabel("字段名:", this); 36 | hLayout2->addWidget(label2); 37 | hLayout2->addWidget(lineEdit2); 38 | layout->addLayout(hLayout2); 39 | 40 | QHBoxLayout* hLayout3 = new QHBoxLayout(); 41 | QLabel* label3 = new QLabel("类型:", this); 42 | // lineEdit3 = new QLineEdit(this); 43 | comboBox = new QComboBox(this); 44 | comboBox->addItem("INT"); 45 | comboBox->addItem("FLOAT"); 46 | comboBox->addItem("STRING"); 47 | hLayout3->addWidget(label3); 48 | hLayout3->addWidget(comboBox); 49 | layout->addLayout(hLayout3); 50 | 51 | // 添加两个按钮:确认和返回 52 | QDialogButtonBox* buttonBox = new QDialogButtonBox(this); 53 | okButton = buttonBox->addButton("OK", QDialogButtonBox::AcceptRole); 54 | cancelButton = buttonBox->addButton("Cancel", QDialogButtonBox::RejectRole); 55 | layout->addWidget(buttonBox); 56 | 57 | // 连接确认按钮的信号和槽函数 58 | connect(okButton, &QPushButton::clicked, this, &ColumnDialog::acceptValues); 59 | connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject); 60 | // 设置窗口标题和大小 61 | setWindowTitle("输入"); 62 | QIcon icon = QIcon(":/images/Colasql.png"); 63 | setWindowIcon(icon); 64 | resize(300, 150); 65 | } 66 | // 返回输入框内容的函数 67 | QStringList ColumnDialog::getValues() 68 | { 69 | QStringList values; 70 | values << lineEdit1->text() << lineEdit2->text() << lineEdit3->text(); 71 | return values; 72 | } 73 | 74 | // 确认按钮的槽函数 75 | void ColumnDialog::acceptValues() { accept(); } 76 | -------------------------------------------------------------------------------- /core/src/constraint/constraint_test.cpp.txt: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "all_constraints.h" 6 | 7 | int main() { 8 | 9 | std::vector constraints; 10 | 11 | constraints.push_back(new PrimaryKeyConstraint("FieldName")); 12 | constraints.push_back(new ForeignKeyConstraint("FieldName", "ReferenceTableName", "ReferenceFieldName")); 13 | constraints.push_back(new NotNullConstraint("FieldName")); 14 | constraints.push_back(new UniqueConstraint("FieldName")); 15 | constraints.push_back(new DefaultConstraint("FieldName", 1)); 16 | constraints.push_back(new DefaultConstraint("FieldName", 1.0f)); 17 | constraints.push_back(new DefaultConstraint("FieldName", std::string("value"))); 18 | constraints.push_back(new DefaultConstraint("FieldName", std::string("1234567890qwertyuiopasdfghjklzxcvbnm"))); 19 | 20 | for(auto &it: constraints) { 21 | if(dynamic_cast(it) != nullptr) { 22 | PrimaryKeyConstraint* p = dynamic_cast(it); 23 | 24 | std::cout << "Primary Key: " << p->GetFieldName() << std::endl; 25 | } else if(dynamic_cast(it) != nullptr) { 26 | ForeignKeyConstraint* p = dynamic_cast(it); 27 | 28 | std::cout << "Foreign Key: " << p->GetFieldName() << " Reference " << p->GetRefenrenceTableName() << "." << p->GetReferenceFieldName() << std::endl; 29 | } else if(dynamic_cast(it) != nullptr) { 30 | NotNullConstraint* p = dynamic_cast(it); 31 | 32 | std::cout << "Not Null: " << p->GetFieldName() << std::endl; 33 | } else if(dynamic_cast(it) != nullptr) { 34 | UniqueConstraint* p = dynamic_cast(it); 35 | 36 | std::cout << "Unique: " << p->GetFieldName() << std::endl; 37 | } else if(dynamic_cast(it) != nullptr) { 38 | DefaultConstraint* p = dynamic_cast(it); 39 | 40 | if(p->GetValue().type() == typeid(int)) 41 | std::cout << "Default: " << p->GetFieldName() << " = " << std::any_cast(p->GetValue()) << std::endl; 42 | else if(p->GetValue().type() == typeid(float)) 43 | std::cout << "Default: " << p->GetFieldName() << " = " << std::any_cast(p->GetValue()) << std::endl; 44 | else if(p->GetValue().type() == typeid(std::string)) 45 | std::cout << "Default: " << p->GetFieldName() << " = " << std::any_cast(p->GetValue()) << std::endl; 46 | else 47 | std::cout << "Default: " << p->GetFieldName() << "; Unknown Type " << p->GetValue().type().name() << std::endl; 48 | } else { 49 | std::cout << "Unknown Constraint." << std::endl; 50 | } 51 | } 52 | 53 | return 0; 54 | } -------------------------------------------------------------------------------- /gui/ColaSqlGui/ui/ui_register.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ui_register 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | 15 | 400 16 | 300 17 | 18 | 19 | 20 | 21 | 400 22 | 300 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | #centralwidget{border-image: url(:/images/register/register-bg.png)} 31 | 32 | 33 | 34 | 35 | 162 36 | 183 37 | 77 38 | 29 39 | 40 | 41 | 42 | QPushButton#pushButton_regist{border-image: url(:/images/register/reg-1.png)} 43 | QPushButton::pressed#pushButton_regist{border-image: url(:/images/register/reg-2.png)} 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 162 53 | 219 54 | 77 55 | 29 56 | 57 | 58 | 59 | QPushButton#pushButton_back{border-image: url(:/images/register/back-1.png)} 60 | QPushButton::pressed#pushButton_back{border-image: url(:/images/register/back-2.png)} 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 178 70 | 65 71 | 100 72 | 26 73 | 74 | 75 | 76 | 77 | 78 | 79 | 178 80 | 101 81 | 100 82 | 26 83 | 84 | 85 | 86 | 87 | 88 | 89 | 178 90 | 137 91 | 100 92 | 26 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/ColaSqlGui.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | QT += sql 3 | 4 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 5 | 6 | CONFIG += c++17 7 | 8 | LIBS += -lstdc++fs 9 | 10 | # The following define makes your compiler emit warnings if you use 11 | # any Qt feature that has been marked deprecated (the exact warnings 12 | # depend on your compiler). Please consult the documentation of the 13 | # deprecated API in order to know how to port your code away from it. 14 | DEFINES += QT_DEPRECATED_WARNINGS 15 | 16 | # You can also make your code fail to compile if it uses deprecated APIs. 17 | # In order to do so, uncomment the following line. 18 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 19 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 20 | 21 | SOURCES += \ 22 | $${PWD}/../../cmd/src/command_processor.cpp \ 23 | $${PWD}/../../cmd/src/my_parser.cpp \ 24 | $${PWD}/../../core/src/colasqltool.cpp \ 25 | $${PWD}/../../core/src/database.cpp \ 26 | $${PWD}/../../core/src/dataprocessor.cpp \ 27 | $${PWD}/../../core/src/table.cpp \ 28 | $${PWD}/../../core/src/user.cpp \ 29 | $${PWD}/../../core/src/constraint/constraint.cpp \ 30 | $${PWD}/../../core/src/constraint/default_constraint.cpp \ 31 | $${PWD}/../../core/src/constraint/foreign_key_constraint.cpp \ 32 | $${PWD}/../../core/src/constraint/foreign_refered_constraint.cpp \ 33 | $${PWD}/../../core/src/constraint/not_null_constraint.cpp \ 34 | $${PWD}/../../core/src/constraint/primary_key_constraint.cpp \ 35 | $${PWD}/../../core/src/constraint/unique_constraint.cpp \ 36 | $${PWD}/../../core/src/index/fhqtreapindex.cpp \ 37 | $${PWD}/../../core/src/index/index.cpp \ 38 | ../../file/src/filemanager.cpp \ 39 | # ./src/*.cpp 40 | ./src/createindex.cpp \ 41 | ./src/createrecord.cpp \ 42 | ./src/createtable.cpp \ 43 | ./src/mainwindow.cpp \ 44 | ./src/ui_login.cpp \ 45 | ./src/ui_register.cpp \ 46 | ./src/columndialog.cpp \ 47 | ./src/main.cpp 48 | 49 | HEADERS += \ 50 | # ./include/*.h \ 51 | ./include/columndialog.h \ 52 | ./include/createindex.h \ 53 | ./include/createrecord.h \ 54 | ./include/createtable.h \ 55 | ./include/mainwindow.h \ 56 | ./include/qtbstreambuf.h \ 57 | ./include/ui_login.h \ 58 | ./include/ui_register.h 59 | 60 | FORMS += \ 61 | # ./ui/*.h 62 | ./ui/createindex.ui \ 63 | ./ui/createrecord.ui \ 64 | ./ui/createtable.ui \ 65 | ./ui/mainwindow.ui \ 66 | ./ui/ui_login.ui \ 67 | ./ui/ui_register.ui \ 68 | ./ui/secondarywindow.ui 69 | 70 | # Default rules for deployment. 71 | qnx: target.path = /tmp/$${TARGET}/bin 72 | else: unix:!android: target.path = /opt/$${TARGET}/bin 73 | !isEmpty(target.path): INSTALLS += target 74 | 75 | INCLUDEPATH +=$$quote("../../cmd/include") 76 | INCLUDEPATH +=$$quote("../../core/include") 77 | INCLUDEPATH +=$$quote("../../core/include/constraint") 78 | INCLUDEPATH +=$$quote("../../core/include/index") 79 | INCLUDEPATH +=$$quote("../../file/include/") 80 | INCLUDEPATH +=$$quote("./include") 81 | 82 | RESOURCES += \ 83 | resource/res.qrc 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/src/createindex.cpp: -------------------------------------------------------------------------------- 1 | #include "createindex.h" 2 | 3 | #include "ui_createindex.h" 4 | 5 | createindex::createindex(std::vector> return_records, 6 | const QString& tbName, QWidget* parent) 7 | : QMainWindow(parent), ui(new Ui::createindex) 8 | { 9 | ui->setupUi(this); 10 | QIcon icon = QIcon(":/images/Colasql.png"); 11 | this->setWindowIcon(icon); 12 | // tableview设置stylesheet有bug 13 | ui->tableView->setStyleSheet("border-style:outset"); 14 | records = return_records; 15 | table = tbName; 16 | display_table(records); 17 | int font_Id = 18 | QFontDatabase::addApplicationFont(":/font/FiraCode-Regular-1.ttf"); 19 | QStringList font_list = QFontDatabase::applicationFontFamilies(font_Id); 20 | if (!font_list.isEmpty()) 21 | { 22 | qDebug() << "add font"; 23 | QFont f; 24 | f.setFamily(font_list[0]); 25 | f.setPointSize(9); 26 | ui->tableView->setFont(f); 27 | } 28 | } 29 | 30 | createindex::~createindex() { delete ui; } 31 | 32 | QString createindex::anyToQString(const std::any& value) 33 | { 34 | QString result; 35 | if (value.type() == typeid(std::string)) 36 | { 37 | result = QString::fromStdString(std::any_cast(value)); 38 | } 39 | else if (value.type() == typeid(int)) 40 | { 41 | result = QString::number(std::any_cast(value)); 42 | } 43 | else if (value.type() == typeid(double)) 44 | { 45 | result = QString::number(std::any_cast(value)); 46 | } 47 | return result; 48 | } 49 | 50 | void createindex::display_table( 51 | std::vector>& return_records) 52 | { 53 | // display table on tableview 54 | std::vector fields = return_records[0]; 55 | QStandardItemModel* model = new QStandardItemModel(); 56 | model->setColumnCount(fields.size()); 57 | for (size_t i = 0; i < fields.size(); ++i) 58 | { 59 | model->setHeaderData(i, Qt::Horizontal, anyToQString(fields[i])); 60 | } 61 | QList items; 62 | // add row 63 | for (size_t i = 0; i < fields.size(); ++i) 64 | { 65 | items.append(new QStandardItem("-")); 66 | } 67 | model->appendRow(items); 68 | ui->tableView->setModel(model); 69 | } 70 | 71 | void createindex::on_btn_cancel_clicked() { this->close(); } 72 | 73 | void createindex::on_btn_finish_clicked() 74 | { 75 | QString fields; 76 | QString opt; 77 | QStandardItemModel* model = 78 | qobject_cast(ui->tableView->model()); 79 | if (model) 80 | { 81 | int cols = model->columnCount(); 82 | for (int i = 0; i < cols; ++i) 83 | { 84 | QString new_data = model->data(model->index(0, i)).toString(); 85 | if (new_data == "*") 86 | { 87 | fields += anyToQString(records[0][i]) + " "; 88 | } 89 | } 90 | qDebug() << fields; 91 | opt = "CREATE INDEX ON " + table + " "; 92 | opt += fields; 93 | opt += ";"; 94 | qDebug() << opt; 95 | emit create_index_signal(opt); 96 | this->close(); 97 | } 98 | else 99 | { 100 | qDebug() << "Failed to get the model"; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/src/createrecord.cpp: -------------------------------------------------------------------------------- 1 | #include "createrecord.h" 2 | 3 | #include "ui_createrecord.h" 4 | 5 | createrecord::createrecord(std::vector> return_records, 6 | const QString& tbName, QWidget* parent) 7 | : QMainWindow(parent), ui(new Ui::createrecord) 8 | { 9 | ui->setupUi(this); 10 | QIcon icon = QIcon(":/images/Colasql.png"); 11 | this->setWindowIcon(icon); 12 | ui->tableView->setStyleSheet("border-style:outset"); 13 | records = return_records; 14 | table = tbName; 15 | display_table(records); 16 | 17 | int font_Id = 18 | QFontDatabase::addApplicationFont(":/font/FiraCode-Regular-1.ttf"); 19 | QStringList font_list = QFontDatabase::applicationFontFamilies(font_Id); 20 | if (!font_list.isEmpty()) 21 | { 22 | QFont f; 23 | f.setFamily(font_list[0]); 24 | f.setPointSize(9); 25 | ui->tableView->setFont(f); 26 | } 27 | } 28 | 29 | createrecord::~createrecord() { delete ui; } 30 | 31 | QString createrecord::anyToQString(const std::any& value) 32 | { 33 | QString result; 34 | if (value.type() == typeid(std::string)) 35 | { 36 | result = QString::fromStdString(std::any_cast(value)); 37 | } 38 | else if (value.type() == typeid(int)) 39 | { 40 | result = QString::number(std::any_cast(value)); 41 | } 42 | else if (value.type() == typeid(double)) 43 | { 44 | result = QString::number(std::any_cast(value)); 45 | } 46 | return result; 47 | } 48 | 49 | void createrecord::display_table( 50 | std::vector>& return_records) 51 | { 52 | // display table on tableview 53 | std::vector fields = return_records[0]; 54 | QStandardItemModel* model = new QStandardItemModel(); 55 | model->setColumnCount(fields.size()); 56 | for (size_t i = 0; i < fields.size(); ++i) 57 | { 58 | model->setHeaderData(i, Qt::Horizontal, anyToQString(fields[i])); 59 | } 60 | QList items; 61 | // add row 62 | for (size_t i = 0; i < fields.size(); ++i) 63 | { 64 | items.append(new QStandardItem()); 65 | } 66 | model->appendRow(items); 67 | ui->tableView->setModel(model); 68 | } 69 | 70 | void createrecord::on_btn_cancel_clicked() { this->close(); } 71 | 72 | void createrecord::on_btn_finish_clicked() 73 | { 74 | QString fields; 75 | QString values; 76 | QString opt; 77 | QStandardItemModel* model = 78 | qobject_cast(ui->tableView->model()); 79 | if (model) 80 | { 81 | int cols = model->columnCount(); 82 | for (int i = 0; i < cols; ++i) 83 | { 84 | QString new_data = model->data(model->index(0, i)).toString(); 85 | if (new_data != "") 86 | { 87 | fields += anyToQString(records[0][i]) + " "; 88 | values += new_data + " "; 89 | } 90 | } 91 | qDebug() << fields; 92 | qDebug() << values; 93 | opt = "INSERT INTO " + table + " "; 94 | opt += fields; 95 | opt += "VALUES "; 96 | opt += values; 97 | opt += ";"; 98 | qDebug() << opt; 99 | emit create_record_signal(opt); 100 | this->close(); 101 | } 102 | else 103 | { 104 | qDebug() << "Failed to get the model"; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /core/include/database.h: -------------------------------------------------------------------------------- 1 | /** 2 | * author: drj 3 | * 数据库类,存储了该数据库里的所有表。 4 | * 由dataprocessor调用,对数据库或表进行操作。 5 | * 接口运行正确时返回kSuccess 6 | * 否则返回./constrants.h里的错误代码 7 | */ 8 | 9 | #ifndef DATABASE_H 10 | #define DATABASE_H 11 | 12 | #include 13 | #include 14 | 15 | #include "table.h" 16 | #include "constants.h" 17 | 18 | class Database { 19 | private: 20 | std::string owner_user; 21 | std::string database_name; 22 | std::vector
tables; 23 | private: 24 | Database(); 25 | public: 26 | Database(std::string database_name, std::string owner_user); 27 | 28 | const std::string& GetOwnerUserName() const; 29 | const std::string& GetDatabaseName() const; 30 | const std::vector
& GetTables() const; 31 | void SetTables(const std::vector
&); 32 | 33 | int FindTable(std::string table_name); 34 | int FindTable(std::string table_name, Table& return_table); 35 | int FindField(std::string table_name, std::string field_name); 36 | int FindField(std::string table_name, std::string field_name, std::any); 37 | Table& FindTableReference(std::string table_name); 38 | int ShowTables(std::vector& return_tables); 39 | int CreateTable(std::string table_name, std::vector> fields, std::vector constraints); 40 | int DropTable(std::string table_name); 41 | int Insert(std::string table_name, std::vector> record_in); 42 | 43 | int Select(std::string table_name, 44 | std::vector field_name, 45 | std::vector> conditions, 46 | std::vector> &return_records, 47 | const std::vector& orderby_key = std::vector()); 48 | int Select(std::vector table_names, 49 | std::vector field_name, 50 | std::vector> conditions, 51 | std::vector>& return_records, 52 | const std::vector& orderby_key = std::vector()); 53 | 54 | int Delete(std::string table_name, std::vector> conditions); 55 | 56 | int Update(std::string table_name, const std::vector>& values, const std::vector>& conditions); 57 | int CheckCondition(const std::unordered_map& record, 58 | const std::vector>& conditions, std::unordered_map field_map); 59 | 60 | int DescribeTable(std::string table_name,std::vector>& fields,std::vector& constraints); 61 | int AlterTableAdd(std::string table_name, std::pair field); 62 | int AlterTableDrop(std::string table_name, std::string field_name); 63 | int AlterTableModify(std::string table_name, std::pair field); 64 | int AlterTableConstraint(std::string table_name, Constraint* constraint); 65 | // 建立索引 66 | int BuildIndex(std::string table_name, const std::vector& compare_key); 67 | 68 | int AlterTableDeleteConstraint(std::string table_name, std::string constraint_name); 69 | int CheckUnique(std::string table_name, std::string field_name); 70 | 71 | }; 72 | 73 | 74 | #endif // DATABASE_H 75 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/src/ui_register.cpp: -------------------------------------------------------------------------------- 1 | #include "ui_register.h" 2 | 3 | #include 4 | 5 | #include "ui_ui_register.h" 6 | 7 | ui_register::ui_register(QWidget* parent) 8 | : QMainWindow(parent), ui(new Ui::ui_register) 9 | { 10 | ui->setupUi(this); 11 | setWindowTitle("Register"); 12 | QIcon icon = QIcon(":/images/Colasql.png"); 13 | this->setWindowIcon(icon); 14 | ui->lineEdit_password1->setEchoMode(QLineEdit::Password); 15 | ui->lineEdit_password2->setEchoMode(QLineEdit::Password); 16 | ui->lineEdit_account->setStyleSheet( 17 | "background:transparent;border-width:0;border-style:outset"); 18 | ui->lineEdit_password1->setStyleSheet( 19 | "background:transparent;border-width:0;border-style:outset"); 20 | ui->lineEdit_password2->setStyleSheet( 21 | "background:transparent;border-width:0;border-style:outset"); 22 | 23 | int font_Id = 24 | QFontDatabase::addApplicationFont(":/font/FiraCode-Regular-1.ttf"); 25 | QStringList font_list = QFontDatabase::applicationFontFamilies(font_Id); 26 | if (!font_list.isEmpty()) 27 | { 28 | QFont f; 29 | f.setFamily(font_list[0]); 30 | f.setPointSize(9); 31 | ui->lineEdit_account->setFont(f); 32 | } 33 | } 34 | 35 | ui_register::~ui_register() { delete ui; } 36 | 37 | void ui_register::on_pushButton_back_clicked() 38 | { 39 | emit back(); 40 | clear(); 41 | this->close(); 42 | } 43 | 44 | void ui_register::clear() 45 | { 46 | ui->lineEdit_account->setText(""); 47 | ui->lineEdit_password2->setText(""); 48 | ui->lineEdit_password1->setText(""); 49 | } 50 | 51 | void ui_register::on_pushButton_regist_clicked() 52 | { 53 | // if passwords are same then register an account 54 | // todo 55 | user_name = ui->lineEdit_account->text(); 56 | user_pwd1 = ui->lineEdit_password1->text(); 57 | user_pwd2 = ui->lineEdit_password2->text(); 58 | if (user_name == "" || user_pwd1 == "" || user_pwd2 == "") 59 | { 60 | QMessageBox::warning(this, "错误", "用户名、密码不能为空!"); 61 | return; 62 | } 63 | if (user_pwd1 == user_pwd2) 64 | { 65 | int ret = DataProcessor::GetInstance().CreateUser( 66 | user_name.toStdString(), user_pwd1.toStdString()); 67 | if (ret == kSuccess) 68 | { 69 | User user(user_name.toStdString(), user_pwd1.toStdString()); 70 | std::vector users; 71 | int get_ret = FileManager::GetInstance().ReadUsersFile(users); 72 | if (get_ret != kSuccess) 73 | { 74 | qDebug() << "get users error" + QString::number(get_ret); 75 | // assert(false); 76 | } 77 | users.push_back(user); 78 | get_ret = FileManager::GetInstance().WriteUsersFile(users); 79 | if (get_ret != kSuccess) 80 | { 81 | qDebug() << "write users error" + QString::number(get_ret); 82 | assert(false); 83 | } 84 | QMessageBox::information(this, "欢迎", "用户注册成功"); 85 | emit back(); 86 | this->close(); 87 | } 88 | else if (ret == kUserNameExisted) 89 | QMessageBox::warning(this, "错误", "用户已存在"); 90 | else 91 | { 92 | qDebug() << "i dont know!fk urself!"; 93 | assert(false); 94 | } 95 | } 96 | else 97 | { 98 | QMessageBox::warning(this, "错误", "两次密码不同"); 99 | } 100 | clear(); 101 | } 102 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/include/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "columndialog.h" 22 | #include "command_processor.h" 23 | #include "createindex.h" 24 | #include "createrecord.h" 25 | #include "createtable.h" 26 | #include "dataprocessor.h" 27 | #include "qtbstreambuf.h" 28 | 29 | QT_BEGIN_NAMESPACE 30 | namespace Ui 31 | { 32 | class MainWindow; 33 | } 34 | QT_END_NAMESPACE 35 | 36 | class MainWindow : public QMainWindow 37 | { 38 | Q_OBJECT 39 | 40 | public: 41 | MainWindow(QWidget* parent = nullptr); 42 | ~MainWindow(); 43 | 44 | private: 45 | // 辅助功能 46 | QString anyToQString(const std::any& value); // any转QString 47 | std::string anytoString(const std::any& value); // any转string 48 | int use_database(std::string database); // 使用数据库 49 | int select_all_from_table(std::string tbName, 50 | std::vector>& 51 | return_records); // select * from table 52 | void display_table( 53 | std::vector>& return_records); // 展示查询结果 54 | 55 | void cancel_change(); // 取消单点修改 56 | void save_change(); // 保存单点修改 57 | 58 | private slots: 59 | // 点击事件 60 | void click_create_database(); // 创建库 61 | void click_create_table(); // 创建表 62 | void click_create_field(); // 创建字段 63 | void click_create_record(); // 创建记录 64 | void click_create_index(); // 新建索引 65 | void click_delete_db(); // 删除数据库 66 | void click_delete_tb(); // 删除表 67 | void click_delete_field(); // 删除字段 68 | void click_delete_record(); // 删除记录 69 | void click_save(); // 保存文件 70 | void click_complex_select(); // 复杂查询 71 | void click_read_sql(); // 执行.sql文件 72 | void click_change_user(); // 切换用户 73 | void on_btn_commit_clicked(); // commit 74 | void on_btn_rollback_clicked(); // rollback 75 | 76 | // 实现功能 77 | void refresh(); // 刷新 78 | void create_table(QString, QString); // 创建表 79 | void create_record(QString); // 创建一条记录 80 | void create_index(QString); // 创建索引 81 | void handleTableModified(); // 点击修改某一记录 82 | 83 | // 树形结构 84 | void init_treeview(); // 初始化树形结构 85 | void on_treeView_doubleClicked(const QModelIndex& index); // 双击树形结构 86 | 87 | // override命令行回车键 88 | void onEnterPressed(); 89 | 90 | protected: 91 | // override事件过滤器 92 | bool eventFilter(QObject* watched, QEvent* event) override; 93 | 94 | private: 95 | // 界面 96 | Ui::MainWindow* ui; // this 97 | ui_login* ui_log; // 登录界面 98 | createtable* ui_create_table; // 新建表界面 99 | createrecord* ui_create_record; // 新建记录界面 100 | createindex* ui_create_index; // 新建索引界面 101 | 102 | // Co1aSQL! 103 | QString prefix = "Co1aSQL @ "; 104 | 105 | QFont f; // fira-code 106 | 107 | // 状态 108 | std::string current_database = ""; // 当前选用的数据库 109 | std::string current_table = ""; // 当前查询表 110 | bool multiple_select = 0; // 是否是多表查询 111 | }; 112 | #endif // MAINWINDOW_H 113 | -------------------------------------------------------------------------------- /cmd/include/my_parser.h: -------------------------------------------------------------------------------- 1 | #ifndef __MY_PARSER_H__ 2 | #define __MY_PARSER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // cmd 11 | #include "all_constraints.h" 12 | #include "colasqltool.h" 13 | 14 | // core 15 | #include "dataprocessor.h" 16 | #include "constants.h" 17 | 18 | namespace ColaSQLCommand { 19 | 20 | /** 21 | * A Co1aSQL Parser 22 | * 读入一句Co1aSQL语句,将其解析成一段core模块的接口调用 23 | */ 24 | class Parser { 25 | public: 26 | /** 27 | * 构造函数 28 | */ 29 | Parser(); 30 | 31 | /** 32 | * Parse一条SQL语句 33 | */ 34 | std::string Parse(const std::vector& seq); 35 | 36 | /** 37 | * Parser一条Select语句,并以vector的方法返回结果,而非打印进stdout 38 | */ 39 | std::string ParseSelect(const std::vector& seq, std::vector>& result); 40 | 41 | /** 42 | * DEBUG参数 43 | */ 44 | const bool DEBUG = false; 45 | 46 | const std::string success = "Success!"; 47 | const std::string error = "Error: "; 48 | const std::string statementIncomplete = "Statement is incomplete."; 49 | const std::string statementError = "Statement has errors."; 50 | const std::string statementRedundant = "Statment has redundant parts."; 51 | 52 | private: 53 | 54 | std::string CreateUser(const std::vector& seq); // 创建用户 55 | std::string GrantUser(const std::vector& seq); // 授予用户权限 56 | std::string RevokeUser(const std::vector& seq); // 收回用户权限 57 | std::string DeleteUser(const std::vector& seq); // 删除用户 58 | std::string Login(const std::vector& seq); // 登陆(切换用户) 59 | 60 | 61 | std::string CreateDatabase(const std::vector& seq);// 创建数据库 62 | std::string DeleteDatabase(const std::vector& seq);// 删除数据库 63 | std::string UseDatabase(const std::vector& seq); // 使用数据库 64 | std::string ShowDatabases(const std::vector& seq); // 显示所有数据库 65 | 66 | std::string CreateTable(const std::vector& seq); // 创建表 67 | std::string DeleteTable(const std::vector& seq); // 删除表 68 | std::string AlterTableAdd(const std::vector& seq); // 修改表(添加一个字段) 69 | std::string AlterTableDrop(const std::vector& seq); // 修改表(删除一个字段) 70 | std::string AlterTableModify(const std::vector& seq); // 修改表(修改一个字段) 71 | std::string AlterTableConstraint(const std::vector& seq); // 修改表(增加一个约束) 72 | std::string AlterTableDeleteConstraint(const std::vector& seq); // 修改表(删除一个约束) 73 | std::string QueryTable(const std::vector& seq); // 描述表结构 74 | std::string ShowTables(const std::vector& seq); // 显示所有表(当前数据库下的) 75 | 76 | std::string InsertRecord(const std::vector& seq); // 插入记录 77 | std::string DeleteRecord(const std::vector& seq); // 删除记录 78 | std::string SelectRecord(const std::vector& seq); // 选择记录 79 | std::string UpdateRecord(const std::vector& seq); // 更新记录 80 | std::string ReturnSelectRecord(const std::vector& seq, std::vector>& result); // 以vector返回result 81 | 82 | std::string BuildIndex(const std::vector& seq); // 构建索引 83 | 84 | std::string ShowConstraints(const std::vector& seq); // 显示所有约束 85 | 86 | std::string Read(bool debug = false); // 读取(Rollback) 87 | std::string Save(); // 存储(Commit) 88 | 89 | std::string GetErrorMessage(int errorCode); // 获取错误信息 90 | 91 | bool PushCondition(std::vector>& conditions, 92 | std::string fieldName, std::string sign, std::string value); // 往conditions中添加一个条件 93 | }; 94 | 95 | } // ColaSQLCommand 96 | 97 | #endif // __MY_PARSER_H__ 98 | -------------------------------------------------------------------------------- /document/FinalDemonstration.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | marp: true 4 | theme: gaia 5 | paginate: true 6 | 7 | --- 8 | 9 | 10 | 11 | # DBMS 演示答辩 12 | 13 | ![w:1152 h:216 Logo](https://raw.githubusercontent.com/YXHXianYu/2023-BJTU-DBMS-Project/main/gui/ColaSqlGui/resource/images/logo.png) 14 | 15 | #### 俞贤皓, 邓人嘉, 付家齐, 谷雅丰 16 | 17 | --- 18 | 19 | # 1. 项目基本介绍 20 | 21 | ## 1.1 项目架构 22 | 23 | - 项目共分为四个模块 24 | - CMD 命令行模块 25 | - CORE 核心模块 26 | - FILE 文件模块 27 | - GUI 图形界面 28 | 29 | --- 30 | 31 | # 1. 项目基本介绍 32 | 33 | ## 1.2 模块架构 34 | 35 | - ![w:619 h:404 ProjectConstruction](./pictures/ProjectConstruction.png) 36 | 37 | --- 38 | 39 | # 1. 项目介绍 40 | 41 | ## 1.3 编译相关 42 | 43 | - gcc 13.1.1 44 | 45 | - cmake 3.26.3 46 | 47 | - qmake 3.1 48 | 49 | - qt 5.15.9 50 | 51 | --- 52 | 53 | # 2. 基本功能展示 54 | 55 | ## 2.1 DDL功能实现 56 | 57 | - 创建数据库 CREATE DATABASE `database_name`; 58 | - 删除数据库 DROP DATABASE `database_name`; 59 | 60 | --- 61 | 62 | # 2. 基本功能展示 63 | 64 | ## 2.1 DDL功能实现 65 | 66 | - 创建数据库 CREATE DATABASE `database_name`; 67 | - 删除数据库 DROP DATABASE `database_name`; 68 | - 创建表 CREATE TABLE ...; 69 | - 添加字段 ALTER TABLE `表名` ADD `列名` `类型名`; 70 | - 删除字段 ALTER TABLE `表名` DROP `列名`; 71 | - 修改字段 ALTER TABLE `表名` MODIFY `列名` `类型名`; 72 | - 删除表 DROP TABLE `表名`; 73 | 74 | --- 75 | 76 | # 2. 基本功能展示 77 | 78 | ## 2.2 DML功能展示 79 | 80 | - 记录插入 INSERT INTO `表名` `列1` `列2` ... VALUES `值1` `值2`; 81 | - 记录删除 DELETE FROM `表名` [WHERE `筛选条件1` `筛选条件2` ...]; 82 | - 记录修改 UPDATE `表名` SET `列1` = `值1` ... [WHERE...]; 83 | 84 | --- 85 | 86 | # 2. 基本功能展示 87 | 88 | ## 2.3 DQL功能展示 89 | 90 | - 查询所有数据库 SHOW DATABASES; 91 | - 查询当前数据库所有表 SHOW TABLES; 92 | - 描述表 DESC TABLE `表名`; 93 | - 查询表的所有记录 SELECT * FROM `表名`; 94 | - 指定字段和where条件 SELECT `列1` `列2` ... WHERE `筛选条件1`...; 95 | 96 | --- 97 | 98 | # 2. 基本功能展示 99 | 100 | ## 2.4 GUI界面 101 | 102 | - GUI界面 103 | 104 | --- 105 | 106 | # 3. 拓展功能展示 107 | 108 | - 读取SQL脚本(RUN) 109 | - 复杂SQL查询(SELECT) 110 | - 提交/回滚(数据持久化) 111 | - 完整性(约束) 112 | - 索引管理(INDEX) 113 | - 安全性(用户权限管理) 114 | - GUI点击修改 115 | 116 | --- 117 | 118 | # 3. 拓展功能展示 119 | 120 | ## 3.1 读取SQL脚本 121 | 122 | - run `脚本路径` 123 | 124 | --- 125 | 126 | # 3. 拓展功能展示 127 | 128 | ## 3.2 复杂的SQL查询 129 | 130 | - 多表 SELECT * FROM `table1` NATURAL JOIN `table2` ...; 131 | 132 | - 多条件 SELECT * FROM `table` WHERE `condition1` ...; 133 | 134 | - 排序 SELECT * FROM `table` ORDER BY `field1` ...; 135 | 136 | --- 137 | 138 | # 3. 拓展功能展示 139 | 140 | ## 3.3 数据持久化/回滚/提交 141 | 142 | - Commit 143 | 144 | - Rollback 145 | 146 | --- 147 | 148 | # 3. 拓展功能展示 149 | 150 | ## 3.4 完整性(约束条件) 151 | 152 | - Primary Key 153 | 154 | - Foreign Key 155 | 156 | - Not Null 157 | 158 | - Unique 159 | 160 | - Default 161 | 162 | --- 163 | 164 | # 3. 拓展功能展示 165 | 166 | ## 3.5 索引 167 | 168 | - 因为是内存数据库,所以使用 [无旋Treap](https://oi-wiki.org/ds/treap/#%E6%97%A0%E6%97%8B-treap) 169 | 170 | - CREATE INDEX ON `TableName` `Field1` ...; 171 | 172 | --- 173 | 174 | # 3. 拓展功能展示 175 | 176 | ## 3.6 用户权限管理 177 | 178 | - Grant User `User` `Database` `AuthorityName`; 179 | 180 | - Revoke User `User` `Database` `AuthorityName`; 181 | 182 | - Authority: 183 | - SELECT 184 | - INSERT 185 | - UPDATE 186 | - etc 187 | 188 | --- 189 | 190 | # 3. 拓展功能展示 191 | 192 | ## 3.7 GUI点击修改 193 | 194 | - GUI点击修改 195 | 196 | --- 197 | 198 | # 4. 项目管理 199 | 200 | ## 4.1 Git&Github版本管理 201 | 202 | - [Co1aSQL](https://github.com/YXHXianYu/2023-BJTU-DBMS-Project/) 203 | 204 | --- 205 | 206 | ![bg 85%](./pictures/Github.png) 207 | 208 | --- 209 | 210 | # 4. 项目管理 211 | 212 | ## 4.2 代码量统计 213 | 214 | - ![pic](./pictures/CodeCounter.png) 215 | 216 | --- 217 | 218 | # 4. 项目管理 219 | 220 | ## 4.3 成员贡献比例 221 | 222 | - 俞贤皓: 26% 223 | 224 | - 邓人嘉: 26% 225 | 226 | - 付家齐: 26% 227 | 228 | - 谷雅丰: 22% 229 | 230 | --- 231 | 232 | 233 | 234 | # Thanks For Listening 235 | -------------------------------------------------------------------------------- /core/README.md: -------------------------------------------------------------------------------- 1 | # Core 2 | * 核心模块 3 | * 使用C++实现 4 | 5 | 6 | 7 | ## 1. 类 8 | 9 | #### 1.1DataProcessor 10 | 11 | ​ DataProcessor主要用于与cmd交互,返回数据库操作结果。 12 | 13 | * 接口 14 | ```C++ 15 | //调用单例 16 | public: 17 | static DataProcessor GetInstance(); 18 | 19 | //数据库 20 | public: 21 | //创建用户 22 | int CreateUser(std::string user_name, 23 | std::string user_password); //登录用户 24 | int Login(std::string user_name, 25 | std::string user_password); 26 | //数据库 27 | public: 28 | //创建数据库 29 | int CreateDatabase(std::string database_name); //使用数据库 30 | int UseDatabase(std::string database_name); //显示所有数据库 31 | std::vector ShowDatabases(); 32 | 33 | //表 34 | public: 35 | // 创建表 36 | int CreateTable(std::string table_name, std::vector> fields, std::vector constraints); int DropTable(std::string table_name); //删除表 37 | int DescribeTable(std::string table_name,std::vector>&,std::vector& constraints); //查看表结构 38 | int ShowTables(std::string table_name); //显示所有表 39 | int AlterTableAdd(std::string table_name, std::pair field);//修改表结构,增加字段 40 | int AlterTableDrop(std::string table_name, std::string field_name); //删除字段 41 | int AlterTableModify(std::string table_name, std::pair field); //修改字段 42 | int AlterTableConstraint(std::string table_name, Constraint constraint); //添加约束条件 43 | int AlterTableDeleteConstraint(std::string table_name, std::string constraint_name); ///删除约束 44 | //记录 45 | public: 46 | // 插入记录 47 | int Insert(std::string table_name, 48 | std::vector> record_in); 49 | // 查询记录 50 | int Select(std::string table_name, 51 | std::vector field_name, 52 | std::vector> conditions, 54 | std::vector> &return_records); 55 | //删除记录 56 | int Delete(std::string table_name, 57 | std::vector> conditions); 58 | ``` 59 | 60 | 61 | 62 | #### 1.2 用户(User) 63 | 64 | * 构造函数 65 | ```C++ 66 | private: 67 | User(); 68 | public: 69 | User(std::string user_name, std::string user_password); 70 | ``` 71 | 72 | * 接口 73 | ```C++ 74 | public: 75 | //验证密码 76 | int Identify(std::string password); 77 | //获取用户名 78 | std::string GetUserName(); 79 | ``` 80 | 81 | 82 | 83 | #### 1.3 表 84 | 85 | * 构造函数 86 | ```c++ 87 | public: 88 | Table(std::string table_name, //表名 89 | std::vector> fields, //字段 91 | std::vector constraints);//约束 92 | ``` 93 | 94 | * 接口 95 | ```c++ 96 | public: 97 | //获取表名 98 | std::string GetTableName() const; 99 | //Select查询记录 100 | int Select(std::vector field_name, 101 | std::vector> conditions, 102 | std::vector> &return_records); 103 | //Insert插入记录 104 | int Insert(std::vector> record_in); 105 | //Delete删除记录 106 | int Delete(std::vector> conditions); 107 | //检查记录是否满足Where条件 108 | int CheckCondition(const std::unordered_map& record, const std::vector>& conditions); 109 | ``` 110 | 111 | 112 | -------------------------------------------------------------------------------- /core/include/index/index.h: -------------------------------------------------------------------------------- 1 | #ifndef __INDEX_H__ 2 | #define __INDEX_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "colasqltool.h" 12 | #include "constants.h" 13 | 14 | /** 15 | * 索引基类 16 | */ 17 | class Index { 18 | public: 19 | /** 20 | * Construct an Index 21 | * compare_key is the keys of Index 22 | */ 23 | Index(const std::vector>& records, 24 | const std::vector>& fields, 25 | const std::unordered_map& field_map, 26 | const std::vector& compare_key); 27 | 28 | /** 29 | * Destructor an Index 30 | */ 31 | virtual ~Index(); 32 | 33 | /** 34 | * build an index (rebuild) 35 | */ 36 | virtual int build(const std::vector>& records, 37 | const std::vector>& fields, 38 | const std::unordered_map& field_map, 39 | const std::vector& compare_key) = 0; 40 | 41 | /** 42 | * query on index 43 | * @return if return value isn't zero, then result is invalid! 44 | */ 45 | virtual int query(const std::vector>& conditions, 46 | std::vector& result_indexes) = 0; 47 | 48 | /** 49 | * get compare keys 50 | */ 51 | const std::vector& getCompareKey() const; 52 | 53 | /** 54 | * get index state 55 | * 0 if valid 56 | * != 0 if invalid 57 | */ 58 | int getState() const { 59 | return _state; 60 | } 61 | 62 | /** 63 | * compare two records 64 | * -1 if r[i] < r[j] 65 | * 0 if r[i] == r[j] 66 | * 1 if r[i] > r[j] 67 | */ 68 | int compare(int i, int j, bool nullIsLess = true) const { 69 | if(!_records_ptr) return 0; 70 | if(i >= _records_ptr->size() || j >= _records_ptr->size()) return 0; 71 | for(const auto& fieldName: _compare_key) { 72 | bool iHave = _records_ptr->at(i).count(fieldName) > 0; 73 | bool jHave = _records_ptr->at(j).count(fieldName) > 0; 74 | 75 | int ret; 76 | if(iHave && jHave) 77 | ret = ColasqlTool::CompareAny(_records_ptr->at(i).at(fieldName), _records_ptr->at(j).at(fieldName)); 78 | else if(iHave && !jHave) 79 | ret = nullIsLess ? 1 : -1; 80 | else if(!iHave && jHave) 81 | ret = nullIsLess ? -1 : 1; 82 | else 83 | ret = 0; 84 | 85 | if(ret == 0) continue; 86 | return ret; 87 | } 88 | return 0; 89 | } 90 | 91 | /** 92 | * compare two records 93 | * -1 if r[i] < r[j] 94 | * 0 if r[i] == r[j] 95 | * 1 if r[i] > r[j] 96 | */ 97 | int compare(const std::unordered_map& i, int j, bool nullIsLess = true) const { 98 | if(!_records_ptr) return 0; 99 | if(j >= _records_ptr->size()) return 0; 100 | for(const auto& fieldName: _compare_key) { 101 | bool iHave = i.count(fieldName) > 0; 102 | bool jHave = _records_ptr->at(j).count(fieldName) > 0; 103 | 104 | int ret; 105 | if(iHave && jHave) 106 | ret = ColasqlTool::CompareAny(i.at(fieldName), _records_ptr->at(j).at(fieldName)); 107 | else if(iHave && !jHave) 108 | ret = nullIsLess ? 1 : -1; 109 | else if(!iHave && jHave) 110 | ret = nullIsLess ? -1 : 1; 111 | else 112 | ret = 0; 113 | 114 | // if(iHave && jHave) 115 | // std::cout << "Comparing: " << fieldName << ", " 116 | // << ColasqlTool::AnyToString(i.at(fieldName)) << "|" << i.at(fieldName).type().name() << ", " 117 | // << ColasqlTool::AnyToString(_records_ptr->at(j).at(fieldName)) << "|" 118 | // << _records_ptr->at(j).at(fieldName).type().name() << ", " 119 | // << ret << std::endl; 120 | 121 | if(ret == 0) continue; 122 | return ret; } 123 | return 0; 124 | } 125 | 126 | protected: 127 | int _state; // 记录index状态 128 | 129 | const std::vector>* _records_ptr; 130 | const std::unordered_map* _field_map_ptr; 131 | std::vector _compare_key; 132 | }; 133 | 134 | #endif // __INDEX_H__ 135 | -------------------------------------------------------------------------------- /core/include/table.h: -------------------------------------------------------------------------------- 1 | /** 2 | * author: drj 3 | * 表类。存储了所有表里的记录,和字段信息、约束等。 4 | * 主要由database调用,正确时返回kSuccess。 5 | * 否则返回./constrants.h里的错误代码 6 | * 本模块中,记录的存储方式是std::vector > records,一条记录的类型是std::unordered_map,其中string为记录对应字段,any是记录在对应字段的值。 7 | * 单行单列交叉处的数据以STL中的any存储,在colasqltool类里有对any进行转换、修改、输出等操作的方法。 8 | */ 9 | #ifndef TABLE_H 10 | #define TABLE_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "all_constraints.h" 19 | #include "colasqltool.h" 20 | #include "constants.h" 21 | #include "index/index.h" 22 | 23 | class Database; 24 | 25 | class Table { 26 | private: 27 | std::string table_name; 28 | std::vector> fields; //pair<字段名, 类型> 29 | std::unordered_map field_map; 30 | std::vector > records; 31 | std::vector constraints; 32 | 33 | Index* index_ptr; 34 | 35 | public: 36 | Table(std::string &table_name); 37 | Table(const std::string& table_name, 38 | const std::vector>& fields, 39 | const std::vector& constraints); 40 | 41 | Table(const std::string& table_name, 42 | const std::vector>& fields, 43 | const std::vector& constraints, 44 | const std::vector>& records); 45 | 46 | ~Table(); // 根据零三五法则,需要同时定义析构、拷贝构造、拷贝赋值函数 47 | Table(const Table&); // 根据零三五法则,需要同时定义析构、拷贝构造、拷贝赋值函数 48 | Table& operator = (Table); // unique_ptr 需要定义 拷贝赋值函数 49 | friend void swap(Table& s1, Table& s2); // 基于友元函数的copy-and-swap策略 50 | 51 | //获取表名 52 | const std::string& GetTableName() const; 53 | const std::vector>& GetFields() const; 54 | const std::unordered_map GetFieldMap() const; 55 | const std::vector >& GetRecords() const; 56 | const std::vector& GetConstraints() const; 57 | 58 | int GetIndex(std::vector& result_key) const; 59 | 60 | //查询记录 61 | int Select(std::vector field_name, // field_name不为常引用的原因是,函数内对field_name进行了修改 62 | const std::vector>& conditions, 63 | std::vector> &return_records, 64 | const std::vector& orderby_key = std::vector()); 65 | //插入记录 66 | int Insert(std::vector> record_in, Database* db); 67 | //删除记录 68 | int Delete(std::vector> conditions, Database* db); 69 | //检查记录是否满足Where条件 70 | int CheckCondition(const std::unordered_map& record, 71 | const std::vector>& conditions); 72 | //更新记录 73 | int Update(const std::vector>& value, 74 | const std::vector>& conditions, Database* db); 75 | //描述表(字段信息、约束等) 76 | int DescribeTable(std::vector>& fields, 77 | std::vector& constraints); 78 | 79 | int CheckDataType(std::string type, std::string value); 80 | //增加字段 81 | int AlterTableAdd(std::pair new_field); 82 | int AlterTableDrop(std::string field_name, Database* db); 83 | int AlterTableModify(std::pair field); 84 | int AlterTableConstraint(Constraint* constraint); 85 | // 建立索引 86 | int BuildIndex(const std::vector& compare_key, int type = kFHQTreapIndex); 87 | //检查一条记录是否约束 88 | int CheckConstraint(std::unordered_map& record, Database* db); 89 | int CheckConstraint(std::unordered_map& record, Database* db, std::vector > records, int current_record_order); 90 | //检查是否被其它表参考 91 | int CheckBeingRefered(std::unordered_map& record, Database* db); 92 | //查找字段,找到返回kSuccess 93 | int FindField(std::string field_name) const; 94 | int FindField(std::string field_name, std::any value) const; 95 | //根据表名来删除外键约束 96 | int DropForeignReferedConstraint(std::string table_name); 97 | //根据表名和字段名来删除外键约束。 98 | int DropForeignReferedConstraint(std::string table_name, std::string field_name); 99 | 100 | int DeleteConstraint(std::string constraint_name, Database* db); 101 | int CheckUnique(std::string field_name) const; 102 | }; 103 | 104 | #endif // TABLE_H 105 | -------------------------------------------------------------------------------- /core/include/dataprocessor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * author: drj 3 | * 数据处理类,单例模式,外部调用时请使用单例。 4 | * 正确处理数据时返回常量kSuccess(0) 5 | * 否则返回./constrants.h里的错误代码 6 | */ 7 | 8 | #ifndef DATAPROCESSOR_H 9 | #define DATAPROCESSOR_H 10 | 11 | #include 12 | #include 13 | #include"database.h" 14 | #include"user.h" 15 | #include"constants.h" 16 | 17 | #include"./constraint/all_constraints.h" 18 | 19 | // file 20 | #include "filemanager.h" 21 | 22 | class DataProcessor { 23 | private: 24 | std::vector databases; 25 | std::vector users; 26 | Database* current_database; 27 | User* current_user; 28 | std::string current_database_name; 29 | std::string current_user_name; 30 | std::unordered_map> constraint_map;//约束名->数据库名,表名 31 | private: 32 | DataProcessor(); 33 | public: 34 | static DataProcessor& GetInstance(); 35 | 36 | //更新指针 37 | public: 38 | int UpdatePointer(); 39 | //数据库,用户 40 | public: 41 | int GetCurrentDatabase(std::string& database_name); 42 | int GetCurrentUser(std::string& user_name); 43 | int CreateUser(std::string user_name, std::string user_password); //创建用户 44 | int Login(std::string user_name, std::string user_password); //登录用户 45 | //数据库 46 | public: 47 | int CreateDatabase(std::string database_name); //创建数据库 48 | int DeleteDatabase(std::string database_name); 49 | int UseDatabase(std::string database_name = ""); //使用数据库 50 | int ShowDatabases(std::vector& return_databases); //显示所有数据库 51 | //表 52 | public: 53 | int ShowTables(std::vector& return_tables); //显示所有表 54 | int CreateTable(std::string table_name, std::vector> fields, std::vector constraints); // 创建表 55 | int DropTable(std::string table_name); //删除表 56 | int DescribeTable(std::string table_name,std::vector>& fields,std::vector& constraints); //查看表结构 57 | int UpdateConstraintMap(); 58 | int AlterTableAdd(std::string table_name, std::pair field);//修改表结构,增加字段 59 | int AlterTableDrop(std::string table_name, std::string field_name); //删除字段 60 | int AlterTableModify(std::string table_name, std::pair field); //修改字段 61 | int AlterTableConstraint(std::string table_name, Constraint* constraint); //添加约束条件 62 | int AlterTableDeleteConstraint(std::string table_name, std::string constraint_name); ///删除约束 63 | int ShowConstraints(std::vector>& ret_records); 64 | 65 | //记录 66 | public: 67 | int Insert(std::string table_name, std::vector> record_in); // 插入记录 68 | int Select(std::string table_name, 69 | std::vector field_name, 70 | std::vector> conditions, 71 | std::vector> &return_records, 72 | const std::vector& orderby_key = std::vector()); // 查询记录 73 | int Select(std::vector table_names, 74 | std::vector field_name, 75 | std::vector> conditions, 76 | std::vector> &return_records, 77 | const std::vector& orderby_key = std::vector()); // 多表查询 78 | int Delete(std::string table_name, std::vector> conditions); // 删除记录 79 | int Update(std::string table_name, const std::vector>& values, const std::vector>& conditions); //更新记录 80 | //values: vector<> 81 | 82 | //权限 83 | public: 84 | bool IsAdmin(); 85 | bool FindDatabase(std::string database_name); 86 | bool FindTable(std::string database_name, std::string table_name); 87 | bool FindUser(std::string user_name); 88 | int GrantAuthority(std::string user_name,std::string database_name, std::string table_name, std::string authority_name);//给出表级权限 89 | int GrantAuthority(std::string user_name,std::string database_name, std::string authority_name);//给出数据库级和表级权限 90 | int RevokeAuthority(std::string user_name,std::string database_name, std::string table_name, std::string authority_name);//收回表级权限 91 | int RevokeAuthority(std::string user_name,std::string database_name, std::string authority_name);//收回数据库级权限 92 | 93 | //索引 94 | public: 95 | int BuildIndex(std::string table_name, const std::vector& compare_key); 96 | 97 | //文件 98 | public: 99 | int Read(bool debug = false); 100 | int Write(); 101 | 102 | }; 103 | 104 | #endif // DATAPROCESSOR_H 105 | -------------------------------------------------------------------------------- /cmd/src/command_processor.cpp: -------------------------------------------------------------------------------- 1 | #include "command_processor.h" 2 | 3 | #include 4 | 5 | namespace ColaSQLCommand { 6 | 7 | CommandProcessor& CommandProcessor::GetInstance() { 8 | static CommandProcessor instance; 9 | return instance; 10 | } 11 | 12 | void CommandProcessor::Start(const std::string& accountName, const std::string& password) { 13 | 14 | // TODO: Login 15 | DataProcessor::GetInstance().CreateUser(accountName, password); 16 | DataProcessor::GetInstance().Login(accountName, password); 17 | 18 | // TODO: Welcome information 19 | 20 | seq.clear(); 21 | int ret; 22 | int outputPrompt = true; 23 | while(true) { // 主循环 24 | if(outputPrompt) { 25 | std::cout << GetPrompt(); 26 | } 27 | 28 | // input 29 | std::string input; 30 | std::getline(std::cin, input); 31 | // char ch = getchar(); 32 | // while(ch != '\r' && ch != '\n') { 33 | // input.push_back(ch); 34 | // ch = getchar(); 35 | // } 36 | 37 | // quit 38 | if(input.length() >= 4 && input.substr(0, 4) == "quit") { 39 | break; 40 | } 41 | if(input.length() >= 3 && input.substr(0, 3) == "run") { 42 | std::cout << std::endl << RunScript(input) << std::endl; 43 | continue; 44 | } 45 | 46 | std::string output = Run(input); 47 | 48 | if(output == "") { 49 | outputPrompt = true; 50 | } else { 51 | outputPrompt = true; 52 | std::cout << std::endl << output << std::endl; 53 | } 54 | } 55 | } 56 | 57 | std::string CommandProcessor::Run(std::string input) { 58 | if(input == "") return ""; 59 | 60 | // preprocess 61 | Preprocess(input); 62 | 63 | // tokenize 64 | int ret = Tokenize(input, seq); 65 | 66 | if(ret == -1) { // 语句异常(语句中包含不正常的分号) 67 | seq.clear(); 68 | return "Error: Statement error!"; 69 | } 70 | 71 | if(ret == 1) { // 语句未结束 72 | return ""; 73 | } 74 | // parse 75 | std::string output; 76 | output = _parser.Parse(seq); 77 | seq.clear(); 78 | return output; 79 | } 80 | 81 | 82 | std::string CommandProcessor::ComplexSelect(std::string input, std::vector>& result){ 83 | if(input == "") return ""; 84 | 85 | // preprocess 86 | Preprocess(input); 87 | 88 | // tokenize 89 | int ret = Tokenize(input, seq); 90 | 91 | if(ret == -1) { // 语句异常(语句中包含不正常的分号) 92 | seq.clear(); 93 | return "Error: Statement error!"; 94 | } 95 | 96 | if(ret == 1) { // 语句未结束 97 | return ""; 98 | } 99 | // parse 100 | std::string output; 101 | output = _parser.ParseSelect(seq, result); 102 | seq.clear(); 103 | return output; 104 | } 105 | 106 | std::string CommandProcessor::RunScript(std::string path) { 107 | if(path.length() <= 4) return "Incomplete statement."; 108 | 109 | path = path.substr(3); 110 | path.erase(0, path.find_first_not_of(" ")); 111 | path.erase(path.find_last_not_of(" ") + 1); 112 | 113 | std::cout << "Opening: " << path << std::endl; 114 | 115 | std::ifstream in(path, std::ifstream::in); 116 | if(!in.is_open()) { 117 | return "Failed to open file"; 118 | } 119 | 120 | 121 | std::string result = ""; 122 | std::string input; 123 | while(std::getline(in, input)) { // 主循环 124 | if(input.length() >= 3 && input.substr(0, 3) == "run") { 125 | result += RunScript(input) + "\n"; 126 | continue; 127 | } 128 | 129 | std::string output = Run(input); 130 | 131 | if(output != "") { 132 | result += output + "\n"; 133 | } 134 | } 135 | return result; 136 | } 137 | 138 | CommandProcessor::CommandProcessor() {} 139 | 140 | std::string CommandProcessor::GetPrompt() { 141 | return "Co1aSQL > "; 142 | } 143 | 144 | // 将input追加进result 145 | // 注意,本函数不会清空result,只会在后面追加! 146 | // 若返回 0,则说明语句已结束 147 | // 若返回 1,则说明语句未结束 148 | // 若返回 -1,则说明语句异常(语句中包含不正常的分号) 149 | int CommandProcessor::Tokenize(std::string input, std::vector& result) { 150 | bool haveEnd = false; // 是否以分号结尾 151 | if(input[input.length() - 1] == ';') { 152 | haveEnd = true; 153 | input = input.substr(0, input.length() - 1); // 删去分号 154 | } 155 | 156 | input = input + " "; 157 | 158 | for(int st = 0, i = 0; i < input.length(); i++) { 159 | if(input[i] == ';') return -1; // ERROR 160 | if(input[i] != ' ' && input[i] != '\t') continue; 161 | 162 | if(i - st >= 1) result.push_back(input.substr(st, i - st)); 163 | st = i + 1; 164 | } 165 | 166 | return haveEnd ? 0 : 1; 167 | } 168 | 169 | 170 | int CommandProcessor::Preprocess(std::string& str) { 171 | if(str.empty()) return -1; 172 | 173 | // 删去前后多余空格 (trim) 174 | str.erase(0, str.find_first_not_of(" ")); 175 | str.erase(str.find_last_not_of(" ") + 1); 176 | 177 | int del = 'a'-'A'; 178 | for(int i = 0; i < str.length(); i++) { 179 | if('A' <= str[i] && str[i] <= 'Z') { // 全小写 180 | str[i] += del; 181 | } else if(str[i] == ',' || str[i] == '(' || str[i] == ')') { // 替换字符 182 | str[i] = ' '; 183 | } 184 | } 185 | 186 | 187 | 188 | return 0; 189 | } 190 | 191 | 192 | } // ColaSQLCommand 193 | -------------------------------------------------------------------------------- /document/FinalDocument.md: -------------------------------------------------------------------------------- 1 | # Co1aSQL 项目结题报告 2 | 3 | ## 1. 实现功能 4 | 5 | ### 1.1 基本功能 6 | 7 | - SQL解析 8 | - DDL功能实现 9 | - DML功能实现 10 | - DQL功能实现 11 | - GUI界面 12 | - (基本功能均完成) 13 | 14 | ### 1.2 拓展功能 15 | 16 | - SQL脚本文件的执行 17 | - 复杂Select语句 18 | - 数据持久化/事务管理(Commit/Rollback) 19 | - 基于无旋Treap的索引 20 | - 完整性管理(主键、外键、UNIQUE、Not Null、DEFAULT) 21 | - 安全性管理(用户、权限) 22 | - GUI点击修改记录 23 | 24 | ### 1.3 GUI 25 | 26 | - ![pic](./pictures/pic1.png) 27 | - ![pic](./pictures/pic2.png) 28 | 29 | ## 2. 技术方案设计 30 | 31 | ### 2.1 C++ 32 | 33 | - 本项目采用C++作为开发语言。 34 | 35 | - C++相对Java、Python等语言,有着执行效率高这一特性,非常适合用于编写数据库管理系统这种对运行效率要求严苛的程序。所以为了使数据库管理系统的运行效率更高,我们采用C++进行开发。 36 | 37 | - 本项目采用的C++版本为C++17 38 | 39 | ### 2.2 Qt 40 | 41 | - 本项目采用C++&Qt来实现可视化的图形界面。 42 | 43 | - Qt是目前最成熟的C++多媒体库,可以方便快速的实现GUI。 44 | 45 | - 同时,Qt也是一个成熟的跨平台库,适用于我们Windows+Linux双平台开发。 46 | 47 | ### 2.3 项目结构 48 | 49 | - 本项目分为四个模块:核心模块、文件模块、命令行接口模块、GUI模块。 50 | 51 | - 核心模块负责维护DBMS的数据结构,并且抛出各类管理数据结构的接口,供其他模块操作数据库。 52 | 53 | - 文件模块负责操作物理文件,提供操作物理文件的接口。 54 | 55 | - 命令行接口模块负责提供命令行接口,使得用户可以通过命令行接口的方式操作数据库。同时,命令行接口模块也负责对SQL语句进行解析,将SQL语句从一条字符串切成一个一个单词,再对单词序列进行解析,转换成对核心模块接口的调用。 56 | 57 | - GUI模块提供了图形化界面,使得用户可以通过图形化界面的方式操作数据库。GUI模块会调用命令行接口模块,从而在GUI中内嵌SQL语句的解析,便于操作。GUI模块也提供了一套直接调用核心模块的方法,使得用户可以不通过SQL语句,仅通过图形界面来操作数据库。 58 | 59 | * ![pic](./pictures/ProjectConstruction.png) 60 | 61 | ## 3. 算法实现描述 62 | 63 | 64 | ## 4. 用户手册 65 | 66 | ### 4.1 项目构建 67 | 68 | #### 4.1.1 项目版本 69 | 70 | * gcc 13.1.1 71 | * c++17 72 | 73 | * qt 5.15.9 74 | * cmake 3.26.3 75 | * qmake 3.1 76 | 77 | #### 4.1.2 构建CLI 78 | 79 | ``` 80 | cd cmd 81 | cmake -Bbuild 82 | make -Cbuild -j8 83 | ``` 84 | 85 | #### 4.1.3 启动CLI 86 | 87 | ``` 88 | build/colasql admin 123456; 89 | ``` 90 | 91 | #### 4.1.4 构建GUI 92 | 93 | ``` 94 | cd gui/ColaSqlGui 95 | qmake -o build/Makefile ColaSqlGui.pro 96 | make -Cbuild -j8 97 | ``` 98 | 99 | #### 4.1.5 启动GUI 100 | 101 | ``` 102 | build/ColaSqlGui 103 | ``` 104 | 105 | ### 4.2 SQL语句 106 | 107 | #### 4.2.1 基本约定 108 | 109 | * Co1aSQL 支持的SQL语法,均为 **大小写不敏感**。 110 | * Co1aSQL 在预处理SQL语句时,会自动将所有的小括号和逗号替换为空格,以尽可能兼容标准SQL。 111 | 112 | #### 4.2.2 用户 113 | 114 | * 登入数据库 115 | 116 | ```sql 117 | colasql 用户名 密码 118 | #管理员用户名admin,密码colasql 119 | LOGIN 用户名 密码; 120 | ``` 121 | 122 | * 创建用户 123 | 124 | ```sql 125 | CREATE USER 用户名 密码; 126 | #所有用户默认拥有数据库的查询权、创建权,只对自己创建的数据库有删除权 127 | #创建用户不需要任何权限,但授予权限只能授予自己拥有的权限 128 | #其它说明见下 129 | ``` 130 | 131 | * 修改用户权限 132 | 133 | ```sql 134 | GRANT USER 用户名 数据库名 表名 权限名; 135 | #数据库名和表名都不能为"*",对某个特定的数据库的表授予权限。 136 | 137 | GRANT USER 用户名 数据库名 权限名; 138 | #数据库名为"*",对所有数据库的所有表授予权限(当前用户拥有该数据库的权限,仅admin可用)。 139 | #数据库名不为"*"时,若为表级权限则授予该数据库里所有表的表级权限(当前用户需拥有授权的所有权限),若为数据库级权限则授予该数据库的数据库级权限(当前用户需拥有该权限)。 140 | ``` 141 | 142 | * 权限名 143 | 144 | ```sql 145 | #表级权限 146 | SELECT 147 | DELETE 148 | INSERT 149 | UPDATE 150 | INDEX 151 | ALTER 152 | 153 | #数据库级权限 154 | CREATE 155 | DROP 156 | 157 | #ALL表示以上所有权限,仅数据库管理员(admin)可用 158 | #ALL 159 | ``` 160 | 161 | * 删除用户(需要管理员权限) 162 | 163 | ```sql 164 | DROP USER 用户名; 165 | ``` 166 | 167 | #### 4.2.3 数据类型 168 | 169 | * ```sql 170 | int # 42位整数,如 1, 14, 514 171 | float # 42位浮点数,如 1.0, 5.1, 2 172 | string # 字符串,如 "dbms", "2002-10-12" 173 | ``` 174 | 175 | #### 4.2.4 数据库 176 | 177 | * 创建数据库(需要管理员权限) 178 | 179 | ```sql 180 | CREATE DATABASE 数据库名; 181 | ``` 182 | 183 | * 删除数据库(需要管理员权限) 184 | 185 | ```sql 186 | DROP DATABASE 数据库名; 187 | ``` 188 | 189 | * 使用数据库 190 | 191 | ```sql 192 | USE 数据库名; 193 | ``` 194 | 195 | * 显示所有数据库 196 | 197 | ```sql 198 | SHOW DATABASES; 199 | ``` 200 | 201 | #### 4.2.5 表 202 | 203 | * 创建表(需要CREATE权限) 204 | 205 | ```sql 206 | CREATE TABLE 表名 207 | 列名1 类型1 208 | 列名2 类型2 209 | ... 210 | 211 | 约束条件1 212 | 约束条件2 213 | ... 214 | ; 215 | ``` 216 | 217 | * 约束条件语法 218 | 219 | ```sql 220 | CONSTRAINT 约束名 PRIMARY KEY 列名; # 指定主键 221 | CONSTRAINT 约束名 FOREIGN KEY 列名 REFERENCES 表名2 列名2; # 指定外键,该列 参考 表2的列2 222 | CONSTRAINT 约束名 UNIQUE 列名; # 指定该列值不可重复(未指定时,默认可重) 223 | CONSTRAINT 约束名 NOT NULL 列名; # 指定该列非空(未指定时,默认可空) 224 | CONSTRAINT 约束名 DEFAULT 列名 值; # 指定该列默认值(未指定时,默认值为NULL) 225 | ``` 226 | 227 | * 删除表(需要DROP权限) 228 | 229 | ```sql 230 | DROP TABLE 表名; 231 | ``` 232 | 233 | * 修改表(需要ALTER权限) 234 | 235 | ```sql 236 | ALTER TABLE 表名 ADD 列名 类型; 237 | ALTER TABLE 表名 DROP 列名; 238 | ALTER TABLE 表名 MODIFY 列名 类型; 239 | ALTER TABLE 表名 约束条件; 240 | ALTER TABLE 表名 DELETE 约束条件名; 241 | ``` 242 | 243 | * 约束条件语法见上文 244 | * 约束条件名可以通过“查看表结构”语句来查看。 245 | 246 | * 查看表结构(需要SELECT权限) 247 | 248 | ```sql 249 | DESC TABLE 表名; 250 | ``` 251 | 252 | * 显示所有表 253 | 254 | ```sql 255 | SHOW TABLES; 256 | ``` 257 | 258 | * 索引相关 259 | 260 | ```sql 261 | CREATE INDEX ON 表名 列名1 列名2 ...; 262 | ``` 263 | 264 | * 以上述列名为关键字建立索引,在Select时Where列需为此处列的前缀才可以触发索引。 265 | 266 | * 查看约束 267 | ```sql 268 | SHOW CONSTRAINTS; 269 | SHOW CONSTRAINT ON 表名; 270 | ``` 271 | 272 | 273 | #### 4.2.6 记录 274 | 275 | * 插入记录 276 | 277 | ```sql 278 | INSERT INTO 表名 列名1 列名2 列名3 ... VALUES 值1 值2 值3 ...; 279 | ``` 280 | 281 | * 删除记录 282 | 283 | ```sql 284 | DELETE FROM 表名 [WHERE 筛选条件1 筛选条件2 ...]; 285 | ``` 286 | 287 | * 筛选条件语法 288 | 289 | ```sql 290 | 列名 = 值 291 | ``` 292 | 293 | * **筛选条件'='左右必须要包含空格**,否则会产生解析错误 294 | 295 | * 选择记录 296 | 297 | ```sql 298 | SELECT 列名1 列名2 列名3 ... 299 | FROM 表名1 [NATURAL JOIN 表名2 ...] 300 | [WHERE 筛选条件1 筛选条件2 ...] 301 | [ORDER BY 列名1 列名2 ...]; 302 | ``` 303 | 304 | * 更新记录 305 | 306 | ```sql 307 | UPDATE 表名 SET 列名1 = 值1 [列名2 = 值2 ...] 308 | [WHERE 筛选条件1 筛选条件2 ...]; 309 | ``` 310 | 311 | #### 4.2.7 文件 312 | 313 | * 储存 & 提交 314 | 315 | ```mysql 316 | SAVE; 317 | COMMIT; 318 | ``` 319 | 320 | * 回滚 & 读取 321 | 322 | ```mysql 323 | READ; 324 | ROLLBACK; 325 | ``` 326 | 327 | #### 4.2.8 Co1aSQL脚本执行 328 | 329 | * 执行Co1aSQL脚本 330 | * ``` 331 | RUN path/to/directory/script.colasql 332 | ``` 333 | 334 | * 注意!此处不能在语句末尾加 `;`,否则会解析失败! 335 | 336 | #### 4.2.9 关键字 337 | 338 | * `NULL` 为Co1aSQL关键字,若占用,则不一定能得到预期结果 339 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/ui/createtable.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | createtable 4 | 5 | 6 | 7 | 0 8 | 0 9 | 600 10 | 450 11 | 12 | 13 | 14 | 15 | 600 16 | 450 17 | 18 | 19 | 20 | 21 | 600 22 | 450 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | #centralwidget{border-image: url(:/images/add_table/add-bg.png)} 31 | 32 | 33 | 34 | 35 | 13 36 | 39 37 | 200 38 | 398 39 | 40 | 41 | 42 | 43 | 44 | 45 | 260 46 | 260 47 | 301 48 | 121 49 | 50 | 51 | 52 | QFrame::StyledPanel 53 | 54 | 55 | QFrame::Raised 56 | 57 | 58 | 59 | 60 | 61 | NOT NULL 62 | 63 | 64 | 65 | 66 | 67 | 68 | reference field name 69 | 70 | 71 | 72 | 73 | 74 | 75 | FOREIGN KEY: 76 | 77 | 78 | 79 | 80 | 81 | 82 | reference table name 83 | 84 | 85 | 86 | 87 | 88 | 89 | PRIMARY KEY 90 | 91 | 92 | 93 | 94 | 95 | 96 | UNIQUE 97 | 98 | 99 | 100 | 101 | 102 | 103 | constrain name 104 | 105 | 106 | 107 | 108 | 109 | 110 | CONSTRAINT NAME: 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 300 120 | 149 121 | 100 122 | 26 123 | 124 | 125 | 126 | 127 | 128 | 129 | 300 130 | 185 131 | 100 132 | 26 133 | 134 | 135 | 136 | 137 | 138 | 139 | 252 140 | 404 141 | 77 142 | 29 143 | 144 | 145 | 146 | QPushButton#add_col{border-image: url(:/images/add_table/tj-1.png)} 147 | QPushButton::pressed#add_col{border-image: url(:/images/add_table/tj-2.png)} 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 338 158 | 404 159 | 77 160 | 29 161 | 162 | 163 | 164 | QPushButton#finished_table{border-image: url(:/images/add_table/comp-1.png)} 165 | QPushButton::pressed#finished_table{border-image: url(:/images/add_table/comp-2.png)} 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 423 176 | 404 177 | 77 178 | 29 179 | 180 | 181 | 182 | QPushButton#cancel_table{border-image: url(:/images/add_table/cancel-1.png)} 183 | QPushButton::pressed#cancel_table{border-image: url(:/images/add_table/cancel-2.png)} 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 300 194 | 221 195 | 100 196 | 26 197 | 198 | 199 | 200 | 201 | 202 | 203 | 513 204 | 223 205 | 72 206 | 22 207 | 208 | 209 | 210 | 211 | INT 212 | 213 | 214 | 215 | 216 | FLOAT 217 | 218 | 219 | 220 | 221 | STRING 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/src/createtable.cpp: -------------------------------------------------------------------------------- 1 | #include "createtable.h" 2 | 3 | #include "ui_createtable.h" 4 | 5 | createtable::createtable(QWidget* parent) 6 | : QMainWindow(parent), ui(new Ui::createtable) 7 | { 8 | ui->setupUi(this); 9 | QIcon icon = QIcon(":/images/Colasql.png"); 10 | this->setWindowIcon(icon); 11 | ui->tableName_lineEdit->setStyleSheet( 12 | "background:transparent;border-width:0;border-style:outset"); 13 | ui->dbName_lineEdit->setStyleSheet( 14 | "background:transparent;border-width:0;border-style:outset"); 15 | ui->col_name->setStyleSheet( 16 | "background:transparent;border-width:0;border-style:outset"); 17 | ui->tableView->setStyleSheet("border-style:outset"); 18 | ui->comboBox->setStyleSheet("border-style:outset"); 19 | 20 | model = new QStandardItemModel(); 21 | model->setColumnCount(3); 22 | model->setHeaderData(0, Qt::Horizontal, "字段"); 23 | model->setHeaderData(1, Qt::Horizontal, "类型"); 24 | model->setHeaderData(2, Qt::Horizontal, "约束"); 25 | ui->tableView->setModel(model); 26 | ui->tableView->setColumnWidth(0, 60); 27 | ui->tableView->setColumnWidth(1, 60); 28 | ui->tableView->setColumnWidth(2, 60); 29 | 30 | int font_Id = 31 | QFontDatabase::addApplicationFont(":/font/FiraCode-Regular-1.ttf"); 32 | QStringList font_list = QFontDatabase::applicationFontFamilies(font_Id); 33 | if (!font_list.isEmpty()) 34 | { 35 | QFont f; 36 | f.setFamily(font_list[0]); 37 | f.setPointSize(9); 38 | ui->dbName_lineEdit->setFont(f); 39 | ui->tableName_lineEdit->setFont(f); 40 | ui->col_name->setFont(f); 41 | ui->tableView->setFont(f); 42 | } 43 | } 44 | 45 | createtable::~createtable() { delete ui; } 46 | 47 | void createtable::on_cancel_table_clicked() { this->close(); } 48 | 49 | void createtable::on_add_col_clicked() 50 | { 51 | ui->tableView->close(); 52 | QString field = ui->col_name->text(); 53 | QString type = ui->comboBox->currentText(); 54 | QString check = ""; 55 | QString constraintName = ui->constraint_name->text(); 56 | if ((ui->foreign_check->isChecked() || ui->notnull_check->isChecked() || 57 | ui->unique_check->isChecked() || ui->pk_check->isChecked()) && 58 | constraintName == "") 59 | { 60 | QMessageBox::warning(this, "警告", "未输入约束名!"); 61 | ui->tableView->show(); 62 | ui->col_name->clear(); 63 | ui->constraint_name->clear(); 64 | ui->foreign_table->clear(); 65 | ui->foreign_field->clear(); 66 | ui->foreign_check->setChecked(false); 67 | ui->notnull_check->setChecked(false); 68 | ui->pk_check->setChecked(false); 69 | ui->unique_check->setChecked(false); 70 | return; 71 | } 72 | if (field == "") 73 | { 74 | QMessageBox::warning(this, "警告", "未输入字段名!"); 75 | ui->tableView->show(); 76 | ui->col_name->clear(); 77 | ui->constraint_name->clear(); 78 | ui->foreign_table->clear(); 79 | ui->foreign_field->clear(); 80 | ui->foreign_check->setChecked(false); 81 | ui->notnull_check->setChecked(false); 82 | ui->pk_check->setChecked(false); 83 | ui->unique_check->setChecked(false); 84 | return; 85 | } 86 | if (ui->foreign_check->isChecked()) 87 | { 88 | QString reference_table = ui->foreign_table->text(); 89 | QString reference_field = ui->foreign_field->text(); 90 | if (reference_table == "" || reference_field == "") 91 | { 92 | QMessageBox::warning(this, "警告", "未输入参考值!"); 93 | ui->tableView->show(); 94 | ui->col_name->clear(); 95 | ui->constraint_name->clear(); 96 | ui->foreign_table->clear(); 97 | ui->foreign_field->clear(); 98 | ui->foreign_check->setChecked(false); 99 | ui->notnull_check->setChecked(false); 100 | ui->pk_check->setChecked(false); 101 | ui->unique_check->setChecked(false); 102 | return; 103 | } 104 | else 105 | { 106 | check = "FOREIGN KEY"; 107 | foreigns.push_back(std::make_tuple( 108 | field, reference_table, reference_field, constraintName)); 109 | } 110 | } 111 | if (ui->notnull_check->isChecked()) 112 | { 113 | check = "NOT NULL"; 114 | not_nulls.push_back({field, constraintName}); 115 | } 116 | if (ui->unique_check->isChecked()) 117 | { 118 | check = "UNIQUE"; 119 | uniques.push_back({field, constraintName}); 120 | } 121 | if (ui->pk_check->isChecked()) 122 | { 123 | check = "PRIMARY KEY"; 124 | primes.push_back({field, constraintName}); 125 | } 126 | record.push_back({field, type}); 127 | QList item; 128 | item.append(new QStandardItem(field)); 129 | item.append(new QStandardItem(type)); 130 | item.append(new QStandardItem(check)); 131 | model->appendRow(item); 132 | 133 | ui->tableView->show(); 134 | ui->col_name->clear(); 135 | ui->constraint_name->clear(); 136 | ui->foreign_table->clear(); 137 | ui->foreign_field->clear(); 138 | ui->foreign_check->setChecked(false); 139 | ui->notnull_check->setChecked(false); 140 | ui->pk_check->setChecked(false); 141 | ui->unique_check->setChecked(false); 142 | } 143 | 144 | void createtable::on_finished_table_clicked() 145 | { 146 | QString db; 147 | QString opt; 148 | database_name = ui->dbName_lineEdit->text(); 149 | if (database_name == "") 150 | { 151 | QMessageBox::warning(this, "警告", "请给出数据库名!"); 152 | return; 153 | } 154 | db += "use " + database_name + ";"; 155 | table_name = ui->tableName_lineEdit->text(); 156 | if (table_name == "") 157 | { 158 | QMessageBox::warning(this, "警告", "请给出表名!"); 159 | return; 160 | } 161 | opt += "create table " + table_name + " "; 162 | for (auto const& pair : record) 163 | { 164 | QString field = pair.first; 165 | QString type = pair.second; 166 | opt += field + ' ' + type + ' '; 167 | } 168 | for (auto const& not_null : not_nulls) 169 | { 170 | opt += "CONSTRAINT " + not_null.second + " NOT NULL " + not_null.first + 171 | " "; 172 | } 173 | for (auto const& unique : uniques) 174 | { 175 | opt += "CONSTRAINT " + unique.second + " UNIQUE " + unique.first + " "; 176 | } 177 | for (auto const& prime : primes) 178 | { 179 | opt += 180 | "CONSTRAINT " + prime.second + " PRIMARY KEY " + prime.first + " "; 181 | } 182 | for (auto const& tuple : foreigns) 183 | { 184 | // QString key = std::get<0>(tuple); 185 | // QString table = std::get<1>(tuple); 186 | // QString field = std::get<0>(tuple); 187 | auto [key, table, field, constraint] = tuple; 188 | opt += "CONSTRAINT " + constraint + " FOREIGN KEY " + key + 189 | " REFERENCES " + table + " " + field + " "; 190 | } 191 | opt += ";"; 192 | qDebug() << opt; 193 | emit create_table_signal(db, opt); 194 | this->close(); 195 | } 196 | -------------------------------------------------------------------------------- /core/src/user.cpp: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | User::User(std::string user_name, std::string user_password, std::vector authorities) { 4 | this->user_name = user_name; 5 | this->user_password = user_password; 6 | this->authorities = authorities; 7 | return; 8 | } 9 | 10 | User::User(std::string user_name, std::string user_password) { 11 | this->user_name = user_name; 12 | this->user_password = user_password; 13 | return; 14 | } 15 | 16 | int User::Identify(std::string password) { 17 | if(user_password == password) return kSuccess; 18 | return kIdentifiedFail; 19 | } 20 | 21 | std::string User::GetUserName() const { 22 | return user_name; 23 | } 24 | 25 | std::string User::GetUserPassword() const { 26 | return user_password; 27 | } 28 | //查询数据库级权限 29 | int User::CheckAuthority(std::string database_name, authority_number number) const { 30 | if(user_name == "admin") { 31 | return kSuccess; 32 | } 33 | for(const auto& authority : authorities) { 34 | if(authority.database_name == database_name && authority.number == number) return kSuccess; 35 | } 36 | return kInsufficientAuthority; 37 | } 38 | //查询表级权限 39 | int User::CheckAuthority(std::string database_name, std::string table_name, authority_number number) const { 40 | if(user_name == "admin") { 41 | return kSuccess; 42 | } 43 | for(const auto& authority : authorities) { 44 | if(authority.database_name != database_name) continue; 45 | if(authority.table_name != table_name) continue; 46 | if(authority.number == number) return kSuccess; 47 | } 48 | return kInsufficientAuthority; 49 | } 50 | //添加数据库级权限 51 | int User::GrantAuthority(std::string database_name, authority_number number) { 52 | if(CheckAuthority(database_name, number) == kSuccess) return kAuthorityExisted; 53 | priviledge authority; 54 | authority.database_name = database_name; 55 | authority.table_name = ""; 56 | authority.number = number; 57 | authorities.push_back(authority); 58 | return kSuccess; 59 | } 60 | //添加表级权限 61 | int User::GrantAuthority(std::string database_name, std::string table_name, authority_number number) { 62 | if(CheckAuthority(database_name, table_name, number) == kSuccess) return kAuthorityExisted; 63 | priviledge authority; 64 | authority.database_name = database_name; 65 | authority.table_name = table_name; 66 | authority.number = number; 67 | authorities.push_back(authority); 68 | return kSuccess; 69 | } 70 | //删除数据库级权限 71 | int User::RevokeAuthority(std::string database_name, authority_number number) { 72 | if(CheckAuthority(database_name, number) != kSuccess) return kAuthorityNotFound; 73 | for(int i = 0; i < authorities.size(); ++i) { 74 | const auto& authority = authorities[i]; 75 | if(authority.database_name == database_name && authority.table_name == "" && authority.number == number) { 76 | authorities.erase(authorities.begin() + i); 77 | return kSuccess; 78 | } 79 | } 80 | return kSuccess; 81 | } 82 | //删除表级权限 83 | int User::RevokeAuthority(std::string database_name, std::string table_name, authority_number number) { 84 | if(CheckAuthority(database_name, table_name, number) != kSuccess) return kAuthorityNotFound; 85 | for(int i = 0; i < authorities.size(); ++i) { 86 | const auto& authority = authorities[i]; 87 | if(authority.database_name == database_name && authority.table_name == table_name && authority.number == number) { 88 | authorities.erase(authorities.begin() + i); 89 | return kSuccess; 90 | } 91 | } 92 | return kSuccess; 93 | } 94 | //授予所有表级权限 95 | int User::GrantAllTableAuthorities(std::string database_name, std::string table_name) { 96 | if(CheckAuthority(database_name, table_name, authority_number::SELECT) != kSuccess) { 97 | GrantAuthority(database_name, table_name, authority_number::SELECT); 98 | } 99 | if(CheckAuthority(database_name, table_name, authority_number::DELETE) != kSuccess) { 100 | GrantAuthority(database_name, table_name, authority_number::DELETE); 101 | } 102 | if(CheckAuthority(database_name, table_name, authority_number::INSERT) != kSuccess) { 103 | GrantAuthority(database_name, table_name, authority_number::INSERT); 104 | } 105 | if(CheckAuthority(database_name, table_name, authority_number::UPDATE) != kSuccess) { 106 | GrantAuthority(database_name, table_name, authority_number::UPDATE); 107 | } 108 | if(CheckAuthority(database_name, table_name, authority_number::INDEX) != kSuccess) { 109 | GrantAuthority(database_name, table_name, authority_number::INDEX); 110 | } 111 | if(CheckAuthority(database_name, table_name, authority_number::ALTER) != kSuccess) { 112 | GrantAuthority(database_name, table_name, authority_number::ALTER); 113 | } 114 | return kSuccess; 115 | } 116 | //授予所有数据库级权限 117 | int User::GrantAllDatabaseAuthorities(std::string database_name) { 118 | if(CheckAuthority(database_name, authority_number::CREATE) != kSuccess) { 119 | GrantAuthority(database_name, authority_number::CREATE); 120 | } 121 | if(CheckAuthority(database_name, authority_number::DROP) != kSuccess) { 122 | GrantAuthority(database_name, authority_number::DROP); 123 | } 124 | return kSuccess; 125 | } 126 | //收回所有表级权限 127 | int User::RevokeAllTableAuthorities(std::string database_name, std::string table_name) { 128 | for(auto it = authorities.begin(); it != authorities.end();) { 129 | if(it->database_name == database_name && it->table_name == table_name) { 130 | authorities.erase(it); 131 | } 132 | else it++; 133 | } 134 | return kSuccess; 135 | } 136 | //收回所有数据库级权限 137 | int User::RevokeAllDatabaseAuthorities(std::string database_name) { 138 | for(auto it = authorities.begin(); it != authorities.end();) { 139 | if(it->database_name == database_name && it->table_name =="") { 140 | authorities.erase(it); 141 | } 142 | else it++; 143 | } 144 | return kSuccess; 145 | } 146 | //收回所有数据库级权限和表级权限,指定数据库名 147 | int User::RevokeAllDatabaseAndTableAuthorities(std::string database_name) { 148 | for(auto it = authorities.begin(); it != authorities.end();) { 149 | if(it->database_name == database_name) { 150 | authorities.erase(it); 151 | } 152 | else it++; 153 | } 154 | return kSuccess; 155 | } 156 | int User::CheckDatabaseInAuthorities(std::string database_name) { 157 | if(user_name == "admin") { 158 | return kSuccess; 159 | } 160 | for(const auto& authority : authorities) { 161 | if(authority.database_name == database_name) return kSuccess; 162 | } 163 | return kDatabaseNotFound; 164 | } 165 | int User::CheckTableInAuthorities(std::string database_name, std::string table_name) { 166 | if(user_name == "admin") { 167 | return kSuccess; 168 | } 169 | for(const auto& authority : authorities) { 170 | if(authority.database_name == database_name && authority.table_name == table_name) return kSuccess; 171 | } 172 | return kDatabaseNotFound; 173 | } 174 | std::vector User::GetAuthorities() const { 175 | return authorities; 176 | } -------------------------------------------------------------------------------- /gui/ColaSqlGui/ui/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 900 10 | 621 11 | 12 | 13 | 14 | 15 | 900 16 | 621 17 | 18 | 19 | 20 | 21 | 900 22 | 621 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | #centralwidget{border-image: url(:/images/main/BIGGERONE.png)} 31 | 32 | 33 | 34 | 35 | 200 36 | 290 37 | 680 38 | 230 39 | 40 | 41 | 42 | 43 | 9 44 | 45 | 46 | 47 | true 48 | 49 | 50 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 51 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 52 | p, li { white-space: pre-wrap; } 53 | </style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;"> 54 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Co1aSQL @ </p></body></html> 55 | 56 | 57 | 58 | 59 | 60 | 200 61 | 20 62 | 680 63 | 230 64 | 65 | 66 | 67 | 68 | 69 | 70 | 637 71 | 554 72 | 77 73 | 29 74 | 75 | 76 | 77 | QPushButton#btn_commit{border-image: url(:/images/main/tijiao-1.png)} 78 | QPushButton::pressed#btn_commit{border-image: url(:/images/main/tijiao-2.png)} 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 723 89 | 554 90 | 77 91 | 29 92 | 93 | 94 | 95 | QPushButton#btn_rollback{border-image: url(:/images/main/huitui-1.png)} 96 | QPushButton::pressed#btn_rollback{border-image: url(:/images/main/huitui-2.png)} 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 13 106 | 45 107 | 150 108 | 521 109 | 110 | 111 | 112 | QAbstractItemView::NoEditTriggers 113 | 114 | 115 | 116 | 117 | 118 | 119 | 0 120 | 0 121 | 900 122 | 21 123 | 124 | 125 | 126 | 127 | 用户 128 | 129 | 130 | 131 | 132 | 133 | 134 | 文件 135 | 136 | 137 | 138 | 139 | 140 | 141 | 新建 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 删除 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 查询 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | current_user 173 | 174 | 175 | 176 | 177 | 切换用户 178 | 179 | 180 | 181 | 182 | 保存 183 | 184 | 185 | 186 | 187 | 读取colasql文件 188 | 189 | 190 | 191 | 192 | SQL 193 | 194 | 195 | 196 | 197 | 删除数据库 198 | 199 | 200 | 201 | 202 | 删除表 203 | 204 | 205 | 206 | 207 | 删除所选字段 208 | 209 | 210 | 211 | 212 | 删除所选记录 213 | 214 | 215 | 216 | 217 | 新建数据库 218 | 219 | 220 | 221 | 222 | 新建表 223 | 224 | 225 | 226 | 227 | 新建字段 228 | 229 | 230 | 231 | 232 | 新建记录 233 | 234 | 235 | 236 | 237 | 新建索引 238 | 239 | 240 | 241 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/ui/mainwindow - 副本.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 600 10 | 471 11 | 12 | 13 | 14 | 15 | 600 16 | 471 17 | 18 | 19 | 20 | 21 | 600 22 | 471 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | 31 | 32 | 33 | #centralwidget{border-image: url(:/images/main/main-bg.png)} 34 | 35 | 36 | 37 | 38 | 13 39 | 44 40 | 150 41 | 371 42 | 43 | 44 | 45 | QAbstractItemView::NoEditTriggers 46 | 47 | 48 | 49 | 50 | 51 | 337 52 | 404 53 | 77 54 | 29 55 | 56 | 57 | 58 | QPushButton#btn_commit{border-image: url(:/images/main/tijiao-1.png)} 59 | QPushButton::pressed#btn_commit{border-image: url(:/images/main/tijiao-2.png)} 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 423 70 | 404 71 | 77 72 | 29 73 | 74 | 75 | 76 | QPushButton#btn_rollback{border-image: url(:/images/main/huitui-1.png)} 77 | QPushButton::pressed#btn_rollback{border-image: url(:/images/main/huitui-2.png)} 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 200 87 | 14 88 | 385 89 | 165 90 | 91 | 92 | 93 | 94 | 95 | 96 | 200 97 | 209 98 | 385 99 | 165 100 | 101 | 102 | 103 | 104 | 9 105 | 106 | 107 | 108 | true 109 | 110 | 111 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 112 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 113 | p, li { white-space: pre-wrap; } 114 | </style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;"> 115 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Co1aSQL @ </p></body></html> 116 | 117 | 118 | 119 | 120 | 121 | 122 | 0 123 | 0 124 | 600 125 | 21 126 | 127 | 128 | 129 | 130 | 新建 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 删除 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 查询 150 | 151 | 152 | 153 | 154 | 155 | 文件 156 | 157 | 158 | 159 | 160 | 161 | 162 | 用户 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | table 176 | 177 | 178 | 179 | 180 | row 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 新建表 191 | 192 | 193 | 194 | 195 | 新建记录 196 | 197 | 198 | 199 | 200 | 新建字段 201 | 202 | 203 | 204 | 205 | 新建数据库 206 | 207 | 208 | 209 | 210 | 删除数据库 211 | 212 | 213 | 214 | 215 | 删除表 216 | 217 | 218 | 219 | 220 | SQL 221 | 222 | 223 | 224 | 225 | 保存 226 | 227 | 228 | 229 | 230 | 加载 231 | 232 | 233 | 234 | 235 | 删除所选字段 236 | 237 | 238 | 239 | 240 | 删除所选记录 241 | 242 | 243 | 244 | 245 | 读取colasql文件 246 | 247 | 248 | 249 | 250 | 新建索引 251 | 252 | 253 | 254 | 255 | 切换用户 256 | 257 | 258 | 259 | 260 | current_user 261 | 262 | 263 | 264 | 265 | 266 | 267 | -------------------------------------------------------------------------------- /gui/ColaSqlGui/ui/secondarywindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 600 10 | 471 11 | 12 | 13 | 14 | 15 | 600 16 | 471 17 | 18 | 19 | 20 | 21 | 600 22 | 471 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | 31 | 32 | 33 | #centralwidget{border-image: url(:/images/main/main-bg.png)} 34 | 35 | 36 | 37 | 38 | 13 39 | 44 40 | 150 41 | 371 42 | 43 | 44 | 45 | QAbstractItemView::NoEditTriggers 46 | 47 | 48 | 49 | 50 | 51 | 337 52 | 404 53 | 77 54 | 29 55 | 56 | 57 | 58 | QPushButton#btn_commit{border-image: url(:/images/main/tijiao-1.png)} 59 | QPushButton::pressed#btn_commit{border-image: url(:/images/main/tijiao-2.png)} 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 423 70 | 404 71 | 77 72 | 29 73 | 74 | 75 | 76 | QPushButton#btn_rollback{border-image: url(:/images/main/huitui-1.png)} 77 | QPushButton::pressed#btn_rollback{border-image: url(:/images/main/huitui-2.png)} 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 200 87 | 14 88 | 385 89 | 165 90 | 91 | 92 | 93 | 94 | 95 | 96 | 200 97 | 209 98 | 385 99 | 165 100 | 101 | 102 | 103 | 104 | 9 105 | 106 | 107 | 108 | true 109 | 110 | 111 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 112 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 113 | p, li { white-space: pre-wrap; } 114 | </style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;"> 115 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Co1aSQL @ </p></body></html> 116 | 117 | 118 | 119 | 120 | 121 | 122 | 0 123 | 0 124 | 600 125 | 21 126 | 127 | 128 | 129 | 130 | 新建 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 删除 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 查询 150 | 151 | 152 | 153 | 154 | 155 | 文件 156 | 157 | 158 | 159 | 160 | 161 | 162 | 用户 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | table 176 | 177 | 178 | 179 | 180 | row 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 新建表 191 | 192 | 193 | 194 | 195 | 新建记录 196 | 197 | 198 | 199 | 200 | 新建字段 201 | 202 | 203 | 204 | 205 | 新建数据库 206 | 207 | 208 | 209 | 210 | 删除数据库 211 | 212 | 213 | 214 | 215 | 删除表 216 | 217 | 218 | 219 | 220 | SQL 221 | 222 | 223 | 224 | 225 | 保存 226 | 227 | 228 | 229 | 230 | 加载 231 | 232 | 233 | 234 | 235 | 删除所选字段 236 | 237 | 238 | 239 | 240 | 删除所选记录 241 | 242 | 243 | 244 | 245 | 读取colasql文件 246 | 247 | 248 | 249 | 250 | 新建索引 251 | 252 | 253 | 254 | 255 | 切换用户 256 | 257 | 258 | 259 | 260 | current_user 261 | 262 | 263 | 264 | 265 | 266 | 267 | -------------------------------------------------------------------------------- /core/src/index/fhqtreapindex.cpp: -------------------------------------------------------------------------------- 1 | #include "index/fhqtreapindex.h" 2 | 3 | #include 4 | 5 | FHQTreapIndex::FHQTreapIndex( 6 | const std::vector>& records, 7 | const std::vector>& fields, 8 | const std::unordered_map& field_map, 9 | const std::vector& compare_key) 10 | : Index(records, fields, field_map, compare_key) 11 | { 12 | _records_ptr = nullptr; 13 | _field_map_ptr = nullptr; 14 | build(records, fields, field_map, compare_key); 15 | } 16 | 17 | FHQTreapIndex::~FHQTreapIndex() 18 | { 19 | // delete _records_ptr; 20 | _records_ptr = nullptr; 21 | // delete _field_map_ptr; 22 | _field_map_ptr = nullptr; 23 | } 24 | 25 | int FHQTreapIndex::build( 26 | const std::vector>& records, 27 | const std::vector>& fields, 28 | const std::unordered_map& field_map, 29 | const std::vector& compare_key) 30 | { 31 | // ===== Records ===== 32 | // delete _records_ptr; 33 | _records_ptr = nullptr; 34 | _records_ptr = 35 | new std::vector>(records); 36 | 37 | // delete _field_map_ptr; 38 | _field_map_ptr = nullptr; 39 | _field_map_ptr = 40 | new std::unordered_map(field_map); 41 | 42 | // ===== Compare Key ===== 43 | // n^2 optimization could be used here 44 | _compare_key = compare_key; 45 | for (const auto& field : fields) 46 | { 47 | int flag = 1; 48 | for (const auto& key : _compare_key) 49 | { 50 | if (field.first == key) 51 | { 52 | flag = 0; 53 | break; 54 | } 55 | } 56 | if (flag) 57 | { 58 | _compare_key.push_back(field.first); 59 | } 60 | } 61 | 62 | // ===== Build Tree ===== 63 | reset(); 64 | t = std::vector(records.size() + 2000); 65 | for (int i = 0; i < records.size(); i++) 66 | { 67 | insert(i); 68 | } 69 | 70 | // ===== End ===== 71 | _state = 0; 72 | return _state; 73 | } 74 | 75 | int FHQTreapIndex::query( 76 | const std::vector>& conditions, 77 | std::vector& result_indexes) 78 | { 79 | result_indexes.clear(); 80 | 81 | if (_state != 0) 82 | { 83 | return kFailedIndexNotBuild; 84 | } 85 | 86 | // 用作比较 87 | std::unordered_map recordBasedOnConditions; 88 | 89 | // 构建 recordBasedOnConditions 90 | for (int i = 0, cnt = 0; i < _compare_key.size() && cnt < conditions.size(); 91 | i++) 92 | { 93 | int flag = false; 94 | for (const auto& [name, value, type] : conditions) 95 | { 96 | if (type != kEqualConditon) 97 | { 98 | return kFailedConditionRelationNotSupport; 99 | } 100 | if (name != _compare_key[i]) 101 | { 102 | continue; 103 | } 104 | if (recordBasedOnConditions.count(name) > 0) 105 | { 106 | return kFailedConditionDuplicate; 107 | } 108 | recordBasedOnConditions.insert( 109 | {name, ColasqlTool::GetAnyByTypeAndValue( 110 | _field_map_ptr->at(name), value)}); 111 | flag = true; 112 | break; 113 | } 114 | if (flag) 115 | { // this key is in condition 116 | cnt += 1; 117 | } 118 | else 119 | { // this key is not in condition 120 | return kFailedIndexCouldnotSpeedup; 121 | } 122 | } 123 | 124 | // for(auto& [str, any]: recordBasedOnConditions) { 125 | // std::cout << str << ", " << ColasqlTool::AnyToString(any) << 126 | // std::endl; 127 | // } 128 | 129 | // query 130 | int a, b, c; 131 | splitvR(rt, recordBasedOnConditions, a, b); 132 | splitv(b, recordBasedOnConditions, b, c, false); 133 | 134 | output(b, result_indexes); 135 | 136 | rt = merge(a, merge(b, c)); 137 | 138 | return 0; // success 139 | } 140 | 141 | // ===== FHQ Treap ===== 142 | #define LC (t[x].c[0]) 143 | #define RC (t[x].c[1]) 144 | 145 | void FHQTreapIndex::reset() 146 | { 147 | rt = 0; 148 | tot = 0; 149 | } 150 | 151 | void FHQTreapIndex::pushup(int x) { t[x].siz = t[LC].siz + t[RC].siz + 1; } 152 | 153 | int FHQTreapIndex::newNode(int va) 154 | { 155 | tot++; 156 | t[tot].c[0] = 0; 157 | t[tot].c[1] = 0; 158 | t[tot].siz = 1; 159 | t[tot].pos = rand() << 15 | rand(); 160 | t[tot].va = va; 161 | return tot; 162 | } 163 | 164 | void FHQTreapIndex::splits(int x, int siz, int& l, int& r) 165 | { 166 | if (x == 0) 167 | { 168 | l = r = 0; 169 | return; 170 | } 171 | if (siz <= t[LC].siz) 172 | { 173 | r = x; 174 | splits(LC, siz, l, LC); 175 | } 176 | else 177 | { 178 | l = x; 179 | splits(RC, siz - t[LC].siz - 1, RC, r); 180 | } 181 | pushup(x); 182 | } 183 | 184 | void FHQTreapIndex::splitv(int x, int va, int& l, int& r, bool nullIsLess) 185 | { 186 | if (x == 0) 187 | { 188 | l = r = 0; 189 | return; 190 | } 191 | if (compare(va, t[x].va, nullIsLess) < 0) 192 | { 193 | r = x; 194 | splitv(LC, va, l, LC, nullIsLess); 195 | } 196 | else 197 | { 198 | l = x; 199 | splitv(RC, va, RC, r, nullIsLess); 200 | } 201 | pushup(x); 202 | } 203 | 204 | void FHQTreapIndex::splitv(int x, 205 | const std::unordered_map& va, 206 | int& l, int& r, bool nullIsLess) 207 | { 208 | if (x == 0) 209 | { 210 | l = r = 0; 211 | return; 212 | } 213 | if (compare(va, t[x].va, nullIsLess) < 0) 214 | { 215 | r = x; 216 | splitv(LC, va, l, LC, nullIsLess); 217 | } 218 | else 219 | { 220 | l = x; 221 | splitv(RC, va, RC, r, nullIsLess); 222 | } 223 | pushup(x); 224 | } 225 | 226 | void FHQTreapIndex::splitvR(int x, int va, int& l, int& r, bool nullIsLess) 227 | { 228 | if (x == 0) 229 | { 230 | l = r = 0; 231 | return; 232 | } 233 | if (compare(va, t[x].va, nullIsLess) <= 0) 234 | { 235 | r = x; 236 | splitvR(LC, va, l, LC, nullIsLess); 237 | } 238 | else 239 | { 240 | l = x; 241 | splitvR(RC, va, RC, r, nullIsLess); 242 | } 243 | pushup(x); 244 | } 245 | 246 | void FHQTreapIndex::splitvR(int x, 247 | const std::unordered_map& va, 248 | int& l, int& r, bool nullIsLess) 249 | { 250 | if (x == 0) 251 | { 252 | l = r = 0; 253 | return; 254 | } 255 | if (compare(va, t[x].va, nullIsLess) <= 0) 256 | { 257 | r = x; 258 | splitvR(LC, va, l, LC, nullIsLess); 259 | } 260 | else 261 | { 262 | l = x; 263 | splitvR(RC, va, RC, r, nullIsLess); 264 | } 265 | pushup(x); 266 | } 267 | 268 | int FHQTreapIndex::merge(int l, int r) 269 | { 270 | if (l == 0 || r == 0) 271 | return l + r; 272 | if (t[l].pos < t[r].pos) 273 | { 274 | t[l].c[1] = merge(t[l].c[1], r); 275 | pushup(l); 276 | return l; 277 | } 278 | else 279 | { 280 | t[r].c[0] = merge(l, t[r].c[0]); 281 | pushup(r); 282 | return r; 283 | } 284 | } 285 | 286 | void FHQTreapIndex::output(int x, std::vector& result) 287 | { 288 | if (x == 0) 289 | return; 290 | result.push_back(t[x].va); 291 | output(LC, result); 292 | output(RC, result); 293 | } 294 | 295 | #undef LC 296 | #undef RC 297 | 298 | void FHQTreapIndex::insert(int va) 299 | { 300 | int a, b; 301 | splitv(rt, va, a, b); 302 | rt = merge(merge(a, newNode(va)), b); 303 | } 304 | 305 | void FHQTreapIndex::erase(int va) 306 | { 307 | int a, b, c; 308 | splitv(rt, va, a, b); 309 | splitv(a, t[a].siz - 1, a, c); 310 | rt = merge(a, b); 311 | } 312 | 313 | int FHQTreapIndex::getRank(int va) 314 | { 315 | int a, b, ans; 316 | splitv(rt, va - 1, a, b); 317 | ans = t[a].siz + 1; 318 | rt = merge(a, b); 319 | return ans; 320 | } 321 | 322 | int FHQTreapIndex::getNumber(int siz) 323 | { 324 | int a, b, c, ans; 325 | splits(rt, siz, a, b); 326 | splits(a, siz - 1, a, c); 327 | ans = t[c].va; 328 | rt = merge(merge(a, c), b); 329 | return ans; 330 | } 331 | 332 | int FHQTreapIndex::getLower(int va) 333 | { 334 | int a, b, c, ans; 335 | splitv(rt, va - 1, a, b); 336 | splits(a, t[a].siz - 1, a, c); 337 | ans = t[c].va; 338 | rt = merge(merge(a, c), b); 339 | return ans; 340 | } 341 | 342 | int FHQTreapIndex::getUpper(int va) 343 | { 344 | int a, b, c, ans; 345 | splitv(rt, va, a, b); 346 | splits(b, 1, b, c); 347 | ans = t[b].va; 348 | rt = merge(a, merge(b, c)); 349 | return ans; 350 | } 351 | -------------------------------------------------------------------------------- /core/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "colasqltool.h" 3 | #include "constants.h" 4 | #include "dataprocessor.h" 5 | #include "all_constraints.h" 6 | int main() { 7 | std::cout<< DataProcessor::GetInstance().CreateUser(std::string("admin"),std::string("123456"))<> fields; 16 | fields.push_back({"Sno", "string"}); 17 | fields.push_back({"Sname", "string"}); 18 | fields.push_back({"Age", "int"}); 19 | std::vector constraints; 20 | std::cout<> record_in; 38 | record_in.clear(); 39 | record_in.push_back({"Cno", "001"}); 40 | record_in.push_back({"Cname", "software"}); 41 | std::cout< field_name; 96 | field_name.push_back("*"); 97 | std::vector> conditions; 98 | //conditions.push_back(std::make_tuple("Age","50", kLargerConditon)); 99 | //conditions.push_back(std::make_tuple("Sname","hahaha", kEqualConditon)); 100 | std::vector> return_records; 101 | std::cout< table_names; 124 | 125 | table_name = "student"; 126 | table_names.push_back(table_name); 127 | table_name = "course"; 128 | table_names.push_back(table_name); 129 | table_name = "sc"; 130 | table_names.push_back(table_name); 131 | 132 | conditions.clear(); 133 | conditions.push_back(std::make_tuple("Grade","50", kLargerEqualCondition)); 134 | conditions.push_back(std::make_tuple("Cname","software", kEqualConditon)); 135 | 136 | field_name.clear(); 137 | field_name.push_back("Sname"); 138 | field_name.push_back("Cname"); 139 | field_name.push_back("Grade"); 140 | return_records.clear(); 141 | std::cout<>& value, const std::vector>& conditions); 167 | std::vector> values; 168 | conditions.clear(); 169 | values.push_back({"Age","70"}); 170 | conditions.push_back({"Sno","21301032",kEqualConditon}); 171 | conditions.push_back({"Sname","drj",kNotEqualConditon}); 172 | std::cout< new_field = {"Ssex","string"}; 179 | DataProcessor::GetInstance().AlterTableAdd("student", new_field); 180 | std::cout< field); 185 | std::cout<<"here : "< databases; 202 | std::cout< tables; 208 | std::cout<>& fields,std::vector& constraints); 213 | std::vector> table_fields; 214 | 215 | std::vector table_constraints; 216 | std::cout< 2023-BJTU-DBMS-Project 6 | > 7 | > 北京交通大学软件学院 2023年春季 实训课项目 数据库管理系统 8 | 9 | ### 1. 简介 10 | 11 | #### 1.1 软件介绍 12 | 13 | * 软件名称:**Co1aSQL** —— 数据库管理系统 14 | * 我们需要实现一个数据库管理系统,支持数据库的创建、数据库表的管理、记录的添加与查询、完整性 约束的实现,索引的创建与实现,多用户等功能。 15 | * 数据库管理系统是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库。它对数据库进行 统一的管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中的数据, 数:据库管理员也通过数据库管理系统进行数据库的维护工作。它可使多个应用程序和用户用不同的方法 在同时或不同时刻去建立,修改和询问数据库。 16 | * 我们也支持用户使用SQL语句来控制数据库,包括DDL、DML、DCL,供用户定义数据库的模式结构与 权限约束,实现对数据的追加、删除等操作。 17 | * 项目结构:![pic](./document/pictures/ProjectConstruction.png) 18 | 19 | #### 1.2 基本功能 20 | 21 | * 创建、删除数据库 22 | * 创建、修改、删除表 23 | * 插入、更新、查询、删除记录 24 | * 三种数据类型:int, float, string 25 | * 数据库文件 26 | 27 | #### 1.3 拓展功能 28 | 29 | * SQL脚本文件 30 | * 复杂Select语句 31 | * 数据持久化/事务管理 32 | * 基于无旋Treap的索引 33 | * 完整性管理(主键、外键、UNIQUE、NOT NULL、DEFAULT) 34 | * 安全性管理(用户、权限) 35 | * GUI点击修改记录 36 | 37 | #### 1.4 结题报告 38 | 39 | * [结题报告](./document/FinalDocument.md) 40 | 41 | *** 42 | 43 | ### 2. 构建与使用 44 | 45 | #### 2.1 Release 46 | 47 | * 本仓库的Release中有已经构建好的可执行程序。 48 | * 使用账户 `admin`与密码 `123456` 即可登录。 49 | 50 | #### 2.2 项目版本 51 | * gcc 13.1.1 52 | * c++17 53 | * qt 5.15.9 54 | * cmake 3.26.3 55 | * qmake 3.1 56 | #### 2.3 构建CLI 57 | ``` 58 | cd cmd 59 | cmake -Bbuild 60 | make -Cbuild -j8 61 | ``` 62 | #### 2.4 启动CLI 63 | ``` 64 | build/colasql admin 123456; 65 | ``` 66 | #### 2.5 构建GUI 67 | ``` 68 | cd gui/ColaSqlGui 69 | qmake -o build/Makefile ColaSqlGui.pro 70 | make -Cbuild -j8 71 | ``` 72 | #### 2.6 启动GUI 73 | ``` 74 | build/ColaSqlGui 75 | ``` 76 | #### 2.7 管理员账户 77 | 78 | * 请使用 `admin` 与 `123456` 来登入数据库 79 | 80 | #### 2.8 FAQ 81 | 82 | * 有关 `#include\` 的编译错误 83 | * gcc在c++17中支持了 `filemanager` 库,但qt5在c++17中只支持 `experimental/filemanager`,需要根据环境具体决定。可以在 `file/src/filemanager.cpp` 中修改对应内容。 84 | 85 | *** 86 | 87 | ### 3. GUI展示 88 | 89 | ![pic](./document/pictures/pic1.png) 90 | 91 | ![pic](./document/pictures/pic2.png) 92 | 93 | ![pic](./document/pictures/pic3.png) 94 | 95 | *** 96 | 97 | ### 4. SQL语法 98 | 99 | #### 4.1 基本约定 100 | 101 | * Co1aSQL 支持的SQL语法,均为 **大小写不敏感**。 102 | * Co1aSQL 在预处理SQL语句时,会自动将所有的小括号和逗号替换为空格,以尽可能兼容标准SQL。 103 | 104 | #### 4.2 用户 105 | 106 | * 登入数据库 107 | 108 | ```sql 109 | colasql 用户名 密码 110 | #管理员用户名admin,密码colasql 111 | LOGIN 用户名 密码; 112 | ``` 113 | 114 | * 创建用户 115 | 116 | ```sql 117 | CREATE USER 用户名 密码; 118 | #所有用户默认拥有数据库的查询权、创建权,只对自己创建的数据库有删除权 119 | #创建用户不需要任何权限,但授予权限只能授予自己拥有的权限 120 | #其它说明见下 121 | ``` 122 | 123 | * 修改用户权限 124 | 125 | ```sql 126 | GRANT USER 用户名 数据库名 表名 权限名; 127 | #数据库名和表名都不能为"*",对某个特定的数据库的表授予权限。 128 | 129 | GRANT USER 用户名 数据库名 权限名; 130 | #数据库名为"*",对所有数据库的所有表授予权限(当前用户拥有该数据库的权限,仅admin可用)。 131 | #数据库名不为"*"时,若为表级权限则授予该数据库里所有表的表级权限(当前用户需拥有授权的所有权限),若为数据库级权限则授予该数据库的数据库级权限(当前用户需拥有该权限)。 132 | ``` 133 | 134 | * 权限名 135 | 136 | ```sql 137 | #表级权限 138 | SELECT 139 | DELETE 140 | INSERT 141 | UPDATE 142 | INDEX 143 | ALTER 144 | 145 | #数据库级权限 146 | CREATE 147 | DROP 148 | 149 | #ALL表示以上所有权限,仅数据库管理员(admin)可用 150 | #ALL 151 | ``` 152 | 153 | * 删除用户(需要管理员权限) 154 | 155 | ```sql 156 | DROP USER 用户名; 157 | ``` 158 | 159 | #### 4.3 数据类型 160 | 161 | * ```sql 162 | int # 42位整数,如 1, 14, 514 163 | float # 42位浮点数,如 1.0, 5.1, 2 164 | string # 字符串,如 "dbms", "2002-10-12" 165 | ``` 166 | 167 | #### 4.4 数据库 168 | 169 | * 创建数据库(需要管理员权限) 170 | 171 | ```sql 172 | CREATE DATABASE 数据库名; 173 | ``` 174 | 175 | * 删除数据库(需要管理员权限) 176 | 177 | ```sql 178 | DROP DATABASE 数据库名; 179 | ``` 180 | 181 | * 使用数据库 182 | 183 | ```sql 184 | USE 数据库名; 185 | ``` 186 | 187 | * 显示所有数据库 188 | 189 | ```sql 190 | SHOW DATABASES; 191 | ``` 192 | 193 | #### 4.5 表 194 | 195 | * 创建表(需要CREATE权限) 196 | 197 | ```sql 198 | CREATE TABLE 表名 199 | 列名1 类型1 200 | 列名2 类型2 201 | ... 202 | 203 | 约束条件1 204 | 约束条件2 205 | ... 206 | ; 207 | ``` 208 | 209 | * 约束条件语法 210 | 211 | ```sql 212 | CONSTRAINT 约束名 PRIMARY KEY 列名; # 指定主键 213 | CONSTRAINT 约束名 FOREIGN KEY 列名 REFERENCES 表名2 列名2; # 指定外键,该列 参考 表2的列2 214 | CONSTRAINT 约束名 UNIQUE 列名; # 指定该列值不可重复(未指定时,默认可重) 215 | CONSTRAINT 约束名 NOT NULL 列名; # 指定该列非空(未指定时,默认可空) 216 | CONSTRAINT 约束名 DEFAULT 列名 值; # 指定该列默认值(未指定时,默认值为NULL) 217 | ``` 218 | 219 | * 删除表(需要DROP权限) 220 | 221 | ```sql 222 | DROP TABLE 表名; 223 | ``` 224 | 225 | * 修改表(需要ALTER权限) 226 | 227 | ```sql 228 | ALTER TABLE 表名 ADD 列名 类型; 229 | ALTER TABLE 表名 DROP 列名; 230 | ALTER TABLE 表名 MODIFY 列名 类型; 231 | ALTER TABLE 表名 约束条件; 232 | ALTER TABLE 表名 DELETE 约束条件名; 233 | ``` 234 | 235 | * 约束条件语法见上文 236 | * 约束条件名可以通过“查看表结构”语句来查看。 237 | 238 | * 查看表结构(需要SELECT权限) 239 | 240 | ```sql 241 | DESC TABLE 表名; 242 | ``` 243 | 244 | * 显示所有表 245 | 246 | ```sql 247 | SHOW TABLES; 248 | ``` 249 | 250 | * 索引相关 251 | 252 | ```sql 253 | CREATE INDEX ON 表名 列名1 列名2 ...; 254 | ``` 255 | 256 | * 以上述列名为关键字建立索引,在Select时Where列需为此处列的前缀才可以触发索引。 257 | 258 | * 查看约束 259 | ```sql 260 | SHOW CONSTRAINTS; 261 | SHOW CONSTRAINT ON 表名; 262 | ``` 263 | 264 | 265 | #### 4.6 记录 266 | 267 | * 插入记录 268 | 269 | ```sql 270 | INSERT INTO 表名 列名1 列名2 列名3 ... VALUES 值1 值2 值3 ...; 271 | ``` 272 | 273 | * 删除记录 274 | 275 | ```sql 276 | DELETE FROM 表名 [WHERE 筛选条件1 筛选条件2 ...]; 277 | ``` 278 | 279 | * 筛选条件语法 280 | 281 | ```sql 282 | 列名 = 值 283 | ``` 284 | 285 | * **筛选条件'='左右必须要包含空格**,否则会产生解析错误 286 | 287 | * 选择记录 288 | 289 | ```sql 290 | SELECT 列名1 列名2 列名3 ... 291 | FROM 表名1 [NATURAL JOIN 表名2 ...] 292 | [WHERE 筛选条件1 筛选条件2 ...] 293 | [ORDER BY 列名1 列名2 ...]; 294 | ``` 295 | 296 | * 更新记录 297 | 298 | ```sql 299 | UPDATE 表名 SET 列名1 = 值1 [列名2 = 值2 ...] 300 | [WHERE 筛选条件1 筛选条件2 ...]; 301 | ``` 302 | 303 | #### 4.7 文件 304 | 305 | * 储存 & 提交 306 | 307 | ```mysql 308 | SAVE; 309 | COMMIT; 310 | ``` 311 | 312 | * 回滚 & 读取 313 | 314 | ```mysql 315 | READ; 316 | ROLLBACK; 317 | ``` 318 | 319 | #### 4.8 Co1aSQL脚本执行 320 | 321 | * 执行Co1aSQL脚本 322 | * ``` 323 | RUN path/to/directory/script.colasql 324 | ``` 325 | 326 | * 注意!此处不能在语句末尾加 `;`,否则会解析失败! 327 | 328 | #### 4.9 关键字 329 | 330 | * `NULL` 为Co1aSQL关键字,若占用,则不一定能得到预期结果 331 | 332 | *** 333 | 334 | ### 5. C++函数接口 335 | 336 | #### 5.1 基本约定 337 | 338 | * 异常 339 | * 不使用异常,而是使用 函数返回值 来表示执行状态,用 assert断言 来处理一些重大异常。 340 | * 若函数返回值为0,则表示操作成功;若函数返回值不为0,则表示操作失败,函数返回值表示失败原因; 341 | * 此处只规定接口的大致形式,细节不做规定,可 **自由发挥**。 342 | * 比如,可以把以下接口置于不同类中; 343 | * 比如,可以让 使用数据库(登录)方法 返回一个 数据库对象,通过该对象来操作数据库。 344 | 345 | #### 5.2 数据载体 346 | 347 | * ```c++ 348 | // 属性(字段) 349 | std::pair field; 350 | std::unordered_map records; 351 | 352 | // 约束条件 353 | Class Constraint {}; 354 | Class PrimaryKeyConstraint: public Constraint {}; 355 | Class ForeignKeyConstraint: public Constraint {}; 356 | Class UniqueConstraint: public Constraint {}; 357 | Class NotNullConstraint: public Constraint {}; 358 | Class DefaultConstraint: public Constraint {}; 359 | ``` 360 | 361 | #### 5.3 用户 362 | 363 | * ```c++ 364 | // 创建用户(需要管理员权限) 365 | int CreateAccount(std::string accountName, 366 | std::string password, 367 | bool ownAllDatabases, 368 | std::string databaseName, 369 | int authority); 370 | 371 | // 删除用户(需要管理员权限) 372 | int DeleteAccount(std::string accountName); 373 | 374 | // 修改用户权限 375 | int GrantAccount(std::string accountName, 376 | bool ownAllDatabases, 377 | std::string databaseName, 378 | int authority); 379 | ``` 380 | 381 | #### 5.4 数据库 382 | 383 | * ```c++ 384 | // 创建数据库(需要管理员权限) 385 | int CreateDatabase(std::string databaseName); 386 | 387 | // 删除数据库(需要管理员权限) 388 | int DeleteDatabase(std::string databaseName); 389 | 390 | // 使用数据库 —— 该函数会对其他函数产生影响 391 | int UseDatabase(std::string databaseName, 392 | std::string accountName, 393 | std::string password); 394 | 395 | // 显示所有数据库 396 | int ShowDatabase(std::string& output); 397 | ``` 398 | 399 | #### 5.5 表 400 | 401 | * ```c++ 402 | // 创建表 403 | int CreateTable(std::string tableName, 404 | const std::vector>& fields, 405 | const std::vector& constraints); 406 | 407 | // 删除表 408 | int DeleteTable(std::string tableName); 409 | 410 | // 修改表 411 | int AlterTableAdd(std::string tableName, Field field); 412 | int AlterTableDrop(std::string tableName, std::string fieldName); 413 | int AlterTableModify(std::string tableName, std::string fieldName, Field field); 414 | int AlterTableConstraint(std::string tableName, Constraint constraint); 415 | int AlterTableDeleteConstraint(std::string tableName, std::string constraintName); 416 | 417 | // 查看表结构(通过&output来输出结果) 418 | int QueryTable(std::string tableName, std::string& output) const; 419 | 420 | // 显示当前数据库的所有表 421 | int ShowTable(std::string& output); 422 | ``` 423 | 424 | #### 5.6 记录 425 | 426 | * ```c++ 427 | // 插入记录 428 | int InsertRecord(std::string tableName, 429 | const std::vector& values); 430 | 431 | // 删除记录(conditions储存筛选条件,根据筛选条件删除记录) 432 | int DeleteRecord(std::string tableName, 433 | const std::vector& conditions); 434 | 435 | // SelectRecord的参数需要修改!!!目前不完善!!! 436 | // 选择(查询)记录(conditions储存筛选条件) 437 | int SelectRecord(std::string tableName, 438 | const std::vector& conditions, 439 | std::string& output) const; 440 | 441 | // 更新记录 442 | int UpdateRecord(std::string tableName, 443 | const std::vector& values, 444 | const std::vector& conditions); 445 | ``` 446 | 447 | *** 448 | 449 | ### 6. 小故事 450 | 451 | * lovekdl测试时发现的Bug 452 | * 管理员给用户授予了查看表和修改表的权限,然后用户不小心把表改错了,所以进行了回滚,然后回滚的时候,系统把他查看表的权限也回滚了,导致他把自己的权限滚掉了(笑死) 453 | * 这个Bug因为过于有趣,所以被保留了,有兴趣可以尝试一下 454 | 455 | *** 456 | 457 | ### 7. 其他 458 | 459 | #### 7.1 资源 460 | 461 | * 本软件图片素材主要来自小组成员 [ZY_](https://space.bilibili.com/67662455) 462 | 463 | #### 7.2 协议 464 | 465 | * 本项目代码采用MIT协议 466 | 467 | #### 7.3 开发人员与分工 468 | 469 | * [F1qi](https://github.com/FooLiqi) 470 | * GUI开发 471 | * [lovekdl](https://github.com/lovekdl) 472 | * 核心模块开发 473 | * [YXH_XianYu](https://github.com/YXHXianYu) 474 | * CLI模块与文件模块开发 475 | * [ZY-MC](https://github.com/ZY-MC) 476 | * GUI设计与素材绘制 477 | --------------------------------------------------------------------------------