Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <string>
- #include <string.h>
- #include <map>
- using namespace std;
- class StrBuilder
- {
- std::vector<char> m_data;
- public:
- StrBuilder(){}
- ~StrBuilder() { m_data.clear();}
- inline void Add(const char& c)
- {
- m_data.push_back(c);
- }
- inline std::string toString()
- {
- static std::string err("");
- if (m_data.size() <= 0)
- err;
- size_t size = m_data.size(); // for null;
- char* c = new char[size+1];
- char* t = c;
- memset(c, 0x00, size+1);
- int i=0;
- for(; i < size; i++)
- {
- c[i] = m_data[i];
- }
- c[i] = 0;
- std::string fix(t);
- delete [] c;
- c = nullptr;
- return fix;
- }
- };
- struct BuilderList
- {
- static std::vector<StrBuilder> s_Builders;
- };
- std::vector<StrBuilder> BuilderList::s_Builders;
- struct CDFixForMSSQLLib
- {
- int m_andCnt ;
- const char* pBeginAnd;
- std::vector<std::string> m_remainings;
- std::vector<std::string> m_test;
- // carful here, we must append in a proper way
- struct
- {
- int index;
- std::map<int, std::vector<std::string> > data;
- } m_appendBuffer;
- public:
- void CollectRemainings(const char* begin)
- {
- const char* orIt = begin;
- std::vector<std::string> rem;
- while ((orIt = strstr(orIt, " OR ")) != NULL)
- {
- StrBuilder sb;
- while (*orIt != '\'')
- orIt++;
- for(;;)
- {
- sb.Add(*orIt++);
- if (*orIt == '\'')
- {
- sb.Add(*orIt--);
- break;
- }
- }
- m_remainings.push_back(sb.toString());
- rem.push_back(sb.toString());
- }
- for(int i=0; i < rem.size(); ++i)
- {
- m_appendBuffer.data[m_appendBuffer.index]
- .push_back(rem.at(i));
- }
- m_appendBuffer.index++;
- }
- std::string GetConstantString(const char* begin)
- {
- StrBuilder sb;
- const char* it = begin;
- const char* end = strstr(begin, " WHERE ");
- while (it != end)
- {
- sb.Add(*it++);
- }
- for(int i=0; i < strlen(" WHERE "); ++i)
- {
- sb.Add(*end++);
- }
- const char* orFirst = strstr(begin, " OR ");
- const char* andFirst = strstr(begin, " AND ");
- if (andFirst > orFirst)
- {
- while (end != orFirst)
- {
- sb.Add(*end++);
- }
- }
- else
- {
- while (end != andFirst)
- {
- sb.Add(*end++);
- }
- }
- std::string ret = sb.toString();
- return ret;
- }
- // new fix new logic
- std::string GetFirstItemBeforeOR(const char* begin, std::string** rem)
- {
- if (!begin)
- return std::string("");
- const char* it = begin;
- const char* end = strstr(it, " OR ");
- StrBuilder sb;
- if (!end)
- {
- return std::string(begin);
- }
- else
- {
- {
- const char* tmp = end;
- StrBuilder sb;
- while (*tmp != '\0')
- {
- sb.Add(*tmp++);
- }
- std::string* s = new std::string(sb.toString().c_str());
- (*rem) = s;
- }
- const char* openStr = strchr(it, '\'');
- while (it != openStr)
- {
- sb.Add(*it++);
- }
- sb.Add(*openStr++);
- while (*openStr != '\'')
- {
- sb.Add(*openStr++);
- }
- sb.Add(*openStr++);
- }
- std::string ret = sb.toString();
- return ret;
- }
- // simple split by AND buffers to be worked on
- void PrepareBuffers(char* next, const char* crit,
- std::vector<std::string> & buff)
- {
- char* it = (char*)strstr(next, crit);
- if (!it)
- return;
- it += strlen(crit);
- StrBuilder sb;
- for(int i=0; i < strlen(crit); ++i)
- {
- sb.Add(crit[i]);
- }
- const char* end = strstr(it, crit);
- if (!end)
- {
- while (*it != '\0')
- {
- sb.Add(*it++);
- }
- }
- else
- {
- while (it != end)
- {
- sb.Add(*it++);
- }
- }
- buff.push_back(std::string(sb.toString()));
- PrepareBuffers(it, crit, buff);
- }
- CDFixForMSSQLLib() : m_andCnt(0) , pBeginAnd(NULL),
- m_appendBuffer{0}
- {
- }
- ~CDFixForMSSQLLib() { }
- bool NeedsFix(const std::string& query)
- {
- const char* andMatch = strstr(query.c_str(), " AND ");
- const char* orMatch = strstr(query.c_str(), " OR ");
- return (andMatch != NULL) && (orMatch != NULL);
- }
- std::string ApplySQLFix(const std::string & queryToFix)
- {
- StrBuilder sb;
- static std::string error(""); // return error empty string
- std::string retString;
- const char* begin = queryToFix.c_str();
- if (!begin)
- {
- return error;
- }
- // find first OR in string (lowercase)
- const char* orIt = begin;
- {
- const char* original = strstr(begin, " OR ");
- const char* tmpOrig = original;
- // bug - crashesh if not handled
- // if not or - return original query
- if (original == NULL)
- {
- return queryToFix;
- }
- // prevent out writing to some bad place
- if (*original == ' ')
- {
- while (*original == ' ')
- original--;
- original++;
- }
- for (const char* it = begin; it != original; )
- {
- sb.Add(*it++);
- }
- retString = std::string(sb.toString());
- }
- while ((orIt = strstr(orIt, " OR ")) != NULL)
- {
- while (*orIt != '\'')
- orIt++;
- StrBuilder sb;
- for (;;)
- {
- sb.Add(*orIt++);
- if (*orIt == '\'')
- break;
- }
- sb.Add(*orIt--);
- BuilderList::s_Builders.push_back(sb);
- }
- printf("String builder size (%d)\n", (int)BuilderList::s_Builders.size());
- return retString;
- }
- };
- static const char* gQueryOld =
- "SELECT name, time, severity.key, severity, userid, userlocation, message, user.resourceid, user.resourcename, user.resourcetype, user.resourcelocation, user.accessgranted, user.audittype, var.MigratedLogDescr "
- "FROM Audit "
- " WHERE "
- "user.resourcetype.key = 'AXIS P3367 Fixed Dome Network Camera (10.4.24.46) - FIRST 1' OR "
- "user.resourcetype.key = 'AXIS P3367 Fixed Dome Network Camera (10.4.24.46) - Camera 1' OR "
- "user.resourcetype.key = 'Arecont Single Camera (10.4.24.131) - Camera 1' OR "
- "user.resourcetype.key = 'Arecont Single Camera (10.4.24.131) - Microphone 1' OR "
- "user.resourcetype.key = 'My window and camera (10.4.24.131) - Camera 1' "
- "AND "
- "A > B";
- static const char *gQueryNew =
- "SELECT name, time, severity.key, severity, userid, userlocation, message, user.resourceid, user.resourcename, user.resourcetype, user.resourcelocation, user.accessgranted, user.audittype, var.MigratedLogDescr "
- "FROM Audit "
- " WHERE "
- " A1 > 300 "
- " AND "
- " B1 > 200 "
- " AND "
- " kur != hui "
- " AND "
- "user.resourcetype.key = '111111111111111111111111111111111111111' OR "
- "user.resourcetype.key = 'AXIS P3367 Fixed Dome Network Camera (10.4.24.46) - Camera 1' OR "
- "user.resourcetype.key = 'Arecont Single Camera (10.4.24.131) - Camera 1' OR "
- "user.resourcetype.key = 'Arecont Single Camera (10.4.24.131) - Microphone 1' OR "
- "user.resourcetype.key = 'My window and camera (10.4.24.131) - Camera 1'"
- " AND "
- " A > 300 "
- " AND "
- "user.resourcename = 'camera' OR "
- "user.resourcename = 'microphone' OR "
- "user.resourcename = '#########################' OR "
- "user.resourcename = 'oooooooooooo' OR "
- "user.resourcename = 'kor kor' OR "
- "user.resourcename = 'cccccccccc ' OR "
- "user.resourcename = 'mor mor ' "
- " AND "
- " B > 200 "
- " AND "
- " C > 100";
- int main()
- {
- FILE* fp = fopen("out.txt", "w");
- if (!fp)
- exit(-1);
- std::string query (gQueryNew);
- CDFixForMSSQLLib fix;
- fprintf(fp, "Original query before CD fix: \r\n");
- fprintf(fp, "[%s]\r\n", gQueryNew);
- std::string new_query ;
- if (fix.NeedsFix(query))
- {
- std::cout << "Needs fix... \n";
- // std::cout << fix.GetFirstItemBeforeOR(query.c_str(), otherhalf);
- std::cout << "\r\n\r\n";
- std::string* otherString;
- std::vector<std::string> a, b;
- //
- // new_query += fix.GetConstantString(query.c_str());
- new_query += fix.GetFirstItemBeforeOR(query.c_str(), &otherString);
- std::cout << new_query.c_str() << "\r\n\r\n";
- fix.PrepareBuffers((char*)query.c_str(), " AND ", a);
- fix.PrepareBuffers((char*)query.c_str(), " OR ", b);
- std::map<int, std::vector<std::string> >remainings;
- for(int i=0; i < a.size(); ++i)
- {
- const char* it = 0;
- if ((it = strstr(a.at(i).c_str(), " OR ")) != NULL)
- {
- const char* t = a.at(i).c_str();
- StrBuilder sb;
- while (t != it)
- {
- sb.Add(*t++);
- }
- a[i] = sb.toString();
- std::vector<std::string> tmp;
- fix.PrepareBuffers((char*)b.at(i).c_str(), " OR ", tmp);
- remainings[i] = tmp;
- }
- //fix.CollectRemainings(a.at(i).c_str());
- }
- for(int i=0; i < a.size(); ++i)
- {
- printf("[%d](%s)\r\n", i, a.at(i).c_str());
- }
- #if 0
- for(int i=0; i < a.size(); ++i)
- {
- std::string tmp = fix.GetFirstItemBeforeOR(
- a.at(i).c_str());
- std::cout << tmp.c_str() << "\n";
- new_query += tmp;
- }
- #endif
- }
- else
- {
- // use old fix for simplicity
- std::string s = fix.ApplySQLFix(query);
- query = std::string(s);
- }
- fprintf(fp, "Fixed query before BOOST SQL generator is: \r\n");
- fprintf(fp, "[%s]\r\n", new_query.c_str());
- fprintf(fp, "\r\nREMAININGS TO BE APPENDED AS OR-s:\r\n");
- for(int i=0; i < fix.m_remainings.size(); ++i)
- {
- fprintf(fp, "fix.m_remainings[%d] = (%s)\r\n", i, fix.m_remainings.at(i).c_str());
- }
- for(int i=0; i < fix.m_appendBuffer.index; ++i)
- {
- // a minor index bug for the map, however it's a map and unique is guaranted
- puts("\r\n");
- for(int j=0; j < fix.m_appendBuffer.data[i].size(); ++j)
- {
- fprintf(fp, "Row(%d)Col(%d) : DATA: %s\r\n", i, j,
- fix.m_appendBuffer.data[i][j].c_str());
- }
- }
- fflush(fp);
- fclose(fp);
- return 0;
- }
Add Comment
Please, Sign In to add comment