AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdio.h>5 6/* Helper to exec SQL and assert rc==SQLITE_OK */7static void exec_or_fail(sqlite3 *db, const char *sql){8 char *errmsg = NULL;9 int rc = sqlite3_exec(db, sql, 0, 0, &errmsg);10 if( rc!=SQLITE_OK ){11 /* Make it visible in Unity output */12 if( errmsg ){13 printf("SQL error: %s\n", errmsg);14 sqlite3_free(errmsg);15 }16 }17 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);18}19 20void setUp(void) {21 /* nothing */22}23void tearDown(void) {24 /* nothing */25}26 27/* Test that sqlite3BtreeUpdateMeta followed by sqlite3BtreeGetMeta works28** both within the same write transaction and after commit, within a read29** transaction. */30static void test_sqlite3BtreeGetMeta_roundtrip_update_read(void){31 sqlite3 *db = NULL;32 int rc = sqlite3_open(":memory:", &db);33 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);34 TEST_ASSERT_NOT_NULL(db);35 36 /* Obtain Btree for the main database */37 Btree *pBtree = db->aDb[0].pBt;38 TEST_ASSERT_NOT_NULL(pBtree);39 40 /* Begin a write transaction */41 rc = sqlite3BtreeBeginTrans(pBtree, 1, NULL);42 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);43 44 /* Choose a meta index (not 0 and not BTREE_DATA_VERSION). */45 const int idx = 5;46 const u32 val = 0x12345678u;47 48 /* Update meta and read it back within the same transaction */49 rc = sqlite3BtreeUpdateMeta(pBtree, idx, val);50 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);51 52 u32 got = 0;53 sqlite3BtreeGetMeta(pBtree, idx, &got);54 TEST_ASSERT_EQUAL_UINT(val, got);55 56 /* Commit the transaction */57 rc = sqlite3BtreeCommit(pBtree);58 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);59 60 /* Start a fresh read transaction and verify meta persisted */61 rc = sqlite3BtreeBeginTrans(pBtree, 0, NULL);62 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);63 got = 0;64 sqlite3BtreeGetMeta(pBtree, idx, &got);65 TEST_ASSERT_EQUAL_UINT(val, got);66 67 /* Rollback (end) the read transaction */68 rc = sqlite3BtreeRollback(pBtree, SQLITE_OK, 0);69 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);70 71 sqlite3_close(db);72}73 74/* Test updating and reading back two distinct meta indices. */75static void test_sqlite3BtreeGetMeta_multiple_indices(void){76 sqlite3 *db = NULL;77 int rc = sqlite3_open(":memory:", &db);78 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);79 TEST_ASSERT_NOT_NULL(db);80 81 Btree *pBtree = db->aDb[0].pBt;82 TEST_ASSERT_NOT_NULL(pBtree);83 84 rc = sqlite3BtreeBeginTrans(pBtree, 1, NULL);85 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);86 87 const int idxA = 2;88 const int idxB = 7;89 const u32 valA = 0xA5A5A5A5u;90 const u32 valB = 0x00BEEF42u;91 92 rc = sqlite3BtreeUpdateMeta(pBtree, idxA, valA);93 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);94 rc = sqlite3BtreeUpdateMeta(pBtree, idxB, valB);95 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);96 97 u32 gotA = 0, gotB = 0;98 sqlite3BtreeGetMeta(pBtree, idxA, &gotA);99 sqlite3BtreeGetMeta(pBtree, idxB, &gotB);100 TEST_ASSERT_EQUAL_UINT(valA, gotA);101 TEST_ASSERT_EQUAL_UINT(valB, gotB);102 103 rc = sqlite3BtreeCommit(pBtree);104 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);105 106 rc = sqlite3BtreeBeginTrans(pBtree, 0, NULL);107 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);108 gotA = gotB = 0;109 sqlite3BtreeGetMeta(pBtree, idxA, &gotA);110 sqlite3BtreeGetMeta(pBtree, idxB, &gotB);111 TEST_ASSERT_EQUAL_UINT(valA, gotA);112 TEST_ASSERT_EQUAL_UINT(valB, gotB);113 rc = sqlite3BtreeRollback(pBtree, SQLITE_OK, 0);114 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);115 116 sqlite3_close(db);117}118 119/* Test that BTREE_DATA_VERSION increases after changes to the database. */120static void test_sqlite3BtreeGetMeta_data_version_increases_on_write(void){121 sqlite3 *db = NULL;122 int rc = sqlite3_open(":memory:", &db);123 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);124 TEST_ASSERT_NOT_NULL(db);125 126 Btree *pBtree = db->aDb[0].pBt;127 TEST_ASSERT_NOT_NULL(pBtree);128 129 /* Create a table (change the database) */130 exec_or_fail(db, "CREATE TABLE t(x)");131 132 /* Read initial data version under a read transaction */133 rc = sqlite3BtreeBeginTrans(pBtree, 0, NULL);134 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);135 u32 dv1 = 0;136 sqlite3BtreeGetMeta(pBtree, BTREE_DATA_VERSION, &dv1);137 rc = sqlite3BtreeRollback(pBtree, SQLITE_OK, 0);138 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);139 140 /* Perform a write (INSERT) that changes the database */141 exec_or_fail(db, "INSERT INTO t VALUES(1)");142 143 /* Read data version again, expect it to have increased */144 rc = sqlite3BtreeBeginTrans(pBtree, 0, NULL);145 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);146 u32 dv2 = 0;147 sqlite3BtreeGetMeta(pBtree, BTREE_DATA_VERSION, &dv2);148 rc = sqlite3BtreeRollback(pBtree, SQLITE_OK, 0);149 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);150 151 TEST_ASSERT_TRUE_MESSAGE(dv2 > dv1, "Data version did not increase after write");152 153 /* Another write and check for another increase */154 exec_or_fail(db, "INSERT INTO t VALUES(2)");155 rc = sqlite3BtreeBeginTrans(pBtree, 0, NULL);156 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);157 u32 dv3 = 0;158 sqlite3BtreeGetMeta(pBtree, BTREE_DATA_VERSION, &dv3);159 rc = sqlite3BtreeRollback(pBtree, SQLITE_OK, 0);160 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);161 162 TEST_ASSERT_TRUE_MESSAGE(dv3 > dv2, "Data version did not increase after second write");163 164 sqlite3_close(db);165}166 167int main(void) {168 UNITY_BEGIN();169 RUN_TEST(test_sqlite3BtreeGetMeta_roundtrip_update_read);170 RUN_TEST(test_sqlite3BtreeGetMeta_multiple_indices);171 RUN_TEST(test_sqlite3BtreeGetMeta_data_version_increases_on_write);172 return UNITY_END();173}