From 63faaf68f98cbebff168bc0234de3e72034fda9a Mon Sep 17 00:00:00 2001
From: StarDust <375670450@qq.com>
Date: Mon, 20 Jun 2016 22:23:04 +0800
Subject: [PATCH 1/2] update readme.md
---
MicroSQL.vcxproj | 1 +
MicroSQL.vcxproj.filters | 3 +
README.docx | Bin 0 -> 13631 bytes
README.md | 179 +++++++++++++++-----
src/IndexScan.hpp | 13 +-
src/Printer.hpp | 347 +++++++++++++++++++++++++++++++++++++++
src/QueryManager.hpp | 42 +++++
src/SystemManager.hpp | 3 +
src/Utils.hpp | 17 +-
9 files changed, 555 insertions(+), 50 deletions(-)
create mode 100644 README.docx
create mode 100644 src/Printer.hpp
diff --git a/MicroSQL.vcxproj b/MicroSQL.vcxproj
index c5e2905..a9aeaea 100644
--- a/MicroSQL.vcxproj
+++ b/MicroSQL.vcxproj
@@ -27,6 +27,7 @@
+
diff --git a/MicroSQL.vcxproj.filters b/MicroSQL.vcxproj.filters
index afb7ee4..80ea2e4 100644
--- a/MicroSQL.vcxproj.filters
+++ b/MicroSQL.vcxproj.filters
@@ -95,5 +95,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/README.docx b/README.docx
new file mode 100644
index 0000000000000000000000000000000000000000..c920d307a73d361fc1ada386049333c2fa568b94
GIT binary patch
literal 13631
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 注:
-> 1. 每个页面的大小(字节)用PF_PAGE_SIZE表示, 默认为4K (4096字节)
-> 2. 内存池中的页面数用PF_BUFFER_SIZE表示, 默认为40
-> 3. 所有作为存储函数返回结果的指针传进来时应保证其原来的数据(如果有的话)已经无需再使用了
-
-
-##RecordManager
-RM模块提供的类和方法用于把记录存储在文件中, 相当于PF模块的客户端. 在这个模块中需要调用PF模块中已经实现的函数.
-
-###文件头
-为了便于管理文件内容, 可以把每个文件的第一个Page作为一个特殊的Header Page, 用于存储空闲空间的信息, 文件存储的记录数, 每个页面存储的记录数, 文件的当前页面数以及其他与整个文件有关的信息. 每个页面也包含一个页面头.
-
-###记录标识符
-RecordIdentifier类对一个指定文件中的所有记录提供唯一标识, 因此一条指定记录的标识符应该是保持不变的. 即一个标识符的属性在记录更新或其他记录插入/删除的条件下都是恒定的. 每个文件的页面有数量不等的Slot(根据每个文件的Record的大小确定), 但一个文件内的所有页面Slot数相同. 在这个系统中只用页面号(PageNum)以及槽号(SlotNum)来构成为RecordIdentifier.
-
-###记录空闲空间
-当需要插入记录时, 不应该线性搜索有空余的页面. 为了提高搜索效率, 可以使用一个页的链表来存储有空余Slot的页面.
-
-
-每个文件中存储的记录必须是等长的, 这样能更方便地管理每个页面上的记录和空闲空间, 而且保证了每个记录的位置都能够方便地访问到. 最好每个表单独存储在一个文件中.
-
-
+
+# MicroSQL 开发文档
+
+----------------------------
+
+##一. 总体框架
+
+#### 1.1 概述
+
+MicroSQL是一个轻量级的关系型数据库, 框架的设计思路主要根据斯坦福大学的[Database System Implementation(CS346)](https://web.stanford.edu/class/cs346/2015/)课程提供的Redbase数据库框架来设计.
+主要包含5个模块:
+ - PageFile(PF)
+ - RecordManager(RM)
+ - IndexManager(IX)
+ - SystemManager(SM)
+ - QueryManager(QM)
+ 在具体的实现中, 为了遵循模块化程序设计的原则, 将各个模块按照不同的功能分成多个类来实现, 具体实现细节将在后面介绍
+
+#### 1.2 层次结构
+
+#### 1.3 基本功能
+ - 支持的数据类型: INT, FLOAT, STRING(需要指定大小).
+ - 数据库的建立和删除,以及数据库的统计信息查询
+ - 表的建立和删除,以及表的统计信息查询
+ - 索引的建立和删除
+ - 使用与MySQL语法相似的SQL语句对表或数据库中的数据执行增、删、改、查操作
+
+#### 1.4 设计语言和运行环境
+开发环境:Visual Studio 2015
+编程语言:C++(主要使用C++11推荐语法)
+
+## 二. 各模块的具体功能
+#### 2.1 Page File Manager(PF)
+PF模块是系统的最底层模块, 主要向高层次的结构(Index Manager和Record Manager)提供以页为基本单元的文件IO操作. 在该模块中, 主要实现了创建, 删除, 打开和关闭文件四个操作.
+对于单个文件(PageFile类)的操作, 必须先从PF模块打开一个PageFile实例为操作对象, 以页(Page)为最小访问单元. PageFile提供了从文件中获取一个新的Page, 获取一个特定页号的Page, 强制更新(Force)文件中特定页号的Page等方法.
+实际上, 由于文件系统IO速度比较慢, 为了提高获取数据的速度, PM模块还需要对每个文件维护一个Buffer(BufferManager类). 每个BufferManager实例管理一个PageFile实例以及一个Buffer(在内存中), 上层模块只能通过BufferManager来间接地访问PageFile获取所需Page.
+
+#### 2.2 Record Manager(RM)
+RM模块是管理记录文件的模块, 主要面向Query Manager和System Manager两个模块. RM模块只提供了对记录文件的创建, 删除, 打开和关闭四个操作.
+在MicroSQL的实现中, 每个表中有若干条记录, 一个表中的所有记录必须存在同一个记录文件(RecordFile)中. 对单个记录文件的操作, 必须通过RecordFile实例进行操作. RecordFile提供了对该文件中记录的增删改查四个操作.
+
+#### 2.3 Index Manager(IX)
+IX模块是管理索引的模块, 主要提供了对某个表的属性进行创建, 删除索引, 并对已创建的索引的打开, 关闭四个操作. 关于索引的具体实现, MicroSQL的索引与大多数数据库引擎类似, 使用B+树作为索引的数据结构, 每个B+树的结点存储在一个Page中, 以达到较高的索引效率.
+其他模块对于单个索引的数据插入, 删除, 查询, 必须先通过Index Manager获取一个IndexHandle实例, 并通过这个IndexHandle实例进行操作.
+
+#### 2.4 System Manager(SM)
+SM模块直接面向Command Parser,提供一些可能会影响整个数据库系统的操作,包括:
+
+ - 创建、删除一个数据库/关系表/索引等(DDL)
+ - 维护系统中各个数据库和表的Catalog
+ - 从文件中导入数据
+ - 设置数据库或表的参数
+ - 输出关系表
+
+#### 2.5 Query Manager(QM)
+QM模块与SM模块类似,主要向Command Parser提供了用于执行特定的SQL操作。当前的实现支持的SQL操作有Select(包括多表联查),Insert,Delete,Update四种操作。操作的执行主要先通过System Manager获取查询表的结构, 分析后通过调用Record Manager的方法查询并解析查询的结果, 返回给Command Parser.
+
+
+## 三. 重要接口
+
+#### 2.1 Page File Manager(PF)
+`RETCODE CreateFile (const char * fileName); // Create a new file`
+创建一个新的文件(索引的结点或是记录文件)
+
+`RETCODE DestroyFile (const char * fileName); // Destroy a file`
+删除一个文件
+
+`RETCODE OpenFile (const char * fileName, PageFilePtr & fileHandle); // Open a file`
+
+
+`RETCODE CloseFile (PageFilePtr &fileHandle); // Close a file`
+
+#### 2.2 Record Manager(RM)
+
+#### 2.3 Index Manager(IX)
+
+#### 2.4 System Manager(SM)
+
+#### 2.5 Query Manager(QM)
+
+
+
+## 四. 使用语法
+
+## 五. 实际测试
+
+
+## 六. 组内分工
+
+
+
+##Page/PageFile
+
+PF模块中除了构造函数与析构函数之外的每个函数都返回一个整数. 返回值为0表示正常完成. 所有非0返回值均暗示了有异常情况或错误发生. 返回值为正数表示遇到异常(比如读到文件尾或关闭一个未打开的文件等对程序影响不大的错误); 返回值为负表示发生了系统无法自动处理的错误.
+
+###页缓冲池
+获取一个文件中某页面上的数据需要先把页面存入缓冲池(维护在内存中), 然后在缓冲池中操作(读写)数据. 当一个内存中的页面和数据正在被操作时, 必须先将页面的状态设为locked (固定). 当某个进程对页面的所有操作均结束后, 必须立即把页面状态改为unlocked, 但此时并不需要把页面移出缓冲池.
+只有当需要读一个新的页, 并且缓冲池中的内存不足时才会选择一个unlocked的页面移出. 所使用的选择算法为Least-Recently-Used (LRU). 当一个页面被移出缓冲池时, 只有该页面被标记为dirty才会将硬盘上页面对应的文件重写以更新页面文件, 即非dirty的页面被移出缓冲池时不需要做任何工作. 但也提供了接口使得PF模块可以强制将一个非dirty的页面数据写入硬盘, 以及在不移出页面的情况下将所有在缓冲池中的dirty页面的数据写入硬盘.
+PageManager必须保证每个页面只能同时被一个事务使用, 即一个locked状态下的页面不能被locked.
+
+###页面号
+一个文件中的页面需要用页面号标识, 页面号对应其在文件中的位置. 当新建一个文件并分配页面时, 页面号是顺序增长的. 但一个页面被删除之后, 新分配的页面其页面号不一定是顺序的, 而是在之前分配过的页面上寻找一个最近被删除的页面(用栈存储删除的页面号)来存放该页面数据. 若栈为空时才在之前的页面之后再分配一个新的页面.
+
+------------------------
+
+> 注:
+> 1. 每个页面的大小(字节)用PF_PAGE_SIZE表示, 默认为4K (4096字节)
+> 2. 内存池中的页面数用PF_BUFFER_SIZE表示, 默认为40
+> 3. 所有作为存储函数返回结果的指针传进来时应保证其原来的数据(如果有的话)已经无需再使用了
+
+
+##RecordManager
+RM模块提供的类和方法用于把记录存储在文件中, 相当于PF模块的客户端. 在这个模块中需要调用PF模块中已经实现的函数.
+
+###文件头
+为了便于管理文件内容, 可以把每个文件的第一个Page作为一个特殊的Header Page, 用于存储空闲空间的信息, 文件存储的记录数, 每个页面存储的记录数, 文件的当前页面数以及其他与整个文件有关的信息. 每个页面也包含一个页面头.
+
+###记录标识符
+RecordIdentifier类对一个指定文件中的所有记录提供唯一标识, 因此一条指定记录的标识符应该是保持不变的. 即一个标识符的属性在记录更新或其他记录插入/删除的条件下都是恒定的. 每个文件的页面有数量不等的Slot(根据每个文件的Record的大小确定), 但一个文件内的所有页面Slot数相同. 在这个系统中只用页面号(PageNum)以及槽号(SlotNum)来构成为RecordIdentifier.
+
+###记录空闲空间
+当需要插入记录时, 不应该线性搜索有空余的页面. 为了提高搜索效率, 可以使用一个页的链表来存储有空余Slot的页面.
+
+
+每个文件中存储的记录必须是等长的, 这样能更方便地管理每个页面上的记录和空闲空间, 而且保证了每个记录的位置都能够方便地访问到. 最好每个表单独存储在一个文件中.
+
+
+###访问记录
+当主程序需要访问表Table中一条标识符为Id的记录时, 分两个步骤: 首先通过RecordManager->OpenFile(Table)申请一个RecordFile(实际上, 只能通过这个类来访问数据库的记录), 通过RecordFile->GetRec(Id)来获取一个Record对象.
+但是由于这样效率比较低下, 因此主要还是用FileScan类来让客户端与数据库进行交互
+
+##Index Manager
+
+
+##System Manager
+
+
+##Query Manager
diff --git a/src/IndexScan.hpp b/src/IndexScan.hpp
index d423f88..96baf04 100644
--- a/src/IndexScan.hpp
+++ b/src/IndexScan.hpp
@@ -19,7 +19,6 @@ class IndexScan {
private:
- //std::vector<>
};
@@ -28,3 +27,15 @@ IndexScan::IndexScan ( ) {
IndexScan::~IndexScan ( ) {
}
+
+inline RETCODE IndexScan::OpenScan (const IndexHandle & indexHandle, CompOp compOp, void * value) {
+
+}
+
+inline RETCODE IndexScan::GetNextEntry (RecordIdentifier & rid) {
+ return RETCODE ( );
+}
+
+inline RETCODE IndexScan::CloseScan ( ) {
+ return RETCODE ( );
+}
diff --git a/src/Printer.hpp b/src/Printer.hpp
new file mode 100644
index 0000000..0eaac3e
--- /dev/null
+++ b/src/Printer.hpp
@@ -0,0 +1,347 @@
+#pragma once
+
+#include "Utils.hpp"
+#include
+#include
+#include
+#include
+
+#ifndef mmin
+#define mmin(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef mmax
+#define mmax(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+const int MAXPRINTSTRING = ( 2 * Utils::MAXNAMELEN) + 5;
+
+// Print some number of spaces
+void Spaces (int maxLength, int printedSoFar);
+
+struct DataAttrInfo;
+class Tuple;
+
+class Printer {
+public:
+ // Constructor. Takes as arguments an array of attributes along with
+ // the length of the array.
+ Printer (const DataAttrInfo *attributes, const int attrCount);
+ Printer (const Tuple& t);
+
+ ~Printer ( );
+
+ void PrintHeader (std::ostream &c) const;
+
+ // Two flavors for the Print routine. The first takes a char* to the
+ // data and is useful when the data corresponds to a single record in
+ // a table -- since in this situation you can just send in the
+ // RecData. The second will be useful in the QL layer.
+ void Print (std::ostream &c, const char * const data);
+ void Print (std::ostream &c, const void * const data[]);
+ void Print (std::ostream &c, const Tuple& t);
+
+ void PrintFooter (std::ostream &c) const;
+
+private:
+ void Init (const DataAttrInfo *attributes_, const int attrCount_);
+
+private:
+ DataAttrInfo *attributes;
+ int attrCount;
+
+ // An array of strings for the header information
+ char **psHeader;
+ // Number of spaces between each attribute
+ int *spaces;
+
+ // The number of tuples printed
+ int iCount;
+};
+
+
+//
+// printer.cc
+//
+
+// This file contains the interface for the Printer class and some
+// functions that will be used by both the SM and QL components.
+
+#include
+#include
+#include
+#include "printer.hpp"
+
+using namespace std;
+
+//
+// void Spaces(int maxLength, int printedSoFar)
+//
+// This method will output some spaces so that print entry will align everythin
+// nice and neat.
+//
+void Spaces (int maxLength, int printedSoFar) {
+ for ( int i = printedSoFar; i < maxLength; i++ )
+ std::cout << " ";
+}
+
+//
+// ------------------------------------------------------------------------------
+//
+Printer::Printer (const Tuple& t) {
+ Init (t.GetAttributes ( ), t.GetAttrCount ( ));
+}
+
+//
+// Printer
+//
+// This class handles the printing of tuples.
+//
+// DataAttrInfo - describes all of the attributes. Defined
+// within sm.h
+// attrCount - the number of attributes
+//
+Printer::Printer (const DataAttrInfo *attributes_, const int attrCount_) {
+ Init (attributes_, attrCount_);
+}
+
+void Printer::Init (const DataAttrInfo *attributes_, const int attrCount_) {
+ attrCount = attrCount_;
+ attributes = new DataAttrInfo[attrCount];
+
+ for ( int i = 0; i < attrCount; i++ ) {
+ attributes[i] = attributes_[i];
+ // std::cout << "Printer::init i, offset " << attributes[i].offset << endl;
+ }
+ // Number of tuples printed
+ iCount = 0;
+
+ // Figure out what the header information will look like. Normally,
+ // we can just use the attribute name, but if that appears more than
+ // once, then we should use "relation.attribute".
+
+ // this line broke when using CC
+ // changing to use malloc and free instead of new and delete
+ // psHeader = (char **) new (char *)[attrCount];
+ psHeader = ( char** ) malloc (attrCount * sizeof (char*));
+
+ // Also figure out the number of spaces between each attribute
+ spaces = new int[attrCount];
+
+ for ( int i = 0; i < attrCount; i++ ) {
+ // Try to find the attribute in another column
+ int bFound = 0;
+ psHeader[i] = new char[MAXPRINTSTRING];
+ memset (psHeader[i], 0, MAXPRINTSTRING);
+
+ for ( int j = 0; j < attrCount; j++ )
+ if ( j != i &&
+ strcmp (attributes[i].attrName,
+ attributes[j].attrName) == 0 ) {
+ bFound = 1;
+ break;
+ }
+
+ if ( bFound )
+ sprintf_s (psHeader[i], MAXPRINTSTRING,"%s.%s",
+ attributes[i].relName, attributes[i].attrName);
+ else
+ strcpy_s (psHeader[i], MAXPRINTSTRING, attributes[i].attrName);
+
+ if ( attributes[i].attrType == STRING )
+ spaces[i] = mmin (attributes[i].attrLength, MAXPRINTSTRING);
+ else
+ spaces[i] = mmax (12, strlen (psHeader[i]));
+
+ // We must subtract out those characters that will be for the
+ // header.
+ spaces[i] -= strlen (psHeader[i]);
+
+ // If there are negative (or zero) spaces, then insert a single
+ // space.
+ if ( spaces[i] < 1 ) {
+ // The psHeader will give us the space we need
+ spaces[i] = 0;
+ strcat_s (psHeader[i], MAXPRINTSTRING," ");
+ }
+ }
+}
+
+
+//
+// Destructor
+//
+Printer::~Printer ( ) {
+ for ( int i = 0; i < attrCount; i++ )
+ delete[] psHeader[i];
+
+ delete[] spaces;
+ //delete [] psHeader;
+ free (psHeader);
+ delete[] attributes;
+}
+
+//
+// PrintHeader
+//
+void Printer::PrintHeader (std::ostream &c) const {
+ int dashes = 0;
+ int iLen;
+ int i, j;
+
+ for ( i = 0; i < attrCount; i++ ) {
+ // Print out the header information name
+ c << psHeader[i];
+ iLen = strlen (psHeader[i]);
+ dashes += iLen;
+
+ for ( j = 0; j < spaces[i]; j++ )
+ c << " ";
+
+ dashes += spaces[i];
+ }
+
+ c << "\n";
+ for ( i = 0; i < dashes; i++ ) c << "-";
+ c << "\n";
+}
+
+//
+// PrintFooter
+//
+void Printer::PrintFooter (std::ostream &c) const {
+ c << "\n";
+ c << iCount << " tuple(s).\n";
+}
+
+//
+// Print
+//
+// data - this is an array of void *. This print routine is used by
+// the QL Layer.
+//
+// Unfortunately, this is essentially the same as the other Print
+// routine.
+//
+void Printer::Print (std::ostream &c, const void * const data[]) {
+ char str[MAXPRINTSTRING], strSpace[50];
+ int i, a;
+ float b;
+
+ // Increment the number of tuples printed
+ iCount++;
+
+ for ( i = 0; iMAXPRINTSTRING ) {
+ strcpy_s (str, MAXPRINTSTRING - 1, ( char * ) data[i]);
+ str[MAXPRINTSTRING - 3] = '.';
+ str[MAXPRINTSTRING - 2] = '.';
+ c << str;
+ Spaces (MAXPRINTSTRING, strlen (str));
+ } else {
+ strcpy_s (str, attributes[i].attrLength, ( char * ) data[i]);
+ c << str;
+ if ( attributes[i].attrLength < ( int ) strlen (psHeader[i]) )
+ Spaces (strlen (psHeader[i]), strlen (str));
+ else
+ Spaces (attributes[i].attrLength, strlen (str));
+ }
+ }
+ if ( attributes[i].attrType == INT ) {
+ memcpy (&a, data[i], sizeof (int));
+ sprintf_s (strSpace, MAXPRINTSTRING,"%d", a);
+ c << a;
+ if ( strlen (psHeader[i]) < 12 )
+ Spaces (12, strlen (strSpace));
+ else
+ Spaces (strlen (psHeader[i]), strlen (strSpace));
+ }
+ if ( attributes[i].attrType == FLOAT ) {
+ memcpy (&b, data[i], sizeof (float));
+ sprintf_s (strSpace, MAXPRINTSTRING,"%f", b);
+ c << strSpace;
+ if ( strlen (psHeader[i]) < 12 )
+ Spaces (12, strlen (strSpace));
+ else
+ Spaces (strlen (psHeader[i]), strlen (strSpace));
+ }
+ }
+ c << "\n";
+}
+
+void Printer::Print (std::ostream &c, const Tuple& t) {
+ const char * data;
+ t.GetData (data);
+ // std::cout << "Printer::Print(tuple) " << t << endl;
+ Print (c, data);
+}
+
+//
+// Print
+//
+// data - the actual data for the tuple to be printed
+//
+// The routine tries to make things line up nice, however no
+// attempt is made to keep the tuple constrained to some number of
+// characters.
+//
+void Printer::Print (std::ostream &c, const char * const data) {
+ char str[MAXPRINTSTRING], strSpace[50];
+ int i, a;
+ float b;
+
+ if ( data == NULL )
+ return;
+
+ // Increment the number of tuples printed
+ iCount++;
+
+ for ( i = 0; iMAXPRINTSTRING ) {
+ strcpy_s (str, MAXPRINTSTRING - 1, data + attributes[i].offset);
+ str[MAXPRINTSTRING - 3] = '.';
+ str[MAXPRINTSTRING - 2] = '.';
+ c << str;
+ Spaces (MAXPRINTSTRING, strlen (str));
+ } else {
+ strcpy_s (str, attributes[i].attrLength, data + attributes[i].offset);
+ c << str;
+ if ( attributes[i].attrLength < ( int ) strlen (psHeader[i]) )
+ Spaces (strlen (psHeader[i]), strlen (str));
+ else
+ Spaces (attributes[i].attrLength, strlen (str));
+ }
+ }
+ if ( attributes[i].attrType == INT ) {
+ memcpy (&a, ( data + attributes[i].offset ), sizeof (int));
+ sprintf_s (strSpace, MAXPRINTSTRING,"%d", a);
+ c << a;
+ if ( strlen (psHeader[i]) < 12 )
+ Spaces (12, strlen (strSpace));
+ else
+ Spaces (strlen (psHeader[i]), strlen (strSpace));
+ }
+ if ( attributes[i].attrType == FLOAT ) {
+ memcpy (&b, ( data + attributes[i].offset ), sizeof (float));
+ sprintf_s (strSpace, MAXPRINTSTRING, "%f", b);
+ c << strSpace;
+ if ( strlen (psHeader[i]) < 12 )
+ Spaces (12, strlen (strSpace));
+ else
+ Spaces (strlen (psHeader[i]), strlen (strSpace));
+ }
+ }
+ c << "\n";
+}
diff --git a/src/QueryManager.hpp b/src/QueryManager.hpp
index f816c85..b9e759f 100644
--- a/src/QueryManager.hpp
+++ b/src/QueryManager.hpp
@@ -6,6 +6,7 @@
#include "Utils.hpp"
#include "Iterator.hpp"
+#include "Printer.hpp"
#include "RecordFile.hpp"
#include "SystemManager.hpp"
#include "IndexManager.hpp"
@@ -101,6 +102,47 @@ inline RETCODE QueryManager::Select (int nSelAttrs, const RelAttr selAttrs[], in
inline RETCODE QueryManager::Insert (const char * relName, int nValues, const Value values[]) {
+ RETCODE rc = smm->SemCheck (relName);
+ if ( rc != 0 ) return rc;
+
+ int attrCount;
+ DataAttrInfo* attr;
+ rc = smm->GetFromTable (relName, attrCount, attr);
+
+ if ( nValues != attrCount ) {
+ delete[] attr;
+ return RETCODE::INVALIDINSERT;
+ }
+
+ int size = 0;
+ for ( int i = 0; i < nValues; i++ ) {
+ if ( values[i].type != attr[i].attrType ) {
+ delete[] attr;
+ return RETCODE::TYPEMISMATCH;
+ }
+ size += attr[i].attrLength;
+ }
+
+ char * buf = new char[size];
+ int offset = 0;
+ for ( int i = 0; i < nValues; i++ ) {
+ assert (values[i].data != NULL);
+ memcpy (buf + offset,
+ values[i].data,
+ attr[i].attrLength);
+ offset += attr[i].attrLength;
+ }
+
+ rc = smm->LoadRecord (relName, size, buf);
+ if ( rc != 0 ) return rc;
+
+ Printer p (attr, attrCount);
+ p.PrintHeader (cout);
+ p.Print (cout, buf);
+ p.PrintFooter (cout);
+
+ delete[] attr;
+ delete[] buf;
return RETCODE::COMPLETE;
diff --git a/src/SystemManager.hpp b/src/SystemManager.hpp
index 95c70a4..c672a66 100644
--- a/src/SystemManager.hpp
+++ b/src/SystemManager.hpp
@@ -13,6 +13,9 @@
#include
class SystemManager {
+
+ friend class QueryManager;
+
public:
SystemManager (const IndexManagerPtr & ixm,
const RecordFileManagerPtr & rm);
diff --git a/src/Utils.hpp b/src/Utils.hpp
index fa4ac5b..864a9ed 100644
--- a/src/Utils.hpp
+++ b/src/Utils.hpp
@@ -8,14 +8,14 @@
#include
#include
#include
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
/*
@@ -97,6 +97,7 @@ enum RETCODE {
TYPEMISMATCH,
ENTRYNOTFOUND,
BADOP,
+ INVALIDINSERT,
};
enum AttrType {
From 4300a2fd2b737849f0df190d7397993431ba86c5 Mon Sep 17 00:00:00 2001
From: StarDust <375670450@qq.com>
Date: Mon, 20 Jun 2016 22:56:04 +0800
Subject: [PATCH 2/2] update readme 20-22:55
---
README.md | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 109 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 67080de..af48ebb 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ MicroSQL是一个轻量级的关系型数据库, 框架的设计思路主要根
#### 2.1 Page File Manager(PF)
PF模块是系统的最底层模块, 主要向高层次的结构(Index Manager和Record Manager)提供以页为基本单元的文件IO操作. 在该模块中, 主要实现了创建, 删除, 打开和关闭文件四个操作.
对于单个文件(PageFile类)的操作, 必须先从PF模块打开一个PageFile实例为操作对象, 以页(Page)为最小访问单元. PageFile提供了从文件中获取一个新的Page, 获取一个特定页号的Page, 强制更新(Force)文件中特定页号的Page等方法.
-实际上, 由于文件系统IO速度比较慢, 为了提高获取数据的速度, PM模块还需要对每个文件维护一个Buffer(BufferManager类). 每个BufferManager实例管理一个PageFile实例以及一个Buffer(在内存中), 上层模块只能通过BufferManager来间接地访问PageFile获取所需Page.
+实际上, 由于文件系统IO速度比较慢, 为了提高获取数据的速度, PM模块还需要对每个文件维护一个Buffer(BufferManager类). 每个BufferManager实例管理一个PageFile实例以及一个Buffer(用哈希表结构存储在内存中), 上层模块只能通过BufferManager来间接地访问PageFile获取所需Page.
#### 2.2 Record Manager(RM)
RM模块是管理记录文件的模块, 主要面向Query Manager和System Manager两个模块. RM模块只提供了对记录文件的创建, 删除, 打开和关闭四个操作.
@@ -58,7 +58,9 @@ QM模块与SM模块类似,主要向Command Parser提供了用于执行特定
## 三. 重要接口
-#### 2.1 Page File Manager(PF)
+### 2.1 PF模块
+#### PageManager类
+
`RETCODE CreateFile (const char * fileName); // Create a new file`
创建一个新的文件(索引的结点或是记录文件)
@@ -66,21 +68,122 @@ QM模块与SM模块类似,主要向Command Parser提供了用于执行特定
删除一个文件
`RETCODE OpenFile (const char * fileName, PageFilePtr & fileHandle); // Open a file`
-
+打开一个文件并获取该文件的PageFile实例
`RETCODE CloseFile (PageFilePtr &fileHandle); // Close a file`
+关闭一个文件并释放PageFile实例
-#### 2.2 Record Manager(RM)
+#### PageFile类(只能由BufferManager调用)
+`RETCODE GetThisPage (PageNum pageNum, PagePtr &pageHandle) ;`
+获取该文件中特定一页, 返回Page实例
-#### 2.3 Index Manager(IX)
+`RETCODE AllocatePage (PagePtr &pageHandle);`
+分配一个新的页, 返回Page实例
+
+`RETCODE DisposePage (PageNum pageNum);`
+释放(不再使用)特定的页
+
+`RETCODE ForcePage (PageNum page, const PagePtr & pageHande);`
+强制把一个页写入文件中的特定页中
+
+#### BufferManager类(由其他类调用, 间接操作PageFile)
+
+`RETCODE GetPage (PageNum page, PagePtr & pBuffer); `
+获取一个特定的页, 返回Page实例
+
+`RETCODE MarkDirty (PageNum page);`
+把一个页标记为Dirty(修改过)
+
+`RETCODE LockPage (PageNum page);`
+把一个页锁定在Buffer中
+
+`RETCODE UnlockPage (PageNum page);`
+把一个已锁定的页释放
+
+`RETCODE ForcePage (PageNum page);`
+强制把一个页写入文件
+
+`RETCODE FlushPages ( );`
+把Buffer中的所有页写入文件
+
+`RETCODE AllocatePage (PagePtr & page); `
+分配一个新的页, 返回Page实例
+
+`RETCODE DisposePage (PageNum page);`
+释放特定的页
+
+### 2.2 RM模块
+
+
+### 2.3 IX模块
-#### 2.4 System Manager(SM)
+
+### 2.4 SM模块
+#### SystemManager 类
+
+`RETCODE CreateDb (const char * dbName, PageFileManagerPtr & pfMgr);`
+创建一个新的数据库
+
+`RETCODE OpenDb (const char *dbName); `
+打开一个数据库
+
+`RETCODE CloseDb ( ); `
+关闭当前打开的数据库
+
+`RETCODE CreateTable (const char *relName, Create relation, int attrCount, AttrInfo *attributes);`
+(在当前打开的数据库中)创建表
+
+`RETCODE DropTable (const char *relName);`
+删除表
+
+`RETCODE CreateIndex (const char *relName, const char *attrName);`
+对某个表的一个属性建立索引
+
+`RETCODE DropIndex (const char *relName, Destroy index, const char *attrName);`
+删除索引
#### 2.5 Query Manager(QM)
+`RETCODE Select (
+int nSelAttrs, // 查询的属性个数
+const RelAttr selAttrs[], // 查询的属性
+int nRelations, // 查询的关系表个数
+const char * const relations[], // 查询的关系表
+int nConditions, // 查询的条件个数
+const Condition conditions[]); // 查询的具体条件`
+根据传入的参数执行查询操作
+
+`RETCODE Insert (const char *relName, // relation to insert into
+int nValues, // # values to insert
+const Value values[]); // values to insert`
+
+`RETCODE Delete (const char *relName, // relation to delete from
+int nConditions, // # conditions in Where clause
+const Condition conditions[]); // conditions in Where clause`
+
+
+`RETCODE Update (const char *relName, // relation to update
+const RelAttr &updAttr, // attribute to update
+const int bIsValue, // 0/1 if RHS of = is attribute/value
+const RelAttr &rhsRelAttr, // attr on RHS of =
+const Value &rhsValue, // value on RHS of =
+int nConditions, // # conditions in Where clause
+const Condition conditions[]); // conditions in Where clause`
+
## 四. 使用语法
+#### Select
+
+
+#### Insert
+
+
+#### Update
+
+
+#### Delete
+
## 五. 实际测试