diff --git a/concordia-server/CMakeLists.txt b/concordia-server/CMakeLists.txt index 6abcb01..548e426 100644 --- a/concordia-server/CMakeLists.txt +++ b/concordia-server/CMakeLists.txt @@ -6,6 +6,10 @@ add_executable(concordia_server_process json_generator.cpp unit_dao.cpp db_connection.cpp + query_param.cpp + string_param.cpp + int_param.cpp + logger.cpp ) target_link_libraries(concordia_server_process fcgi fcgi++ pq concordia config++ log4cpp ${Boost_LIBRARIES} divsufsort utf8case) diff --git a/concordia-server/concordia_server.cpp b/concordia-server/concordia_server.cpp index 4d5f1ac..e7da983 100644 --- a/concordia-server/concordia_server.cpp +++ b/concordia-server/concordia_server.cpp @@ -31,7 +31,6 @@ std::string ConcordiaServer::handleRequest(std::string & requestString) { rapidjson::Writer jsonWriter(outputJson); std::stringstream outputString; - try { outputString << "Content-type: application/json\r\n\r\n"; rapidjson::Document d; diff --git a/concordia-server/db_connection.cpp b/concordia-server/db_connection.cpp index f4bd8c3..5ffaba3 100644 --- a/concordia-server/db_connection.cpp +++ b/concordia-server/db_connection.cpp @@ -1,6 +1,11 @@ #include "db_connection.hpp" +#include +#include + + #include "config.hpp" +#include "logger.hpp" DBconnection::DBconnection() throw(ConcordiaException) { std::string connectionInfo = "dbname="DB_NAME" user="DB_USER; @@ -53,9 +58,12 @@ PGresult * DBconnection::execute(std::string query) throw(ConcordiaException) { if (_connection != NULL) { PGresult * result = PQexec(_connection, query.c_str()); if (PQresultStatus(result) != PGRES_COMMAND_OK) { + std::stringstream ss; + ss << "query execution failed with message: "; + ss << PQresultErrorMessage(result) << std::endl; PQclear(result); close(); - throw ConcordiaException("ending transaction failed"); + throw ConcordiaException(ss.str()); } else { return result; } @@ -65,7 +73,42 @@ PGresult * DBconnection::execute(std::string query) throw(ConcordiaException) { } PGresult * DBconnection::execute(std::string query, - std::vector params) throw(ConcordiaException) { + std::vector params) throw(ConcordiaException) { + if (_connection != NULL) { + const char * paramValues[params.size()]; + int paramLengths[params.size()]; + int paramFormats[params.size()]; + int index = 0; + BOOST_FOREACH (QueryParam * param, params) { + paramValues[index] = param->getValue(); + paramLengths[index] = param->getLength(); + paramFormats[index] = param->isBinary(); + index++; + } + + + PGresult * result = PQexecParams(_connection, + query.c_str(), + params.size(), + NULL, + paramValues, + paramLengths, + paramFormats, + 0 + ); + if (PQresultStatus(result) != PGRES_COMMAND_OK) { + std::stringstream ss; + ss << "parametrized query execution failed with message: "; + ss << PQresultErrorMessage(result) << std::endl; + PQclear(result); + close(); + throw ConcordiaException(ss.str()); + } else { + return result; + } + } else { + throw ConcordiaException("requested query execution but the database connection is not ready"); + } } diff --git a/concordia-server/db_connection.hpp b/concordia-server/db_connection.hpp index cf8e7d9..2c04183 100644 --- a/concordia-server/db_connection.hpp +++ b/concordia-server/db_connection.hpp @@ -7,6 +7,8 @@ #include +#include "query_param.hpp" + class DBconnection { public: /*! Constructor. @@ -23,7 +25,7 @@ public: PGresult * execute(std::string query) throw(ConcordiaException); PGresult * execute(std::string query, - std::vector params) throw(ConcordiaException); + std::vector params) throw(ConcordiaException); private: void close(); diff --git a/concordia-server/index_controller.cpp b/concordia-server/index_controller.cpp index 393dd6c..0506a05 100644 --- a/concordia-server/index_controller.cpp +++ b/concordia-server/index_controller.cpp @@ -1,6 +1,5 @@ #include "index_controller.hpp" -#include #include "json_generator.hpp" IndexController::IndexController(boost::shared_ptr concordia) @@ -20,7 +19,7 @@ void IndexController::addSentence( try { boost::shared_ptr tokenizedSentence = _concordia->tokenize(sourceSentence); - SUFFIX_MARKER_TYPE sentenceId = _unitDAO.addSentence(tokenizedSentence, targetSentence, tmId); + int sentenceId = _unitDAO.addSentence(tokenizedSentence, targetSentence, tmId); _concordia->addTokenizedExample(tokenizedSentence, sentenceId); _concordia->refreshSAfromRAM(); diff --git a/concordia-server/int_param.cpp b/concordia-server/int_param.cpp new file mode 100644 index 0000000..6d2dfb1 --- /dev/null +++ b/concordia-server/int_param.cpp @@ -0,0 +1,23 @@ +#include "int_param.hpp" + +#include +#include + +IntParam::IntParam(int value) { + _value = htonl((unsigned long int) value); +} + +IntParam::~IntParam() { +} + +const char * IntParam::getValue() { + return (const char *) &_value; +} + +const int IntParam::getLength() { + return sizeof(_value); +} + +const int IntParam::isBinary() { + return 1; +} diff --git a/concordia-server/int_param.hpp b/concordia-server/int_param.hpp new file mode 100644 index 0000000..aae6949 --- /dev/null +++ b/concordia-server/int_param.hpp @@ -0,0 +1,24 @@ +#ifndef INT_PARAM_HDR +#define INT_PARAM_HDR + +#include "query_param.hpp" + +class IntParam : public QueryParam { +public: + /*! Constructor. + */ + IntParam(int value); + /*! Destructor. + */ + virtual ~IntParam(); + + const char * getValue(); + + const int getLength(); + + const int isBinary(); +private: + unsigned int _value; +}; + +#endif diff --git a/concordia-server/logger.cpp b/concordia-server/logger.cpp new file mode 100644 index 0000000..77a0a48 --- /dev/null +++ b/concordia-server/logger.cpp @@ -0,0 +1,31 @@ +#include "logger.hpp" + +#include "log4cpp/Category.hh" +#include "log4cpp/Appender.hh" +#include "log4cpp/FileAppender.hh" +#include "log4cpp/BasicLayout.hh" +#include "log4cpp/Priority.hh" + +Logger::Logger() { +} + +Logger::~Logger() { +} + +int Logger::initialized = 0; + +void Logger::log(std::string message) { + log4cpp::Category & root = log4cpp::Category::getRoot(); + if (initialized == 0) { + log4cpp::Appender *appender = new log4cpp::FileAppender("default", "/tmp/concordia-server.log"); + appender->setLayout(new log4cpp::BasicLayout()); + + root.setPriority(log4cpp::Priority::INFO); + root.addAppender(appender); + + initialized = 1; + } + root.info(message); +} + + diff --git a/concordia-server/logger.hpp b/concordia-server/logger.hpp new file mode 100644 index 0000000..9653c19 --- /dev/null +++ b/concordia-server/logger.hpp @@ -0,0 +1,21 @@ +#ifndef LOGGER_HDR +#define LOGGER_HDR + +#include +#include + +class Logger { +public: + /*! Constructor. + */ + Logger(); + /*! Destructor. + */ + virtual ~Logger(); + + static void log(std::string message); +private: + static int initialized; +}; + +#endif diff --git a/concordia-server/query_param.cpp b/concordia-server/query_param.cpp index f4bd8c3..df34889 100644 --- a/concordia-server/query_param.cpp +++ b/concordia-server/query_param.cpp @@ -1,71 +1,16 @@ -#include "db_connection.hpp" +#include "query_param.hpp" -#include "config.hpp" +QueryParam::QueryParam() { +} -DBconnection::DBconnection() throw(ConcordiaException) { - std::string connectionInfo = "dbname="DB_NAME" user="DB_USER; - _connection = PQconnectdb(connectionInfo.c_str()); - if (PQstatus(_connection) != CONNECTION_OK) { - close(); - throw ConcordiaException("Could not establish connection with the database"); - } +QueryParam::~QueryParam() { +} + +const char * QueryParam::getValue() { +} +const int QueryParam::getLength() { } -DBconnection::~DBconnection() { - close(); +const int QueryParam::isBinary() { } - -void DBconnection::close() { - if (_connection != NULL) { - PQfinish(_connection); - _connection = NULL; - } -} - -void DBconnection::startTransaction() throw(ConcordiaException) { - if (_connection != NULL) { - PGresult * result = PQexec(_connection, "BEGIN"); - if (PQresultStatus(result) != PGRES_COMMAND_OK) { - PQclear(result); - close(); - throw ConcordiaException("starting transaction failed"); - } - } else { - throw ConcordiaException("requested start transaction but the database connection is not ready"); - } -} - -void DBconnection::endTransaction() throw(ConcordiaException) { - if (_connection != NULL) { - PGresult * result = PQexec(_connection, "END"); - if (PQresultStatus(result) != PGRES_COMMAND_OK) { - PQclear(result); - close(); - throw ConcordiaException("ending transaction failed"); - } - } else { - throw ConcordiaException("requested end transaction but the database connection is not ready"); - } -} - -PGresult * DBconnection::execute(std::string query) throw(ConcordiaException) { - if (_connection != NULL) { - PGresult * result = PQexec(_connection, query.c_str()); - if (PQresultStatus(result) != PGRES_COMMAND_OK) { - PQclear(result); - close(); - throw ConcordiaException("ending transaction failed"); - } else { - return result; - } - } else { - throw ConcordiaException("requested query execution but the database connection is not ready"); - } -} - -PGresult * DBconnection::execute(std::string query, - std::vector params) throw(ConcordiaException) { -} - - diff --git a/concordia-server/query_param.hpp b/concordia-server/query_param.hpp index 7972635..2afd1f8 100644 --- a/concordia-server/query_param.hpp +++ b/concordia-server/query_param.hpp @@ -5,11 +5,16 @@ class QueryParam { public: /*! Constructor. */ - QueryParam() throw(ConcordiaException); + QueryParam(); /*! Destructor. */ virtual ~QueryParam(); + virtual const char * getValue(); + + virtual const int getLength(); + + virtual const int isBinary(); private: }; diff --git a/concordia-server/string_param.cpp b/concordia-server/string_param.cpp new file mode 100644 index 0000000..c5469c7 --- /dev/null +++ b/concordia-server/string_param.cpp @@ -0,0 +1,19 @@ +#include "string_param.hpp" + +StringParam::StringParam(std::string value) : _value(value) { +} + +StringParam::~StringParam() { +} + +const char * StringParam::getValue() { + return _value.c_str(); +} + +const int StringParam::getLength() { + return _value.size(); +} + +const int StringParam::isBinary() { + return 0; +} diff --git a/concordia-server/string_param.hpp b/concordia-server/string_param.hpp new file mode 100644 index 0000000..c58c913 --- /dev/null +++ b/concordia-server/string_param.hpp @@ -0,0 +1,26 @@ +#ifndef STRING_PARAM_HDR +#define STRING_PARAM_HDR + +#include "query_param.hpp" + +#include + +class StringParam : public QueryParam { +public: + /*! Constructor. + */ + StringParam(std::string value); + /*! Destructor. + */ + virtual ~StringParam(); + + const char * getValue(); + + const int getLength(); + + const int isBinary(); +private: + std::string _value; +}; + +#endif diff --git a/concordia-server/unit_dao.cpp b/concordia-server/unit_dao.cpp index 9a0bcc6..453115d 100644 --- a/concordia-server/unit_dao.cpp +++ b/concordia-server/unit_dao.cpp @@ -1,6 +1,13 @@ #include "unit_dao.hpp" #include "db_connection.hpp" +#include "query_param.hpp" +#include "string_param.hpp" +#include "int_param.hpp" +#include "logger.hpp" + +#include +#include UnitDAO::UnitDAO() { } @@ -8,15 +15,28 @@ UnitDAO::UnitDAO() { UnitDAO::~UnitDAO() { } -SUFFIX_MARKER_TYPE UnitDAO::addSentence( +int UnitDAO::addSentence( boost::shared_ptr sourceSentence, std::string & targetSentence, int tmId) { - + DBconnection connection; connection.startTransaction(); - connection.execute("INSERT INTO unit(source_segment) values('just testing')"); + std::string query = "INSERT INTO unit(source_segment, target_segment, tm_id) values($1::text,$2::text,$3::integer)"; + std::vector params; + params.push_back(new StringParam(sourceSentence->getSentence())); + params.push_back(new StringParam(targetSentence)); + params.push_back(new IntParam(tmId)); + + connection.execute(query, params); connection.endTransaction(); + + BOOST_FOREACH (QueryParam * param, params) { + delete param; + } + + //todo return new unit id + return 0; } diff --git a/concordia-server/unit_dao.hpp b/concordia-server/unit_dao.hpp index f3aa37f..97fa334 100644 --- a/concordia-server/unit_dao.hpp +++ b/concordia-server/unit_dao.hpp @@ -4,7 +4,6 @@ #include #include -#include #include class UnitDAO { @@ -16,7 +15,7 @@ public: */ virtual ~UnitDAO(); - SUFFIX_MARKER_TYPE addSentence( + int addSentence( boost::shared_ptr sourceSentence, std::string & targetSentence, int tmId); diff --git a/tests/testCurl.sh b/tests/testCurl.sh index 882fb40..c7b1750 100755 --- a/tests/testCurl.sh +++ b/tests/testCurl.sh @@ -1,5 +1,7 @@ #!/bin/sh -curl -H "Content-Type: application/json" -X POST -d '{"operation":"addSentence", "sentence":"zupełnie nowe zdanie"}' http://localhost +curl -H "Content-Type: application/json" -X POST -d '{"operation":"addSentence", "sourceSentence":"zupełnie nowe zdanie", "targetSentence":"zażółć gęślą jaźńZAŻÓŁĆ GĘŚLĄ JAŹŃ", "tmId":1234782314}' http://localhost + + #curl -H "Content-Type: application/json" -X POST -d '{"operation":"simpleSearch", "sentence":"zupełnie nowe"}' http://localhost