mirror of
https://github.com/isar/rusqlite.git
synced 2025-03-25 23:06:04 +08:00
Use C string literal for database name
No alloc for "main" and "temp". No alloc possible when the attached database name is known at compile time / a C string literal can be usd. No alloc when the database name is given by SQLite (`sqlite3_wal_hook`).
This commit is contained in:
parent
0af8bfc603
commit
3d85c79891
@ -207,8 +207,8 @@ impl Backup<'_, '_> {
|
||||
to: &'b mut Connection,
|
||||
to_name: DatabaseName<'_>,
|
||||
) -> Result<Backup<'a, 'b>> {
|
||||
let to_name = to_name.as_cstring()?;
|
||||
let from_name = from_name.as_cstring()?;
|
||||
let to_name = to_name.as_cstr()?;
|
||||
let from_name = from_name.as_cstr()?;
|
||||
|
||||
let to_db = to.db.borrow_mut().db;
|
||||
|
||||
|
@ -346,7 +346,7 @@ impl InnerConnection {
|
||||
fn remove_preupdate_hook(&mut self) {}
|
||||
|
||||
pub fn db_readonly(&self, db_name: super::DatabaseName<'_>) -> Result<bool> {
|
||||
let name = db_name.as_cstring()?;
|
||||
let name = db_name.as_cstr()?;
|
||||
let r = unsafe { ffi::sqlite3_db_readonly(self.db, name.as_ptr()) };
|
||||
match r {
|
||||
0 => Ok(false),
|
||||
@ -368,7 +368,7 @@ impl InnerConnection {
|
||||
db_name: Option<super::DatabaseName<'_>>,
|
||||
) -> Result<super::transaction::TransactionState> {
|
||||
let r = if let Some(ref name) = db_name {
|
||||
let name = name.as_cstring()?;
|
||||
let name = name.as_cstr()?;
|
||||
unsafe { ffi::sqlite3_txn_state(self.db, name.as_ptr()) }
|
||||
} else {
|
||||
unsafe { ffi::sqlite3_txn_state(self.db, ptr::null()) }
|
||||
|
30
src/lib.rs
30
src/lib.rs
@ -347,12 +347,12 @@ fn path_to_cstring(p: &Path) -> Result<CString> {
|
||||
pub enum DatabaseName<'a> {
|
||||
/// The main database.
|
||||
Main,
|
||||
|
||||
/// The temporary database (e.g., any "CREATE TEMPORARY TABLE" tables).
|
||||
Temp,
|
||||
|
||||
/// A database that has been attached via "ATTACH DATABASE ...".
|
||||
Attached(&'a str),
|
||||
/// Optim
|
||||
C(&'a CStr),
|
||||
}
|
||||
|
||||
/// Shorthand for [`DatabaseName::Main`].
|
||||
@ -361,16 +361,24 @@ pub const MAIN_DB: DatabaseName<'static> = DatabaseName::Main;
|
||||
/// Shorthand for [`DatabaseName::Temp`].
|
||||
pub const TEMP_DB: DatabaseName<'static> = DatabaseName::Temp;
|
||||
|
||||
// Currently DatabaseName is only used by the backup and blob mods, so hide
|
||||
// this (private) impl to avoid dead code warnings.
|
||||
impl DatabaseName<'_> {
|
||||
#[inline]
|
||||
fn as_cstring(&self) -> Result<SmallCString> {
|
||||
use self::DatabaseName::{Attached, Main, Temp};
|
||||
match *self {
|
||||
Main => str_to_cstring("main"), // TODO C-string literals
|
||||
Temp => str_to_cstring("temp"),
|
||||
Attached(s) => str_to_cstring(s),
|
||||
fn as_cstr(&self) -> Result<std::borrow::Cow<'_, CStr>> {
|
||||
Ok(match *self {
|
||||
DatabaseName::Main => std::borrow::Cow::Borrowed(c"main"),
|
||||
DatabaseName::Temp => std::borrow::Cow::Borrowed(c"temp"),
|
||||
DatabaseName::Attached(s) => std::borrow::Cow::Owned(CString::new(s)?),
|
||||
DatabaseName::C(s) => std::borrow::Cow::Borrowed(s),
|
||||
})
|
||||
}
|
||||
#[cfg(feature = "hooks")]
|
||||
pub(crate) fn from_cstr(cs: &std::ffi::CStr) -> DatabaseName<'_> {
|
||||
if cs == c"main" {
|
||||
DatabaseName::Main
|
||||
} else if cs == c"temp" {
|
||||
DatabaseName::Temp
|
||||
} else {
|
||||
DatabaseName::C(cs)
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "hooks")]
|
||||
@ -647,7 +655,7 @@ impl Connection {
|
||||
pub fn path(&self) -> Option<&str> {
|
||||
unsafe {
|
||||
let db = self.handle();
|
||||
let db_name = DatabaseName::Main.as_cstring().unwrap();
|
||||
let db_name = DatabaseName::Main.as_cstr().unwrap();
|
||||
let db_filename = ffi::sqlite3_db_filename(db, db_name.as_ptr());
|
||||
if db_filename.is_null() {
|
||||
None
|
||||
|
@ -47,6 +47,7 @@ impl Sql {
|
||||
DatabaseName::Main => self.buf.push_str("main"),
|
||||
DatabaseName::Temp => self.buf.push_str("temp"),
|
||||
DatabaseName::Attached(s) => self.push_identifier(s),
|
||||
DatabaseName::C(s) => self.push_identifier(s.to_str().expect("invalid database name")),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ impl Deref for Data<'_> {
|
||||
impl Connection {
|
||||
/// Serialize a database.
|
||||
pub fn serialize(&self, schema: DatabaseName) -> Result<Data> {
|
||||
let schema = schema.as_cstring()?;
|
||||
let schema = schema.as_cstr()?;
|
||||
let mut sz = 0;
|
||||
let mut ptr: *mut u8 = unsafe {
|
||||
ffi::sqlite3_serialize(
|
||||
@ -102,7 +102,7 @@ impl Connection {
|
||||
data: OwnedData,
|
||||
read_only: bool,
|
||||
) -> Result<()> {
|
||||
let schema = schema.as_cstring()?;
|
||||
let schema = schema.as_cstr()?;
|
||||
let (data, sz) = data.into_raw();
|
||||
let sz = sz.try_into().unwrap();
|
||||
let flags = if read_only {
|
||||
|
@ -42,7 +42,7 @@ impl Session<'_> {
|
||||
db: &'conn Connection,
|
||||
name: DatabaseName<'_>,
|
||||
) -> Result<Session<'conn>> {
|
||||
let name = name.as_cstring()?;
|
||||
let name = name.as_cstr()?;
|
||||
|
||||
let db = db.db.borrow_mut().db;
|
||||
|
||||
@ -154,7 +154,7 @@ impl Session<'_> {
|
||||
|
||||
/// Load the difference between tables.
|
||||
pub fn diff(&mut self, from: DatabaseName<'_>, table: &str) -> Result<()> {
|
||||
let from = from.as_cstring()?;
|
||||
let from = from.as_cstr()?;
|
||||
let table = str_to_cstring(table)?;
|
||||
let table = table.as_ptr();
|
||||
unsafe {
|
||||
|
Loading…
x
Reference in New Issue
Block a user