|
|
#include "sqliteInt.h" |
|
|
#include "unity.h" |
|
|
|
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
static sqlite3 *gDb = NULL; |
|
|
|
|
|
|
|
|
static void execSQL(const char *zSql){ |
|
|
char *zErr = 0; |
|
|
int rc = sqlite3_exec(gDb, zSql, 0, 0, &zErr); |
|
|
if( rc!=SQLITE_OK ){ |
|
|
|
|
|
TEST_FAIL_MESSAGE(zErr ? zErr : "sqlite3_exec error"); |
|
|
} |
|
|
sqlite3_free(zErr); |
|
|
} |
|
|
|
|
|
|
|
|
static Token makeToken(const char *z){ |
|
|
Token t; |
|
|
t.z = z; |
|
|
t.n = (int)strlen(z); |
|
|
t.dyn = 0; |
|
|
t.enc = 0; |
|
|
t.term = 0; |
|
|
return t; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static SrcList* mkSrcList(sqlite3 *db, const char *zDb, const char *zTab){ |
|
|
Token tTab = makeToken(zTab); |
|
|
if( zDb ){ |
|
|
Token tDb = makeToken(zDb); |
|
|
return sqlite3SrcListAppend(db, 0, &tTab, &tDb); |
|
|
}else{ |
|
|
return sqlite3SrcListAppend(db, 0, &tTab, 0); |
|
|
} |
|
|
} |
|
|
|
|
|
void setUp(void) { |
|
|
int rc = sqlite3_initialize(); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
rc = sqlite3_open(":memory:", &gDb); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
} |
|
|
|
|
|
void tearDown(void) { |
|
|
if( gDb ){ |
|
|
sqlite3_close(gDb); |
|
|
gDb = NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void test_sqlite3AlterRenameTable_success_generates_vdbe(void){ |
|
|
execSQL("CREATE TABLE t1(a)"); |
|
|
Parse parse; |
|
|
memset(&parse, 0, sizeof(parse)); |
|
|
parse.db = gDb; |
|
|
|
|
|
SrcList *pSrc = mkSrcList(gDb, "main", "t1"); |
|
|
Token newName = makeToken("t2"); |
|
|
|
|
|
sqlite3BtreeEnterAll(gDb); |
|
|
sqlite3AlterRenameTable(&parse, pSrc, &newName); |
|
|
sqlite3BtreeLeaveAll(gDb); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, parse.nErr); |
|
|
TEST_ASSERT_NULL(parse.zErrMsg); |
|
|
TEST_ASSERT_NOT_NULL(parse.pVdbe); |
|
|
|
|
|
if( parse.pVdbe ) sqlite3VdbeDelete(parse.pVdbe); |
|
|
} |
|
|
|
|
|
|
|
|
void test_sqlite3AlterRenameTable_error_duplicate_name_table(void){ |
|
|
execSQL("CREATE TABLE t1(a)"); |
|
|
execSQL("CREATE TABLE t2(b)"); |
|
|
Parse parse; |
|
|
memset(&parse, 0, sizeof(parse)); |
|
|
parse.db = gDb; |
|
|
|
|
|
SrcList *pSrc = mkSrcList(gDb, "main", "t1"); |
|
|
Token newName = makeToken("t2"); |
|
|
|
|
|
sqlite3BtreeEnterAll(gDb); |
|
|
sqlite3AlterRenameTable(&parse, pSrc, &newName); |
|
|
sqlite3BtreeLeaveAll(gDb); |
|
|
|
|
|
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
TEST_ASSERT_NULL(parse.pVdbe); |
|
|
|
|
|
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg); |
|
|
} |
|
|
|
|
|
|
|
|
void test_sqlite3AlterRenameTable_error_duplicate_name_index(void){ |
|
|
execSQL("CREATE TABLE t1(a)"); |
|
|
execSQL("CREATE INDEX t2 ON t1(a)"); |
|
|
Parse parse; |
|
|
memset(&parse, 0, sizeof(parse)); |
|
|
parse.db = gDb; |
|
|
|
|
|
SrcList *pSrc = mkSrcList(gDb, "main", "t1"); |
|
|
Token newName = makeToken("t2"); |
|
|
|
|
|
sqlite3BtreeEnterAll(gDb); |
|
|
sqlite3AlterRenameTable(&parse, pSrc, &newName); |
|
|
sqlite3BtreeLeaveAll(gDb); |
|
|
|
|
|
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
TEST_ASSERT_NULL(parse.pVdbe); |
|
|
|
|
|
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg); |
|
|
} |
|
|
|
|
|
|
|
|
void test_sqlite3AlterRenameTable_error_view_not_alterable(void){ |
|
|
execSQL("CREATE TABLE t1(a)"); |
|
|
execSQL("CREATE VIEW v1 AS SELECT a FROM t1"); |
|
|
Parse parse; |
|
|
memset(&parse, 0, sizeof(parse)); |
|
|
parse.db = gDb; |
|
|
|
|
|
SrcList *pSrc = mkSrcList(gDb, "main", "v1"); |
|
|
Token newName = makeToken("v2"); |
|
|
|
|
|
sqlite3BtreeEnterAll(gDb); |
|
|
sqlite3AlterRenameTable(&parse, pSrc, &newName); |
|
|
sqlite3BtreeLeaveAll(gDb); |
|
|
|
|
|
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
TEST_ASSERT_NULL(parse.pVdbe); |
|
|
|
|
|
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg); |
|
|
} |
|
|
|
|
|
|
|
|
void test_sqlite3AlterRenameTable_error_system_table_not_alterable(void){ |
|
|
|
|
|
execSQL("CREATE TABLE tauto(id INTEGER PRIMARY KEY AUTOINCREMENT, x)"); |
|
|
execSQL("INSERT INTO tauto(x) VALUES (1)"); |
|
|
|
|
|
Parse parse; |
|
|
memset(&parse, 0, sizeof(parse)); |
|
|
parse.db = gDb; |
|
|
|
|
|
SrcList *pSrc = mkSrcList(gDb, "main", "sqlite_sequence"); |
|
|
Token newName = makeToken("seq2"); |
|
|
|
|
|
sqlite3BtreeEnterAll(gDb); |
|
|
sqlite3AlterRenameTable(&parse, pSrc, &newName); |
|
|
sqlite3BtreeLeaveAll(gDb); |
|
|
|
|
|
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
TEST_ASSERT_NULL(parse.pVdbe); |
|
|
|
|
|
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg); |
|
|
} |
|
|
|
|
|
|
|
|
void test_sqlite3AlterRenameTable_error_reserved_new_name(void){ |
|
|
execSQL("CREATE TABLE t1(a)"); |
|
|
Parse parse; |
|
|
memset(&parse, 0, sizeof(parse)); |
|
|
parse.db = gDb; |
|
|
|
|
|
SrcList *pSrc = mkSrcList(gDb, "main", "t1"); |
|
|
Token newName = makeToken("sqlite_stat1"); |
|
|
|
|
|
sqlite3BtreeEnterAll(gDb); |
|
|
sqlite3AlterRenameTable(&parse, pSrc, &newName); |
|
|
sqlite3BtreeLeaveAll(gDb); |
|
|
|
|
|
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr); |
|
|
TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
TEST_ASSERT_NULL(parse.pVdbe); |
|
|
|
|
|
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg); |
|
|
} |
|
|
|
|
|
int main(void) { |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_sqlite3AlterRenameTable_success_generates_vdbe); |
|
|
RUN_TEST(test_sqlite3AlterRenameTable_error_duplicate_name_table); |
|
|
RUN_TEST(test_sqlite3AlterRenameTable_error_duplicate_name_index); |
|
|
RUN_TEST(test_sqlite3AlterRenameTable_error_view_not_alterable); |
|
|
RUN_TEST(test_sqlite3AlterRenameTable_error_system_table_not_alterable); |
|
|
RUN_TEST(test_sqlite3AlterRenameTable_error_reserved_new_name); |
|
|
return UNITY_END(); |
|
|
} |