#include "sqlgen.h" #include "../stringtools.h" #include #include enum CPPFileTokenType { CPPFileTokenType_Code, CPPFileTokenType_Comment }; struct CPPToken { CPPToken(const std::string& data, CPPFileTokenType type) : data(data), type(type) { } std::string data; CPPFileTokenType type; }; enum TokenizeState { TokenizeState_None, TokenizeState_CommentMultiline, TokenizeState_CommentSingleline }; std::vector tokenizeFile(std::string &cppfile) { std::regex find_comments("(/\\*(\\S|\\s)*?\\*/)|(//.*)", std::regex::ECMAScript); auto comments_begin=std::regex_iterator(cppfile.begin(), cppfile.end(), find_comments); auto comments_end=std::regex_iterator(); std::vector tokens; size_t lastPos=0; for(auto i=comments_begin;i!=comments_end;++i) { auto m=*i; size_t pos=m.position(0); if(lastPos annotations, std::string code) : annotations(annotations), code(code) { } AnnotatedCode(std::string code) : code(code) { } std::map annotations; std::string code; }; std::string cleanup_annotation(const std::string& annotation) { int state=0; std::string ret; for(size_t i=0;i0) { was_in_function=true; } if(c==0 && was_in_function) { return data.substr(0, i); } } return std::string(); } std::vector getAnnotatedCode(const std::vector& tokens) { std::vector ret; for(size_t i=0;i annotations; std::regex find_annotations("@([^ \\r\\n]*)[ ]*((\\S|\\s)*?)(?=(\\*/)|@)", std::regex::ECMAScript); for(auto it=std::regex_iterator(tokens[i].data.begin(), tokens[i].data.end(), find_annotations); it!=std::regex_iterator();++it) { auto m=*it; std::string annotation_text=m[2].str(); annotations[m[1].str()]=trim(cleanup_annotation(annotation_text)); } ret.push_back(AnnotatedCode(tokens[i].data)); if(!annotations.empty()) { if(i+1 parseReturnTypes(std::string return_str) { std::vector toks; Tokenize(return_str, toks, ","); std::vector ret; for(size_t i=0;i& types) { std::regex find_var(":([^ (])*(\\([^)]*?\\))",std::regex::ECMAScript); size_t lastPos=0; std::string retSql; for(auto it=std::regex_iterator(sql.begin(), sql.end(), find_var); it!=std::regex_iterator();++it) { auto m=*it; if(m.position()>lastPos) { retSql+=sql.substr(lastPos, m.position()-lastPos); lastPos=m.position(); } retSql+="?"; types.push_back(ReturnType(m[2].str(), m[1].str())); } if(lastPos return_types, GeneratedData& gen_data) { gen_data.structures+="\tstruct "+name+"\r\n"; gen_data.structures+="\t{\r\n"; for(size_t i=0;i", return_type); return_vector=true; } bool select_statement=false; if(strlower(sql).find("select")) { select_statement=true; } std::string return_vals=input.annotations["return"]; std::vector return_types=parseReturnTypes(return_vals); std::vector params; std::string parsedSql=parseSqlString(sql, params); IQuery *q=db->Prepare("EXPLAIN "+parsedSql, true); if(q==NULL) { std::cout << "ERROR preparing statement: " << parsedSql << std::endl; return; } generateStructure(struct_name, return_types, gen_data); std::string code=return_type+" "+funcsig+"("; for(size_t i=0;i0) { code+=" ,"; } std::string type=params[i].type; if(type=="string") { type="std::string"; } code+=type+" "+params[i].name; } if(params.empty()) { code+="void"; } code+=")\r\n{\r\n"; gen_data.createQueriesCode+="\t"+query_name+"="+"db->Prepare(\""+parsedSql+"\", false);\r\n"; gen_data.destroyQueriesCode+="\tdb->destroyQuery("+query_name+");\r\n"; for(size_t i=0;iBind("+params[i].name+");\r\n"; } if(select_statement) { code+="\tdb_results res="+query_name+"->Read();\r\n"; } if(!params.empty()) { code+="\t"+query_name+"->Reset();\r\n"; } if(return_vector) { code+="\tstd::vector<"+struct_name+"> ret;\r\n"; code+="\tfor(size_t i=0;i annotated_code) { for(size_t i=0;i tokens=tokenizeFile(cppfile); std::vector annotated_code=getAnnotatedCode(tokens); }