usesuper::ffi; usesuper::StatementStatus; usecrate::util::ParamIndexCache; usecrate::util::SqliteMallocString; use std::ffi::CStr; use std::os::raw::c_int; use std::ptr; use std::sync::Arc;
// Private newtype for raw sqlite3_stmts that finalize themselves when dropped. #[derive(Debug)] pubstruct RawStatement {
ptr: *mut ffi::sqlite3_stmt,
tail: usize, // Cached indices of named parameters, computed on the fly.
cache: ParamIndexCache, // Cached SQL (trimmed) that we use as the key when we're in the statement // cache. This is None for statements which didn't come from the statement // cache. // // This is probably the same as `self.sql()` in most cases, but we don't // care either way -- It's a better cache key as it is anyway since it's the // actual source we got from rust. // // One example of a case where the result of `sqlite_sql` and the value in // `statement_cache_key` might differ is if the statement has a `tail`.
statement_cache_key: Option<Arc<str>>,
}
#[inline] pubfn column_count(&self) -> usize { // Note: Can't cache this as it changes if the schema is altered. unsafe { ffi::sqlite3_column_count(self.ptr) as usize }
}
#[inline] pubfn column_name(&self, idx: usize) -> Option<&CStr> { let idx = idx as c_int; if idx < 0 || idx >= self.column_count() as c_int { return None;
} unsafe { let ptr = ffi::sqlite3_column_name(self.ptr, idx); // If ptr is null here, it's an OOM, so there's probably nothing // meaningful we can do. Just assert instead of returning None.
assert!(
!ptr.is_null(), "Null pointer from sqlite3_column_name: Out of memory?"
);
Some(CStr::from_ptr(ptr))
}
}
#[cfg(feature = "unlock_notify")] pubfn step(&self) -> c_int { usecrate::unlock_notify; letmut db = ptr::null_mut::<ffi::sqlite3>(); loop { unsafe { letmut rc = ffi::sqlite3_step(self.ptr); // Bail out early for success and errors unrelated to locking. We // still need check `is_locked` after this, but checking now lets us // avoid one or two (admittedly cheap) calls into SQLite that we // don't need to make. if (rc & 0xff) != ffi::SQLITE_LOCKED { break rc;
} if db.is_null() {
db = ffi::sqlite3_db_handle(self.ptr);
} if !unlock_notify::is_locked(db, rc) { break rc;
}
rc = unlock_notify::wait_for_unlock_notify(db); if rc != ffi::SQLITE_OK { break rc;
} self.reset();
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.