6 Star 3 Fork 2

GPLme / SG-Database

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
table.hpp 11.43 KB
一键复制 编辑 原始数据 按行查看 历史
ECIR 提交于 2021-04-07 15:50 . 存储时将,转义
#pragma once
#include "expParse.h"
#include <QThread>
#include <QRunnable>
#include <QThreadPool>
#include "IO.hpp"
#ifdef JsInBasicClass
#include "jsCollection.h"
#endif
class table : public QObject, public manageable
{
Q_OBJECT
protected:
static QMutex tranMutex;
bool flag=false;
vector<col*> allCol; //如果hasOwnership=true,push进来的由table对象持有所有权
vector<index*> allIndex;
list<record> allRecord;
vector<int> allBlocksLen;
bool hasOwnership;
map<vector<string>,vector<int>> memSearchSet;
void saveFile(const string& path);
void updateFile(const string& path);
void clear()
{
for(col* c : allCol)
delete c;
for(index* i : allIndex)
delete i;
}
public:
string ID;
string getStrTitle();
#ifdef JsInBasicClass
Q_INVOKABLE QString toStr();
#endif
vector<string> toStr(const int& fileLen);
static void loadStr(const int& num,const string& path);
static table* loadFile(const string& _ID);
table(string ID, vector<col*> allCol,const vector<int>& blocksLen={}, bool hasOwnership=true,vector<IndexType> indTypes={}) : ID(ID), hasOwnership(hasOwnership)
{
if(indTypes.empty()){
indTypes=vector<IndexType>(allCol.size(),TV);
}
int index=0;
for(col* c : allCol)
{
if(c->getLen()!=allCol[0]->getLen()) { //以allCol第一个长度为准
throw string("The number of columns is different");
}
if(this->hasOwnership)
c->setSystemManage(); //默认hasOwnership=true,所以一定转移所有权
this->allCol.push_back(c);
this->allIndex.push_back(getCorIndex(c,indTypes[index])); //默认都是遍历索引
++index;
}
this->allBlocksLen=blocksLen;
}
#ifdef JsInBasicClass
Q_INVOKABLE table(const table& t, bool hasOwnership=true) : ID(t.ID), hasOwnership(hasOwnership)
{
for(col* c : t.allCol)
{
col* rc=new col(*c);
if(this->hasOwnership)
rc->setSystemManage();
this->allCol.push_back(rc);
this->allIndex.push_back(new traversalIndex(rc)); //索引不拷贝,重建
}
this->memSearchSet=t.memSearchSet;
this->allBlocksLen=t.allBlocksLen;
}
#endif
string getLocStr(const int& rIndex,const int& lIndex){
return allCol[lIndex]->getLocStr(rIndex);
}
int getColNum(){return this->allCol.size();}
int getColLen(){return this->allCol[0]->getLen();}
vector<col*> getAllCol(){return this->allCol;}
#ifdef JsInBasicClass
Q_INVOKABLE col* getCol(int i) { return this->allCol[i]; }
#endif
#ifdef JsInBasicClass
Q_INVOKABLE col* getCol(const QString& colName);
#endif
int getColIndex(const string& colName)
{
for(int i=0;i<allCol.size();++i) {
if(allCol[i]->ID==colName) {
return i;
}
}
throw string("Wrong column name");
}
#ifdef JsInBasicClass
Q_INVOKABLE int getColIndex(const QString& colName);
#endif
void abandonOwnShip(){
this->hasOwnership=false;
}
void changeIndex(int sub, index* ind)
{
delete this->allIndex[sub];
this->allIndex[sub]=ind;
}
void setIndex(const string& colName,const IndexType& indType){
int index=getColIndex(colName);
col* tmpCol=getCol(index);
changeIndex(index,getCorIndex(tmpCol,indType));
}
#ifdef JsInBasicClass
Q_INVOKABLE void setIndex(const QString& colName,const QString& indType);
#endif
table* genNewTable(const vector<int>& colSubList,const vector<int>& tupSubList) //会拷贝
{
vector<col*> newAllCol;
for(int i : colSubList)
{
col* selectCol=allCol[i]->genNewCol(tupSubList);
newAllCol.push_back(selectCol);
}
return new table(this->ID, newAllCol);
}
table* genNewTable(const vector<string>& colNames,const vector<int>& tupSubList)
{
return genNewTable(findCol(colNames),tupSubList);
}
#ifdef JsInBasicClass
Q_INVOKABLE table* genNewTable(const QScriptValue& colNames,jsCollection* tupSubList);
#endif
#ifdef JsInBasicClass
Q_INVOKABLE void saveFile(){
this->table::saveFile(ID);
}
#endif
#ifdef JsInBasicClass
Q_INVOKABLE void updateFile(){
this->table::updateFile(ID);
}
#endif
#ifdef JsInBasicClass
Q_INVOKABLE void rollback() {
this->clear();
table* newTable=table::loadFile(this->ID);
newTable->hasOwnership=false; //放弃所有权,不delete里面东西了
//在这里,之后必须接着转移数据,否则就内存泄漏了(没有人指向刚读进来那些数据对象)
this->allCol=newTable->allCol;
this->allRecord=newTable->allRecord;
this->allIndex=newTable->allIndex;
delete newTable;
}
#endif
void add(vector<Basic*> tuple)
{
if(tuple.size()!=this->allCol.size())
throw string("Col Size mismatch");
for(int i=0;i<this->allCol.size();i++)
{
col* c=this->allCol[i];
index* ind=this->allIndex[i];
if(ind->isSupportMod())
ind->add(tuple[i]);
c->add(tuple[i]);
}
//写入记录
this->allRecord.push_back(record(tuple));
memSearchSet.clear();
}
#ifdef JsInBasicClass
Q_INVOKABLE void add(const QScriptValue& tuple);
#endif
int mod(int opSub, vector<Basic*> tuple) //tuple里的东西会拷贝
{
if(tuple.size()!=this->allCol.size())
throw string("Col Size mismatch");
int resultSub=opSub; //记录结果
vector<Basic*> recordTuple;
for(int i=0;i<this->allCol.size();i++)
{
col* c=this->allCol[i];
index* ind=this->allIndex[i];
if(ind->isSupportMod())
ind->mod(opSub,tuple[i]);
c->mod(opSub,tuple[i]);
auto copyObj=typeHelper::typehelper->copy(tuple[i]);
copyObj->setSystemManage();
recordTuple.push_back(copyObj);
}
//写入记录
this->allRecord.push_back(record(opSub,recordTuple));
memSearchSet.clear();
return resultSub; //返回
}
#ifdef JsInBasicClass
Q_INVOKABLE void mod(int opSub,const QScriptValue& tuple);
#endif
#ifdef JsInBasicClass
Q_INVOKABLE void mod(jsCollection* opSubs,const QScriptValue& tuple);
#endif
#ifdef JsInBasicClass
Q_INVOKABLE void del(int opSub)
{
for(int i=0;i<this->allCol.size();i++)
{
index* ind=this->allIndex[i];
if(ind->isSupportMod())
ind->del(opSub);
this->allCol[i]->del(opSub);
}
//写入记录
this->allRecord.push_back(record(opSub));
memSearchSet.clear();
}
#endif
void del(vector<int> allOpSub) //对选择出来的一系列下标一起进行删除,要求有序
{
int opFinishedNum=0;
for(int i : allOpSub)
{
this->del(i-opFinishedNum); //前面的删掉了后面下标会向前串
opFinishedNum++;
}
}
#ifdef JsInBasicClass
Q_INVOKABLE void del(jsCollection* allOpSub);
#endif
vector<int> find_in(const string& colName,vector<Basic*> target_vec)
{
vector<int> result_index_vec;
int index=getColIndex(colName);
for(int i=0;i<target_vec.size();++i)
{
vector<ruleExp*> rule_vec(this->allCol.size(),nullptr);
rule_vec[index]=new ruleExp (EQU,typeHelper::typehelper->copy(target_vec[i]));
vector<int> temp_result=this->doFind(rule_vec);
result_index_vec.insert(result_index_vec.end(),temp_result.begin(),temp_result.end());
}
set<int> s(result_index_vec.begin(), result_index_vec.end());
result_index_vec.assign(s.begin(), s.end());
return result_index_vec;
}
#ifdef JsInBasicClass
Q_INVOKABLE jsCollection* find_in(const QString& colName,jsCollection* target_vec);
#endif
#ifdef JsInBasicClass
Q_INVOKABLE jsCollection* find_in(const QString& colName,const QScriptValue& target_vec);
#endif
vector<int> find_not_in(const string& colName,vector<Basic*> target_vec)
{
vector<int> notResult;
vector<int> inResult=find_in(colName,target_vec);
int col_size=this->allCol[0]->getAllData().size();
int tmp=0;
for(int i=0;i<col_size;++i)
{
if(i==inResult[tmp])
{
++tmp;
continue;
}
notResult.push_back(i);
}
return notResult;
}
#ifdef JsInBasicClass
Q_INVOKABLE jsCollection* find_not_in(const QString& colName,jsCollection* target_vec);
#endif
#ifdef JsInBasicClass
Q_INVOKABLE jsCollection* find_not_in(const QString& colName,const QScriptValue& target_vec);
#endif
vector<int> doFind(vector<ruleExp*> allExp)
{
//先生成一个完整的范围,用于作为nullptr(无条件)的结果
const int len=allCol[0]->getLen();
//正式逐个进行WHERE
vector<char> allInds(len,0);
int notNullNum=0;
for(int i=0;i<this->allIndex.size();i++)
{
if(allExp[i]!=nullptr)
{
const vector<char>& tmpInd=this->allIndex[i]->find(allExp[i]);
helper::markInd(allInds,tmpInd);
notNullNum++;
}
}
vector<int> result;
for(int i=0;i<len;++i){
if(allInds[i]==notNullNum){
result.push_back(i);
}
}
return result;
}
vector<int> find(const vector<string>& allExp)
{
auto res=memSearchSet.find(allExp);
if(res!=memSearchSet.end()){
return res->second;
}
vector<ruleExp*> allRule;
for(const string& str:allExp){
allRule.push_back(expParse::total_strrule_parse(str));
}
auto result=doFind(allRule);
memSearchSet[allExp]=result;
for(ruleExp* i : allRule){
delete i;
}
return result;
}
#ifdef JsInBasicClass
Q_INVOKABLE jsCollection* find(const QScriptValue& allExp);
#endif
vector<int> findCol(vector<string> colID)
{
vector<int> result;
for(int i=0;i<this->allCol.size();i++)
{
col* c=this->allCol[i];
vector<string>::iterator it;
it=std::find(colID.begin(),colID.end(),c->ID);
if (it!=colID.end())
result.push_back(i);
}
return result;
}
static table* doJoin(const string& newID,table* lTable,table* rTable){
if(lTable->allCol.empty()||rTable->allCol.empty()){
throw string("Empty table");
}
if(lTable->allCol[0]->getLen()!=rTable->allCol[0]->getLen()){
throw string("Tables of different lengths");
}
vector<col*> joinCols;
for(int i=0;i<lTable->allCol.size();++i){
joinCols.push_back(lTable->allCol[i]);
}
for(int i=0;i<rTable->allCol.size();++i){
joinCols.push_back(rTable->allCol[i]);
}
return new table (newID,joinCols);
}
virtual ~table()
{
if(this->hasOwnership)
this->clear();
}
};
C++
1
https://gitee.com/sg-first/SG-Database.git
git@gitee.com:sg-first/SG-Database.git
sg-first
SG-Database
SG-Database
master

搜索帮助