AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Wrapper for the static function provided by the build harness */7void test_sqliteViewResetAll(sqlite3 *db, int idx);8 9void setUp(void) {10 /* Setup code here, or leave empty */11}12void tearDown(void) {13 /* Cleanup code here, or leave empty */14}15 16static void enter_db_mutexes(sqlite3 *db){17 sqlite3_mutex_enter(db->mutex);18 sqlite3BtreeEnterAll(db);19}20static void leave_db_mutexes(sqlite3 *db){21 sqlite3BtreeLeaveAll(db);22 sqlite3_mutex_leave(db->mutex);23}24 25static void create_or_fail(sqlite3 *db, const char *sql){26 int rc = sqlite3_exec(db, sql, 0, 0, 0);27 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, sqlite3_errmsg(db));28}29 30/* Test: When DB_UnresetViews is set, columns for views are cleared and flag is cleared. */31void test_sqliteViewResetAll_clears_view_columns_and_property(void) {32 sqlite3 *db = 0;33 int rc = sqlite3_open(":memory:", &db);34 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);35 36 create_or_fail(db, "CREATE TABLE t(x);"37 "CREATE VIEW v AS SELECT 1 AS a, 2 AS b;");38 39 enter_db_mutexes(db);40 Table *pView = sqlite3FindTable(db, "v", "main");41 Table *pTab = sqlite3FindTable(db, "t", "main");42 TEST_ASSERT_NOT_NULL(pView);43 TEST_ASSERT_NOT_NULL(pTab);44 TEST_ASSERT_NOT_NULL(pView->aCol);45 TEST_ASSERT_EQUAL_INT(2, pView->nCol);46 Column *pViewColsBefore = pView->aCol;47 Column *pTabColsBefore = pTab->aCol;48 int nTabColBefore = pTab->nCol;49 50 DbSetProperty(db, 0, DB_UnresetViews);51 test_sqliteViewResetAll(db, 0);52 53 /* View columns cleared */54 TEST_ASSERT_NULL(pView->aCol);55 TEST_ASSERT_EQUAL_INT(0, pView->nCol);56 57 /* Ordinary table unaffected */58 TEST_ASSERT_EQUAL_PTR(pTabColsBefore, pTab->aCol);59 TEST_ASSERT_EQUAL_INT(nTabColBefore, pTab->nCol);60 61 /* Property cleared */62 TEST_ASSERT_EQUAL_INT(0, DbHasProperty(db, 0, DB_UnresetViews) ? 1 : 0);63 64 leave_db_mutexes(db);65 sqlite3_close(db);66}67 68/* Test: If flag is not set, function is a no-op. */69void test_sqliteViewResetAll_noop_when_flag_not_set(void) {70 sqlite3 *db = 0;71 int rc = sqlite3_open(":memory:", &db);72 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);73 74 create_or_fail(db, "CREATE VIEW v AS SELECT 1 AS a, 2 AS b;");75 76 enter_db_mutexes(db);77 Table *pView = sqlite3FindTable(db, "v", "main");78 TEST_ASSERT_NOT_NULL(pView);79 TEST_ASSERT_NOT_NULL(pView->aCol);80 TEST_ASSERT_EQUAL_INT(2, pView->nCol);81 Column *pViewColsBefore = pView->aCol;82 int nViewColBefore = pView->nCol;83 84 /* Ensure flag is not set */85 TEST_ASSERT_EQUAL_INT(0, DbHasProperty(db, 0, DB_UnresetViews) ? 1 : 0);86 87 test_sqliteViewResetAll(db, 0);88 89 /* No change expected */90 TEST_ASSERT_EQUAL_PTR(pViewColsBefore, pView->aCol);91 TEST_ASSERT_EQUAL_INT(nViewColBefore, pView->nCol);92 TEST_ASSERT_EQUAL_INT(0, DbHasProperty(db, 0, DB_UnresetViews) ? 1 : 0);93 94 leave_db_mutexes(db);95 sqlite3_close(db);96}97 98/* Test: Multiple views are all processed; ordinary tables remain unchanged. */99void test_sqliteViewResetAll_multiple_views_only_views_affected(void) {100 sqlite3 *db = 0;101 int rc = sqlite3_open(":memory:", &db);102 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);103 104 create_or_fail(db,105 "CREATE TABLE t1(a);"106 "CREATE VIEW v1 AS SELECT 10 AS x, 20 AS y;"107 "CREATE VIEW v2 AS SELECT 30 AS p;"108 "CREATE TABLE t2(b, c);"109 );110 111 enter_db_mutexes(db);112 Table *pV1 = sqlite3FindTable(db, "v1", "main");113 Table *pV2 = sqlite3FindTable(db, "v2", "main");114 Table *pT1 = sqlite3FindTable(db, "t1", "main");115 Table *pT2 = sqlite3FindTable(db, "t2", "main");116 TEST_ASSERT_NOT_NULL(pV1);117 TEST_ASSERT_NOT_NULL(pV2);118 TEST_ASSERT_NOT_NULL(pT1);119 TEST_ASSERT_NOT_NULL(pT2);120 121 Column *pT1ColsBefore = pT1->aCol;122 int nT1Before = pT1->nCol;123 Column *pT2ColsBefore = pT2->aCol;124 int nT2Before = pT2->nCol;125 126 /* Precondition: views have columns */127 TEST_ASSERT_NOT_NULL(pV1->aCol);128 TEST_ASSERT_TRUE(pV1->nCol > 0);129 TEST_ASSERT_NOT_NULL(pV2->aCol);130 TEST_ASSERT_TRUE(pV2->nCol > 0);131 132 DbSetProperty(db, 0, DB_UnresetViews);133 test_sqliteViewResetAll(db, 0);134 135 /* Views cleared */136 TEST_ASSERT_NULL(pV1->aCol);137 TEST_ASSERT_EQUAL_INT(0, pV1->nCol);138 TEST_ASSERT_NULL(pV2->aCol);139 TEST_ASSERT_EQUAL_INT(0, pV2->nCol);140 141 /* Tables unchanged */142 TEST_ASSERT_EQUAL_PTR(pT1ColsBefore, pT1->aCol);143 TEST_ASSERT_EQUAL_INT(nT1Before, pT1->nCol);144 TEST_ASSERT_EQUAL_PTR(pT2ColsBefore, pT2->aCol);145 TEST_ASSERT_EQUAL_INT(nT2Before, pT2->nCol);146 147 /* Property cleared */148 TEST_ASSERT_EQUAL_INT(0, DbHasProperty(db, 0, DB_UnresetViews) ? 1 : 0);149 150 leave_db_mutexes(db);151 sqlite3_close(db);152}153 154/* Test: No views present, but flag set -> should still clear the flag and not affect tables. */155void test_sqliteViewResetAll_no_views_property_cleared_tables_unchanged(void) {156 sqlite3 *db = 0;157 int rc = sqlite3_open(":memory:", &db);158 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);159 160 create_or_fail(db, "CREATE TABLE t(a INTEGER, b TEXT);");161 162 enter_db_mutexes(db);163 Table *pT = sqlite3FindTable(db, "t", "main");164 TEST_ASSERT_NOT_NULL(pT);165 Column *pTColsBefore = pT->aCol;166 int nTBefore = pT->nCol;167 168 DbSetProperty(db, 0, DB_UnresetViews);169 test_sqliteViewResetAll(db, 0);170 171 /* No views -> table unchanged */172 TEST_ASSERT_EQUAL_PTR(pTColsBefore, pT->aCol);173 TEST_ASSERT_EQUAL_INT(nTBefore, pT->nCol);174 175 /* Property cleared */176 TEST_ASSERT_EQUAL_INT(0, DbHasProperty(db, 0, DB_UnresetViews) ? 1 : 0);177 178 leave_db_mutexes(db);179 sqlite3_close(db);180}181 182/* Test: Operates correctly on the TEMP schema (idx = 1). */183void test_sqliteViewResetAll_temp_schema(void) {184 sqlite3 *db = 0;185 int rc = sqlite3_open(":memory:", &db);186 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);187 188 create_or_fail(db,189 "CREATE TEMP VIEW tv AS SELECT 42 AS z;"190 "CREATE TABLE main.t(x);" /* ensure main exists too */191 );192 193 enter_db_mutexes(db);194 Table *pTempView = sqlite3FindTable(db, "tv", "temp");195 Table *pMainTable = sqlite3FindTable(db, "t", "main");196 TEST_ASSERT_NOT_NULL(pTempView);197 TEST_ASSERT_NOT_NULL(pTempView->aCol);198 TEST_ASSERT_TRUE(pTempView->nCol > 0);199 TEST_ASSERT_NOT_NULL(pMainTable);200 201 Column *pMainColsBefore = pMainTable->aCol;202 int nMainBefore = pMainTable->nCol;203 204 DbSetProperty(db, 1, DB_UnresetViews);205 test_sqliteViewResetAll(db, 1);206 207 /* Temp view cleared */208 TEST_ASSERT_NULL(pTempView->aCol);209 TEST_ASSERT_EQUAL_INT(0, pTempView->nCol);210 211 /* Main table unaffected */212 TEST_ASSERT_EQUAL_PTR(pMainColsBefore, pMainTable->aCol);213 TEST_ASSERT_EQUAL_INT(nMainBefore, pMainTable->nCol);214 215 /* Property cleared for temp schema */216 TEST_ASSERT_EQUAL_INT(0, DbHasProperty(db, 1, DB_UnresetViews) ? 1 : 0);217 218 leave_db_mutexes(db);219 sqlite3_close(db);220}221 222int main(void) {223 UNITY_BEGIN();224 RUN_TEST(test_sqliteViewResetAll_clears_view_columns_and_property);225 RUN_TEST(test_sqliteViewResetAll_noop_when_flag_not_set);226 RUN_TEST(test_sqliteViewResetAll_multiple_views_only_views_affected);227 RUN_TEST(test_sqliteViewResetAll_no_views_property_cleared_tables_unchanged);228 RUN_TEST(test_sqliteViewResetAll_temp_schema);229 return UNITY_END();230}