aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <hallo@tomsmeding.nl>2015-05-26 09:53:09 +0200
committertomsmeding <hallo@tomsmeding.nl>2015-05-26 09:53:09 +0200
commitba869e07df4824a13b5b90f18aa5be8a0f3cc9c3 (patch)
tree1d7863d6dcea072b88e875843b14e6d189f517bc
parent934e7d22b43247ebe7ec5f4990814117baab7fda (diff)
Start scripting (fuck commit)
-rw-r--r--engine.cpp6
-rw-r--r--enginedata.cpp11
-rw-r--r--enginedata.h7
-rw-r--r--query.cpp44
-rw-r--r--query.h23
-rw-r--r--script.cpp86
-rw-r--r--script.h60
7 files changed, 207 insertions, 30 deletions
diff --git a/engine.cpp b/engine.cpp
index ea81602..8b34f29 100644
--- a/engine.cpp
+++ b/engine.cpp
@@ -99,7 +99,7 @@ int main(int argc,char **argv){
RowItem ri;
ri.v.rh_bytes=new unsigned char[10];
memcpy(ri.v.rh_bytes,"hallo daar",10);
- uqu.where.push_back({2,ri});
+ uqu.where.push_back({2,{ri}});
delete[] ri.v.rh_bytes;
ri.v.rh_int32=20;
@@ -119,7 +119,7 @@ int main(int argc,char **argv){
RowItem ri;
ri.v.rh_uint32=UINT_MAX;
- uqu.where.push_back({1,ri});
+ uqu.where.push_back({1,{ri}});
ri.v.rh_uint32=12345;
uqu.updates.push_back({1,ri});
@@ -136,7 +136,7 @@ int main(int argc,char **argv){
DeleteQuery dqu;
dqu.tablename="hoi";
RowItem ri; ri.v.rh_int32=-1;
- dqu.where.emplace_back(0,ri);
+ dqu.where.push_back({0,{ri}});
QueryResult res=dqu.execute(tables);
diff --git a/enginedata.cpp b/enginedata.cpp
index ff67f4d..a1e8da4 100644
--- a/enginedata.cpp
+++ b/enginedata.cpp
@@ -24,7 +24,7 @@ RowItem RowItem::copy(const ColHeader &header){
}
Row::Row(void):nc(0),table(NULL){}
-Row::Row(const int _nc,const Table *const _t):nc(_nc),table(_t){
+Row::Row(const int _nc,Table *_t):nc(_nc),table(_t){
items=new RowItem[nc];
}
Row::~Row(void){
@@ -35,11 +35,18 @@ Row::Row(Row &&other):nc(other.nc),table(other.table),items(other.items){ //move
}
Row::Row(const Row &other):nc(other.nc),table(other.table){ //copy constr
items=new RowItem[nc];
- //memcpy(items,other.items,nc*sizeof(RowItem));
for(int i=0;i<nc;i++){
items[i]=other.items[i].copy(table->header[i]);
}
}
+Row& Row::operator=(const Row &other){ //copy assignment
+ nc=other.nc; table=other.table;
+ items=new RowItem[nc];
+ for(int i=0;i<nc;i++){
+ items[i]=other.items[i].copy(table->header[i]);
+ }
+ return *this;
+}
ostream& operator<<(ostream &os,const Row &r){
os<<'[';
for(int i=0;i<r.nc;i++){
diff --git a/enginedata.h b/enginedata.h
index 071dd93..0b6b472 100644
--- a/enginedata.h
+++ b/enginedata.h
@@ -31,15 +31,16 @@ struct ColHeader{
};
struct Row{
- const int nc;
- const Table *table; //pointer to the parent table; don't delete!
+ int nc;
+ Table *table; //pointer to the parent table; don't delete!
RowItem *items;
Row(void);
- Row(const int _nc,const Table *const _t);
+ Row(const int _nc,Table *_t);
~Row(void);
Row(Row &&other); //move constr
Row(const Row &other); //copy constr
+ Row& operator=(const Row &other); //copy assignment
friend ostream& operator<<(ostream &os,const Row &r);
};
diff --git a/query.cpp b/query.cpp
index b88fbd8..5d2e3fd 100644
--- a/query.cpp
+++ b/query.cpp
@@ -4,8 +4,11 @@
using namespace std;
-ColValueClause::ColValueClause(void):col(0){}
-ColValueClause::ColValueClause(const int _c,const RowItem &_v):col(_c),value(_v){}
+WhereClause::WhereClause(void):col(0){}
+WhereClause::WhereClause(const int _c,const vector<RowItem> &_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){}
@@ -16,6 +19,7 @@ QueryResult::QueryResult(int _res,const string &_m):res(_res),msg(_m){}
QueryResult Query::execute(map<string,Table> &tables){return QueryResult(-1);}
+Query::~Query(void){}
CreateQuery::CreateQuery(void):nc(0),header(NULL){}
@@ -47,24 +51,31 @@ pair<vector<map<string,Row>::const_iterator>,string> FindQuery::executeIterators
pair<vector<map<string,Row>::const_iterator>,string> FindQuery::executeIterators(const Table &table){
if(limit==0)return {{},"zero limit (FQ:eI)"};
- int i,j;
+ int i,j,k;
for(i=0;i<(int)where.size();i++){
if(where[i].col==0)break;
}
if(i!=(int)where.size()){
- const map<string,Row>::const_iterator rit=table.rows.find(serialise(table.header[0],where[i].value));
- 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(riCompare(table.header[col],row.items[col],where[j].value)!=0)break;
+ for(const RowItem &wh : where[i].values){
+ const map<string,Row>::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<where[j].values.size();k++){
+ if(riCompare(table.header[col],row.items[col],where[j].values[k])==0)break;
+ }
+ if(k==where[j].values.size())return {{},""};
+ }
+ vector<map<string,Row>::const_iterator> v;
+ v.push_back(rit);
+ return {v,""};
}
- if(j!=(int)where.size())return {{},""};
- vector<map<string,Row>::const_iterator> v;
- v.push_back(rit);
- return {v,""};
}
typedef map<string,Row>::const_iterator cit_t;
@@ -81,7 +92,10 @@ pair<vector<map<string,Row>::const_iterator>,string> FindQuery::executeIterators
for(cit_t it=table.rows.begin();it!=end;it++){
for(i=0;i<(int)where.size();i++){
const int col=where[i].col;
- if(riCompare(table.header[col],it->second.items[col],where[i].value)!=0)break;
+ for(j=0;j<where[i].values.size();j++){
+ if(riCompare(table.header[col],it->second.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);
diff --git a/query.h b/query.h
index b265496..264463d 100644
--- a/query.h
+++ b/query.h
@@ -7,16 +7,24 @@
using namespace std;
+struct WhereClause{
+ int col;
+ vector<RowItem> values;
+
+ WhereClause(void);
+ WhereClause(const int _c,const vector<RowItem> &_v);
+};
-struct ColValueClause{
+struct UpdateClause{
int col;
RowItem value;
- ColValueClause(void);
- ColValueClause(const int _c,const RowItem &_v);
+ UpdateClause(void);
+ UpdateClause(const int _c,const RowItem &_v);
};
+
struct QueryResult{
int res;
vector<Row> rows;
@@ -34,6 +42,7 @@ struct Query{
string tablename;
virtual QueryResult execute(map<string,Table>&);
+ virtual ~Query(void);
};
struct CreateQuery : public Query{
@@ -47,7 +56,7 @@ struct CreateQuery : public Query{
struct FindQuery : public Query{
unsigned int limit; //-1=unlimited
- vector<ColValueClause> where;
+ vector<WhereClause> where;
FindQuery(void);
pair<vector<map<string,Row>::const_iterator>,string> executeIterators(map<string,Table> &tables);
@@ -64,15 +73,15 @@ struct InsertQuery : public Query{
};
struct UpdateQuery : public Query{
- vector<ColValueClause> where;
- vector<ColValueClause> updates;
+ vector<WhereClause> where;
+ vector<UpdateClause> updates;
UpdateQuery(void);
QueryResult execute(map<string,Table> &tables);
};
struct DeleteQuery : public Query{
- vector<ColValueClause> where;
+ vector<WhereClause> where;
DeleteQuery(void);
QueryResult execute(map<string,Table> &tables);
diff --git a/script.cpp b/script.cpp
new file mode 100644
index 0000000..689066f
--- /dev/null
+++ b/script.cpp
@@ -0,0 +1,86 @@
+#include "script.h"
+
+bool validateExprNodeType(ExprNodeType type){
+ return type>=EFN_ADD&&type<=EFN_INVALID;
+}
+
+/*//returns parsed func and length of func
+pair<ExprFunction,int> parseExprFunction(const string &s,int start=0){
+ switch(s[start]){
+ case '+':
+ return {EFN_ADD,1};
+ case '-':
+ return {EFN_SUBTRACT,1};
+ case '*':
+ return {EFN_MULTIPLY,1};
+ case '/':
+ return {EFN_DIVIDE,1};
+ case '%':
+ return {EFN_MODULO,1};
+ case '=':
+ if(s[start+1]=='=')return {EFN_EQUAL,2};
+ else return {EFN_INVALID,0};
+ case '!':
+ if(s[start+1]=='=')return {EFN_UNEQUAL,2};
+ else return {EFN_NOT,1};
+ case '<':
+ if(s[start+1]=='=')return {EFN_LESSEQUAL,2};
+ else return {EFN_LESS,1};
+ case '>':
+ if(s[start+1]=='=')return {EFN_GREATEREQUAL,2};
+ else return {EFN_GREATER,1};
+ case '&':
+ if(s[start+1]=='&')return {EFN_AND,2};
+ else return {EFN_INVALID,0};
+ case '|':
+ if(s[start+1]=='|')return {EFN_OR,2};
+ else return {EFN_INVALID,0};
+ default:
+ return {EFN_INVALID,0};
+ }
+}*/
+
+
+int Expression::evaluate(unordered_map<string,QueryResult> &vars){
+ ;
+}
+
+
+ScriptLine::~ScriptLine(void){
+ if(querystub)delete querystub;
+ if(destvar)delete destvar;
+ if(expr)delete expr;
+ if(block)delete block;
+}
+
+vector<QueryResult> ScriptLine::execute(map<string,Table> &tables,unordered_map<string,QueryResult> &vars){
+ if(type==SLT_QUERYSTUB&&querystub){
+ Query *qu=resolveQueryStub(*querystub,tables,vars);
+ QueryResult res=qu->execute(tables);
+ delete qu;
+ if(destvar)vars[*destvar]=res;
+ return {res};
+ } else if(type==SLT_IF&&expr&&block){
+ if(expr->evaluate(vars))return block->execute(tables,vars);
+ } else if(type==SLT_WHILE&&expr&&block){
+ while(expr->evaluate(vars))return block->execute(tables,vars);
+ } else if(type==SLT_ASSIGNMENT&&destvar&&expr){
+ vars[*destvar]=QueryResult(expr->evaluate(vars));
+ return {};
+ }
+ return {};
+}
+
+
+vector<QueryResult> Script::execute(map<string,Table> &tables){
+ unordered_map<string,QueryResult> vars;
+ return execute(tables,vars);
+}
+vector<QueryResult> Script::execute(map<string,Table> &tables,unordered_map<string,QueryResult> &vars){
+ ;
+}
+
+
+Query* resolveQueryStub(const string &stub,map<string,Table> &tables,unordered_map<string,QueryResult> &vars){
+ ;
+}
diff --git a/script.h b/script.h
new file mode 100644
index 0000000..05427ca
--- /dev/null
+++ b/script.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "enginedata.h"
+#include "query.h"
+#include <vector>
+#include <unordered_map>
+#include <map>
+
+struct Script;
+struct Query;
+
+
+enum ExprNodeType {
+ EFN_ADD=0, EFN_SUBTRACT, EFN_MULTIPLY, EFN_DIVIDE, EFN_MODULO,
+ EFN_EQUAL, EFN_UNEQUAL,
+ EFN_LESS, EFN_GREATER, EFN_LESSEQUAL, EFN_GREATEREQUAL,
+ EFN_AND, EFN_OR,
+ EFN_NOT, //1 arg
+ EFN_MAX, EFN_MIN,
+
+ EFN_NUMBER, EFN_VARIABLE, //0 arg
+ EFN_INVALID //invalid
+};
+
+bool validateExprNodeType(ExprNodeType);
+
+struct Expression {
+ ExprNodeType type;
+ vector<Expression> args;
+ int evaluate(unordered_map<string,QueryResult>&);
+};
+
+
+enum ScriptLineType {
+ SLT_QUERYSTUB,
+ SLT_IF,
+ SLT_WHILE,
+ SLT_ASSIGNMENT
+};
+
+struct ScriptLine {
+ ScriptLineType type;
+ string *querystub=NULL;
+ string *destvar=NULL;
+ Expression *expr=NULL;
+ Script *block=NULL;
+
+ ~ScriptLine(void);
+ vector<QueryResult> execute(map<string,Table>&,unordered_map<string,QueryResult>&);
+};
+
+struct Script {
+ vector<ScriptLine> lines;
+
+ vector<QueryResult> execute(map<string,Table>&);
+ vector<QueryResult> execute(map<string,Table>&,unordered_map<string,QueryResult>&);
+};
+
+//just hands over pointer, CALLING FUNCTION TAKES OWNERSHIP
+Query* resolveQueryStub(const string &stub,map<string,Table>&,unordered_map<string,QueryResult>&);