AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6static sqlite3 *gDb = NULL;7 8static Table* makeTableWithCols(sqlite3 *db, int eTabType, const char *names[], int nNames, int withDfltList){9 Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));10 TEST_ASSERT_NOT_NULL_MESSAGE(pTab, "Failed to allocate Table");11 12 /* Set as ordinary/view/etc. */13 pTab->eTabType = (u8)eTabType;14 15 pTab->nCol = nNames;16 if( nNames > 0 ){17 pTab->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nNames);18 TEST_ASSERT_NOT_NULL_MESSAGE(pTab->aCol, "Failed to allocate Column array");19 for(int i=0; i<nNames; i++){20 if( names && names[i] ){21 pTab->aCol[i].zCnName = sqlite3DbStrDup(db, names[i]);22 TEST_ASSERT_NOT_NULL_MESSAGE(pTab->aCol[i].zCnName, "Failed to allocate column name");23 pTab->aCol[i].hName = sqlite3StrIHash(pTab->aCol[i].zCnName);24 }else{25 pTab->aCol[i].zCnName = 0;26 pTab->aCol[i].hName = 0;27 }28 }29 }else{30 pTab->aCol = 0;31 }32 33 if( withDfltList ){34 pTab->u.tab.pDfltList = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));35 TEST_ASSERT_NOT_NULL_MESSAGE(pTab->u.tab.pDfltList, "Failed to allocate ExprList");36 }else{37 pTab->u.tab.pDfltList = 0;38 }39 40 return pTab;41}42 43void setUp(void) {44 int rc = sqlite3_open(":memory:", &gDb);45 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");46}47 48void tearDown(void) {49 if( gDb ){50 sqlite3_close(gDb);51 gDb = NULL;52 }53}54 55/* Basic free/reset behavior for ordinary table with mixed column names */56void test_sqlite3DeleteColumnNames_basic_frees_and_resets(void) {57 const char *names[] = { "a", "B", NULL };58 Table *pTab = makeTableWithCols(gDb, TABTYPETABLE, names, 3, 1);59 60 /* Preconditions */61 TEST_ASSERT_NOT_NULL(pTab->aCol);62 TEST_ASSERT_EQUAL_INT(3, pTab->nCol);63 TEST_ASSERT_NOT_NULL(pTab->u.tab.pDfltList);64 TEST_ASSERT_NOT_NULL(pTab->aCol[0].zCnName);65 TEST_ASSERT_NOT_NULL(pTab->aCol[1].zCnName);66 TEST_ASSERT_NULL(pTab->aCol[2].zCnName);67 68 sqlite3DeleteColumnNames(gDb, pTab);69 70 /* After normal free: pointers cleared and counts zeroed */71 TEST_ASSERT_NULL(pTab->aCol);72 TEST_ASSERT_EQUAL_INT(0, pTab->nCol);73 TEST_ASSERT_NULL(pTab->u.tab.pDfltList);74 75 /* Cleanup */76 sqlite3DbFree(gDb, pTab);77}78 79/* In byte-counting mode: allocations are accounted but Table fields are unchanged */80void test_sqlite3DeleteColumnNames_bytesFreedMode_does_not_reset_and_counts(void) {81 const char *names[] = { "x", "y" };82 Table *pTab = makeTableWithCols(gDb, TABTYPETABLE, names, 2, 1);83 84 Column *pSavedCols = pTab->aCol;85 ExprList *pSavedDflt = pTab->u.tab.pDfltList;86 int savedNCol = pTab->nCol;87 88 size_t bytesFreed = 0;89 gDb->pnBytesFreed = &bytesFreed;90 91 sqlite3DeleteColumnNames(gDb, pTab);92 93 /* In bytes-freed mode: fields remain unchanged, but accounting increases */94 TEST_ASSERT_NOT_EQUAL_SIZE_T(0, bytesFreed);95 TEST_ASSERT_EQUAL_PTR(pSavedCols, pTab->aCol);96 TEST_ASSERT_EQUAL_INT(savedNCol, pTab->nCol);97 TEST_ASSERT_EQUAL_PTR(pSavedDflt, pTab->u.tab.pDfltList);98 99 /* Now actually free by switching to normal mode */100 gDb->pnBytesFreed = 0;101 sqlite3DeleteColumnNames(gDb, pTab);102 103 TEST_ASSERT_NULL(pTab->aCol);104 TEST_ASSERT_EQUAL_INT(0, pTab->nCol);105 TEST_ASSERT_NULL(pTab->u.tab.pDfltList);106 107 sqlite3DbFree(gDb, pTab);108}109 110/* No columns: aCol==0, nCol==0 -> no-op */111void test_sqlite3DeleteColumnNames_noColumns_noop(void) {112 Table *pTab = makeTableWithCols(gDb, TABTYPETABLE, NULL, 0, 0);113 TEST_ASSERT_NULL(pTab->aCol);114 TEST_ASSERT_EQUAL_INT(0, pTab->nCol);115 116 sqlite3DeleteColumnNames(gDb, pTab);117 118 /* Still unchanged */119 TEST_ASSERT_NULL(pTab->aCol);120 TEST_ASSERT_EQUAL_INT(0, pTab->nCol);121 122 sqlite3DbFree(gDb, pTab);123}124 125/* Non-ordinary table (e.g., view): pDfltList must not be deleted by this function */126void test_sqlite3DeleteColumnNames_nonOrdinary_does_not_touch_pDfltList(void) {127 const char *names[] = { "c1" };128 /* Make a "view" table; still allocate pDfltList so we can check it is untouched */129 Table *pTab = makeTableWithCols(gDb, TABTYPEVIEW, names, 1, 1);130 131 ExprList *pSavedDflt = pTab->u.tab.pDfltList;132 Column *pSavedCols = pTab->aCol;133 TEST_ASSERT_NOT_NULL(pSavedDflt);134 TEST_ASSERT_NOT_NULL(pSavedCols);135 136 sqlite3DeleteColumnNames(gDb, pTab);137 138 /* aCol freed/reset; nCol reset; pDfltList unchanged for non-ordinary */139 TEST_ASSERT_NULL(pTab->aCol);140 TEST_ASSERT_EQUAL_INT(0, pTab->nCol);141 TEST_ASSERT_EQUAL_PTR(pSavedDflt, pTab->u.tab.pDfltList);142 143 /* Manually free the default list since the function should not have done it */144 sqlite3ExprListDelete(gDb, pSavedDflt);145 pTab->u.tab.pDfltList = 0;146 147 sqlite3DbFree(gDb, pTab);148}149 150int main(void) {151 UNITY_BEGIN();152 RUN_TEST(test_sqlite3DeleteColumnNames_basic_frees_and_resets);153 RUN_TEST(test_sqlite3DeleteColumnNames_bytesFreedMode_does_not_reset_and_counts);154 RUN_TEST(test_sqlite3DeleteColumnNames_noColumns_noop);155 RUN_TEST(test_sqlite3DeleteColumnNames_nonOrdinary_does_not_touch_pDfltList);156 return UNITY_END();157}