Add SQLite handler (refdb) and hook into master/workers/job -> commands

This commit is contained in:
2026-08-31 00:18:31 +02:00
parent 7e4e738c19
commit 7b5514bf67
13 changed files with 376 additions and 10 deletions
+2
View File
@@ -7,9 +7,11 @@
#include <hammy/types.h>
#include <hammy/command.h>
#include <hammy/refdb.h>
struct hammy_bot_t {
struct discord* client; // Owning reference to the client - handoff from main.c
hammy_refdb_t* refdb; // Owning reference to sqlite - the master and each worker has their own
bool commandsRegistered; // A flag if commands have been registered. Avoid re-registering every reconnect.
vector_t* commands; // vector_t of commands. Owning the vector, NOT the elements.
hammy_pool_t* pool; // Owning reference to the thread pool.
+2 -1
View File
@@ -6,6 +6,7 @@
#include <stdbool.h>
#include <hammy/types.h>
#include <hammy/refdb.h>
// A command handler. Runs either on the gateway thread (instant commands) or on
// a worker thread (deferred ones), so it must not assume either. client is
@@ -16,7 +17,7 @@
// or discord_edit_original_interaction_response().
//
// The handler does NOT own the job and must not destroy it.
typedef void (*hammy_command_fn)(const hammy_job_t* job, struct discord* client);
typedef void (*hammy_command_fn)(const hammy_job_t* job, struct discord* client, const hammy_refdb_t* refdb);
// Plain old data. Every field points at static storage, so this struct owns
// nothing, copies freely, and needs no destructor - the vector can be created
+2 -1
View File
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <hammy/types.h>
#include <hammy/refdb.h>
// A single slash-command option. Flattened out of the interaction event.
// Both strings are owned by the job.
@@ -52,7 +53,7 @@ int64_t hammy_job_age_ms(const hammy_job_t* job, struct discord* client);
// Runs the job to completion and sends the reply. Called from a worker thread,
// so client MUST be that worker's own clone, never the gateway client.
// Does not destroy the job.
void hammy_job_run(hammy_job_t* job, struct discord* client);
void hammy_job_run(hammy_job_t* job, struct discord* client, hammy_refdb_t* refdb);
// Edits the (already deferred) interaction response with a plain text body.
// Used by hammy_job_run() and by the pool's error paths.
+59
View File
@@ -0,0 +1,59 @@
#ifndef HAMMY_REFDB_H
#define HAMMY_REFDB_H
#include <stdbool.h>
#include <stddef.h>
#include <sqlite3.h>
#include <hammy/types.h>
// Read-only handle to the reference bundle. Owned by exactly one thread.
// Theading rules: Do NOT share a hammy_refdb_t between threads. Instead, a worker should
// open it's own in hammy_worker_start(), and the gateway should open one for instant
// commands. The bundle is read-only, so no writers for sync. Seperate sqlite3 connections
// never contend.
#define HAMMY_CALLSIGN_MAX 32
#define HAMMY_ENTITY_NAME_MAX 64
struct hammy_refdb_t {
sqlite3* handle;
sqlite3_stmt* stExact;
sqlite3_stmt* stPrefix;
char version[64];
};
struct hammy_dxcc_t {
int entityId; // ADIF DXCC entity code
char name[HAMMY_ENTITY_NAME_MAX];
char continent[4];
int cqZone; // Override applied if present
int ituZone;
double latitude; // North-positive
double longitude; // East-positive
double utcOffset; // UTC + utcOffset = local
char matchedPrefix[HAMMY_CALLSIGN_MAX];
bool exact;
};
// Opens the bundle read-only and prepares the hot statements.
// Returns NULL and logs on failure.
hammy_refdb_t* hammy_refdb_open(const char* path);
// Finalises statements and closes the connection. NULLs the passing reference.
bool hammy_refdb_close(hammy_refdb_t** db);
// Resolves a callsign to a DXCC entity.
//
// Uses candidate-prefix equality seeks rather than "? GLOB prefix || '*'". The
// GLOB form puts the indexed column on the wrong side of the comparison, so
// SQLite scans all 7000 prefix rows; generating the candidates and seeking by
// equality is roughly 40x faster on the current bundle.
//
// Returns false if nothing matched.
bool hammy_refdb_dxcc(hammy_refdb_t* db, const char* callsign, hammy_dxcc_t* out);
// Bundle version string from ref_meta, or NULL. Owned by the refdb.
const char* hammy_refdb_version(hammy_refdb_t* db);
#endif
+2
View File
@@ -6,5 +6,7 @@ typedef struct hammy_job_t hammy_job_t;
typedef struct hammy_worker_t hammy_worker_t;
typedef struct hammy_command_t hammy_command_t;
typedef struct hammy_bot_t hammy_bot_t;
typedef struct hammy_refdb_t hammy_refdb_t;
typedef struct hammy_dxcc_t hammy_dxcc_t;
#endif
+3
View File
@@ -5,10 +5,13 @@
#include <hammy/types.h>
#include <pthread.h>
#include <hammy/refdb.h>
struct hammy_worker_t {
pthread_t thread;
struct discord* clientCopy; // Clone of the client for concord threading safety - owning
hammy_pool_t* pool; // Non-owning back-reference
hammy_refdb_t* refdb; // Owning sqlite ref
int id; // Log logging mainly
bool started; // For joining
};