#include "query.h" #include using namespace std; WhereClause::WhereClause(void):col(0){} WhereClause::WhereClause(const int _c,const vector &_v):col(_c),values(_v){} UpdateClause::UpdateClause(void):col(0){} UpdateClause::UpdateClause(const int _c,const RowItem &_v):col(_c),value(_v){} QueryResult::QueryResult(void):res(0){} QueryResult::QueryResult(int _res):res(_res){} QueryResult::QueryResult(int _res,const vector &_rows):res(_res),rows(_rows){} QueryResult::QueryResult(int _res,const vector &_rows,const string &_m):res(_res),rows(_rows),msg(_m){} QueryResult::QueryResult(int _res,const string &_m):res(_res),msg(_m){} QueryResult Query::execute(map &tables){return QueryResult(-1);} Query::~Query(void){} CreateQuery::CreateQuery(void):nc(0),header(NULL){} void CreateQuery::setHeader(const ColHeader *hd){ header=new ColHeader[nc]; memcpy(header,hd,nc*sizeof(ColHeader)); } QueryResult CreateQuery::execute(map &tables){ if(nc==0)return QueryResult(0,"zero nc (CQ:ex)"); if(header==NULL)return QueryResult(0,"null header (CQ:ex)"); const map::const_iterator tit=tables.find(tablename); if(tit!=tables.cend())return QueryResult(0,"existing table (CQ:ex)"); tables.emplace(piecewise_construct, forward_as_tuple(tablename), forward_as_tuple(tablename,nc,header)); return QueryResult(1); } FindQuery::FindQuery(void):limit(-1){}; pair::const_iterator>,string> FindQuery::executeIterators(map &tables){ const map::const_iterator tit=tables.find(tablename); if(tit==tables.cend())return {{},"non-existent table (FQ:eI)"}; return executeIterators(tit->second); } pair::const_iterator>,string> FindQuery::executeIterators(const Table &table){ if(limit==0)return {{},"zero limit (FQ:eI)"}; int i,j,k; for(i=0;i<(int)where.size();i++){ if(where[i].col==0)break; } if(i!=(int)where.size()){ for(const RowItem &wh : where[i].values){ const map::const_iterator rit=table.rows.find(serialise(table.header[0],wh)); if(rit==table.rows.end())return {{},""}; const Row &row=rit->second; for(j=0;j<(int)where.size();j++){ if(j==i)continue; const int col=where[j].col; if(col<0||col>=table.nc){ return {{},"invalid col (DQ:eI)"}; } for(k=0;k::const_iterator> v; v.push_back(rit); return {v,""}; } } typedef map::const_iterator cit_t; cit_t end=table.rows.end(); pair::const_iterator>,string> ret; for(i=0;i<(int)where.size();i++){ const int col=where[i].col; if(col<0||col>=table.nc){ ret.second="invalid col (DQ:eI)"; return ret; } } for(cit_t it=table.rows.begin();it!=end;it++){ for(i=0;i<(int)where.size();i++){ const int col=where[i].col; for(j=0;jsecond.items[col],where[i].values[j])==0)break; } if(j==where[i].values.size())break; } if(i==(int)where.size()){ ret.first.push_back(it); if(ret.first.size()==limit)return ret; } } return ret; } QueryResult FindQuery::execute(map &tables){ pair::const_iterator>,string> ret=executeIterators(tables); QueryResult qres; qres.res=ret.first.size(); for(int i=0;isecond); } qres.msg=ret.second; return qres; } InsertQuery::InsertQuery(const Row &_r):row(_r){} InsertQuery::InsertQuery(Row &&_r):row(move(_r)){} QueryResult InsertQuery::execute(map &tables){ map::iterator tit=tables.find(tablename); if(tit==tables.end())return QueryResult(0,"non-existent table (IQ:ex)"); Table &table=tit->second; if(table.nc!=row.nc)return QueryResult(0,"non-conformant row width (IQ:ex)"); const string primkey=serialise(table.header[0],row.items[0]); const map::const_iterator rit=table.rows.find(primkey); if(rit!=table.rows.cend())return QueryResult(0,"existing primary key (IQ:ex)"); table.rows.insert(make_pair(primkey,row)); return QueryResult(1); } UpdateQuery::UpdateQuery(void){}; QueryResult UpdateQuery::execute(map &tables){ const map::iterator tit=tables.find(tablename); if(tit==tables.cend())return QueryResult(0,"non-existent table (UQ:ex)"); Table &table=tit->second; FindQuery fqu; fqu.tablename=tablename; fqu.where=where; pair::const_iterator>,string> ret=fqu.executeIterators(table); if(ret.second.size()!=0)return QueryResult(0,ret.second); map::const_iterator it; int i,j; const int numupdates=updates.size(); for(i=0;i=table.nc)return QueryResult(0,"invalid col (UQ:ex)"); if(col==0)return QueryResult(0,"update primary key (UQ:ex)"); } for(i=0;i<(int)ret.first.size();i++){ for(j=0;jsecond.items[col]=updates[j].value.copy(table.header[col]); } } return QueryResult(ret.first.size()); } DeleteQuery::DeleteQuery(void){}; QueryResult DeleteQuery::execute(map &tables){ const map::iterator tit=tables.find(tablename); if(tit==tables.cend())return QueryResult(0,"non-existent table (DQ:ex)"); Table &table=tit->second; FindQuery fqu; fqu.tablename=tablename; fqu.where=where; pair::const_iterator>,string> ret=fqu.executeIterators(table); if(ret.second.size()!=0)return QueryResult(0,ret.second); map::const_iterator it; for(int i=0;i &tables){ const map::iterator tit=tables.find(tablename); if(tit==tables.cend())return QueryResult(0,"non-existent table (DrQ:ex)"); tables.erase(tit); return QueryResult(1); }