Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3UnlinkAndDeleteTable.c139 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Global database handle for tests */6static sqlite3 *gDb = NULL;7 8/* Helper: enter/leave the schema-related mutexes expected by sqlite3SchemaMutexHeld */9static void enterSchemaMutex(sqlite3 *db, int iDb){10  /* db->mutex must be held before entering any Btree mutex */11  sqlite3_mutex_enter(db->mutex);12  if( iDb>=0 && iDb<db->nDb && db->aDb[iDb].pBt ){13    sqlite3BtreeEnter(db->aDb[iDb].pBt);14  }15}16static void leaveSchemaMutex(sqlite3 *db, int iDb){17  if( iDb>=0 && iDb<db->nDb && db->aDb[iDb].pBt ){18    sqlite3BtreeLeave(db->aDb[iDb].pBt);19  }20  sqlite3_mutex_leave(db->mutex);21}22 23/* Helpers to find table/index in schema hash */24static Table* findTable(sqlite3 *db, int iDb, const char *zName){25  Schema *pSchema = db->aDb[iDb].pSchema;26  return (Table*)sqlite3HashFind(&pSchema->tblHash, zName);27}28static Index* findIndex(sqlite3 *db, int iDb, const char *zName){29  Schema *pSchema = db->aDb[iDb].pSchema;30  return (Index*)sqlite3HashFind(&pSchema->idxHash, zName);31}32 33/* Unity setup/teardown */34void setUp(void) {35  int rc = sqlite3_open(":memory:", &gDb);36  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);37  TEST_ASSERT_NOT_NULL(gDb);38}39void tearDown(void) {40  if( gDb ){41    int rc = sqlite3_close(gDb);42    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);43    gDb = NULL;44  }45}46 47/* Test: Remove main schema table with multiple indices */48void test_sqlite3UnlinkAndDeleteTable_removes_table_and_indices_main(void){49  int rc;50 51  rc = sqlite3_exec(gDb, "CREATE TABLE t1(a, b);", 0, 0, 0);52  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);53  rc = sqlite3_exec(gDb, "CREATE INDEX i1 ON t1(a);", 0, 0, 0);54  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);55  rc = sqlite3_exec(gDb, "CREATE INDEX i2 ON t1(b);", 0, 0, 0);56  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);57 58  /* Pre-check under schema mutex */59  enterSchemaMutex(gDb, 0);60  TEST_ASSERT_NOT_NULL(findTable(gDb, 0, "t1"));61  TEST_ASSERT_NOT_NULL(findIndex(gDb, 0, "i1"));62  TEST_ASSERT_NOT_NULL(findIndex(gDb, 0, "i2"));63 64  /* Call function under required mutex */65  sqlite3UnlinkAndDeleteTable(gDb, 0, "t1");66 67  /* Verify removal and DBFLAG_SchemaChange set */68  TEST_ASSERT_NULL(findTable(gDb, 0, "t1"));69  TEST_ASSERT_NULL(findIndex(gDb, 0, "i1"));70  TEST_ASSERT_NULL(findIndex(gDb, 0, "i2"));71  TEST_ASSERT_TRUE( (gDb->mDbFlags & DBFLAG_SchemaChange)!=0 );72  leaveSchemaMutex(gDb, 0);73}74 75/* Test: Non-existent table name should not modify schema, but sets flag */76void test_sqlite3UnlinkAndDeleteTable_nonexistent_table_sets_flag_only(void){77  int rc;78 79  rc = sqlite3_exec(gDb, "CREATE TABLE t3(x);", 0, 0, 0);80  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);81 82  enterSchemaMutex(gDb, 0);83  TEST_ASSERT_NOT_NULL(findTable(gDb, 0, "t3"));84  TEST_ASSERT_NULL(findTable(gDb, 0, "nosuch"));85 86  /* Call for a non-existent table */87  sqlite3UnlinkAndDeleteTable(gDb, 0, "nosuch");88 89  /* Ensure existing table unchanged and flag set */90  TEST_ASSERT_NOT_NULL(findTable(gDb, 0, "t3"));91  TEST_ASSERT_TRUE( (gDb->mDbFlags & DBFLAG_SchemaChange)!=0 );92  leaveSchemaMutex(gDb, 0);93}94 95/* Test: Remove TEMP schema table and index (iDb=1) */96void test_sqlite3UnlinkAndDeleteTable_removes_temp_table_and_index(void){97  int rc;98 99  rc = sqlite3_exec(gDb, "CREATE TEMP TABLE tt(a);", 0, 0, 0);100  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);101  rc = sqlite3_exec(gDb, "CREATE INDEX ii ON tt(a);", 0, 0, 0);102  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);103 104  /* Ensure TEMP schema was initialized */105  TEST_ASSERT_TRUE(gDb->nDb>=2);106  TEST_ASSERT_NOT_NULL(gDb->aDb[1].pSchema);107 108  enterSchemaMutex(gDb, 1);109  TEST_ASSERT_NOT_NULL(findTable(gDb, 1, "tt"));110  TEST_ASSERT_NOT_NULL(findIndex(gDb, 1, "ii"));111 112  sqlite3UnlinkAndDeleteTable(gDb, 1, "tt");113 114  TEST_ASSERT_NULL(findTable(gDb, 1, "tt"));115  TEST_ASSERT_NULL(findIndex(gDb, 1, "ii"));116  TEST_ASSERT_TRUE( (gDb->mDbFlags & DBFLAG_SchemaChange)!=0 );117  leaveSchemaMutex(gDb, 1);118}119 120/* Test: Zero-length table name (allowed by function's testcase), should be no-op but set flag */121void test_sqlite3UnlinkAndDeleteTable_zero_length_name_noop_sets_flag(void){122  /* Ensure mDbFlags starts clear for this connection */123  TEST_ASSERT_TRUE( (gDb->mDbFlags & DBFLAG_SchemaChange)==0 );124 125  enterSchemaMutex(gDb, 0);126  /* This should not crash or modify schema; it simply attempts to remove empty-name key */127  sqlite3UnlinkAndDeleteTable(gDb, 0, "");128  TEST_ASSERT_TRUE( (gDb->mDbFlags & DBFLAG_SchemaChange)!=0 );129  leaveSchemaMutex(gDb, 0);130}131 132int main(void) {133  UNITY_BEGIN();134  RUN_TEST(test_sqlite3UnlinkAndDeleteTable_removes_table_and_indices_main);135  RUN_TEST(test_sqlite3UnlinkAndDeleteTable_nonexistent_table_sets_flag_only);136  RUN_TEST(test_sqlite3UnlinkAndDeleteTable_removes_temp_table_and_index);137  RUN_TEST(test_sqlite3UnlinkAndDeleteTable_zero_length_name_noop_sets_flag);138  return UNITY_END();139}