pcloudcc-lneely/tests/helpers/psql_test_helpers.c

131 lines
3.9 KiB
C

/*
* psql_test_helpers.c — in-memory SQLite harness for unit tests.
*
* Opens ":memory:" and applies the PSYNC_DATABASE_STRUCTURE schema from
* pdatabase.h. All tests that need a live database use this file.
*/
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <sqlite3.h>
#include "pdatabase.h"
#include "psql_test_helpers.h"
static sqlite3 *g_db = NULL;
int psql_test_open(void) {
if (g_db) {
sqlite3_close(g_db);
g_db = NULL;
}
if (sqlite3_open(":memory:", &g_db) != SQLITE_OK) {
fprintf(stderr, "psql_test_open: sqlite3_open failed: %s\n",
sqlite3_errmsg(g_db));
sqlite3_close(g_db);
g_db = NULL;
return -1;
}
/*
* Enable foreign key enforcement — sqlite3 disables it by default.
* Must be set before the schema is applied so CASCADE/FK constraints
* take effect from the start (mirrors psql_connect's DATABASE_CONFIG).
*/
sqlite3_exec(g_db, "PRAGMA foreign_keys=ON;", NULL, NULL, NULL);
/*
* PSYNC_DATABASE_STRUCTURE begins with "PRAGMA page_size=4096;…" and ends
* with "COMMIT;\n". For :memory: the pragmas are silently ignored and the
* DDL is applied inside a BEGIN/COMMIT block.
*/
char *err = NULL;
int rc = sqlite3_exec(g_db, PSYNC_DATABASE_STRUCTURE, NULL, NULL, &err);
if (rc != SQLITE_OK) {
fprintf(stderr, "psql_test_open: schema error: %s\n",
err ? err : "(null)");
sqlite3_free(err);
sqlite3_close(g_db);
g_db = NULL;
return -1;
}
return 0;
}
void psql_test_close(void) {
if (g_db) {
sqlite3_close(g_db);
g_db = NULL;
}
}
sqlite3 *psql_test_db(void) {
return g_db;
}
int psql_test_exec(const char *sql) {
char *err = NULL;
int rc = sqlite3_exec(g_db, sql, NULL, NULL, &err);
if (rc != SQLITE_OK) {
fprintf(stderr, "psql_test_exec: %s\n SQL: %s\n",
err ? err : "(null)", sql);
sqlite3_free(err);
}
return rc;
}
int64_t psql_test_insert_fstask(int type, int status, int64_t folderid,
const char *text1) {
sqlite3_stmt *stmt;
const char *sql = "INSERT INTO fstask (type, status, folderid, sfolderid,"
" text1) VALUES (?, ?, ?, ?, ?)";
if (sqlite3_prepare_v2(g_db, sql, -1, &stmt, NULL) != SQLITE_OK)
return -1;
sqlite3_bind_int(stmt, 1, type);
sqlite3_bind_int(stmt, 2, status);
sqlite3_bind_int64(stmt, 3, folderid);
sqlite3_bind_int64(stmt, 4, folderid);
if (text1)
sqlite3_bind_text(stmt, 5, text1, -1, SQLITE_TRANSIENT);
else
sqlite3_bind_null(stmt, 5);
int rc = sqlite3_step(stmt);
sqlite3_finalize(stmt);
if (rc != SQLITE_DONE) return -1;
return (int64_t)sqlite3_last_insert_rowid(g_db);
}
int psql_test_count_fstask(const char *where_clause) {
char sql[512];
if (where_clause && *where_clause)
snprintf(sql, sizeof(sql),
"SELECT COUNT(*) FROM fstask WHERE %s", where_clause);
else
snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM fstask");
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(g_db, sql, -1, &stmt, NULL) != SQLITE_OK) return -1;
int count = -1;
if (sqlite3_step(stmt) == SQLITE_ROW)
count = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
return count;
}
int psql_test_count_fstaskdepend(const char *where_clause) {
char sql[512];
if (where_clause && *where_clause)
snprintf(sql, sizeof(sql),
"SELECT COUNT(*) FROM fstaskdepend WHERE %s", where_clause);
else
snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM fstaskdepend");
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(g_db, sql, -1, &stmt, NULL) != SQLITE_OK) return -1;
int count = -1;
if (sqlite3_step(stmt) == SQLITE_ROW)
count = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
return count;
}