mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-05-11 05:44:05 +02:00
users balance add
This commit is contained in:
parent
b811c208c9
commit
974f057dc1
@ -40,12 +40,13 @@ void route_get_products_all(HttpCtx* ctx);
|
|||||||
void route_post_carts_purchase(HttpCtx* ctx);
|
void route_post_carts_purchase(HttpCtx* ctx);
|
||||||
|
|
||||||
void route_post_users_register(HttpCtx* ctx);
|
void route_post_users_register(HttpCtx* ctx);
|
||||||
|
void route_post_users_balance_add(HttpCtx* ctx);
|
||||||
|
|
||||||
void route_post_sessions_login(HttpCtx* ctx);
|
void route_post_sessions_login(HttpCtx* ctx);
|
||||||
void route_post_sessions_logout(HttpCtx* ctx);
|
void route_post_sessions_logout(HttpCtx* ctx);
|
||||||
void route_get_sessions_user(HttpCtx* ctx);
|
void route_get_sessions_user(HttpCtx* ctx);
|
||||||
|
|
||||||
void route_get_receipt(HttpCtx* ctx);
|
void route_get_receipts_one(HttpCtx* ctx);
|
||||||
|
|
||||||
const Session* header_session(HttpCtx* ctx);
|
const Session* header_session(HttpCtx* ctx);
|
||||||
const Session* middleware_session(HttpCtx* ctx);
|
const Session* middleware_session(HttpCtx* ctx);
|
||||||
|
@ -40,7 +40,7 @@ void query_params_destroy(QueryParams* query_params)
|
|||||||
query_param_vec_destroy(&query_params->vec);
|
query_param_vec_destroy(&query_params->vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* query_params_get(const QueryParams* query_params, const char* key)
|
char* query_params_get(const QueryParams* query_params, const char* key)
|
||||||
{
|
{
|
||||||
size_t key_len = strlen(key);
|
size_t key_len = strlen(key);
|
||||||
for (size_t i = 0; i < query_params->vec.size; ++i) {
|
for (size_t i = 0; i < query_params->vec.size; ++i) {
|
||||||
@ -52,7 +52,7 @@ const char* query_params_get(const QueryParams* query_params, const char* key)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void route_get_receipt(HttpCtx* ctx)
|
void route_get_receipts_one(HttpCtx* ctx)
|
||||||
{
|
{
|
||||||
Cx* cx = http_ctx_user_ctx(ctx);
|
Cx* cx = http_ctx_user_ctx(ctx);
|
||||||
const Session* session = middleware_session(ctx);
|
const Session* session = middleware_session(ctx);
|
||||||
@ -61,7 +61,7 @@ void route_get_receipt(HttpCtx* ctx)
|
|||||||
|
|
||||||
const char* query = http_ctx_req_query(ctx);
|
const char* query = http_ctx_req_query(ctx);
|
||||||
QueryParams params = parse_query_params(query);
|
QueryParams params = parse_query_params(query);
|
||||||
const char* receipt_id_str = query_params_get(¶ms, "receipt_id");
|
char* receipt_id_str = query_params_get(¶ms, "receipt_id");
|
||||||
query_params_destroy(¶ms);
|
query_params_destroy(¶ms);
|
||||||
if (!receipt_id_str) {
|
if (!receipt_id_str) {
|
||||||
RESPOND_BAD_REQUEST(ctx, "no receipt_id parameter");
|
RESPOND_BAD_REQUEST(ctx, "no receipt_id parameter");
|
||||||
@ -69,6 +69,7 @@ void route_get_receipt(HttpCtx* ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t receipt_id = strtol(receipt_id_str, NULL, 10);
|
int64_t receipt_id = strtol(receipt_id_str, NULL, 10);
|
||||||
|
free(receipt_id_str);
|
||||||
|
|
||||||
Receipt receipt;
|
Receipt receipt;
|
||||||
DbRes db_rizz = db_receipt_with_id(cx->db, &receipt, receipt_id);
|
DbRes db_rizz = db_receipt_with_id(cx->db, &receipt, receipt_id);
|
||||||
|
@ -61,24 +61,27 @@ void route_post_users_register(HttpCtx* ctx)
|
|||||||
RESPOND_JSON(ctx, 200, "{\"ok\":true}");
|
RESPOND_JSON(ctx, 200, "{\"ok\":true}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void route_add_balance(HttpCtx* ctx)
|
void route_post_users_balance_add(HttpCtx* ctx)
|
||||||
{
|
{
|
||||||
Cx* cx = http_ctx_user_ctx(ctx);
|
Cx* cx = http_ctx_user_ctx(ctx);
|
||||||
const Session* session = middleware_session(ctx);
|
const Session* session = middleware_session(ctx);
|
||||||
if (!session)
|
if (!session)
|
||||||
return;
|
return;
|
||||||
printf("token: %s\n user_id: %ld\n", session->token, session->user_id);
|
|
||||||
|
|
||||||
const char* body_str = http_ctx_req_body(ctx);
|
User user;
|
||||||
JsonValue* body_json = json_parse(body_str, strlen(body_str));
|
if (db_user_with_id(cx->db, &user, session->user_id) != DbRes_Ok) {
|
||||||
if (!body_json) {
|
RESPOND_SERVER_ERROR(ctx);
|
||||||
RESPOND_BAD_REQUEST(ctx, "bad request");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
json_free(body_json);
|
|
||||||
|
|
||||||
|
user.balance_dkk_cent += 10000;
|
||||||
|
|
||||||
|
DbRes db_res = db_user_update(cx->db, &user);
|
||||||
|
user_destroy(&user);
|
||||||
|
if (db_res != DbRes_Ok) {
|
||||||
|
RESPOND_SERVER_ERROR(ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RESPOND_JSON(ctx, 200, "{\"ok\":true}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@ typedef struct Db Db;
|
|||||||
|
|
||||||
/// `user.id` field is ignored.
|
/// `user.id` field is ignored.
|
||||||
DbRes db_user_insert(Db* db, const User* user);
|
DbRes db_user_insert(Db* db, const User* user);
|
||||||
|
|
||||||
|
/// Uses `user.id` to find model.
|
||||||
|
DbRes db_user_update(Db* db, const User* user);
|
||||||
|
|
||||||
/// `user` field is an out parameter.
|
/// `user` field is an out parameter.
|
||||||
DbRes db_user_with_id(Db* db, User* user, int64_t id);
|
DbRes db_user_with_id(Db* db, User* user, int64_t id);
|
||||||
|
|
||||||
|
@ -48,7 +48,10 @@ void db_sqlite_free(Db* db)
|
|||||||
|
|
||||||
static inline DbRes connect(sqlite3** connection)
|
static inline DbRes connect(sqlite3** connection)
|
||||||
{
|
{
|
||||||
int res = sqlite3_open("database.db", connection);
|
int res = sqlite3_open_v2("database.db",
|
||||||
|
connection,
|
||||||
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX,
|
||||||
|
NULL);
|
||||||
if (res != SQLITE_OK) {
|
if (res != SQLITE_OK) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"error: could not open sqlite 'database.db'\n %s\n",
|
"error: could not open sqlite 'database.db'\n %s\n",
|
||||||
@ -84,18 +87,65 @@ DbRes db_user_insert(Db* db, const User* user)
|
|||||||
DbRes res;
|
DbRes res;
|
||||||
|
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt* stmt;
|
||||||
sqlite3_prepare_v2(connection,
|
int prepare_res = sqlite3_prepare_v2(connection,
|
||||||
"INSERT INTO users (name, email, password_hash, balance_dkk_cent) "
|
"INSERT INTO users (name, email, password_hash, balance_dkk_cent) "
|
||||||
"VALUES (?, ?, ?, ?)",
|
"VALUES (?, ?, ?, ?)",
|
||||||
-1,
|
-1,
|
||||||
&stmt,
|
&stmt,
|
||||||
NULL);
|
NULL);
|
||||||
|
if (prepare_res != SQLITE_OK) {
|
||||||
|
REPORT_SQLITE3_ERROR();
|
||||||
|
res = DbRes_Error;
|
||||||
|
goto l0_return;
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3_bind_text(stmt, 1, user->name, -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 1, user->name, -1, SQLITE_STATIC);
|
||||||
sqlite3_bind_text(stmt, 2, user->email, -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 2, user->email, -1, SQLITE_STATIC);
|
||||||
sqlite3_bind_text(stmt, 3, user->password_hash, -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 3, user->password_hash, -1, SQLITE_STATIC);
|
||||||
sqlite3_bind_int64(stmt, 4, user->balance_dkk_cent);
|
sqlite3_bind_int64(stmt, 4, user->balance_dkk_cent);
|
||||||
|
|
||||||
|
int step_res = sqlite3_step(stmt);
|
||||||
|
if (step_res != SQLITE_DONE) {
|
||||||
|
REPORT_SQLITE3_ERROR();
|
||||||
|
res = DbRes_Error;
|
||||||
|
goto l0_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = DbRes_Ok;
|
||||||
|
l0_return:
|
||||||
|
if (stmt)
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
DISCONNECT;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbRes db_user_update(Db* db, const User* user)
|
||||||
|
{
|
||||||
|
static_assert(sizeof(User) == 40, "model has changed");
|
||||||
|
|
||||||
|
sqlite3* connection;
|
||||||
|
CONNECT;
|
||||||
|
DbRes res;
|
||||||
|
|
||||||
|
sqlite3_stmt* stmt;
|
||||||
|
int prepare_res = sqlite3_prepare_v2(connection,
|
||||||
|
"UPDATE users SET name = ?, email = ?, password_hash= ?, "
|
||||||
|
"balance_dkk_cent= ? WHERE id = ?",
|
||||||
|
-1,
|
||||||
|
&stmt,
|
||||||
|
NULL);
|
||||||
|
if (prepare_res != SQLITE_OK) {
|
||||||
|
REPORT_SQLITE3_ERROR();
|
||||||
|
res = DbRes_Error;
|
||||||
|
goto l0_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_bind_text(stmt, 1, user->name, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(stmt, 2, user->email, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(stmt, 3, user->password_hash, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_int64(stmt, 4, user->balance_dkk_cent);
|
||||||
|
sqlite3_bind_int64(stmt, 5, user->id);
|
||||||
|
|
||||||
int step_res = sqlite3_step(stmt);
|
int step_res = sqlite3_step(stmt);
|
||||||
if (step_res != SQLITE_DONE) {
|
if (step_res != SQLITE_DONE) {
|
||||||
fprintf(stderr, "error: %s\n", sqlite3_errmsg(connection));
|
fprintf(stderr, "error: %s\n", sqlite3_errmsg(connection));
|
||||||
@ -120,12 +170,17 @@ DbRes db_user_with_id(Db* db, User* user, int64_t id)
|
|||||||
DbRes res;
|
DbRes res;
|
||||||
|
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt* stmt;
|
||||||
sqlite3_prepare_v2(connection,
|
int prepare_res = sqlite3_prepare_v2(connection,
|
||||||
"SELECT id, name, email, password_hash, balance_dkk_cent"
|
"SELECT id, name, email, password_hash, balance_dkk_cent"
|
||||||
" FROM users WHERE id = ?",
|
" FROM users WHERE id = ?",
|
||||||
-1,
|
-1,
|
||||||
&stmt,
|
&stmt,
|
||||||
NULL);
|
NULL);
|
||||||
|
if (prepare_res != SQLITE_OK) {
|
||||||
|
REPORT_SQLITE3_ERROR();
|
||||||
|
res = DbRes_Error;
|
||||||
|
goto l0_return;
|
||||||
|
}
|
||||||
sqlite3_bind_int64(stmt, 1, id);
|
sqlite3_bind_int64(stmt, 1, id);
|
||||||
|
|
||||||
int step_res = sqlite3_step(stmt);
|
int step_res = sqlite3_step(stmt);
|
||||||
@ -526,6 +581,7 @@ DbRes db_receipt_with_id(Db* db, Receipt* receipt, int64_t id)
|
|||||||
|
|
||||||
receipt_product_vec_construct(&receipt->products);
|
receipt_product_vec_construct(&receipt->products);
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
prepare_res = sqlite3_prepare_v2(connection,
|
prepare_res = sqlite3_prepare_v2(connection,
|
||||||
"SELECT id, receipt, product_price, amount FROM receipt_products"
|
"SELECT id, receipt, product_price, amount FROM receipt_products"
|
||||||
" WHERE receipt = ?",
|
" WHERE receipt = ?",
|
||||||
|
@ -41,9 +41,12 @@ int main(void)
|
|||||||
|
|
||||||
http_server_post(server, "/api/carts/purchase", route_post_carts_purchase);
|
http_server_post(server, "/api/carts/purchase", route_post_carts_purchase);
|
||||||
|
|
||||||
http_server_get(server, "/api/receipts/one", route_get_receipt);
|
http_server_get(server, "/api/receipts/one", route_get_receipts_one);
|
||||||
|
|
||||||
http_server_post(server, "/api/users/register", route_post_users_register);
|
http_server_post(server, "/api/users/register", route_post_users_register);
|
||||||
|
http_server_post(
|
||||||
|
server, "/api/users/balance/add", route_post_users_balance_add);
|
||||||
|
|
||||||
http_server_post(server, "/api/sessions/login", route_post_sessions_login);
|
http_server_post(server, "/api/sessions/login", route_post_sessions_login);
|
||||||
http_server_post(
|
http_server_post(
|
||||||
server, "/api/sessions/logout", route_post_sessions_logout);
|
server, "/api/sessions/logout", route_post_sessions_logout);
|
||||||
|
@ -14,7 +14,7 @@ char* str_dup(const char* str)
|
|||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* str_slice_copy(const StrSlice* slice)
|
char* str_slice_copy(const StrSlice* slice)
|
||||||
{
|
{
|
||||||
char* copy = malloc(slice->len + 1);
|
char* copy = malloc(slice->len + 1);
|
||||||
strncpy(copy, slice->ptr, slice->len);
|
strncpy(copy, slice->ptr, slice->len);
|
||||||
|
@ -12,7 +12,7 @@ typedef struct {
|
|||||||
size_t len;
|
size_t len;
|
||||||
} StrSlice;
|
} StrSlice;
|
||||||
|
|
||||||
const char* str_slice_copy(const StrSlice* slice);
|
char* str_slice_copy(const StrSlice* slice);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* text;
|
const char* text;
|
||||||
|
@ -49,7 +49,18 @@ Deno.test("test backend", async (t) => {
|
|||||||
// console.log(sessionUserRes.user);
|
// console.log(sessionUserRes.user);
|
||||||
});
|
});
|
||||||
|
|
||||||
await testCartsAndReceipts(t, token);
|
await t.step("test /api/users/balance/add", async () => {
|
||||||
|
const sessionUserRes = await post<{ ok: boolean }>(
|
||||||
|
"/api/users/balance/add",
|
||||||
|
{},
|
||||||
|
{ "Session-Token": token! },
|
||||||
|
);
|
||||||
|
|
||||||
|
// console.log(sessionUserRes);
|
||||||
|
assertEquals(sessionUserRes.ok, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
await testCartsAndReceipts(t, token!);
|
||||||
|
|
||||||
await t.step("test /api/sessions/logout", async () => {
|
await t.step("test /api/sessions/logout", async () => {
|
||||||
const logoutRes = await post<{ ok: boolean }>(
|
const logoutRes = await post<{ ok: boolean }>(
|
||||||
@ -91,7 +102,7 @@ async function testCartsAndReceipts(t: Deno.TestContext, token: string) {
|
|||||||
{ "Session-Token": token },
|
{ "Session-Token": token },
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(res);
|
// console.log(res);
|
||||||
assertEquals(res.ok, true);
|
assertEquals(res.ok, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user