AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdio.h>5#include <string.h>6 7/* Helper macros to safely enter/leave the DB mutex */8#define ENTER_DB_MUTEX(db) do { if ((db) && (db)->mutex) sqlite3_mutex_enter((db)->mutex); } while (0)9#define LEAVE_DB_MUTEX(db) do { if ((db) && (db)->mutex) sqlite3_mutex_leave((db)->mutex); } while (0)10 11void setUp(void) {12 /* No-op */13}14 15void tearDown(void) {16 /* No-op */17}18 19/* Open an in-memory database connection and assert success */20static sqlite3* open_memory_db(void){21 sqlite3 *db = 0;22 int rc = sqlite3_open(":memory:", &db);23 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");24 TEST_ASSERT_NOT_NULL(db);25 return db;26}27 28/* Close the database and assert success */29static void close_db(sqlite3 *db){30 int rc = sqlite3_close(db);31 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_close failed");32}33 34/* Execute SQL and assert it returns SQLITE_OK */35static void exec_sql_ok(sqlite3 *db, const char *sql){36 char *errmsg = 0;37 int rc = sqlite3_exec(db, sql, 0, 0, &errmsg);38 if( rc != SQLITE_OK ){39 /* Provide any error message to the test output */40 if( errmsg ){41 /* Unity prints strings through assertions */42 TEST_FAIL_MESSAGE(errmsg);43 sqlite3_free(errmsg);44 }else{45 TEST_FAIL_MESSAGE("sqlite3_exec failed without error message");46 }47 }48 if( errmsg ) sqlite3_free(errmsg);49}50 51/* Test: main schema maps to index 0 */52void test_sqlite3SchemaToIndex_main_schema_is_zero(void){53 sqlite3 *db = open_memory_db();54 55 ENTER_DB_MUTEX(db);56 Schema *pMain = db->aDb[0].pSchema;57 TEST_ASSERT_NOT_NULL_MESSAGE(pMain, "Main schema pointer is NULL");58 int idx = sqlite3SchemaToIndex(db, pMain);59 LEAVE_DB_MUTEX(db);60 61 TEST_ASSERT_EQUAL_INT(0, idx);62 63 close_db(db);64}65 66/* Test: temp schema maps to index 1 (ensure temp schema is initialized) */67void test_sqlite3SchemaToIndex_temp_schema_is_one(void){68 sqlite3 *db = open_memory_db();69 70 /* Ensure TEMP schema is initialized by creating a temp table */71 exec_sql_ok(db, "CREATE TEMP TABLE ttemp(x)");72 73 ENTER_DB_MUTEX(db);74 Schema *pTemp = db->aDb[1].pSchema;75 TEST_ASSERT_NOT_NULL_MESSAGE(pTemp, "Temp schema pointer is NULL after creating TEMP table");76 int idx = sqlite3SchemaToIndex(db, pTemp);77 LEAVE_DB_MUTEX(db);78 79 TEST_ASSERT_EQUAL_INT(1, idx);80 81 close_db(db);82}83 84/* Test: attached database schema maps to last index (nDb - 1) */85void test_sqlite3SchemaToIndex_attached_db_maps_to_last_index(void){86 sqlite3 *db = open_memory_db();87 88 int nBefore = 0;89 ENTER_DB_MUTEX(db);90 nBefore = db->nDb;91 LEAVE_DB_MUTEX(db);92 93 /* Attach a new in-memory database */94 exec_sql_ok(db, "ATTACH DATABASE ':memory:' AS aux1");95 96 int nAfter = 0;97 ENTER_DB_MUTEX(db);98 nAfter = db->nDb;99 TEST_ASSERT_EQUAL_INT_MESSAGE(nBefore + 1, nAfter, "ATTACH did not increase db->nDb by 1");100 Schema *pAux1 = db->aDb[nAfter - 1].pSchema;101 TEST_ASSERT_NOT_NULL_MESSAGE(pAux1, "Attached schema pointer is NULL");102 int idx = sqlite3SchemaToIndex(db, pAux1);103 LEAVE_DB_MUTEX(db);104 105 TEST_ASSERT_EQUAL_INT(nAfter - 1, idx);106 107 close_db(db);108}109 110/* Test: passing NULL schema returns -32768 */111void test_sqlite3SchemaToIndex_null_schema_returns_neg32768(void){112 sqlite3 *db = open_memory_db();113 114 ENTER_DB_MUTEX(db);115 int idx = sqlite3SchemaToIndex(db, NULL);116 LEAVE_DB_MUTEX(db);117 118 TEST_ASSERT_EQUAL_INT(-32768, idx);119 120 close_db(db);121}122 123/* Test: multiple attachments map correctly to distinct indices */124void test_sqlite3SchemaToIndex_multiple_attachments(void){125 sqlite3 *db = open_memory_db();126 127 int n0 = 0;128 ENTER_DB_MUTEX(db);129 n0 = db->nDb;130 LEAVE_DB_MUTEX(db);131 132 /* Attach two databases */133 exec_sql_ok(db, "ATTACH DATABASE ':memory:' AS a1");134 exec_sql_ok(db, "ATTACH DATABASE ':memory:' AS a2");135 136 ENTER_DB_MUTEX(db);137 int n2 = db->nDb;138 TEST_ASSERT_EQUAL_INT_MESSAGE(n0 + 2, n2, "db->nDb did not increase by 2 after two ATTACHes");139 140 Schema *pA1 = db->aDb[n2 - 2].pSchema;141 Schema *pA2 = db->aDb[n2 - 1].pSchema;142 TEST_ASSERT_NOT_NULL_MESSAGE(pA1, "Schema for a1 is NULL");143 TEST_ASSERT_NOT_NULL_MESSAGE(pA2, "Schema for a2 is NULL");144 145 int idxA1 = sqlite3SchemaToIndex(db, pA1);146 int idxA2 = sqlite3SchemaToIndex(db, pA2);147 LEAVE_DB_MUTEX(db);148 149 TEST_ASSERT_EQUAL_INT(n2 - 2, idxA1);150 TEST_ASSERT_EQUAL_INT(n2 - 1, idxA2);151 TEST_ASSERT_NOT_EQUAL(idxA1, idxA2);152 153 close_db(db);154}155 156int main(void){157 UNITY_BEGIN();158 RUN_TEST(test_sqlite3SchemaToIndex_main_schema_is_zero);159 RUN_TEST(test_sqlite3SchemaToIndex_temp_schema_is_one);160 RUN_TEST(test_sqlite3SchemaToIndex_attached_db_maps_to_last_index);161 RUN_TEST(test_sqlite3SchemaToIndex_null_schema_returns_neg32768);162 RUN_TEST(test_sqlite3SchemaToIndex_multiple_attachments);163 return UNITY_END();164}