| | #include "sqliteInt.h" |
| | #include "unity.h" |
| | #include <stdio.h> |
| | #include <stdlib.h> |
| | #include <string.h> |
| |
|
| | |
| | extern void test_addConstraintFunc(sqlite3_context*, int, sqlite3_value**); |
| |
|
| | static sqlite3 *gDb = NULL; |
| | static const char *gFuncName = "test_addc"; |
| |
|
| | |
| | static void register_add_constraint_func(void){ |
| | int rc = sqlite3_create_function(gDb, gFuncName, 3, SQLITE_UTF8, 0, |
| | test_addConstraintFunc, 0, 0); |
| | TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_create_function failed"); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | static char* call_add_constraint(const char *zCreate, const char *zCons, int iCol, |
| | int *out_step_rc, int *out_errcode){ |
| | char *zSql = sqlite3_mprintf("SELECT %s(%Q,%Q,%d)", gFuncName, zCreate, zCons, iCol); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(zSql, "sqlite3_mprintf returned NULL"); |
| | sqlite3_stmt *pStmt = NULL; |
| | int rc = sqlite3_prepare_v2(gDb, zSql, -1, &pStmt, 0); |
| | sqlite3_free(zSql); |
| | TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_prepare_v2 failed"); |
| | rc = sqlite3_step(pStmt); |
| | if( out_step_rc ) *out_step_rc = rc; |
| | if( out_errcode ) *out_errcode = sqlite3_errcode(gDb); |
| | char *res = NULL; |
| | if( rc==SQLITE_ROW ){ |
| | const unsigned char *txt = sqlite3_column_text(pStmt, 0); |
| | if( txt ){ |
| | res = (char*)sqlite3_mprintf("%s", txt); |
| | } |
| | } |
| | sqlite3_finalize(pStmt); |
| | return res; |
| | } |
| |
|
| | void setUp(void) { |
| | int rc = sqlite3_open(":memory:", &gDb); |
| | TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed"); |
| | register_add_constraint_func(); |
| | } |
| |
|
| | void tearDown(void) { |
| | if( gDb ){ |
| | sqlite3_close(gDb); |
| | gDb = NULL; |
| | } |
| | } |
| |
|
| | |
| | void test_addConstraintFunc_adds_to_first_column_simple(void){ |
| | int stepRc = 0, err = 0; |
| | const char *inSql = "CREATE TABLE t(a, b)"; |
| | const char *cons = "CHECK(a>0)"; |
| | char *out = call_add_constraint(inSql, cons, 0, &stepRc, &err); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_ROW, stepRc); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| | TEST_ASSERT_NOT_NULL(out); |
| | TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a CHECK(a>0), b)", out); |
| | sqlite3_free(out); |
| | } |
| |
|
| | |
| | void test_addConstraintFunc_adds_to_second_column_simple(void){ |
| | int stepRc = 0, err = 0; |
| | const char *inSql = "CREATE TABLE t(a, b)"; |
| | const char *cons = "DEFAULT 5"; |
| | char *out = call_add_constraint(inSql, cons, 1, &stepRc, &err); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_ROW, stepRc); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| | TEST_ASSERT_NOT_NULL(out); |
| | TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a, b DEFAULT 5)", out); |
| | sqlite3_free(out); |
| | } |
| |
|
| | |
| | void test_addConstraintFunc_appends_table_constraint_neg1(void){ |
| | int stepRc = 0, err = 0; |
| | const char *inSql = "CREATE TABLE t(a INTEGER, b TEXT)"; |
| | const char *cons = "UNIQUE(a,b)"; |
| | char *out = call_add_constraint(inSql, cons, -1, &stepRc, &err); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_ROW, stepRc); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| | TEST_ASSERT_NOT_NULL(out); |
| | TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a INTEGER, b TEXT, UNIQUE(a,b))", out); |
| | sqlite3_free(out); |
| | } |
| |
|
| | |
| | |
| | |
| | void test_addConstraintFunc_handles_comments_and_parens(void){ |
| | int stepRc = 0, err = 0; |
| | const char *inSql = |
| | "CREATE TABLE t( /*c*/ a DECIMAL(10, 5) /*x*/, b TEXT )"; |
| | const char *cons = "NOT NULL"; |
| | char *out = call_add_constraint(inSql, cons, 0, &stepRc, &err); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_ROW, stepRc); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| | TEST_ASSERT_NOT_NULL(out); |
| | TEST_ASSERT_EQUAL_STRING( |
| | "CREATE TABLE t( /*c*/ a DECIMAL(10, 5) /*x*/ NOT NULL, b TEXT )", out); |
| | sqlite3_free(out); |
| | } |
| |
|
| | |
| | void test_addConstraintFunc_handles_nested_parens_in_defaults(void){ |
| | int stepRc = 0, err = 0; |
| | const char *inSql = |
| | "CREATE TABLE t(a TEXT DEFAULT (printf('x(%d)', 1)), b INT)"; |
| | const char *cons = "CHECK(length(a)>0)"; |
| | char *out = call_add_constraint(inSql, cons, 0, &stepRc, &err); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_ROW, stepRc); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| | TEST_ASSERT_NOT_NULL(out); |
| | TEST_ASSERT_EQUAL_STRING( |
| | "CREATE TABLE t(a TEXT DEFAULT (printf('x(%d)', 1)) CHECK(length(a)>0), b INT)", out); |
| | sqlite3_free(out); |
| | } |
| |
|
| | |
| | void test_addConstraintFunc_null_sql_returns_null(void){ |
| | int stepRc = 0, err = 0; |
| | char *out = call_add_constraint(NULL, "ANY", 0, &stepRc, &err); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_ROW, stepRc); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, err); |
| | TEST_ASSERT_NULL(out); |
| | sqlite3_free(out); |
| | } |
| |
|
| | |
| | void test_addConstraintFunc_out_of_range_column_reports_corrupt(void){ |
| | int stepRc = 0, err = 0; |
| | |
| | const char *inSql = "CREATE TABLE t(a)"; |
| | char *out = call_add_constraint(inSql, "ZZZ", 5, &stepRc, &err); |
| | TEST_ASSERT(out == NULL); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, stepRc); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_CORRUPT, err); |
| | } |
| |
|
| | |
| | void test_addConstraintFunc_malformed_sql_reports_corrupt(void){ |
| | int stepRc = 0, err = 0; |
| | |
| | const char *inSql = "CREATE TABLE t(a DEFAULT 'unterminated, b INT)"; |
| | char *out = call_add_constraint(inSql, "NOT NULL", 0, &stepRc, &err); |
| | TEST_ASSERT(out == NULL); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, stepRc); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_CORRUPT, err); |
| | } |
| |
|
| | int main(void) { |
| | UNITY_BEGIN(); |
| | RUN_TEST(test_addConstraintFunc_adds_to_first_column_simple); |
| | RUN_TEST(test_addConstraintFunc_adds_to_second_column_simple); |
| | RUN_TEST(test_addConstraintFunc_appends_table_constraint_neg1); |
| | RUN_TEST(test_addConstraintFunc_handles_comments_and_parens); |
| | RUN_TEST(test_addConstraintFunc_handles_nested_parens_in_defaults); |
| | RUN_TEST(test_addConstraintFunc_null_sql_returns_null); |
| | RUN_TEST(test_addConstraintFunc_out_of_range_column_reports_corrupt); |
| | RUN_TEST(test_addConstraintFunc_malformed_sql_reports_corrupt); |
| | return UNITY_END(); |
| | } |