void Session::processSQL(std::string& sqlQuery) { std::ostringstream oss; if (this->m_current_db_cfg) { boost::posix_time::ptime begin(boost::posix_time::microsec_clock::local_time()); try { tnode *pNode = NULL; int nRet; // // Prepare TProjectSettings settings(*m_current_db_cfg->settings); std::string displayFile; // // generate ident and ini file std::string queryIdentStr = ""; boost::uuids::uuid queryIdent = boost::uuids::random_generator()(); std::ostringstream queryIdentOSS; queryIdentOSS << queryIdent; queryIdentStr = queryIdentOSS.str(); settings.changeIdent(queryIdentOSS.str()); // // create directories std::list<fs::path> lpaths; lpaths.push_back(fs::path(settings.szRootPath + "/calculus/" + queryIdentOSS.str())); lpaths.push_back(fs::path(settings.szTempPath1)); lpaths.push_back(fs::path(settings.szTempPath2)); for (std::list<fs::path>::const_iterator dir = lpaths.begin(); dir != lpaths.end(); ++dir) { std::ostringstream ossDirName; ossDirName << *dir; aq::Logger::getInstance().log(AQ_DEBUG, "create directory '%s'\n", ossDirName.str().c_str()); if (fs::exists(*dir)) { aq::Logger::getInstance().log(AQ_ERROR, "directory already exist '%s'\n", ossDirName.str().c_str()); return; } if (!fs::create_directory(*dir)) { aq::Logger::getInstance().log(AQ_ERROR, "cannot create directory '%s'\n", ossDirName.str().c_str()); return; } aq::Logger::getInstance().log(AQ_DEBUG, "directory '%s' created\n", ossDirName.str().c_str()); } // // write ini file (it is needed for now by AQEngine) std::ofstream iniFile(settings.iniFile.c_str()); settings.writeAQEngineIni(iniFile); iniFile.close(); // generate answer file displayFile = settings.szRootPath + "/calculus/" + queryIdentStr + "/display.txt"; // TODO aq::Logger::getInstance().log(AQ_INFO, "save answer to %s\n", displayFile.c_str()); // // Parse SQL request aq::Logger::getInstance().log(AQ_INFO, "parse sql request %s\n", sqlQuery.c_str()); if ((nRet = SQLParse(sqlQuery.c_str(), &pNode)) != 0 ) { oss << "error parsing sql query '" << sqlQuery << "'" << std::endl; aq::Logger::getInstance().log(AQ_ERROR, oss.str().c_str()); throw generic_error(generic_error::INVALID_QUERY, oss.str()); } // // Transform SQL request in prefix form unsigned int id = 1; QueryResolver queryResolver(pNode, &settings, this->m_current_db_cfg->m_aq_engine, *this->m_current_db_cfg->baseDesc.get(), id); aq::Logger::getInstance().log(AQ_INFO, "execute query %s\n", sqlQuery.c_str()); queryResolver.solve(); // // Generate result file Table::Ptr result = queryResolver.getResult(); if (result) { aq::Timer timer; result->saveToAnswer(settings.szAnswerFN, settings.fieldSeparator); aq::Logger::getInstance().log(AQ_INFO, "Save Answer: Time Elapsed = %s\n", aq::Timer::getString(timer.getTimeElapsed()).c_str()); std::ofstream fresult(settings.szAnswerFN, std::ios::app); fresult << "EOS"; fresult.close(); } // // read result file and deliver on the socket aq::Logger::getInstance().log(AQ_DEBUG, "read answer file %s\n", settings.szAnswerFN); std::ifstream answerFile(settings.szAnswerFN); std::string bloc; std::string line; while (std::getline(answerFile, line)) { line += "\n"; bloc += line; if (bloc.size() > 2048) { this->deliver(bloc); bloc = ""; } } if (bloc.size()) this->deliver(bloc); oss << "sql request successfully executed" << std::endl; } catch (const generic_error& ex) { aq::Logger::getInstance().log(AQ_ERROR, "%s\n", ex.what()); oss << "error during sql processing: " << ex.what() << std::endl; } boost::posix_time::ptime end(boost::posix_time::microsec_clock::local_time()); oss << "Time elapsed: " << (end - begin) << std::endl; } else { oss << "not connected to any database" << std::endl; aq::Logger::getInstance().log(AQ_NOTICE, oss.str().c_str()); } this->deliver(oss.str()); }