|
|
#include "sqliteInt.h" |
|
|
#include "unity.h" |
|
|
#include <string.h> |
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
|
extern int test_isRealTable(Parse *pParse, Table *pTab, int iOp); |
|
|
|
|
|
void setUp(void) { |
|
|
|
|
|
} |
|
|
|
|
|
void tearDown(void) { |
|
|
|
|
|
} |
|
|
|
|
|
static sqlite3* open_mem_db(void){ |
|
|
sqlite3 *db = 0; |
|
|
int rc = sqlite3_open(":memory:", &db); |
|
|
TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed"); |
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(db, "db is NULL after sqlite3_open"); |
|
|
return db; |
|
|
} |
|
|
|
|
|
static void clear_parse_err(sqlite3 *db, Parse *pParse){ |
|
|
if( pParse->zErrMsg ){ |
|
|
sqlite3DbFree(db, pParse->zErrMsg); |
|
|
pParse->zErrMsg = 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void init_parse(Parse *pParse, sqlite3 *db){ |
|
|
memset(pParse, 0, sizeof(*pParse)); |
|
|
pParse->db = db; |
|
|
} |
|
|
|
|
|
|
|
|
static void make_real_table(Table *pTab, const char *zName){ |
|
|
memset(pTab, 0, sizeof(*pTab)); |
|
|
pTab->zName = (char*)zName; |
|
|
} |
|
|
|
|
|
|
|
|
static void make_view_table(Table *pTab, const char *zName){ |
|
|
memset(pTab, 0, sizeof(*pTab)); |
|
|
pTab->zName = (char*)zName; |
|
|
|
|
|
static Select dummySelect; |
|
|
memset(&dummySelect, 0, sizeof(dummySelect)); |
|
|
pTab->pSelect = &dummySelect; |
|
|
#ifdef TF_View |
|
|
pTab->tabFlags |= TF_View; |
|
|
#endif |
|
|
} |
|
|
|
|
|
|
|
|
static void make_virtual_table(Table *pTab, const char *zName){ |
|
|
memset(pTab, 0, sizeof(*pTab)); |
|
|
pTab->zName = (char*)zName; |
|
|
#ifdef TF_Virtual |
|
|
pTab->tabFlags |= TF_Virtual; |
|
|
#else |
|
|
|
|
|
pTab->tabFlags = 0xFFFFFFFF; |
|
|
#endif |
|
|
} |
|
|
|
|
|
void test_isRealTable_returns_zero_for_real_table(void){ |
|
|
sqlite3 *db = open_mem_db(); |
|
|
Parse parse; |
|
|
init_parse(&parse, db); |
|
|
|
|
|
Table tab; |
|
|
make_real_table(&tab, "t_real"); |
|
|
|
|
|
int rc = test_isRealTable(&parse, &tab, 0); |
|
|
TEST_ASSERT_EQUAL_INT(0, rc); |
|
|
TEST_ASSERT_NULL(parse.zErrMsg); |
|
|
|
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_isRealTable_view_rename_columns_sets_error(void){ |
|
|
sqlite3 *db = open_mem_db(); |
|
|
Parse parse; |
|
|
init_parse(&parse, db); |
|
|
|
|
|
Table tab; |
|
|
make_view_table(&tab, "v1"); |
|
|
|
|
|
int rc = test_isRealTable(&parse, &tab, 0); |
|
|
TEST_ASSERT_EQUAL_INT(1, rc); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
|
|
|
|
|
|
const char *msg = parse.zErrMsg; |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "cannot ")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "rename columns of")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "view")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "\"v1\"")); |
|
|
|
|
|
clear_parse_err(db, &parse); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_isRealTable_view_drop_column_sets_error(void){ |
|
|
sqlite3 *db = open_mem_db(); |
|
|
Parse parse; |
|
|
init_parse(&parse, db); |
|
|
|
|
|
Table tab; |
|
|
make_view_table(&tab, "v_drop"); |
|
|
|
|
|
int rc = test_isRealTable(&parse, &tab, 1); |
|
|
TEST_ASSERT_EQUAL_INT(1, rc); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
|
|
|
const char *msg = parse.zErrMsg; |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "cannot ")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "drop column from")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "view")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "\"v_drop\"")); |
|
|
|
|
|
clear_parse_err(db, &parse); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_isRealTable_virtual_edit_constraints_sets_error(void){ |
|
|
sqlite3 *db = open_mem_db(); |
|
|
Parse parse; |
|
|
init_parse(&parse, db); |
|
|
|
|
|
Table tab; |
|
|
make_virtual_table(&tab, "vt1"); |
|
|
|
|
|
int rc = test_isRealTable(&parse, &tab, 2); |
|
|
TEST_ASSERT_EQUAL_INT(1, rc); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
|
|
|
const char *msg = parse.zErrMsg; |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "cannot ")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "edit constraints of")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "virtual table")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "\"vt1\"")); |
|
|
|
|
|
clear_parse_err(db, &parse); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_isRealTable_both_view_and_virtual_prefers_virtual_in_message(void){ |
|
|
sqlite3 *db = open_mem_db(); |
|
|
Parse parse; |
|
|
init_parse(&parse, db); |
|
|
|
|
|
Table tab; |
|
|
make_view_table(&tab, "bothy"); |
|
|
|
|
|
#ifdef TF_Virtual |
|
|
tab.tabFlags |= TF_Virtual; |
|
|
#endif |
|
|
|
|
|
int rc = test_isRealTable(&parse, &tab, 0); |
|
|
TEST_ASSERT_EQUAL_INT(1, rc); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
|
|
|
const char *msg = parse.zErrMsg; |
|
|
|
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "virtual table")); |
|
|
TEST_ASSERT_NOT_NULL(strstr(msg, "\"bothy\"")); |
|
|
|
|
|
clear_parse_err(db, &parse); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
int main(void) { |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_isRealTable_returns_zero_for_real_table); |
|
|
RUN_TEST(test_isRealTable_view_rename_columns_sets_error); |
|
|
RUN_TEST(test_isRealTable_view_drop_column_sets_error); |
|
|
RUN_TEST(test_isRealTable_virtual_edit_constraints_sets_error); |
|
|
RUN_TEST(test_isRealTable_both_view_and_virtual_prefers_virtual_in_message); |
|
|
return UNITY_END(); |
|
|
} |