Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_prepare_sqlite3Prepare.c172 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* External wrapper provided in the source under test */7extern int test_sqlite3Prepare(sqlite3 *db, const char *zSql, int nBytes,8                               u32 prepFlags, Vdbe *pReprepare,9                               sqlite3_stmt **ppStmt, const char **pzTail);10 11/* Helper to call the internal prepare with required locks held */12static int call_prepare(sqlite3 *db, const char *zSql, int nBytes, u32 prepFlags,13                        Vdbe *pReprepare, sqlite3_stmt **ppStmt, const char **pzTail){14  int rc;15  sqlite3_mutex_enter(db->mutex);16  sqlite3BtreeEnterAll(db);17  rc = test_sqlite3Prepare(db, zSql, nBytes, prepFlags, pReprepare, ppStmt, pzTail);18  sqlite3BtreeLeaveAll(db);19  sqlite3_mutex_leave(db->mutex);20  return rc;21}22 23static sqlite3 *gDb = NULL;24 25void setUp(void) {26  int rc = sqlite3_open(":memory:", &gDb);27  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory SQLite DB");28}29 30void tearDown(void) {31  if( gDb ){32    int rc = sqlite3_close(gDb);33    TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to close SQLite DB");34    gDb = NULL;35  }36}37 38/* Utility to finalize and null-out a statement pointer if non-NULL */39static void finalize_if(sqlite3_stmt **ppStmt){40  if( ppStmt && *ppStmt ){41    sqlite3_finalize(*ppStmt);42    *ppStmt = NULL;43  }44}45 46void test_sqlite3Prepare_basic_ok(void) {47  const char *sql = "SELECT 1;";48  sqlite3_stmt *pStmt = NULL;49  const char *zTail = NULL;50 51  int rc = call_prepare(gDb, sql, -1, 0, NULL, &pStmt, &zTail);52  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);53  TEST_ASSERT_NOT_NULL(pStmt);54  TEST_ASSERT_NOT_NULL(zTail);55  TEST_ASSERT_EQUAL_CHAR('\0', *zTail);56 57  finalize_if(&pStmt);58}59 60void test_sqlite3Prepare_tail_for_next_stmt(void) {61  const char *sql = "SELECT 1;SELECT 2;";62  sqlite3_stmt *pStmt = NULL;63  const char *zTail = NULL;64 65  int rc = call_prepare(gDb, sql, -1, 0, NULL, &pStmt, &zTail);66  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);67  TEST_ASSERT_NOT_NULL(pStmt);68  TEST_ASSERT_NOT_NULL(zTail);69  /* Expect tail to point at the start of the second statement */70  TEST_ASSERT_EQUAL_INT(0, strncmp(zTail, "SELECT 2;", 9));71 72  finalize_if(&pStmt);73}74 75void test_sqlite3Prepare_with_nBytes_substring(void) {76  /* Provide extra bytes after the first statement and specify nBytes to end at ';' */77  char sql[] = "SELECT 1;XYZ";78  int nBytes = (int)strlen("SELECT 1;"); /* Truncate before the 'X' */79  sqlite3_stmt *pStmt = NULL;80  const char *zTail = NULL;81 82  int rc = call_prepare(gDb, sql, nBytes, 0, NULL, &pStmt, &zTail);83  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);84  TEST_ASSERT_NOT_NULL(pStmt);85  TEST_ASSERT_NOT_NULL(zTail);86  /* Tail should map back into the original buffer at offset nBytes */87  TEST_ASSERT_EQUAL_PTR(sql + nBytes, zTail);88  TEST_ASSERT_EQUAL_CHAR('X', *zTail);89 90  finalize_if(&pStmt);91}92 93void test_sqlite3Prepare_invalid_sql_returns_error(void) {94  const char *sql = "SELEC 1;"; /* Intentionally invalid (missing 'T') */95  sqlite3_stmt *pStmt = NULL;96  const char *zTail = NULL;97 98  int rc = call_prepare(gDb, sql, -1, 0, NULL, &pStmt, &zTail);99  TEST_ASSERT_NOT_EQUAL(SQLITE_OK, rc);100  TEST_ASSERT_NULL(pStmt);101  /* zTail may be set by the parser; not asserting a specific value here */102}103 104void test_sqlite3Prepare_empty_sql_ok_no_stmt(void) {105  const char *sql = "   \n\t";106  sqlite3_stmt *pStmt = NULL;107  const char *zTail = NULL;108 109  int rc = call_prepare(gDb, sql, -1, 0, NULL, &pStmt, &zTail);110  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);111  TEST_ASSERT_NULL(pStmt);112  TEST_ASSERT_NOT_NULL(zTail);113  TEST_ASSERT_EQUAL_CHAR('\0', *zTail);114}115 116void test_sqlite3Prepare_persistent_flag_ok(void) {117  const char *sql = "SELECT 1;";118  sqlite3_stmt *pStmt = NULL;119  const char *zTail = NULL;120 121  int rc = call_prepare(gDb, sql, -1, SQLITE_PREPARE_PERSISTENT, NULL, &pStmt, &zTail);122  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);123  TEST_ASSERT_NOT_NULL(pStmt);124  TEST_ASSERT_NOT_NULL(zTail);125  TEST_ASSERT_EQUAL_CHAR('\0', *zTail);126 127  finalize_if(&pStmt);128}129 130void test_sqlite3Prepare_with_reprepare_handle(void) {131  /* Prepare a statement using the public API, then pass it as pReprepare */132  const char *sql = "SELECT 1;";133  sqlite3_stmt *pExisting = NULL;134  int rc = sqlite3_prepare_v2(gDb, sql, -1, &pExisting, NULL);135  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);136  TEST_ASSERT_NOT_NULL(pExisting);137 138  sqlite3_stmt *pNew = NULL;139  const char *zTail = NULL;140  rc = call_prepare(gDb, sql, -1, 0, (Vdbe*)pExisting, &pNew, &zTail);141  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);142  TEST_ASSERT_NOT_NULL(pNew);143  TEST_ASSERT_NOT_NULL(zTail);144  TEST_ASSERT_EQUAL_CHAR('\0', *zTail);145 146  finalize_if(&pExisting);147  finalize_if(&pNew);148}149 150void test_sqlite3Prepare_null_tail_parameter(void) {151  const char *sql = "SELECT 42;";152  sqlite3_stmt *pStmt = NULL;153 154  int rc = call_prepare(gDb, sql, -1, 0, NULL, &pStmt, NULL);155  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);156  TEST_ASSERT_NOT_NULL(pStmt);157 158  finalize_if(&pStmt);159}160 161int main(void) {162  UNITY_BEGIN();163  RUN_TEST(test_sqlite3Prepare_basic_ok);164  RUN_TEST(test_sqlite3Prepare_tail_for_next_stmt);165  RUN_TEST(test_sqlite3Prepare_with_nBytes_substring);166  RUN_TEST(test_sqlite3Prepare_invalid_sql_returns_error);167  RUN_TEST(test_sqlite3Prepare_empty_sql_ok_no_stmt);168  RUN_TEST(test_sqlite3Prepare_persistent_flag_ok);169  RUN_TEST(test_sqlite3Prepare_with_reprepare_handle);170  RUN_TEST(test_sqlite3Prepare_null_tail_parameter);171  return UNITY_END();172}