Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3ResetAllSchemasOfConnection.c153 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdio.h>4#include <string.h>5 6/* Forward declaration of the function under test (in case not in headers) */7void sqlite3ResetAllSchemasOfConnection(sqlite3 *db);8 9static void exec_ok(sqlite3 *db, const char *sql){10  char *zErr = 0;11  int rc = sqlite3_exec(db, sql, 0, 0, &zErr);12  if( rc!=SQLITE_OK ){13    if( zErr ){14      fprintf(stderr, "SQL error: %s\n", zErr);15      sqlite3_free(zErr);16    }17  }18  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);19}20 21static int tbl_count(sqlite3 *db, int iDb){22  Schema *pSchema = db->aDb[iDb].pSchema;23  if( pSchema==0 ) return -1;24  return pSchema->tblHash.count;25}26 27void setUp(void) {28  /* no-op */29}30 31void tearDown(void) {32  /* no-op */33}34 35/* Test 1: When unlocked, schemas are cleared and DB flags are cleared */36void test_sqlite3ResetAllSchemasOfConnection_clears_schema_and_flags_no_lock(void){37  sqlite3 *db = 0;38  int rc = sqlite3_open(":memory:", &db);39  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);40  TEST_ASSERT_NOT_NULL(db);41 42  /* Create an object in main schema so that schema is populated */43  exec_ok(db, "CREATE TABLE t1(a);");44 45  /* Sanity: schema should have at least one table */46  TEST_ASSERT_TRUE(tbl_count(db, 0) > 0);47 48  /* Set flags that should be cleared by the function */49  db->mDbFlags |= (DBFLAG_SchemaChange | DBFLAG_SchemaKnownOk);50 51  /* Ensure unlocked */52  db->nSchemaLock = 0;53 54  sqlite3ResetAllSchemasOfConnection(db);55 56  /* After reset with no lock, schema hashes should be cleared */57  TEST_ASSERT_EQUAL_INT(0, tbl_count(db, 0));58 59  /* Flags should be cleared */60  TEST_ASSERT_EQUAL_INT(0, db->mDbFlags & (DBFLAG_SchemaChange | DBFLAG_SchemaKnownOk));61 62  sqlite3_close(db);63}64 65/* Test 2: When locked, schemas are not cleared, DB_ResetWanted is set, and nDb unchanged */66void test_sqlite3ResetAllSchemasOfConnection_sets_reset_wanted_when_locked(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  exec_ok(db, "CREATE TABLE t1(a);");73 74  int before = tbl_count(db, 0);75  TEST_ASSERT_TRUE(before > 0);76 77  /* Simulate lock to prevent schema clear */78  db->nSchemaLock = 1;79 80  /* Set flags that should be cleared regardless */81  db->mDbFlags |= (DBFLAG_SchemaChange | DBFLAG_SchemaKnownOk);82 83  int nDb_before = db->nDb;84 85  sqlite3ResetAllSchemasOfConnection(db);86 87  /* Schema should remain intact */88  TEST_ASSERT_EQUAL_INT(before, tbl_count(db, 0));89 90  /* DB_ResetWanted property should be set for "main" db (index 0) */91  TEST_ASSERT_TRUE(DbHasProperty(db, 0, DB_ResetWanted));92 93  /* Number of dbs should not change when locked */94  TEST_ASSERT_EQUAL_INT(nDb_before, db->nDb);95 96  /* Flags should be cleared */97  TEST_ASSERT_EQUAL_INT(0, db->mDbFlags & (DBFLAG_SchemaChange | DBFLAG_SchemaKnownOk));98 99  sqlite3_close(db);100}101 102/* Test 3: Collapse removes entries with pBt == 0 from aDb[] when unlocked */103void test_sqlite3ResetAllSchemasOfConnection_collapses_database_array(void){104  sqlite3 *db = 0;105  int rc = sqlite3_open(":memory:", &db);106  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);107  TEST_ASSERT_NOT_NULL(db);108 109  /* Attach two databases to create entries at indices >= 2 */110  exec_ok(db, "ATTACH DATABASE ':memory:' AS aux1;");111  exec_ok(db, "ATTACH DATABASE ':memory:' AS aux2;");112 113  TEST_ASSERT_TRUE(db->nDb >= 4);114 115  /* Capture current pointers for verification */116  Db *pAux1 = &db->aDb[2];117  Db *pAux2 = &db->aDb[3];118  char *zAux1Name = pAux1->zDbSName;119  char *zAux2Name = pAux2->zDbSName;120  TEST_ASSERT_NOT_NULL(zAux1Name);121  TEST_ASSERT_NOT_NULL(zAux2Name);122  TEST_ASSERT_NOT_NULL(pAux1->pBt);123  TEST_ASSERT_NOT_NULL(pAux2->pBt);124 125  /* Simulate a closed/removed btree for aux1 so collapse removes it. */126  pAux1->pBt = 0;127 128  int nDb_before = db->nDb;129 130  /* Ensure unlocked so collapse runs */131  db->nSchemaLock = 0;132 133  sqlite3ResetAllSchemasOfConnection(db);134 135  /* One entry should have been removed (aux1) */136  TEST_ASSERT_EQUAL_INT(nDb_before - 1, db->nDb);137 138  /* The entry at index 2 should now be the previous aux2 */139  TEST_ASSERT_EQUAL_PTR(zAux2Name, db->aDb[2].zDbSName);140 141  /* Sanity: removed entry's name pointer should no longer be present at index 2 */142  TEST_ASSERT_TRUE(db->aDb[2].zDbSName != zAux1Name);143 144  sqlite3_close(db);145}146 147int main(void) {148  UNITY_BEGIN();149  RUN_TEST(test_sqlite3ResetAllSchemasOfConnection_clears_schema_and_flags_no_lock);150  RUN_TEST(test_sqlite3ResetAllSchemasOfConnection_sets_reset_wanted_when_locked);151  RUN_TEST(test_sqlite3ResetAllSchemasOfConnection_collapses_database_array);152  return UNITY_END();153}