Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_btree_sqlite3BtreeClearTable.c237 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <string.h>5#include <stdlib.h>6 7static sqlite3 *gDb = NULL;8static Btree *gBtree = NULL;9 10static int open_memory_db(void){11  int rc = sqlite3_open(":memory:", &gDb);12  if( rc!=SQLITE_OK ) return rc;13  /* Main DB handle's Btree is in aDb[0] */14  gBtree = gDb->aDb[0].pBt;15  return SQLITE_OK;16}17 18static void close_db(void){19  if( gDb ){20    sqlite3_close(gDb);21    gDb = NULL;22    gBtree = NULL;23  }24}25 26/* Create a new intkey table and return its root page number */27static int create_intkey_table(Pgno *pRoot){28  int rc;29  TEST_ASSERT_NOT_NULL(gBtree);30  rc = sqlite3BtreeBeginTrans(gBtree, 1, 0);31  if( rc!=SQLITE_OK ) return rc;32  rc = sqlite3BtreeCreateTable(gBtree, pRoot, BTREE_INTKEY | BTREE_LEAFDATA);33  return rc;34}35 36static int open_cursor(Pgno root, int wr, BtCursor **ppCur){37  int rc;38  int n = sqlite3BtreeCursorSize();39  BtCursor *pCur = (BtCursor*)sqlite3_malloc(n);40  TEST_ASSERT_NOT_NULL_MESSAGE(pCur, "malloc cursor failed");41  sqlite3BtreeCursorZero(pCur);42  rc = sqlite3BtreeCursor(gBtree, root, wr?BTREE_WRCSR:0, NULL, pCur);43  if( rc!=SQLITE_OK ){44    sqlite3_free(pCur);45    return rc;46  }47  *ppCur = pCur;48  return SQLITE_OK;49}50 51static void close_cursor(BtCursor *pCur){52  if( pCur ){53    sqlite3BtreeCloseCursor(pCur);54    sqlite3_free(pCur);55  }56}57 58/* Insert n rows with rowids 1..n and small payload */59static int insert_rows(Pgno root, int nrow){60  int rc;61  BtCursor *pCur = NULL;62  rc = open_cursor(root, 1, &pCur);63  if( rc!=SQLITE_OK ) return rc;64 65  for(int i=1;i<=nrow;i++){66    const char payload[] = "x";67    BtreePayload x;68    memset(&x, 0, sizeof(x));69    x.pKey = NULL;70    x.nKey = (i64)i;71    x.pData = payload;72    x.nData = (int)sizeof(payload)-1;73    x.nZero = 0;74    rc = sqlite3BtreeInsert(pCur, &x, 0, 0);75    if( rc!=SQLITE_OK ){76      close_cursor(pCur);77      return rc;78    }79  }80  close_cursor(pCur);81  return SQLITE_OK;82}83 84/* Count rows by scanning the Btree */85static int count_rows(Pgno root, int *pCount){86  int rc;87  BtCursor *pCur = NULL;88  int cnt = 0;89  int res = 0;90 91  rc = open_cursor(root, 0, &pCur);92  if( rc!=SQLITE_OK ) return rc;93 94  rc = sqlite3BtreeFirst(pCur, &res);95  if( rc!=SQLITE_OK ){96    close_cursor(pCur);97    return rc;98  }99  if( res==0 ){100    /* valid at first row */101    cnt++;102    while( (rc = sqlite3BtreeNext(pCur, 0))==SQLITE_OK ){103      cnt++;104    }105    if( rc==SQLITE_DONE ) rc = SQLITE_OK;106  }107  close_cursor(pCur);108  *pCount = cnt;109  return rc;110}111 112void setUp(void){113  int rc = open_memory_db();114  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory db");115}116 117void tearDown(void){118  close_db();119}120 121void test_sqlite3BtreeClearTable_counts_and_empties(void){122  int rc;123  Pgno root = 0;124  i64 nChanged = -1;125  int cnt = -1;126 127  rc = create_intkey_table(&root);128  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);129  TEST_ASSERT_TRUE(root>1);130 131  rc = insert_rows(root, 10);132  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);133 134  /* Sanity check inserted rows */135  rc = count_rows(root, &cnt);136  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);137  TEST_ASSERT_EQUAL_INT(10, cnt);138 139  /* Clear the table */140  rc = sqlite3BtreeClearTable(gBtree, (int)root, &nChanged);141  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);142  TEST_ASSERT_EQUAL_INT64(10, nChanged);143 144  /* Verify table is empty using a Btree cursor */145  BtCursor *pCur = NULL;146  int res = -1;147  rc = open_cursor(root, 0, &pCur);148  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);149  rc = sqlite3BtreeFirst(pCur, &res);150  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);151  TEST_ASSERT_EQUAL_INT_MESSAGE(1, res, "Table should be empty after clear");152  close_cursor(pCur);153 154  /* Optional: commit the transaction cleanly */155  rc = sqlite3BtreeCommit(gBtree);156  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);157}158 159void test_sqlite3BtreeClearTable_empty_table(void){160  int rc;161  Pgno root = 0;162  i64 nChanged = -1;163 164  rc = create_intkey_table(&root);165  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);166 167  /* Verify empty */168  int cnt = 123;169  rc = count_rows(root, &cnt);170  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);171  TEST_ASSERT_EQUAL_INT(0, cnt);172 173  rc = sqlite3BtreeClearTable(gBtree, (int)root, &nChanged);174  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);175  TEST_ASSERT_EQUAL_INT64(0, nChanged);176 177  /* Still empty */178  int res = -1;179  BtCursor *pCur = NULL;180  rc = open_cursor(root, 0, &pCur);181  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);182  rc = sqlite3BtreeFirst(pCur, &res);183  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);184  TEST_ASSERT_EQUAL_INT(1, res);185  close_cursor(pCur);186 187  rc = sqlite3BtreeCommit(gBtree);188  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);189}190 191void test_sqlite3BtreeClearTable_incrblob_invalidation(void){192  int rc;193  Pgno root = 0;194  i64 nChanged = -1;195 196  rc = create_intkey_table(&root);197  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);198  rc = insert_rows(root, 1);199  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);200 201  /* Open a cursor positioned at rowid=1 and mark as incrblob */202  BtCursor *pCur = NULL;203  rc = open_cursor(root, 0, &pCur);204  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);205  int res = 0;206  /* Seek to rowid=1 */207  rc = sqlite3BtreeTableMoveto(pCur, 1, 0, &res);208  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);209  /* res==0 should indicate exact match (found) */210  TEST_ASSERT_EQUAL_INT(0, res);211  TEST_ASSERT_EQUAL_INT(CURSOR_VALID, pCur->eState);212 213  sqlite3BtreeIncrblobCursor(pCur);214  TEST_ASSERT_TRUE( (pCur->curFlags & BTCF_Incrblob)!=0 );215 216  /* Clear the whole table; should invalidate incrblob cursor(s) */217  rc = sqlite3BtreeClearTable(gBtree, (int)root, &nChanged);218  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);219  TEST_ASSERT_EQUAL_INT64(1, nChanged);220 221  /* Cursor should be invalid now */222  TEST_ASSERT_EQUAL_INT(CURSOR_INVALID, pCur->eState);223  close_cursor(pCur);224 225  rc = sqlite3BtreeCommit(gBtree);226  TEST_ASSERT_EQUAL_INT(rc, SQLITE_OK);227}228 229int main(void){230  UNITY_BEGIN();231 232  RUN_TEST(test_sqlite3BtreeClearTable_counts_and_empties);233  RUN_TEST(test_sqlite3BtreeClearTable_empty_table);234  RUN_TEST(test_sqlite3BtreeClearTable_incrblob_invalidation);235 236  return UNITY_END();237}