mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-07-07 20:45:01 +00:00
sqlite3: Add libsql_wal_frame_count() API
This commit is contained in:
parent
78eb901940
commit
524a523036
6 changed files with 160 additions and 0 deletions
|
@ -486,6 +486,10 @@ impl Connection {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn wal_frame_count(&self) -> Result<u64> {
|
||||||
|
self.pager.wal_frame_count()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cacheflush(&self) -> Result<CheckpointStatus> {
|
pub fn cacheflush(&self) -> Result<CheckpointStatus> {
|
||||||
self.pager.cacheflush()
|
self.pager.cacheflush()
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,6 +398,15 @@ impl Pager {
|
||||||
dirty_pages.insert(page_id);
|
dirty_pages.insert(page_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn wal_frame_count(&self) -> Result<u64> {
|
||||||
|
let mut frame_count = 0;
|
||||||
|
let wal = self.wal.clone();
|
||||||
|
if let Some(wal) = &wal {
|
||||||
|
frame_count = wal.borrow().get_max_frame_in_wal();
|
||||||
|
}
|
||||||
|
Ok(frame_count)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cacheflush(&self) -> Result<CheckpointStatus> {
|
pub fn cacheflush(&self) -> Result<CheckpointStatus> {
|
||||||
let mut checkpoint_result = CheckpointResult::default();
|
let mut checkpoint_result = CheckpointResult::default();
|
||||||
loop {
|
loop {
|
||||||
|
|
34
docs/manual.md
Normal file
34
docs/manual.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# Limbo Documentation
|
||||||
|
|
||||||
|
## SQLite C API
|
||||||
|
|
||||||
|
### WAL manipulation
|
||||||
|
|
||||||
|
#### `libsql_wal_frame_count`
|
||||||
|
|
||||||
|
Get the number of frames in the WAL.
|
||||||
|
|
||||||
|
**Synopsis:**
|
||||||
|
|
||||||
|
```c
|
||||||
|
int libsql_wal_frame_count(sqlite3 *db, uint32_t *p_frame_count);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Description:**
|
||||||
|
|
||||||
|
The `libsql_wal_frame_count` function returns the number of frames in the WAL
|
||||||
|
in the `p_frame_count` parameter.
|
||||||
|
|
||||||
|
**Return Values:**
|
||||||
|
|
||||||
|
* `SQLITE_OK` if the number of frames in the WAL file is successfully returned.
|
||||||
|
* `SQLITE_MISUSE` if the `db` is NULL.
|
||||||
|
* SQLITE_ERROR if an error occurs while getting the number of frames in the WAL
|
||||||
|
file.
|
||||||
|
|
||||||
|
**Safety Requirements:**
|
||||||
|
|
||||||
|
* The `db` parameter must be a valid pointer to a `sqlite3` database
|
||||||
|
connection.
|
||||||
|
* The `p_frame_count` must be a valid pointer to a `u32` that will store the
|
||||||
|
* number of frames in the WAL file.
|
|
@ -266,6 +266,28 @@ int sqlite3_wal_checkpoint(sqlite3 *_db, const char *_db_name);
|
||||||
|
|
||||||
int sqlite3_wal_checkpoint_v2(sqlite3 *db, const char *_db_name, int _mode, int *_log_size, int *_checkpoint_count);
|
int sqlite3_wal_checkpoint_v2(sqlite3 *db, const char *_db_name, int _mode, int *_log_size, int *_checkpoint_count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of frames in the WAL.
|
||||||
|
*
|
||||||
|
* The `libsql_wal_frame_count` function returns the number of frames
|
||||||
|
* in the WAL in the `p_frame_count` parameter.
|
||||||
|
*
|
||||||
|
* # Returns
|
||||||
|
*
|
||||||
|
* - `SQLITE_OK` if the number of frames in the WAL file is
|
||||||
|
* successfully returned.
|
||||||
|
* - `SQLITE_MISUSE` if the `db` is `NULL`.
|
||||||
|
* - `SQLITE_ERROR` if an error occurs while getting the number of frames
|
||||||
|
* in the WAL file.
|
||||||
|
*
|
||||||
|
* # Safety
|
||||||
|
*
|
||||||
|
* - The `db` must be a valid pointer to a `sqlite3` database connection.
|
||||||
|
* - The `p_frame_count` must be a valid pointer to a `u32` that will store
|
||||||
|
* the number of frames in the WAL file.
|
||||||
|
*/
|
||||||
|
int libsql_wal_frame_count(sqlite3 *db, uint32_t *p_frame_count);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
|
@ -1097,3 +1097,38 @@ pub unsafe extern "C" fn sqlite3_wal_checkpoint_v2(
|
||||||
}
|
}
|
||||||
SQLITE_OK
|
SQLITE_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the number of frames in the WAL.
|
||||||
|
///
|
||||||
|
/// The `libsql_wal_frame_count` function returns the number of frames
|
||||||
|
/// in the WAL in the `p_frame_count` parameter.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// - `SQLITE_OK` if the number of frames in the WAL file is
|
||||||
|
/// successfully returned.
|
||||||
|
/// - `SQLITE_MISUSE` if the `db` is `NULL`.
|
||||||
|
/// - `SQLITE_ERROR` if an error occurs while getting the number of frames
|
||||||
|
/// in the WAL file.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// - The `db` must be a valid pointer to a `sqlite3` database connection.
|
||||||
|
/// - The `p_frame_count` must be a valid pointer to a `u32` that will store
|
||||||
|
/// the number of frames in the WAL file.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn libsql_wal_frame_count(
|
||||||
|
db: *mut sqlite3,
|
||||||
|
p_frame_count: *mut u32,
|
||||||
|
) -> ffi::c_int {
|
||||||
|
if db.is_null() {
|
||||||
|
return SQLITE_MISUSE;
|
||||||
|
}
|
||||||
|
let db: &mut sqlite3 = &mut *db;
|
||||||
|
let frame_count = match db.conn.wal_frame_count() {
|
||||||
|
Ok(count) => count as u32,
|
||||||
|
Err(_) => return SQLITE_ERROR,
|
||||||
|
};
|
||||||
|
*p_frame_count = frame_count;
|
||||||
|
SQLITE_OK
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ extern "C" {
|
||||||
stmt: *mut *mut sqlite3_stmt,
|
stmt: *mut *mut sqlite3_stmt,
|
||||||
tail: *mut *const libc::c_char,
|
tail: *mut *const libc::c_char,
|
||||||
) -> i32;
|
) -> i32;
|
||||||
|
fn sqlite3_step(stmt: *mut sqlite3_stmt) -> i32;
|
||||||
fn sqlite3_finalize(stmt: *mut sqlite3_stmt) -> i32;
|
fn sqlite3_finalize(stmt: *mut sqlite3_stmt) -> i32;
|
||||||
fn sqlite3_wal_checkpoint(db: *mut sqlite3, db_name: *const libc::c_char) -> i32;
|
fn sqlite3_wal_checkpoint(db: *mut sqlite3, db_name: *const libc::c_char) -> i32;
|
||||||
fn sqlite3_wal_checkpoint_v2(
|
fn sqlite3_wal_checkpoint_v2(
|
||||||
|
@ -35,10 +37,13 @@ extern "C" {
|
||||||
log_size: *mut i32,
|
log_size: *mut i32,
|
||||||
checkpoint_count: *mut i32,
|
checkpoint_count: *mut i32,
|
||||||
) -> i32;
|
) -> i32;
|
||||||
|
fn libsql_wal_frame_count(db: *mut sqlite3, p_frame_count: *mut u32) -> i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SQLITE_OK: i32 = 0;
|
const SQLITE_OK: i32 = 0;
|
||||||
const SQLITE_CANTOPEN: i32 = 14;
|
const SQLITE_CANTOPEN: i32 = 14;
|
||||||
|
const SQLITE_DONE: i32 = 101;
|
||||||
|
|
||||||
const SQLITE_CHECKPOINT_PASSIVE: i32 = 0;
|
const SQLITE_CHECKPOINT_PASSIVE: i32 = 0;
|
||||||
const SQLITE_CHECKPOINT_FULL: i32 = 1;
|
const SQLITE_CHECKPOINT_FULL: i32 = 1;
|
||||||
const SQLITE_CHECKPOINT_RESTART: i32 = 2;
|
const SQLITE_CHECKPOINT_RESTART: i32 = 2;
|
||||||
|
@ -195,4 +200,55 @@ mod tests {
|
||||||
assert_eq!(sqlite3_close(db), SQLITE_OK);
|
assert_eq!(sqlite3_close(db), SQLITE_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "sqlite3"))]
|
||||||
|
mod libsql_ext {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wal_frame_count() {
|
||||||
|
unsafe {
|
||||||
|
let mut db = ptr::null_mut();
|
||||||
|
assert_eq!(
|
||||||
|
sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db),
|
||||||
|
SQLITE_OK
|
||||||
|
);
|
||||||
|
// Ensure that WAL is initially empty.
|
||||||
|
let mut frame_count = 0;
|
||||||
|
assert_eq!(libsql_wal_frame_count(db, &mut frame_count), SQLITE_OK);
|
||||||
|
assert_eq!(frame_count, 0);
|
||||||
|
// Create a table and insert a row.
|
||||||
|
let mut stmt = ptr::null_mut();
|
||||||
|
assert_eq!(
|
||||||
|
sqlite3_prepare_v2(
|
||||||
|
db,
|
||||||
|
b"CREATE TABLE test (id INTEGER PRIMARY KEY)\0".as_ptr() as *const i8,
|
||||||
|
-1,
|
||||||
|
&mut stmt,
|
||||||
|
ptr::null_mut()
|
||||||
|
),
|
||||||
|
SQLITE_OK
|
||||||
|
);
|
||||||
|
assert_eq!(sqlite3_step(stmt), SQLITE_DONE);
|
||||||
|
assert_eq!(sqlite3_finalize(stmt), SQLITE_OK);
|
||||||
|
let mut stmt = ptr::null_mut();
|
||||||
|
assert_eq!(
|
||||||
|
sqlite3_prepare_v2(
|
||||||
|
db,
|
||||||
|
b"INSERT INTO test (id) VALUES (1)\0".as_ptr() as *const i8,
|
||||||
|
-1,
|
||||||
|
&mut stmt,
|
||||||
|
ptr::null_mut()
|
||||||
|
),
|
||||||
|
SQLITE_OK
|
||||||
|
);
|
||||||
|
assert_eq!(sqlite3_step(stmt), SQLITE_DONE);
|
||||||
|
assert_eq!(sqlite3_finalize(stmt), SQLITE_OK);
|
||||||
|
// Check that WAL has three frames.
|
||||||
|
assert_eq!(libsql_wal_frame_count(db, &mut frame_count), SQLITE_OK);
|
||||||
|
assert_eq!(frame_count, 3);
|
||||||
|
assert_eq!(sqlite3_close(db), SQLITE_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue