AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6static Btree* getMainBtree(sqlite3 *db){7 /* Main database is aDb[0] */8 return db->aDb[0].pBt;9}10 11void setUp(void) {12 /* Nothing */13}14void tearDown(void) {15 /* Nothing */16}17 18/* Test: Passing NULL Btree pointer returns SQLITE_OK (no-op) */19void test_sqlite3BtreeSavepoint_null_ptr_returns_ok(void) {20 int rc = sqlite3BtreeSavepoint(NULL, SAVEPOINT_RELEASE, 0);21 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);22 23 rc = sqlite3BtreeSavepoint(NULL, SAVEPOINT_ROLLBACK, -1);24 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);25}26 27/* Test: When no write transaction is active, returns SQLITE_OK and no crash */28void test_sqlite3BtreeSavepoint_without_write_txn(void) {29 sqlite3 *db = 0;30 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));31 TEST_ASSERT_NOT_NULL(db);32 33 Btree *p = getMainBtree(db);34 TEST_ASSERT_NOT_NULL(p);35 /* Ensure not in write transaction */36 TEST_ASSERT_NOT_EQUAL(TRANS_WRITE, p->inTrans);37 38 int rc = sqlite3BtreeSavepoint(p, SAVEPOINT_ROLLBACK, -1);39 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);40 41 rc = sqlite3_close(db);42 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);43}44 45/* Test: With a write-transaction on an initially empty DB, SAVEPOINT_ROLLBACK46 * with iSavepoint=-1 should reset and recreate the database (nPage >= 1) */47void test_sqlite3BtreeSavepoint_rollback_initially_empty_recreates_db(void) {48 sqlite3 *db = 0;49 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));50 TEST_ASSERT_NOT_NULL(db);51 52 Btree *p = getMainBtree(db);53 TEST_ASSERT_NOT_NULL(p);54 55 /* Begin write transaction */56 int rc = sqlite3BtreeBeginTrans(p, 1, 0);57 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);58 59 /* Call savepoint rollback of entire transaction; should be OK even if60 no explicit savepoints were opened. For an initially empty DB,61 it resets nPage to 0 then recreates the database (newDatabase). */62 BtShared *pBt = p->pBt;63 TEST_ASSERT_NOT_NULL(pBt);64 65 rc = sqlite3BtreeSavepoint(p, SAVEPOINT_ROLLBACK, -1);66 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);67 68 /* After the call, the database should exist and have at least page 1 */69 TEST_ASSERT_TRUE(pBt->nPage >= 1);70 71 /* Clean up transaction and close */72 rc = sqlite3BtreeCommit(p);73 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);74 75 rc = sqlite3_close(db);76 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);77}78 79/* Test: Open a statement savepoint and then release it via sqlite3BtreeSavepoint */80void test_sqlite3BtreeSavepoint_release_statement_savepoint(void) {81 sqlite3 *db = 0;82 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));83 TEST_ASSERT_NOT_NULL(db);84 85 Btree *p = getMainBtree(db);86 TEST_ASSERT_NOT_NULL(p);87 88 /* Begin write transaction */89 int rc = sqlite3BtreeBeginTrans(p, 1, 0);90 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);91 92 /* Open a statement-level savepoint with index 1 */93 rc = sqlite3BtreeBeginStmt(p, 1);94 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);95 96 /* Release the savepoint using sqlite3BtreeSavepoint */97 rc = sqlite3BtreeSavepoint(p, SAVEPOINT_RELEASE, 1);98 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);99 100 /* Also test rolling back a (non-existent) savepoint index 1 again should still be safe:101 The pager will handle it. This should remain SQLITE_OK. */102 rc = sqlite3BtreeSavepoint(p, SAVEPOINT_ROLLBACK, 1);103 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);104 105 /* Commit and close */106 rc = sqlite3BtreeCommit(p);107 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);108 109 rc = sqlite3_close(db);110 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);111}112 113int main(void) {114 UNITY_BEGIN();115 RUN_TEST(test_sqlite3BtreeSavepoint_null_ptr_returns_ok);116 RUN_TEST(test_sqlite3BtreeSavepoint_without_write_txn);117 RUN_TEST(test_sqlite3BtreeSavepoint_rollback_initially_empty_recreates_db);118 RUN_TEST(test_sqlite3BtreeSavepoint_release_statement_savepoint);119 return UNITY_END();120}