From 5aa99f674330b395cd168a2f3c7e8e4ea830eba1 Mon Sep 17 00:00:00 2001 From: Lucas Forato Date: Mon, 4 Aug 2025 08:30:06 -0300 Subject: [PATCH] feat: listing all modules --- core/lib.rs | 14 ++++++++++++++ core/pragma.rs | 5 +++++ core/translate/pragma.rs | 12 ++++++++++++ core/vtab.rs | 8 ++++++++ 4 files changed, 39 insertions(+) diff --git a/core/lib.rs b/core/lib.rs index 85321fbe0..eb74d975f 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -62,6 +62,7 @@ pub use io::{ }; use parking_lot::RwLock; use schema::Schema; +use std::ffi::CStr; use std::{ borrow::Cow, cell::{Cell, RefCell, UnsafeCell}, @@ -1838,6 +1839,19 @@ impl Connection { pub fn get_pager(&self) -> Rc { self.pager.borrow().clone() + pub fn get_used_vtab_mods(&self) -> std::collections::HashSet { + let mut mods = std::collections::HashSet::new(); + + let schema = self._db.schema.lock().unwrap(); + for table in schema.tables.values() { + if let Table::Virtual(vtab) = table.as_ref() { + if let Some(module_name) = vtab.module_name() { + mods.insert(module_name.to_string()); + } + } + } + + mods } pub fn get_query_only(&self) -> bool { diff --git a/core/pragma.rs b/core/pragma.rs index 6ca573ace..152745eac 100644 --- a/core/pragma.rs +++ b/core/pragma.rs @@ -58,6 +58,11 @@ pub fn pragma_for(pragma: &PragmaName) -> Pragma { LegacyFileFormat => { unreachable!("pragma_for() called with LegacyFileFormat, which is unsupported") } + ModuleList => Pragma::new( + // TODO:: change the flags below + PragmaFlags::NeedSchema | PragmaFlags::Result0 | PragmaFlags::SchemaReq, + &["module_list"], + ), PageCount => Pragma::new( PragmaFlags::NeedSchema | PragmaFlags::Result0 | PragmaFlags::SchemaReq, &["page_count"], diff --git a/core/translate/pragma.rs b/core/translate/pragma.rs index 935bb5b7e..0713dd1e1 100644 --- a/core/translate/pragma.rs +++ b/core/translate/pragma.rs @@ -146,6 +146,7 @@ fn update_pragma( connection, program, ), + PragmaName::ModuleList => Ok((program, TransactionMode::None)), PragmaName::PageCount => query_pragma( PragmaName::PageCount, schema, @@ -399,6 +400,17 @@ fn query_pragma( program.emit_result_row(register, 3); Ok((program, TransactionMode::None)) } + PragmaName::ModuleList => { + let modules = connection.get_used_vtab_mods(); + + for module in modules { + program.emit_string8(module.to_string(), register); + program.emit_result_row(register, 1); + } + + program.add_pragma_result_column(pragma.to_string()); + Ok((program, TransactionMode::None)) + } PragmaName::PageCount => { program.emit_insn(Insn::PageCount { db: 0, diff --git a/core/vtab.rs b/core/vtab.rs index 686158e57..9e1a7e3a0 100644 --- a/core/vtab.rs +++ b/core/vtab.rs @@ -22,10 +22,15 @@ pub struct VirtualTable { pub(crate) name: String, pub(crate) columns: Vec, pub(crate) kind: VTabKind, + pub(crate) module_name: Option, vtab_type: VirtualTableType, } impl VirtualTable { + pub fn module_name(&self) -> Option<&str> { + self.module_name.as_deref() + } + pub(crate) fn readonly(self: &Arc) -> bool { match &self.vtab_type { VirtualTableType::Pragma(_) => true, @@ -43,6 +48,7 @@ impl VirtualTable { columns: Self::resolve_columns(schema) .expect("built-in function schema resolution should not fail"), kind: VTabKind::TableValuedFunction, + module_name: Some("pragma".to_string()), vtab_type: VirtualTableType::Pragma(tab), }; Arc::new(vtab) @@ -65,6 +71,7 @@ impl VirtualTable { name: name.to_owned(), columns: Self::resolve_columns(schema)?, kind: VTabKind::TableValuedFunction, + module_name: Some(name.to_string()), vtab_type, }; Ok(Arc::new(vtab)) @@ -83,6 +90,7 @@ impl VirtualTable { name: tbl_name.unwrap_or(module_name).to_owned(), columns: Self::resolve_columns(schema)?, kind: VTabKind::VirtualTable, + module_name: Some(module_name.to_string()), vtab_type: VirtualTableType::External(table), }; Ok(Arc::new(vtab))