-
Notifications
You must be signed in to change notification settings - Fork 470
Expand file tree
/
Copy pathvtab.rs
More file actions
108 lines (90 loc) · 2.84 KB
/
vtab.rs
File metadata and controls
108 lines (90 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! Ensure Virtual tables can be declared outside `rusqlite` crate.
#[cfg(all(feature = "vtab", target_family = "wasm", target_os = "unknown"))]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[cfg(feature = "vtab")]
#[test]
fn test_dummy_module() -> rusqlite::Result<()> {
use rusqlite::vtab::{
sqlite3_vtab, sqlite3_vtab_cursor, Context, Filters, IndexInfo, Module, VTab,
VTabConnection, VTabCursor,
};
use rusqlite::{version_number, Connection, Result};
use std::borrow::Cow;
use std::ffi::CStr;
use std::marker::PhantomData;
use std::os::raw::c_int;
const MODULE: Module<DummyTab> = Module::eponymous_only_module();
#[repr(C)]
struct DummyTab {
/// Base class. Must be first
base: sqlite3_vtab,
}
unsafe impl<'vtab> VTab<'vtab> for DummyTab {
type Aux = ();
type Cursor = DummyTabCursor<'vtab>;
fn connect(
_: &mut VTabConnection,
aux: Option<&()>,
_module_name: &[u8],
_database_name: &[u8],
_table_name: &[u8],
_args: &[&[u8]],
) -> Result<(Cow<'static, CStr>, Self)> {
debug_assert_eq!(aux, None);
let vtab = Self {
base: sqlite3_vtab::default(),
};
Ok((Cow::Borrowed(c"CREATE TABLE x(value)"), vtab))
}
fn best_index(&self, info: &mut IndexInfo) -> Result<bool> {
info.set_estimated_cost(1.);
Ok(true)
}
fn open(&'vtab mut self) -> Result<DummyTabCursor<'vtab>> {
Ok(DummyTabCursor::default())
}
}
#[derive(Default)]
#[repr(C)]
struct DummyTabCursor<'vtab> {
/// Base class. Must be first
base: sqlite3_vtab_cursor,
/// The rowid
row_id: i64,
phantom: PhantomData<&'vtab DummyTab>,
}
unsafe impl VTabCursor for DummyTabCursor<'_> {
fn filter(
&mut self,
_idx_num: c_int,
_idx_str: Option<&str>,
_args: &Filters<'_>,
) -> Result<()> {
self.row_id = 1;
Ok(())
}
fn next(&mut self) -> Result<()> {
self.row_id += 1;
Ok(())
}
fn eof(&self) -> bool {
self.row_id > 1
}
fn column(&self, ctx: &mut Context, _: c_int) -> Result<()> {
ctx.set_result(&self.row_id)
}
fn rowid(&self) -> Result<i64> {
Ok(self.row_id)
}
}
let db = Connection::open_in_memory()?;
db.create_module::<DummyTab, _>(c"dummy", &MODULE, None)?;
let version = version_number();
if version < 3_009_000 {
return Ok(());
}
let mut s = db.prepare("SELECT * FROM dummy()")?;
let dummy = s.query_row([], |row| row.get::<_, i32>(0))?;
assert_eq!(1, dummy);
Ok(())
}