| | #include "sqliteInt.h" |
| | #include "unity.h" |
| | #include <string.h> |
| | #include <stdlib.h> |
| |
|
| | |
| | void setUp(void) { |
| | |
| | } |
| | void tearDown(void) { |
| | |
| | } |
| |
|
| | |
| | static SrcList *makeSrcListOne(sqlite3 *db, const char *zDb, const char *zTab){ |
| | |
| | SrcList *p = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList)); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(p, "sqlite3DbMallocZero failed creating SrcList"); |
| | p->nAlloc = 1; |
| | p->nSrc = 1; |
| | p->a[0].zName = sqlite3DbStrDup(db, zTab); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zName, "sqlite3DbStrDup failed for table name"); |
| | if( zDb ){ |
| | p->a[0].zDatabase = sqlite3DbStrDup(db, zDb); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zDatabase, "sqlite3DbStrDup failed for database name"); |
| | } |
| | return p; |
| | } |
| |
|
| | |
| | static Token makeToken(const char *z){ |
| | Token t; |
| | t.z = z; |
| | t.n = (int)strlen(z); |
| | return t; |
| | } |
| |
|
| | |
| | static void initParse(Parse *pParse, sqlite3 *db){ |
| | memset(pParse, 0, sizeof(*pParse)); |
| | pParse->db = db; |
| | } |
| |
|
| | |
| | static void execSqlOk(sqlite3 *db, const char *zSql){ |
| | int rc = sqlite3_exec(db, zSql, 0, 0, 0); |
| | if( rc!=SQLITE_OK ){ |
| | const char *err = sqlite3_errmsg(db); |
| | char msg[512]; |
| | sqlite3_snprintf(sizeof(msg), msg, "SQL exec failed (%d): %s; SQL: %s", rc, err ? err : "(null)", zSql); |
| | TEST_FAIL_MESSAGE(msg); |
| | } |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropConstraint_nonexistent_table(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | Parse p; |
| | initParse(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcListOne(db, NULL, "nosuchtable"); |
| | Token cons = makeToken("c1"); |
| |
|
| | sqlite3AlterDropConstraint(&p, pSrc, &cons, 0); |
| |
|
| | TEST_ASSERT_NULL_MESSAGE(p.pVdbe, "VDBE should not be created for nonexistent table"); |
| | TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "An error should be recorded for nonexistent table"); |
| |
|
| | sqlite3SrcListDelete(db, pSrc); |
| | if( p.pVdbe ) sqlite3VdbeDelete(p.pVdbe); |
| | sqlite3_close(db); |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropConstraint_drop_not_null_on_existing_col_generates_code(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | execSqlOk(db, "CREATE TABLE t1(a INTEGER NOT NULL, b TEXT);"); |
| |
|
| | Parse p; |
| | initParse(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcListOne(db, NULL, "t1"); |
| | Token col = makeToken("a"); |
| |
|
| | sqlite3AlterDropConstraint(&p, pSrc, 0, &col); |
| |
|
| | TEST_ASSERT_NOT_NULL_MESSAGE(p.pVdbe, "VDBE should be created for valid DROP NOT NULL operation"); |
| | |
| |
|
| | sqlite3SrcListDelete(db, pSrc); |
| | if( p.pVdbe ) sqlite3VdbeDelete(p.pVdbe); |
| | sqlite3_close(db); |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropConstraint_nonexistent_column_reports_error(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | execSqlOk(db, "CREATE TABLE t2(a INTEGER NOT NULL, b TEXT);"); |
| |
|
| | Parse p; |
| | initParse(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcListOne(db, NULL, "t2"); |
| | Token col = makeToken("no_such_col"); |
| |
|
| | sqlite3AlterDropConstraint(&p, pSrc, 0, &col); |
| |
|
| | TEST_ASSERT_NULL_MESSAGE(p.pVdbe, "VDBE should not be created when column does not exist"); |
| | TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "An error should be recorded for nonexistent column"); |
| |
|
| | sqlite3SrcListDelete(db, pSrc); |
| | if( p.pVdbe ) sqlite3VdbeDelete(p.pVdbe); |
| | sqlite3_close(db); |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropConstraint_drop_named_constraint_generates_code(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | |
| | execSqlOk(db, "CREATE TABLE t3(x INT, y INT, CONSTRAINT c1 CHECK(x>0));"); |
| |
|
| | Parse p; |
| | initParse(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcListOne(db, NULL, "t3"); |
| | Token cons = makeToken("c1"); |
| |
|
| | sqlite3AlterDropConstraint(&p, pSrc, &cons, 0); |
| |
|
| | TEST_ASSERT_NOT_NULL_MESSAGE(p.pVdbe, "VDBE should be created for valid DROP CONSTRAINT operation"); |
| |
|
| | sqlite3SrcListDelete(db, pSrc); |
| | if( p.pVdbe ) sqlite3VdbeDelete(p.pVdbe); |
| | sqlite3_close(db); |
| | } |
| |
|
| | int main(void){ |
| | UNITY_BEGIN(); |
| | RUN_TEST(test_sqlite3AlterDropConstraint_nonexistent_table); |
| | RUN_TEST(test_sqlite3AlterDropConstraint_drop_not_null_on_existing_col_generates_code); |
| | RUN_TEST(test_sqlite3AlterDropConstraint_nonexistent_column_reports_error); |
| | RUN_TEST(test_sqlite3AlterDropConstraint_drop_named_constraint_generates_code); |
| | return UNITY_END(); |
| | } |