-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
каркас сервера posts #5
base: main
Are you sure you want to change the base?
Changes from 7 commits
808d8a2
368a702
4b927e9
05fda6d
b823773
308ef32
94c7f7d
d2f6347
707eba9
5256e1a
ee97ed0
67236ac
73acb9c
3d77334
f994c23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
cmake_minimum_required(VERSION 3.17) | ||
project(server_posts) | ||
set(CMAKE_CXX_STANDARD 20) | ||
|
||
# set(CMAKE_CXX_FLAGS "-g -Wall -lpthread -lgtest -L/usr/local/lib") | ||
set(CMAKE_CXX_FLAGS "-g -Wall -lpthread -lgtest -L/usr/local/lib -lpqxx -lpq") | ||
|
||
|
||
#find_package(PQXX) | ||
find_package(GTest REQUIRED) | ||
find_package(Threads REQUIRED) | ||
|
||
|
||
|
||
|
||
find_package(Boost) | ||
include_directories(${Boost_INCLUDE_DIRS}) | ||
|
||
set(DIR ${CMAKE_CURRENT_SOURCE_DIR}) | ||
|
||
set(INC_DIR ${DIR}/include) | ||
set(SRC_DIR ${DIR}/src) | ||
|
||
|
||
add_library(server_posts STATIC | ||
${SRC_DIR}/main.cpp | ||
${SRC_DIR}/database.cpp include/post.h) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. в библиотеке не может быть функции main() |
||
|
||
add_executable(server_posts_test src/main.cpp) | ||
target_link_libraries(server_posts_test ${Boost_LIBRARIES} Threads::Threads pthread) | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// | ||
// Created by steve on 05.12.2020. | ||
// | ||
|
||
#ifndef POSTS_DATABASE_H | ||
#define POSTS_DATABASE_H | ||
|
||
#include <string> | ||
#include <pqxx/pqxx> | ||
#include <map> | ||
#include <iostream> | ||
#include <boost/format.hpp> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. много лишних include в хедере |
||
|
||
|
||
#include "../include/post.h" | ||
// Класс Post | ||
// id поста | ||
// id пользователя создавшего пост | ||
// дата создания поста | ||
// title поста | ||
// text поста | ||
// attach url картинок | ||
|
||
class PostsDataBase { | ||
public: | ||
// Конектится к базе данных, создается объет таблицы | ||
PostsDataBase(); | ||
|
||
~PostsDataBase(); | ||
|
||
std::string create_post(int user_id, Post& post); | ||
std::string update_post(int user_id, Post& updated); | ||
std::string delete_post(int user_id, int post_id); | ||
|
||
std::vector<Post> get_all_posts(); | ||
std::vector<Post> get_user_posts(int user_id); | ||
std::vector<Post> get_posts_for_user(int fuser_id); | ||
Post& get_one_post(int post_id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. методы, которые не изменяют поведения объекты, должны иметь префикс const |
||
|
||
bool is_opened(); | ||
|
||
private: | ||
// Table Posts_; | ||
pqxx::connection database_; | ||
void do_modifying_request(const std::string& sql_request); | ||
pqxx::result do_select_request(const std::string& sql_request); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. для работы с БД надо создать wrapper, в которые надо инкапсулировать функции |
||
}; | ||
|
||
#endif //POSTS_DATABASE_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// | ||
// Created by steve on 07.12.2020. | ||
// | ||
|
||
#ifndef POSTS_HANDLERS_H | ||
#define POSTS_HANDLERS_H | ||
|
||
#include "types.h" | ||
#include "database.h" | ||
#include "../include/utility_parser.h" | ||
|
||
|
||
|
||
std::string for_user(const std::string& id_request, const std::map<std::string, size_t>& args) { | ||
// TODO: реализовать работу с БД | ||
std::string result = "id_request: " + id_request + | ||
" posts for user with id: " + std::to_string(args.at("user_id")); | ||
return result; | ||
} | ||
|
||
std::string all_posts(const std::string& id_request, const std::map<std::string, size_t>& args) { | ||
// TODO: реализовать работу с БД | ||
std::string result = "id_request: " + id_request + " all posts\n"; | ||
|
||
std::vector<Post> vec_posts = db.get_all_posts(); | ||
std::string posts = vec_posts_to_str(vec_posts); | ||
return result + posts; | ||
} | ||
|
||
std::string user_posts(std::string const& id_request, std::map<std::string, size_t> const& args) { | ||
// TODO: реализовать работу с БД | ||
std::string result = "id_request: " + id_request + | ||
" user`s posts with id: " + std::to_string(args.at("user_id")); | ||
return result; | ||
} | ||
|
||
std::string one_post(std::string const& id_request, std::map<std::string, size_t> const& args) { | ||
// TODO: реализовать работу с БД | ||
std::string result = "id_request: " + id_request + | ||
" post with id: " + std::to_string(args.at("post_id")); | ||
return result; | ||
} | ||
std::string delete_post(std::string const& id_request, std::map<std::string, size_t> const& args) { | ||
// TODO: реализовать работу с БД | ||
std::string result = "id_request: " + id_request + | ||
" deleting a post with id: " + std::to_string(args.at("post_id")) + | ||
" by a user with id: " + std::to_string(args.at("user_id")); | ||
return result; | ||
} | ||
|
||
std::string create_post(std::string const& id_request, | ||
std::map<std::string, size_t> const& args, | ||
std::string const& body) { | ||
// TODO: реализовать работу с БД | ||
Post new_post = parse_body(body); | ||
boost::format parsed_body = | ||
(boost::format( | ||
"post_id: %1%,\n" | ||
" creator_id: %2%,\n" | ||
" creation_date: %3%,\n" | ||
" title: %4%,\n" | ||
" text: %5%,\n" | ||
" attach: %6%\n") | ||
%new_post.post_id | ||
%new_post.creator_id | ||
%new_post.creation_date | ||
%new_post.title | ||
%new_post.text | ||
%new_post.attach); | ||
std::string body_str = boost::str(parsed_body); | ||
std::string result = "id_request: " | ||
+ id_request | ||
+ " creating a post by a user with id: " | ||
+ std::to_string(args.at("user_id")) | ||
+ "\n" + body_str; | ||
return result; | ||
} | ||
|
||
std::string update_post(std::string const& id_request, | ||
std::map<std::string, size_t> const& args, | ||
std::string const& body) { | ||
// TODO: реализовать работу с БД | ||
Post for_update = parse_body(body); | ||
boost::format parsed_body = | ||
(boost::format( | ||
"post_id: %1%,\n" | ||
" creator_id: %2%,\n" | ||
" creation_date: %3%,\n" | ||
" title: %4%,\n" | ||
" text: %5%,\n" | ||
" attach: %6%\n") | ||
%for_update.post_id | ||
%for_update.creator_id | ||
%for_update.creation_date | ||
%for_update.title | ||
%for_update.text | ||
%for_update.attach); | ||
std::string body_str = boost::str(parsed_body); | ||
std::string result = "id_request: " | ||
+ id_request | ||
+ " changing a post with id: " | ||
+ std::to_string(args.at("post_id")) | ||
+ " by a user with id: " | ||
+ std::to_string(args.at("user_id")) | ||
+ "\n" + body_str;; | ||
return result; | ||
} | ||
|
||
#endif //POSTS_HANDLERS_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// | ||
// Created by steve on 10.12.2020. | ||
// | ||
|
||
#ifndef SERVER_POSTS_POST_H | ||
#define SERVER_POSTS_POST_H | ||
|
||
|
||
class Post { | ||
public: | ||
Post( | ||
int post_id, | ||
int creator_id, | ||
std::string creation_date, | ||
std::string title, | ||
std::string text, | ||
std::string attach) : post_id(post_id), | ||
creator_id(creator_id), | ||
creation_date(std::move(creation_date)), | ||
title(std::move(title)), | ||
text(std::move(text)), | ||
attach(std::move(attach)) {} | ||
|
||
int post_id; | ||
int creator_id; | ||
std::string creation_date{}; | ||
std::string title{}; | ||
std::string text{}; | ||
std::string attach{}; | ||
|
||
}; | ||
|
||
#endif //SERVER_POSTS_POST_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// | ||
// Created by steve on 04.12.2020. | ||
// | ||
|
||
#ifndef POSTS_SERVER_H | ||
#define POSTS_SERVER_H | ||
|
||
// как работает сервер | ||
// 1 Принимаем входящее соединение на заданном порту | ||
// 2 Создаем объект сеанса для принятого соединения | ||
// 3 Переходим к шагу 1 | ||
|
||
// как работают сессии | ||
// 1 Считываем строку до тех пор, пока не будет найден символ \n | ||
// 2 Парсинг типа команды и ее аргументов | ||
// 3 Вызываем обработчик ответственный за эту команду, и формируем ответную строку | ||
// 4 Отправляем ответ клиенту | ||
|
||
#include "../include/session.h" | ||
#include "../include/handlers.h" | ||
|
||
class TCPServer { | ||
public: | ||
|
||
TCPServer(io::io_context& io_context, std::uint16_t port) | ||
: io_context(io_context) | ||
, acceptor (io_context, tcp::endpoint(tcp::v4(), port)) { | ||
|
||
accept(); | ||
} | ||
|
||
|
||
void add_endpoint() { | ||
dispatcher.emplace("/posts/fuser/", dispatcher_entry{1, for_user}); | ||
dispatcher.emplace("/posts/all/", dispatcher_entry{0, all_posts}); | ||
dispatcher.emplace("/posts/user/", dispatcher_entry{1, user_posts}); | ||
dispatcher.emplace("/posts/post/", dispatcher_entry{1, one_post}); | ||
dispatcher.emplace("/posts/dlt/", dispatcher_entry{2, delete_post}); | ||
// ендпоинты требующие боди | ||
dispatcher_with_body.emplace( | ||
"/posts/create/", | ||
dispatcher_entry_with_body{1, create_post} | ||
); | ||
dispatcher_with_body.emplace( | ||
"/posts/upd/", | ||
dispatcher_entry_with_body{2, update_post} | ||
); | ||
} | ||
|
||
private: | ||
|
||
void accept() { | ||
socket.emplace(io_context); | ||
|
||
acceptor.async_accept(*socket, [&] (error_code error) { | ||
std::make_shared<Session>(std::move(*socket), dispatcher, dispatcher_with_body)->Session::start(); | ||
accept(); | ||
}); | ||
} | ||
io::io_context& io_context; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. зачем тут ссылка? |
||
tcp::acceptor acceptor; | ||
std::optional<tcp::socket> socket; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. почему socket optional??? |
||
dispatcher_type dispatcher; // map обработчиков команд описан в types.hpp | ||
dispatcher_type_with_body dispatcher_with_body; | ||
}; | ||
|
||
|
||
#endif // POSTS_SERVER_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
#include "../include/types.h" | ||
#include "../include/utility_parser.h" | ||
|
||
|
||
|
||
class Session : public std::enable_shared_from_this<Session> { | ||
public: | ||
|
||
Session(tcp::socket&& socket, | ||
dispatcher_type const& dispatcher, | ||
dispatcher_type_with_body const& dispatcher_with_body) | ||
: socket (std::move(socket)) | ||
, dispatcher(dispatcher) | ||
, dispatcher_with_body(dispatcher_with_body) {} | ||
|
||
void start() { | ||
write("POSTS server is ready to serve"); | ||
write(); | ||
read(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. мне не реализация этой функции |
||
} | ||
|
||
private: | ||
|
||
void write(std::string const& string) { | ||
outgoing.push(string + "\r\n> "); | ||
} | ||
|
||
|
||
void read() { | ||
io::async_read_until( | ||
socket, | ||
incoming, | ||
"\n", | ||
std::bind(&Session::on_read, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); | ||
} | ||
|
||
|
||
void on_read(error_code error, std::size_t bytes_transferred) { | ||
if(!error) { | ||
std::istream stream(&incoming); | ||
std::string line; | ||
std::getline(stream, line); | ||
incoming.consume(bytes_transferred); | ||
boost::algorithm::trim(line); | ||
if(!line.empty()) { | ||
dispatch(line); | ||
} | ||
read(); | ||
} | ||
} | ||
|
||
// TODO: реализовать функцию отправки на сокет http сервера | ||
|
||
void write() { | ||
io::async_write( | ||
socket, | ||
io::buffer(outgoing.front()), | ||
std::bind(&Session::on_write, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); | ||
} | ||
|
||
|
||
void on_write(error_code error, std::size_t bytes_transferred) { | ||
if(!error) { | ||
outgoing.pop(); | ||
if(!outgoing.empty()) { | ||
write(); | ||
} | ||
} | ||
} | ||
|
||
|
||
// Находим соответствующий обработчик команд, применяем его, | ||
// если он найден, отправляем ответ обратно. | ||
void dispatch(std::string const& line) { | ||
std::stringstream response; // строка ответа | ||
auto parameters_request = split(line, " "); | ||
|
||
if (parameters_request.size() == 2) { // боди нет | ||
try { | ||
RequestWithoutBody result = parse_without_body(parameters_request); | ||
if(auto it = dispatcher.find(result.command); it != dispatcher.cend()) { // поиск хендлера | ||
auto const& entry = it->second; | ||
if(entry.args == result.args.size()) { | ||
try { | ||
response << entry.handler(result.id_request, result.args); // вызов хендлера | ||
} catch(std::exception const& e) { | ||
response << "404"; | ||
} | ||
} else { | ||
response << "404"; | ||
} | ||
} else { | ||
response << "404"; | ||
} | ||
} catch(boost::bad_lexical_cast &) { | ||
response << "404"; | ||
} | ||
|
||
} else if (parameters_request.size() == 3) { // боди есть | ||
try { | ||
RequestWithBody result = parse_with_body(parameters_request); | ||
if(auto it = dispatcher_with_body.find(result.command); it != dispatcher_with_body.cend()) { // поиск хендлера | ||
auto const& entry = it->second; | ||
if(entry.args == result.args.size()) { | ||
try { | ||
response << entry.handler(result.id_request, result.args, result.body); // вызов хендлера | ||
} catch(std::exception const& e) { | ||
response << "404"; | ||
} | ||
} else { | ||
response << "404"; | ||
} | ||
} else { | ||
response << "404"; | ||
} | ||
} catch(boost::bad_lexical_cast &) { | ||
response << "404"; | ||
} | ||
} else { | ||
response << "404"; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. слишком большая вложенность, вложенность больше 3-х плохо читается |
||
|
||
// Поместим ответ в исходящую очередь | ||
write(response.str()); | ||
|
||
// Если очередь была пуста до этого, то мы должны инициировать доставку сообщения обратно клиенту | ||
if(outgoing.size() == 1) { | ||
write(); | ||
} | ||
} | ||
|
||
// Сеанс считывает входящие данные с помощью async_read_until до тех пор, | ||
// пока не будет найден символ \n, а затем анализирует полученную строку. | ||
|
||
// TODO: добавить еще сокет для отправки на сразу на http сервер | ||
tcp::socket socket; | ||
// сохраняем диспетчер внутри объекта сервера и передаем ссылку на него в сеанс | ||
dispatcher_type const& dispatcher; | ||
dispatcher_type_with_body const& dispatcher_with_body; | ||
io::streambuf incoming; | ||
std::queue<std::string> outgoing; | ||
}; | ||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#pragma once | ||
|
||
#include <iostream> | ||
#include <optional> | ||
#include <queue> | ||
#include <functional> | ||
|
||
#include <boost/algorithm/string.hpp> | ||
#include <boost/asio.hpp> | ||
#include <boost/date_time.hpp> | ||
#include <boost/filesystem.hpp> | ||
#include <boost/lexical_cast.hpp> | ||
#include <boost/tokenizer.hpp> | ||
#include <boost/property_tree/ptree.hpp> | ||
#include <boost/property_tree/json_parser.hpp> | ||
#include <boost/foreach.hpp> | ||
|
||
|
||
|
||
namespace io = boost::asio; | ||
namespace ip = io::ip; | ||
using tcp = ip::tcp; | ||
using error_code = boost::system::error_code; | ||
using namespace std::placeholders; | ||
|
||
using boost::property_tree::ptree; | ||
|
||
using string_group = std::vector<std::string>; | ||
|
||
struct dispatcher_entry { | ||
std::size_t const args; // количество аргументов | ||
// bool body_required; | ||
std::function<std::string (const std::string& , const std::map<std::string, size_t>& )> const handler; | ||
}; | ||
|
||
struct dispatcher_entry_with_body { | ||
std::size_t const args; // количество аргументов | ||
// bool body_required; | ||
std::function<std::string (const std::string& , const std::map<std::string, size_t>&, const std::string& )> const handler; | ||
}; | ||
|
||
// map обработчиков команд (название - диспетчер) | ||
using dispatcher_type = std::map<std::string, dispatcher_entry>; | ||
using dispatcher_type_with_body = std::map<std::string, dispatcher_entry_with_body>; | ||
|
||
|
||
using separator = boost::char_separator<char>; | ||
using tokenizer = boost::tokenizer<separator>; | ||
// вспомогательная функция, которая разбивает заданную строку на вектор строк | ||
// drop - символ по которому разбивается строка | ||
string_group split(std::string const& string, const char *drop) { | ||
string_group group; | ||
for(auto&& str : tokenizer(string, separator(drop))) { | ||
group.emplace_back(str); | ||
} | ||
return group; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// | ||
// Created by steve on 09.12.2020. | ||
// | ||
|
||
#ifndef SERVER_POSTS_UTILITY_PARSER_H | ||
#define SERVER_POSTS_UTILITY_PARSER_H | ||
|
||
#include "../include/types.h" | ||
#include "../include/post.h" | ||
|
||
|
||
|
||
|
||
class RequestWithBody { | ||
public: | ||
RequestWithBody( | ||
std::string id_request, | ||
std::string command, | ||
std::map<std::string, size_t> args, | ||
std::string body) : | ||
id_request(std::move(id_request)), | ||
command(std::move(command)), | ||
args(std::move(args)), | ||
body(std::move(body)) {} | ||
|
||
std::string id_request; | ||
std::string command; | ||
std::map<std::string, size_t> args; | ||
std::string body; | ||
}; | ||
|
||
class RequestWithoutBody { | ||
public: | ||
RequestWithoutBody( | ||
std::string id_request, | ||
std::string command, | ||
std::map<std::string, size_t> args | ||
) : | ||
id_request(std::move(id_request)), | ||
command(std::move(command)), | ||
args(std::move(args)) {} | ||
|
||
std::string id_request; | ||
std::string command; | ||
std::map<std::string, size_t> args; | ||
}; | ||
|
||
|
||
|
||
Post parse_body(const std::string& body_str) { | ||
std::stringstream ss; | ||
ss << body_str; | ||
|
||
std::map<std::string, std::string> result; | ||
ptree pt; | ||
boost::property_tree::read_json(ss, pt); | ||
// if (pt.empty()) {std::cout << "bad body" << std::endl;} | ||
for (ptree::const_iterator it = pt.begin(); it != pt.end(); ++it) { | ||
result[std::string(it->first)] = it->second.get_value<std::string>(); | ||
} | ||
|
||
Post post( | ||
boost::lexical_cast<std::uint16_t>(result["post_id"]), | ||
boost::lexical_cast<std::uint16_t>(result["user_id"]), | ||
result["creation_date"], | ||
result["title"], | ||
result["text"], | ||
result["attach"] | ||
); | ||
return post; | ||
} | ||
|
||
std::map<std::string, size_t> get_url_parameters(const string_group& vector_parameters) { | ||
std::map<std::string, size_t> result; | ||
if (vector_parameters.size() % 2 != 0) { | ||
std::cout << "bad vector_parameters" << std::endl; | ||
} | ||
for (size_t i = 0; i < vector_parameters.size() - 1; i += 2) { | ||
result[vector_parameters[i]] = boost::lexical_cast<std::uint16_t>(vector_parameters[i + 1]); | ||
} | ||
return result; | ||
} | ||
|
||
|
||
RequestWithoutBody parse_without_body(const string_group& args) { | ||
std::string id_request = args[0]; | ||
std::string url_request = args[1]; | ||
|
||
string_group url_param = split(url_request, "?"); | ||
std::string command = url_param[0]; | ||
std::map<std::string, size_t> parameters; | ||
|
||
if (url_param.size() == 2) { // если query string есть | ||
std::string query_string = url_param[1]; | ||
parameters = get_url_parameters(split(query_string, "=&")); | ||
} | ||
return RequestWithoutBody(id_request, command, parameters); | ||
} | ||
|
||
|
||
RequestWithBody parse_with_body(const string_group& args) { | ||
std::string id_request = args[0]; | ||
std::string url_request = args[1]; | ||
std::string body_request = args[2]; | ||
|
||
string_group url_param = split(url_request, "?"); | ||
std::string command = url_param[0]; | ||
std::map<std::string, size_t> parameters; | ||
|
||
if (url_param.size() == 2) { // если query string есть | ||
std::string query_string = url_param[1]; | ||
parameters = get_url_parameters(split(query_string, "=&")); | ||
} | ||
return RequestWithBody(id_request, command, parameters, body_request); | ||
} | ||
|
||
std::string vec_posts_to_str(std::vector<Post>& vec_posts) { | ||
std::string res = ""; | ||
for (const auto& i : vec_posts) { | ||
boost::format parsed_body = | ||
(boost::format( | ||
"post_id: %1%,\n" | ||
" creator_id: %2%,\n" | ||
" creation_date: %3%,\n" | ||
" title: %4%,\n" | ||
" text: %5%,\n" | ||
" attach: %6%\n\n") | ||
%i.post_id | ||
%i.creator_id | ||
%i.creation_date | ||
%i.title | ||
%i.text | ||
%i.attach); | ||
std::string body_str = boost::str(parsed_body); | ||
res += body_str; | ||
} | ||
return res; | ||
} | ||
//try { | ||
// dispatch("123 /posts/all/ {}"); | ||
//} catch(boost::bad_lexical_cast &) { | ||
// std::cout << "hui" << std::endl; | ||
//} | ||
|
||
#endif //SERVER_POSTS_UTILITY_PARSER_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// | ||
// Created by steve on 04.12.2020. | ||
// | ||
#include "../include/database.h" | ||
|
||
PostsDataBase::PostsDataBase() : | ||
database_("dbname=db_posts host=localhost user=amartery password=amartery") {} | ||
|
||
PostsDataBase::~PostsDataBase() { | ||
database_.disconnect(); | ||
} | ||
|
||
void PostsDataBase::do_modifying_request(const std::string& sql_request) { | ||
pqxx::work W(database_); | ||
W.exec(sql_request); | ||
W.commit(); | ||
} | ||
|
||
pqxx::result PostsDataBase::do_select_request(const std::string& sql_request) { | ||
pqxx::nontransaction N(database_); | ||
return N.exec(sql_request); | ||
} | ||
|
||
std::string PostsDataBase::create_post(int user_id, Post& post) { | ||
boost::format creating_sql_req = | ||
(boost::format( | ||
"insert into " | ||
"posts(post_id, creator_id, creation_date, title, text, attach) " | ||
"values (%1%, %2%, '%3%', '%4%', '%5%', '%6%')") | ||
%post.post_id | ||
%post.creator_id | ||
%post.creation_date | ||
%post.title | ||
%post.text | ||
%post.attach); | ||
std::string sql_req = boost::str(creating_sql_req); | ||
do_modifying_request(sql_req); | ||
return "OK"; | ||
} | ||
|
||
|
||
std::string PostsDataBase::update_post(int user_id, Post& updated) { | ||
|
||
} | ||
|
||
std::string PostsDataBase::delete_post(int user_id, int post_id) { | ||
|
||
} | ||
|
||
|
||
std::vector<Post> PostsDataBase::get_all_posts() { | ||
std::string sql_request = "select * from posts"; | ||
pqxx::result r = do_select_request(sql_request); | ||
std::vector<Post> result; | ||
for (pqxx::result::const_iterator c = r.begin(); c != r.end(); ++c) { | ||
Post temp( | ||
c[0].as<int>(), | ||
c[1].as<int>(), | ||
c[2].as<std::string>(), | ||
c[3].as<std::string>(), | ||
c[4].as<std::string>(), | ||
c[5].as<std::string>()); | ||
result.push_back(temp); | ||
} | ||
return result; | ||
} | ||
|
||
|
||
std::vector<Post> PostsDataBase::get_user_posts(int user_id) { | ||
|
||
} | ||
std::vector<Post> PostsDataBase::get_posts_for_user(int fuser_id) { | ||
|
||
} | ||
Post& PostsDataBase::get_one_post(int post_id) { | ||
|
||
} | ||
|
||
bool PostsDataBase::is_opened() { | ||
if (database_.is_open()) { | ||
std::cout << "Соединение с бд открыто" << std::endl; | ||
return true; | ||
} | ||
std::cout << "Соединение с бд закрыто" << std::endl; | ||
return false; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// | ||
// Created by steve on 04.12.2020. | ||
// | ||
|
||
#include "../include/server.h" | ||
|
||
// id_request /posts/fuser/?user_id=% - Запрос постов для конкретного пользователя | ||
// id_request /posts/all/ - Запрос всех постов | ||
// id_request /posts/user/?user_id=% - Запрос постов конкретного пользователя | ||
// id_request /posts/post/?post_id=% - Запрос определённого поста из БД | ||
// id_request /posts/dlt/?post_id=%&user_id=% - Запрос на удаление post_id поста пользователем id (второй параметр) | ||
// id_request /posts/create/?user_id=% {body} - Запрос на создание поста пользователем id | ||
// id_request /posts/upd/?user_id=%&post_id=% {body} - Запрос на изменение поста post_id пользователем id (второй параметр) | ||
|
||
|
||
|
||
int main() { | ||
|
||
io::io_context io_context; | ||
TCPServer server(io_context, 2348); // boost::lexical_cast<std::uint16_t>(argv[1]) | ||
server.add_endpoint(); | ||
io_context.run(); | ||
|
||
return 0; | ||
} | ||
|
||
// "123 /posts/upd/?user_id=3&post_id=7" | ||
// "123 /posts/all/" | ||
// "123 /posts/upd/?user_id=3&post_id=7 {\"post_id\":0,\"user_id\":0,\"creation_date\":\"2016-08-29T09:12:33.001Z\",\"title\":\"string\",\"text\":\"string\",\"attach\":\"string\"}" | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
попробуй сделать через cmake большую часть флагов, например find_package(PostgreSQL)