| #include "sqliteInt.h" |
| #include "unity.h" |
|
|
| #include <stdlib.h> |
| #include <string.h> |
|
|
| |
| extern void test_dropColumnFunc(sqlite3_context *context, int NotUsed, sqlite3_value **argv); |
|
|
| static sqlite3 *gDb = NULL; |
|
|
| |
| static void udf_call_drop_column(sqlite3_context *ctx, int argc, sqlite3_value **argv){ |
| |
| if( argc!=3 ){ |
| sqlite3_result_error_code(ctx, SQLITE_MISUSE); |
| return; |
| } |
| test_dropColumnFunc(ctx, 0, argv); |
| } |
|
|
| |
| static int run_drop_and_capture( |
| int iSchema, |
| const char *zCreate, |
| int iCol, |
| char **pzResult, |
| int *pDbErr |
| ){ |
| sqlite3_stmt *pStmt = NULL; |
| int rcPrep = sqlite3_prepare_v2(gDb, "SELECT call_drop_column(?, ?, ?)", -1, &pStmt, 0); |
| if( rcPrep!=SQLITE_OK ){ |
| if( pDbErr ) *pDbErr = rcPrep; |
| return rcPrep; |
| } |
| sqlite3_bind_int(pStmt, 1, iSchema); |
| if( zCreate ){ |
| sqlite3_bind_text(pStmt, 2, zCreate, -1, SQLITE_TRANSIENT); |
| }else{ |
| sqlite3_bind_null(pStmt, 2); |
| } |
| sqlite3_bind_int(pStmt, 3, iCol); |
|
|
| int rcStep = sqlite3_step(pStmt); |
| if( rcStep==SQLITE_ROW ){ |
| const unsigned char *z = sqlite3_column_text(pStmt, 0); |
| if( z && pzResult ){ |
| *pzResult = sqlite3_mprintf("%s", z); |
| } |
| if( pDbErr ) *pDbErr = SQLITE_OK; |
| }else{ |
| if( pDbErr ) *pDbErr = sqlite3_errcode(gDb); |
| } |
|
|
| sqlite3_finalize(pStmt); |
| return rcStep; |
| } |
|
|
| void setUp(void) { |
| int rc = sqlite3_open(":memory:", &gDb); |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
| sqlite3_extended_result_codes(gDb, 1); |
| rc = sqlite3_create_function(gDb, "call_drop_column", 3, SQLITE_UTF8, NULL, |
| udf_call_drop_column, NULL, NULL); |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
| } |
|
|
| void tearDown(void) { |
| if( gDb ){ |
| sqlite3_close(gDb); |
| gDb = NULL; |
| } |
| } |
|
|
| |
| void test_dropColumnFunc_drop_first_simple(void){ |
| char *zOut = NULL; int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, "CREATE TABLE t(a,b,c)", 0, &zOut, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| TEST_ASSERT_NOT_NULL(zOut); |
| TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(b,c)", zOut); |
| sqlite3_free(zOut); |
| } |
|
|
| |
| void test_dropColumnFunc_drop_middle_simple(void){ |
| char *zOut = NULL; int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, "CREATE TABLE t(a,b,c)", 1, &zOut, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| TEST_ASSERT_NOT_NULL(zOut); |
| TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a,c)", zOut); |
| sqlite3_free(zOut); |
| } |
|
|
| |
| void test_dropColumnFunc_drop_last_simple(void){ |
| char *zOut = NULL; int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, "CREATE TABLE t(a,b,c)", 2, &zOut, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| TEST_ASSERT_NOT_NULL(zOut); |
| TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a,b)", zOut); |
| sqlite3_free(zOut); |
| } |
|
|
| |
| void test_dropColumnFunc_drop_last_with_nested_constraints(void){ |
| const char *zCreate = |
| "CREATE TABLE t(a, b TEXT CHECK(b IN (1,2,3) AND (b IS NOT NULL)), c)"; |
| char *zOut = NULL; int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, zCreate, 2, &zOut, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| TEST_ASSERT_NOT_NULL(zOut); |
| TEST_ASSERT_EQUAL_STRING( |
| "CREATE TABLE t(a, b TEXT CHECK(b IN (1,2,3) AND (b IS NOT NULL)))", zOut); |
| sqlite3_free(zOut); |
| } |
|
|
| |
| void test_dropColumnFunc_invalid_index_error(void){ |
| int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, "CREATE TABLE t(a,b)", 5, NULL, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_CORRUPT, err); |
| } |
|
|
| |
| void test_dropColumnFunc_single_column_error(void){ |
| int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, "CREATE TABLE t(a)", 0, NULL, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_CORRUPT, err); |
| } |
|
|
| |
| void test_dropColumnFunc_invalid_sql_error(void){ |
| int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, "DROP TABLE t", 0, NULL, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_CORRUPT, err); |
| } |
|
|
| |
| void test_dropColumnFunc_temp_schema(void){ |
| char *zOut = NULL; int err = SQLITE_OK; |
| int rc = run_drop_and_capture(1, "CREATE TABLE t(a,b)", 1, &zOut, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| TEST_ASSERT_NOT_NULL(zOut); |
| TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a)", zOut); |
| sqlite3_free(zOut); |
| } |
|
|
| |
| void test_dropColumnFunc_preserves_quotes_and_spacing(void){ |
| const char *zCreate = |
| "CREATE TABLE \"My T\"( \"a1\" INTEGER PRIMARY KEY, \"b-2\" TEXT, c )"; |
| char *zOut = NULL; int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, zCreate, 1, &zOut, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| TEST_ASSERT_NOT_NULL(zOut); |
| TEST_ASSERT_EQUAL_STRING( |
| "CREATE TABLE \"My T\"( \"a1\" INTEGER PRIMARY KEY, c )", zOut); |
| sqlite3_free(zOut); |
| } |
|
|
| |
| void test_dropColumnFunc_null_sql_error(void){ |
| int err = SQLITE_OK; |
| int rc = run_drop_and_capture(0, NULL, 0, NULL, &err); |
| TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc); |
| TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, err); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_dropColumnFunc_drop_first_simple); |
| RUN_TEST(test_dropColumnFunc_drop_middle_simple); |
| RUN_TEST(test_dropColumnFunc_drop_last_simple); |
| RUN_TEST(test_dropColumnFunc_drop_last_with_nested_constraints); |
| RUN_TEST(test_dropColumnFunc_invalid_index_error); |
| RUN_TEST(test_dropColumnFunc_single_column_error); |
| RUN_TEST(test_dropColumnFunc_invalid_sql_error); |
| RUN_TEST(test_dropColumnFunc_temp_schema); |
| RUN_TEST(test_dropColumnFunc_preserves_quotes_and_spacing); |
| RUN_TEST(test_dropColumnFunc_null_sql_error); |
| return UNITY_END(); |
| } |