mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-27 16:24:07 +02:00
implement api/cart
This commit is contained in:
parent
70b8244e62
commit
b486bb7970
@ -42,9 +42,12 @@ CREATE TABLE IF NOT EXISTS carts (
|
||||
CREATE TABLE IF NOT EXISTS cart_items (
|
||||
id INTEGER PRIMARY KEY,
|
||||
cart INTEGER NOT NULL,
|
||||
product INTEGER NOT NULL,
|
||||
amount INTEGER NOT NULL,
|
||||
|
||||
FOREIGN KEY(cart) REFERENCES carts(id)
|
||||
|
||||
FOREIGN KEY(cart) REFERENCES carts(id),
|
||||
FOREIGN KEY(product) REFERENCES product(id)
|
||||
);
|
||||
|
||||
|
||||
|
@ -32,6 +32,8 @@ void route_get_not_found(HttpCtx* ctx);
|
||||
|
||||
void route_get_products_all(HttpCtx* ctx);
|
||||
|
||||
void route_get_cart_items_from_session(HttpCtx* ctx);
|
||||
|
||||
void route_post_users_register(HttpCtx* ctx);
|
||||
|
||||
void route_post_sessions_login(HttpCtx* ctx);
|
||||
|
42
backend/src/controllers/carts.c
Normal file
42
backend/src/controllers/carts.c
Normal file
@ -0,0 +1,42 @@
|
||||
#include "../controllers.h"
|
||||
#include "../http_server.h"
|
||||
#include "../models_json.h"
|
||||
#include "../str_util.h"
|
||||
|
||||
void route_get_cart_items_from_session(HttpCtx* ctx)
|
||||
{
|
||||
Cx* cx = http_ctx_user_ctx(ctx);
|
||||
const Session* session = middleware_session(ctx);
|
||||
if (!session)
|
||||
return;
|
||||
|
||||
|
||||
CartItemVec cart_items;
|
||||
cart_item_vec_construct(&cart_items);
|
||||
|
||||
DbRes db_res = db_cart_items_with_user_id(cx->db, &cart_items, session->user_id);
|
||||
if (db_res != DbRes_Ok) {
|
||||
RESPOND_BAD_REQUEST(ctx, "Could not find cart for user");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String res;
|
||||
string_construct(&res);
|
||||
|
||||
string_push_str(&res, "{\"ok\":true,\"products\":[");
|
||||
for (size_t i = 0; i < cart_items.size; ++i) {
|
||||
if (i != 0) {
|
||||
string_push_str(&res, ",");
|
||||
}
|
||||
char* json = cart_item_to_json_string(&cart_items.data[i]);
|
||||
string_push_str(&res, json);
|
||||
free(json);
|
||||
}
|
||||
string_push_str(&res, "]}");
|
||||
|
||||
|
||||
cart_item_vec_destroy(&cart_items);
|
||||
RESPOND_JSON(ctx, 200, "%s", res.data);
|
||||
string_destroy(&res);
|
||||
}
|
@ -27,7 +27,7 @@ void route_post_sessions_login(HttpCtx* ctx)
|
||||
}
|
||||
|
||||
User user;
|
||||
DbRes db_res = db_user_from_email(cx->db, &user, req.email);
|
||||
DbRes db_res = db_user_with_email(cx->db, &user, req.email);
|
||||
if (db_res == DbRes_NotFound) {
|
||||
RESPOND_BAD_REQUEST(ctx, "user with email not found");
|
||||
goto l0_return;
|
||||
@ -71,7 +71,7 @@ void route_get_sessions_user(HttpCtx* ctx)
|
||||
return;
|
||||
|
||||
User user;
|
||||
DbRes db_res = db_user_from_id(cx->db, &user, session->user_id);
|
||||
DbRes db_res = db_user_with_id(cx->db, &user, session->user_id);
|
||||
if (db_res != DbRes_Ok) {
|
||||
RESPOND_BAD_REQUEST(ctx, "user not found");
|
||||
return;
|
||||
|
@ -2,9 +2,12 @@
|
||||
|
||||
#include "collection.h"
|
||||
#include "models.h"
|
||||
#include <stdint.h>
|
||||
|
||||
DEFINE_VEC(int64_t, Ids, ids, 8)
|
||||
DEFINE_VEC(Product, ProductVec, product_vec, 32)
|
||||
DEFINE_VEC(CartItem, CartItemVec, cart_item_vec, 32)
|
||||
|
||||
|
||||
typedef enum {
|
||||
DbRes_Ok,
|
||||
@ -17,7 +20,7 @@ typedef struct Db Db;
|
||||
/// `user.id` field is ignored.
|
||||
DbRes db_user_insert(Db* db, const User* user);
|
||||
/// `user` field is an out parameter.
|
||||
DbRes db_user_from_id(Db* db, User* user, int64_t id);
|
||||
DbRes db_user_with_id(Db* db, User* user, int64_t id);
|
||||
|
||||
|
||||
/// Expects `ids` to be constructed.
|
||||
@ -25,7 +28,10 @@ DbRes db_users_with_email(Db* db, Ids* ids, const char* email);
|
||||
|
||||
|
||||
/// `user` is an out parameter.
|
||||
DbRes db_user_from_email(Db* db, User* user, const char* email);
|
||||
DbRes db_user_with_email(Db* db, User* user, const char* email);
|
||||
|
||||
/// Expects `vec` to be constructed.
|
||||
DbRes db_product_all(Db* db, ProductVec* vec);
|
||||
|
||||
DbRes db_cart_items_with_user_id(Db* db, CartItemVec* vec, int64_t user_id);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "str_util.h"
|
||||
#include <assert.h>
|
||||
#include <sqlite3.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static inline char* get_str_safe(sqlite3_stmt* stmt, int col)
|
||||
@ -100,7 +101,7 @@ l0_return:
|
||||
return res;
|
||||
}
|
||||
|
||||
DbRes db_user_from_id(Db* db, User* user, int64_t id)
|
||||
DbRes db_user_with_id(Db* db, User* user, int64_t id)
|
||||
{
|
||||
static_assert(sizeof(User) == 40, "model has changed");
|
||||
|
||||
@ -118,7 +119,6 @@ DbRes db_user_from_id(Db* db, User* user, int64_t id)
|
||||
int step_res = sqlite3_step(stmt);
|
||||
if (step_res == SQLITE_DONE) {
|
||||
res = DbRes_NotFound;
|
||||
puts("didn't find user");
|
||||
goto l0_return;
|
||||
} else if (step_res != SQLITE_ROW) {
|
||||
fprintf(stderr, "error: %s\n", sqlite3_errmsg(connection));
|
||||
@ -173,7 +173,7 @@ l0_return:
|
||||
return res;
|
||||
}
|
||||
|
||||
DbRes db_user_from_email(Db* db, User* user, const char* email)
|
||||
DbRes db_user_with_email(Db* db, User* user, const char* email)
|
||||
{
|
||||
static_assert(sizeof(User) == 40, "model has changed");
|
||||
|
||||
@ -263,3 +263,65 @@ l0_return:
|
||||
DISCONNECT;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
DbRes db_cart_items_with_user_id(Db* db, CartItemVec* vec, int64_t user_id) {
|
||||
static_assert(sizeof(Cart) == 16, "model has changed");
|
||||
static_assert(sizeof(CartItem) == 32, "model has changed");
|
||||
|
||||
sqlite3* connection;
|
||||
CONNECT;
|
||||
DbRes res;
|
||||
|
||||
sqlite3_stmt* stmt;
|
||||
int sqlite_res = sqlite3_prepare_v2(connection,
|
||||
"SELECT id "
|
||||
" FROM carts WHERE user = ?",
|
||||
-1, &stmt, NULL);
|
||||
if (sqlite_res != SQLITE_OK) {
|
||||
fprintf(stderr, "error: %s\n at %s:%d\n", sqlite3_errmsg(connection),
|
||||
__func__, __LINE__);
|
||||
res = DbRes_Error;
|
||||
goto l0_return;
|
||||
}
|
||||
sqlite3_bind_int64(stmt, 1, user_id);
|
||||
|
||||
int step_res = sqlite3_step(stmt);
|
||||
if (step_res == SQLITE_DONE) {
|
||||
res = DbRes_NotFound;
|
||||
goto l0_return;
|
||||
} else if (step_res != SQLITE_ROW) {
|
||||
fprintf(stderr, "error: %s\n", sqlite3_errmsg(connection));
|
||||
res = DbRes_Error;
|
||||
goto l0_return;
|
||||
}
|
||||
int64_t cart_id = GET_INT(0);
|
||||
|
||||
sqlite_res = sqlite3_prepare_v2(
|
||||
connection, "SELECT id, cart, product, amount FROM cart_items WHERE cart = ?", -1, &stmt, NULL);
|
||||
sqlite3_bind_int64(stmt, 1, cart_id);
|
||||
|
||||
while ((sqlite_res = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||||
CartItem cart_item = {
|
||||
.id = GET_INT(0),
|
||||
.cart_id = GET_INT(1),
|
||||
.product_id = GET_INT(2),
|
||||
.amount = GET_INT(3),
|
||||
};
|
||||
cart_item_vec_push(vec, cart_item);
|
||||
}
|
||||
if (sqlite_res != SQLITE_DONE) {
|
||||
fprintf(stderr, "error: %s\n", sqlite3_errmsg(connection));
|
||||
res = DbRes_Error;
|
||||
goto l0_return;
|
||||
}
|
||||
|
||||
res = DbRes_Ok;
|
||||
l0_return:
|
||||
if (stmt)
|
||||
sqlite3_finalize(stmt);
|
||||
DISCONNECT;
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,8 @@ int main(void)
|
||||
|
||||
http_server_get(server, "/api/products/all", route_get_products_all);
|
||||
|
||||
http_server_get(server, "/api/cart", route_get_cart_items_from_session);
|
||||
|
||||
http_server_post(server, "/api/users/register", route_post_users_register);
|
||||
http_server_post(server, "/api/sessions/login", route_post_sessions_login);
|
||||
http_server_post(
|
||||
|
@ -47,7 +47,7 @@ void cart_destroy(Cart* m)
|
||||
|
||||
void cart_item_destroy(CartItem* m)
|
||||
{
|
||||
static_assert(sizeof(CartItem) == 24, "model has changed");
|
||||
static_assert(sizeof(CartItem) == 32, "model has changed");
|
||||
|
||||
(void)m;
|
||||
}
|
||||
@ -170,7 +170,7 @@ char* cart_to_json_string(const Cart* m)
|
||||
|
||||
char* cart_item_to_json_string(const CartItem* m)
|
||||
{
|
||||
static_assert(sizeof(CartItem) == 24, "model has changed");
|
||||
static_assert(sizeof(CartItem) == 32, "model has changed");
|
||||
|
||||
String string;
|
||||
string_construct(&string);
|
||||
@ -178,9 +178,10 @@ char* cart_item_to_json_string(const CartItem* m)
|
||||
"{"
|
||||
"\"id\":%ld,"
|
||||
"\"cart_id\":%ld,"
|
||||
"\"product_id\":%ld,"
|
||||
"\"amount\":%ld"
|
||||
"}",
|
||||
m->id, m->cart_id, m->amount);
|
||||
m->id, m->cart_id, m->product_id, m->amount);
|
||||
|
||||
char* result = string_copy(&string);
|
||||
string_destroy(&string);
|
||||
@ -354,11 +355,12 @@ int cart_from_json(Cart* m, const JsonValue* json)
|
||||
|
||||
int cart_item_from_json(CartItem* m, const JsonValue* json)
|
||||
{
|
||||
static_assert(sizeof(CartItem) == 24, "model has changed");
|
||||
static_assert(sizeof(CartItem) == 32, "model has changed");
|
||||
|
||||
ObjField fields[] = {
|
||||
{ "id", JsonType_Number },
|
||||
{ "cart_id", JsonType_Number },
|
||||
{ "product_id", JsonType_Number },
|
||||
{ "amount", JsonType_Number },
|
||||
};
|
||||
if (!obj_conforms(json, fields, sizeof(fields) / sizeof(fields[0])))
|
||||
@ -366,6 +368,7 @@ int cart_item_from_json(CartItem* m, const JsonValue* json)
|
||||
*m = (CartItem) {
|
||||
.id = GET_INT("id"),
|
||||
.cart_id = GET_INT("cart_id"),
|
||||
.product_id = GET_INT("product_id"),
|
||||
.amount = GET_INT("amount"),
|
||||
};
|
||||
return 0;
|
||||
|
@ -39,6 +39,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
int64_t id;
|
||||
int64_t cart_id;
|
||||
int64_t product_id;
|
||||
int64_t amount;
|
||||
} CartItem;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user