createTicket working, solves #3

This commit is contained in:
odweta
2026-08-16 17:41:56 +02:00
parent 94d743edfc
commit 8ae9cccc69
13 changed files with 127 additions and 34 deletions
+1 -1
View File
@@ -17,4 +17,4 @@ Both clients can:
### Dependencies:
+ `libpqxx` for the API to the PostgreSQL database management system (official link: https://github.com/jtv/libpqxx)
+ `libcurl` for accessing the webserver
+10
View File
@@ -0,0 +1,10 @@
CC := g++
SRC := dao.cpp handler.cpp main.cpp parser.cpp printer.cpp json_serializer.cpp
FLAGS := -lcurl -g -Wall -Wextra
OUTDIR := ./build
OUT := tickets
build:
mkdir -p $(OUTDIR)
$(CC) -o $(OUTDIR)/$(OUT) $(SRC) $(FLAGS)
BIN
View File
Binary file not shown.
+58 -7
View File
@@ -1,19 +1,70 @@
#include <cstdlib>
#include <vector>
#include "include/dao.h"
using namespace std;
void Dao::populate_env() {
Dao::Dao() {
this->api_key = getenv("FRONTEND_API_KEY");
this->db_url = getenv("DB_URL");
if (this->api_key.empty()) {
cout << "FRONTEND_API_KEY environment variable is not set" << endl;
exit(1);
}
this->base_url = getenv("BASE_API_URL");
if (this->base_url.empty()) {
cout << "BASE_API_URL environment variable is not set" << endl;
exit(1);
}
}
ticket_t Dao::fetch_ticket_create(string title, string description) {
static size_t write_callback(void* contents, size_t size, size_t nmemb, void* userp) {
size_t total = size * nmemb;
std::string* s = static_cast<std::string*>(userp);
s->append(static_cast<char*>(contents), total);
return total;
}
ticket_t Dao::fetch_ticket_create(std::string title, std::string description) {
string response;
string url = this->base_url + "/tickets";
CURL *handle = curl_easy_init();
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, ("Authorization: Bearer " + this->api_key).c_str());
string body = nlohmann::json{
{"title", title},
{"description", description}
}.dump();
curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(handle, CURLOPT_POST, 1L);
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response);
CURLcode rc = curl_easy_perform(handle);
curl_slist_free_all(headers);
curl_easy_cleanup(handle);
if (rc != CURLE_OK) {
throw std::runtime_error(std::string("curl_easy_perform failed: ") + curl_easy_strerror(rc));
}
nlohmann::json j = nlohmann::json::parse(response);
ticket_t t = j.get<ticket_t>();
return t;
}
vector<ticket_t> Dao::fetch_ticket_get_all() {
}
+10 -8
View File
@@ -3,20 +3,22 @@
#include <string>
#include <vector>
#include <curl/curl.h>
#include <curl/easy.h>
#include <iostream>
#include "ticket.h"
using namespace std;
#include "json_serializer.h"
class Dao {
public:
string api_key;
string db_url;
void populate_env();
std::string api_key;
std::string base_url;
ticket_t fetch_ticket_create(string title, string description);
vector<ticket_t> fetch_ticket_get_all();
vector<ticket_t> fetch_ticket_get_by_status(string status);
Dao();
ticket_t fetch_ticket_create(std::string title, std::string description);
std::vector<ticket_t> fetch_ticket_get_all();
std::vector<ticket_t> fetch_ticket_get_by_status(std::string status);
ticket_t fetch_ticket_get_by_id(unsigned long id);
};
+2 -4
View File
@@ -5,11 +5,9 @@
#include "dao.h"
using namespace std;
int handle_create(Dao *dao, string title, string description);
int handle_create(Dao *dao, std::string title, std::string description);
int handle_list(Dao *dao);
int handle_list(Dao *dao, string status);
int handle_list(Dao *dao, std::string status);
int handle_detail(Dao *dao, unsigned long id);
#endif // HANDLER_H
+13
View File
@@ -0,0 +1,13 @@
#include <string>
#include <optional>
#include <nlohmann/json.hpp>
#include "ticket.h"
using json = nlohmann::json;
// Deserialize JSON -> class
void from_json(const json& j, ticket_t& t);
// Serialize class
void to_json(json& j, const ticket_t& t);
+1 -3
View File
@@ -5,8 +5,6 @@
#include "ticket.h"
using namespace std;
void print_tickets(vector<ticket_t> tickets);
void print_tickets(std::vector<ticket_t> tickets);
#endif // PRINTER_H
+5 -8
View File
@@ -2,17 +2,14 @@
#define TICKET_H
#include <string>
#include <ctime>
using namespace std;
typedef struct {
unsigned long id;
string title;
string description;
string status;
string created_at;
string updated_at;
std::string title;
std::string description;
std::string status;
std::string created_at;
std::string updated_at;
} ticket_t;
#endif // TICKET_H
+23
View File
@@ -0,0 +1,23 @@
#include "include/json_serializer.h"
// Deserialize JSON -> class
void from_json(const json& j, ticket_t& t) {
t.id = j.at("id").get<int>();
t.title = j.at("title").get<std::string>();
t.description = j.at("description").get<std::string>();
t.status = j.at("status").get<std::string>();
t.created_at = j.at("created_at").get<std::string>();
t.updated_at = j.at("updated_at").get<std::string>();
}
// Serialize class -> JSON
void to_json(json& j, const ticket_t& t) {
j = json{
{"id", t.id},
{"title", t.title},
{"description", t.description},
{"status", t.status},
{"created_at", t.created_at},
{"updated_at", t.updated_at}
};
}
-1
View File
@@ -3,7 +3,6 @@
int main(int argc, char *argv[], char *envp[]) {
Dao *dao = new Dao();
dao->populate_env();
int retval = parse_args(dao, argc, argv);
delete dao;
}
+2
View File
@@ -2,6 +2,8 @@
#include "include/printer.h"
using namespace std;
void print_tickets(vector<ticket_t> tickets) {
for (ticket_t t : tickets) {
cout << "/------+-------\n"
+2 -2
View File
@@ -171,9 +171,9 @@ func createTicket(w http.ResponseWriter, r *http.Request) {
err = db.QueryRow(
context.Background(),
"INSERT INTO tickets(title, description) VALUES($1, $2) RETURNING id;",
"INSERT INTO tickets(title, description) VALUES($1, $2) RETURNING id, status, created_at, updated_at;",
t.Title, t.Description,
).Scan(&t.Id)
).Scan(&t.Id, &t.Status, &t.CreatedAt, &t.UpdatedAt)
if err != nil {
http.Error(w, err.Error(), 500)