1
0
mirror of https://gitlab.cvh-server.de/skrause/flashcards.git synced 2026-03-16 04:30:15 +01:00
Files
flashcards/src/database.c
2026-03-06 15:48:13 +01:00

236 lines
6.5 KiB
C

#include "database.h"
#include <stdio.h>
sqlite3 *
database_connect (const char *path)
{
sqlite3 *db;
gchar *file = g_build_filename (path, "cards.db", NULL);
int rc = sqlite3_open (file, &db);
if (rc)
{
fprintf (stderr, "Can't open database: %s\n", sqlite3_errmsg (db));
return nullptr;
}
fprintf (stdout, "Opened database successfully\n");
g_free (file);
database_create_tables (db);
return db;
}
void
database_close (sqlite3 *db)
{
sqlite3_close (db);
}
void
database_create_tables (sqlite3 *db)
{
sqlite3_stmt *stmt;
const char *sql = "CREATE TABLE IF NOT EXISTS `cards` ("
"`id` INTEGER NOT NULL,"
"`category` INTEGER NOT NULL,"
"`title` TEXT NOT NULL,"
"`answer` TEXT NOT NULL,"
"`next_time` INTEGER NOT NULL DEFAULT (unixepoch()),"
"PRIMARY KEY(`id` AUTOINCREMENT)"
")";
int rc = sqlite3_prepare_v2 (db, sql, -1, &stmt, nullptr);
if (rc != SQLITE_OK)
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
sqlite3_step (stmt);
sqlite3_finalize (stmt);
sql = "CREATE TABLE IF NOT EXISTS `categories` ("
"`id` INTEGER NOT NULL,"
"`name` TEXT NOT NULL,"
"PRIMARY KEY(`id` AUTOINCREMENT)"
")";
rc = sqlite3_prepare_v2 (db, sql, -1, &stmt, nullptr);
if (rc != SQLITE_OK)
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
sqlite3_step (stmt);
sqlite3_finalize (stmt);
}
void
database_save_category (sqlite3 *db, const char *c)
{
sqlite3_stmt *stmt;
fprintf (stdout, "%s\n", c);
int rc = sqlite3_prepare_v2 (db, "INSERT INTO categories (name) VALUES(?)",
-1, &stmt, nullptr);
if (rc == SQLITE_OK)
sqlite3_bind_text (stmt, 1, c, -1, SQLITE_STATIC);
else
printf ("Failed to execute statement: %s\n", sqlite3_errmsg (db));
rc = sqlite3_step (stmt);
if (rc != SQLITE_DONE)
{
fprintf (stderr, "Failed to execute statement: %s\n",
sqlite3_errmsg (db));
}
sqlite3_finalize (stmt);
}
GArray *
database_load_categories (sqlite3 *db)
{
sqlite3_stmt *stmt;
GArray *categories = g_array_new (TRUE, FALSE, sizeof (category));
int rc = sqlite3_prepare_v2 (db, "SELECT * FROM categories", -1, &stmt,
nullptr);
if (rc != SQLITE_OK)
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
while (sqlite3_step (stmt) == SQLITE_ROW)
{
category c;
c.id = sqlite3_column_int (stmt, 0);
c.name = strdup ((char *)sqlite3_column_text (stmt, 1));
g_array_append_val (categories, c);
}
sqlite3_finalize (stmt);
return categories;
}
void
database_delete_category (sqlite3 *db, const int id)
{
// delete all cards in the category
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2 (db, "DELETE FROM cards WHERE category = ?", -1,
&stmt, nullptr);
if (rc == SQLITE_OK)
sqlite3_bind_int (stmt, 1, id);
else
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
rc = sqlite3_step (stmt);
if (rc != SQLITE_DONE)
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
sqlite3_finalize (stmt);
// delete the category
rc = sqlite3_prepare_v2 (db, "DELETE FROM categories WHERE id = ?", -1,
&stmt, nullptr);
if (rc == SQLITE_OK)
sqlite3_bind_int (stmt, 1, id);
else
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
rc = sqlite3_step (stmt);
if (rc != SQLITE_DONE)
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
sqlite3_finalize (stmt);
}
void
database_save_card (sqlite3 *db, const int category, const char *title,
const char *answer)
{
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2 (
db, "INSERT INTO cards (category, title, answer) VALUES(?, ?, ?)", -1,
&stmt, nullptr);
if (rc == SQLITE_OK)
{
sqlite3_bind_int (stmt, 1, category);
sqlite3_bind_text (stmt, 2, title, -1, SQLITE_STATIC);
sqlite3_bind_text (stmt, 3, answer, -1, SQLITE_STATIC);
}
else
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
rc = sqlite3_step (stmt);
if (rc != SQLITE_DONE)
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
sqlite3_finalize (stmt);
}
GArray *
database_load_cards (sqlite3 *db, const int category)
{
GArray *cards = g_array_new (TRUE, FALSE, sizeof (card));
sqlite3_stmt *stmt;
int rc
= sqlite3_prepare_v2 (db,
"SELECT * FROM cards WHERE category = ? AND "
"next_time <= unixepoch() ORDER BY next_time ASC",
-1, &stmt, nullptr);
if (rc == SQLITE_OK)
sqlite3_bind_int (stmt, 1, category);
else
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
while (sqlite3_step (stmt) == SQLITE_ROW)
{
card c;
c.id = sqlite3_column_int (stmt, 0);
c.category = sqlite3_column_int (stmt, 1);
c.title = strdup ((char *)sqlite3_column_text (stmt, 2));
c.answer = strdup ((char *)sqlite3_column_text (stmt, 3));
c.next_time
= g_date_time_new_from_unix_utc (sqlite3_column_int64 (stmt, 4));
g_array_append_val (cards, c);
}
sqlite3_finalize (stmt);
return cards;
}
void
database_schedule_card (sqlite3 *db, const int id, GDateTime *next_time)
{
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2 (
db, "UPDATE cards SET next_time = ? WHERE id = ?", -1, &stmt, nullptr);
if (rc == SQLITE_OK)
{
sqlite3_bind_int64 (stmt, 1, g_date_time_to_unix (next_time));
sqlite3_bind_int (stmt, 2, id);
}
else
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
rc = sqlite3_step (stmt);
if (rc != SQLITE_DONE)
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
sqlite3_finalize (stmt);
}
void
database_delete_card (sqlite3 *db, const int id)
{
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2 (db, "DELETE FROM cards WHERE id = ?", -1, &stmt,
nullptr);
if (rc == SQLITE_OK)
sqlite3_bind_int (stmt, 1, id);
else
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
rc = sqlite3_step (stmt);
if (rc != SQLITE_DONE)
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
sqlite3_finalize (stmt);
}