AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6static Table* addTable(sqlite3 *db, Schema *pSchema, const char *zName, Pgno tnum){7 Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));8 TEST_ASSERT_NOT_NULL_MESSAGE(pTab, "Failed to allocate Table");9 pTab->zName = sqlite3DbStrDup(db, zName);10 TEST_ASSERT_NOT_NULL_MESSAGE(pTab->zName, "Failed to allocate Table name");11 pTab->tnum = tnum;12 /* Insert into schema hash (string-keyed) */13 void *pPrev = sqlite3HashInsert(&pSchema->tblHash, pTab->zName, pTab);14 TEST_ASSERT_NULL_MESSAGE(pPrev, "Unexpected pre-existing table with same name in schema");15 return pTab;16}17 18static Index* addIndex(sqlite3 *db, Schema *pSchema, const char *zName, Pgno tnum){19 Index *pIdx = (Index*)sqlite3DbMallocZero(db, sizeof(Index));20 TEST_ASSERT_NOT_NULL_MESSAGE(pIdx, "Failed to allocate Index");21 pIdx->zName = sqlite3DbStrDup(db, zName);22 TEST_ASSERT_NOT_NULL_MESSAGE(pIdx->zName, "Failed to allocate Index name");23 pIdx->tnum = tnum;24 /* Insert into schema index hash (string-keyed) */25 void *pPrev = sqlite3HashInsert(&pSchema->idxHash, pIdx->zName, pIdx);26 TEST_ASSERT_NULL_MESSAGE(pPrev, "Unexpected pre-existing index with same name in schema");27 return pIdx;28}29 30static void removeTable(sqlite3 *db, Schema *pSchema, Table *pTab){31 if( pTab==0 ) return;32 void *pOld = sqlite3HashInsert(&pSchema->tblHash, pTab->zName, 0);33 TEST_ASSERT_EQUAL_PTR_MESSAGE(pTab, pOld, "Hash removal returned unexpected Table pointer");34 sqlite3DbFree(db, pTab->zName);35 sqlite3DbFree(db, pTab);36}37 38static void removeIndex(sqlite3 *db, Schema *pSchema, Index *pIdx){39 if( pIdx==0 ) return;40 void *pOld = sqlite3HashInsert(&pSchema->idxHash, pIdx->zName, 0);41 TEST_ASSERT_EQUAL_PTR_MESSAGE(pIdx, pOld, "Hash removal returned unexpected Index pointer");42 sqlite3DbFree(db, pIdx->zName);43 sqlite3DbFree(db, pIdx);44}45 46void setUp(void) {47 /* Setup code here, or leave empty */48}49void tearDown(void) {50 /* Cleanup code here, or leave empty */51}52 53/* Test: updates table tnum when matching iFrom */54void test_sqlite3RootPageMoved_updates_table_tnum(void){55#ifndef SQLITE_OMIT_AUTOVACUUM56 sqlite3 *db = 0;57 int rc = sqlite3_open(":memory:", &db);58 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);59 TEST_ASSERT_NOT_NULL(db);60 TEST_ASSERT_NOT_NULL(db->aDb);61 Schema *pSchema = db->aDb[0].pSchema;62 TEST_ASSERT_NOT_NULL(pSchema);63 64 sqlite3_mutex_enter(db->mutex);65 66 Table *t1 = addTable(db, pSchema, "t1", 5);67 Table *t2 = addTable(db, pSchema, "t2", 7);68 69 sqlite3RootPageMoved(db, 0, (Pgno)5, (Pgno)99);70 71 TEST_ASSERT_EQUAL_UINT32(99, t1->tnum);72 TEST_ASSERT_EQUAL_UINT32(7, t2->tnum);73 74 removeTable(db, pSchema, t1);75 removeTable(db, pSchema, t2);76 77 sqlite3_mutex_leave(db->mutex);78 sqlite3_close(db);79#else80 TEST_IGNORE_MESSAGE("SQLITE_OMIT_AUTOVACUUM defined; sqlite3RootPageMoved not available.");81#endif82}83 84/* Test: updates index tnum when matching iFrom */85void test_sqlite3RootPageMoved_updates_index_tnum(void){86#ifndef SQLITE_OMIT_AUTOVACUUM87 sqlite3 *db = 0;88 int rc = sqlite3_open(":memory:", &db);89 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);90 TEST_ASSERT_NOT_NULL(db);91 Schema *pSchema = db->aDb[0].pSchema;92 TEST_ASSERT_NOT_NULL(pSchema);93 94 sqlite3_mutex_enter(db->mutex);95 96 Index *i1 = addIndex(db, pSchema, "i1", 123);97 Index *i2 = addIndex(db, pSchema, "i2", 456);98 99 sqlite3RootPageMoved(db, 0, (Pgno)123, (Pgno)321);100 101 TEST_ASSERT_EQUAL_UINT32(321, i1->tnum);102 TEST_ASSERT_EQUAL_UINT32(456, i2->tnum);103 104 removeIndex(db, pSchema, i1);105 removeIndex(db, pSchema, i2);106 107 sqlite3_mutex_leave(db->mutex);108 sqlite3_close(db);109#else110 TEST_IGNORE_MESSAGE("SQLITE_OMIT_AUTOVACUUM defined; sqlite3RootPageMoved not available.");111#endif112}113 114/* Test: updates multiple matches (tables and indexes) */115void test_sqlite3RootPageMoved_updates_multiple_matches(void){116#ifndef SQLITE_OMIT_AUTOVACUUM117 sqlite3 *db = 0;118 int rc = sqlite3_open(":memory:", &db);119 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);120 TEST_ASSERT_NOT_NULL(db);121 Schema *pSchema = db->aDb[0].pSchema;122 TEST_ASSERT_NOT_NULL(pSchema);123 124 sqlite3_mutex_enter(db->mutex);125 126 Table *tA = addTable(db, pSchema, "tA", 42);127 Table *tB = addTable(db, pSchema, "tB", 42);128 Index *iA = addIndex(db, pSchema, "iA", 42);129 Index *iB = addIndex(db, pSchema, "iB", 1); /* control */130 131 sqlite3RootPageMoved(db, 0, (Pgno)42, (Pgno)77);132 133 TEST_ASSERT_EQUAL_UINT32(77, tA->tnum);134 TEST_ASSERT_EQUAL_UINT32(77, tB->tnum);135 TEST_ASSERT_EQUAL_UINT32(77, iA->tnum);136 TEST_ASSERT_EQUAL_UINT32(1, iB->tnum);137 138 removeTable(db, pSchema, tA);139 removeTable(db, pSchema, tB);140 removeIndex(db, pSchema, iA);141 removeIndex(db, pSchema, iB);142 143 sqlite3_mutex_leave(db->mutex);144 sqlite3_close(db);145#else146 TEST_IGNORE_MESSAGE("SQLITE_OMIT_AUTOVACUUM defined; sqlite3RootPageMoved not available.");147#endif148}149 150/* Test: no change when no entries match iFrom */151void test_sqlite3RootPageMoved_no_match_no_change(void){152#ifndef SQLITE_OMIT_AUTOVACUUM153 sqlite3 *db = 0;154 int rc = sqlite3_open(":memory:", &db);155 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);156 TEST_ASSERT_NOT_NULL(db);157 Schema *pSchema = db->aDb[0].pSchema;158 TEST_ASSERT_NOT_NULL(pSchema);159 160 sqlite3_mutex_enter(db->mutex);161 162 Table *t1 = addTable(db, pSchema, "nx_t1", 10);163 Index *i1 = addIndex(db, pSchema, "nx_i1", 20);164 165 sqlite3RootPageMoved(db, 0, (Pgno)777, (Pgno)888);166 167 TEST_ASSERT_EQUAL_UINT32(10, t1->tnum);168 TEST_ASSERT_EQUAL_UINT32(20, i1->tnum);169 170 removeTable(db, pSchema, t1);171 removeIndex(db, pSchema, i1);172 173 sqlite3_mutex_leave(db->mutex);174 sqlite3_close(db);175#else176 TEST_IGNORE_MESSAGE("SQLITE_OMIT_AUTOVACUUM defined; sqlite3RootPageMoved not available.");177#endif178}179 180int main(void) {181 UNITY_BEGIN();182 RUN_TEST(test_sqlite3RootPageMoved_updates_table_tnum);183 RUN_TEST(test_sqlite3RootPageMoved_updates_index_tnum);184 RUN_TEST(test_sqlite3RootPageMoved_updates_multiple_matches);185 RUN_TEST(test_sqlite3RootPageMoved_no_match_no_change);186 return UNITY_END();187}