Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_dbpage_dbpageBeginTrans.c155 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdio.h>4#include <stdlib.h>5#include <string.h>6 7/* Forward declaration of internal type and test wrapper from dbpage.c */8typedef struct DbpageTable DbpageTable;9int test_dbpageBeginTrans(DbpageTable *pTab);10 11/* Helper to run SQL and assert success */12static void exec_sql_ok(sqlite3 *db, const char *sql){13  char *zErr = 0;14  int rc = sqlite3_exec(db, sql, 0, 0, &zErr);15  if( rc!=SQLITE_OK ){16    fprintf(stderr, "SQL error (%d): %s\nSQL: %s\n", rc, zErr?zErr:"(null)", sql);17  }18  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_exec failed");19  sqlite3_free(zErr);20}21 22/* Get the DbpageTable* for a created temp virtual table named zTab */23static DbpageTable* get_dbpage_table(sqlite3 *db, const char *zSchema, const char *zTab){24  /* Ensure module is registered */25  int rc = sqlite3DbpageRegister(db);26  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);27 28  /* Create the vtab if it doesn't exist already */29  char sql[256];30  sqlite3_snprintf(sizeof(sql), sql, "CREATE VIRTUAL TABLE %s.%s USING sqlite_dbpage", zSchema, zTab);31  exec_sql_ok(db, sql);32 33  /* Find the Table object using internal API */34  Table *pT = sqlite3FindTable(db, zTab, zSchema);35  TEST_ASSERT_NOT_NULL_MESSAGE(pT, "sqlite3FindTable returned NULL for dbpage vtab");36 37  TEST_ASSERT_NOT_NULL_MESSAGE(pT->pVTable, "Table->pVTable is NULL");38  TEST_ASSERT_NOT_NULL_MESSAGE(pT->pVTable->pVtab, "VTable->pVtab is NULL");39  return (DbpageTable*)pT->pVTable->pVtab;40}41 42void setUp(void) {43  /* No-op */44}45 46void tearDown(void) {47  /* No-op */48}49 50/* Test 1: Basic success on a writable in-memory database */51void test_dbpageBeginTrans_ok_inmemory(void){52  sqlite3 *db = 0;53  int rc = sqlite3_open(":memory:", &db);54  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);55  TEST_ASSERT_NOT_NULL(db);56 57  DbpageTable *pTab = get_dbpage_table(db, "temp", "t1");58 59  rc = test_dbpageBeginTrans(pTab);60  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);61 62  sqlite3_close(db);63}64 65/* Test 2: Success with multiple writable databases attached (in-memory) */66void test_dbpageBeginTrans_ok_with_attach_memory(void){67  sqlite3 *db = 0;68  int rc = sqlite3_open(":memory:", &db);69  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);70  TEST_ASSERT_NOT_NULL(db);71 72  DbpageTable *pTab = get_dbpage_table(db, "temp", "t2");73 74  /* Attach an in-memory database as 'aux' (writable) */75  exec_sql_ok(db, "ATTACH DATABASE ':memory:' AS aux");76 77  rc = test_dbpageBeginTrans(pTab);78  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);79 80  /* Detach and cleanup */81  exec_sql_ok(db, "DETACH DATABASE aux");82  sqlite3_close(db);83}84 85/* Helper: create a small on-disk database file */86static void create_sqlite_file(const char *zPath){87  sqlite3 *db = 0;88  int rc = sqlite3_open(zPath, &db);89  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);90  exec_sql_ok(db, "PRAGMA journal_mode=OFF");91  exec_sql_ok(db, "CREATE TABLE IF NOT EXISTS t(x)");92  sqlite3_close(db);93}94 95/* Test 3: Failure when an attached database is opened read-only */96void test_dbpageBeginTrans_fail_on_readonly_attached(void){97  const char *zFile = "ro_attached.sqlite";98 99  /* Create the file (writable connection) then close */100  create_sqlite_file(zFile);101 102  sqlite3 *db = 0;103  int rc = sqlite3_open(":memory:", &db);104  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);105 106  DbpageTable *pTab = get_dbpage_table(db, "temp", "t3");107 108  /* Attach the file in read-only mode via URI */109  rc = sqlite3_exec(db,110    "ATTACH DATABASE 'file:ro_attached.sqlite?mode=ro' AS auxro", 0, 0, 0);111  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "ATTACH read-only database failed");112 113  /* This should attempt to begin a write transaction on all Btrees.114     Main (in-memory) succeeds, auxro (read-only) should fail. */115  rc = test_dbpageBeginTrans(pTab);116  TEST_ASSERT_EQUAL_INT(SQLITE_READONLY, rc);117 118  /* Cleanup */119  sqlite3_exec(db, "DETACH DATABASE auxro", 0, 0, 0);120  sqlite3_close(db);121  remove(zFile);122}123 124/* Test 4: Failure when main database is opened read-only */125void test_dbpageBeginTrans_fail_on_readonly_main(void){126  const char *zFile = "ro_main.sqlite";127 128  /* Create file */129  create_sqlite_file(zFile);130 131  /* Open read-only connection to this file */132  sqlite3 *db = 0;133  int rc = sqlite3_open_v2(zFile, &db, SQLITE_OPEN_READONLY, 0);134  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);135  TEST_ASSERT_NOT_NULL(db);136 137  /* Create the dbpage vtab in temp schema (allowed even with RO main) */138  DbpageTable *pTab = get_dbpage_table(db, "temp", "t4");139 140  /* This should fail because main Btree is read-only */141  rc = test_dbpageBeginTrans(pTab);142  TEST_ASSERT_EQUAL_INT(SQLITE_READONLY, rc);143 144  sqlite3_close(db);145  remove(zFile);146}147 148int main(void){149  UNITY_BEGIN();150  RUN_TEST(test_dbpageBeginTrans_ok_inmemory);151  RUN_TEST(test_dbpageBeginTrans_ok_with_attach_memory);152  RUN_TEST(test_dbpageBeginTrans_fail_on_readonly_attached);153  RUN_TEST(test_dbpageBeginTrans_fail_on_readonly_main);154  return UNITY_END();155}