mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
Make dc_get_info() work on a closed context
There is very little API guarantees about this, but clients seem to expect *something* to work on a closed context. So split this up into static info an more dynamic context-related info, but let's not provide any guarantees about what keys are available when. Fixes #599
This commit is contained in:
committed by
Floris Bruynooghe
parent
2b46f01fe3
commit
69f1497986
@@ -405,9 +405,14 @@ char* dc_get_config (dc_context_t* context, const char*
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get information about the context.
|
* Get information about the context.
|
||||||
|
*
|
||||||
* The information is returned by a multi-line string
|
* The information is returned by a multi-line string
|
||||||
* and contains information about the current configuration.
|
* and contains information about the current configuration.
|
||||||
*
|
*
|
||||||
|
* If the context is not open or configured only a subset of the information
|
||||||
|
* will be available. There is no guarantee about which information will be
|
||||||
|
* included when however.
|
||||||
|
*
|
||||||
* @memberof dc_context_t
|
* @memberof dc_context_t
|
||||||
* @param context The context as created by dc_context_new().
|
* @param context The context as created by dc_context_new().
|
||||||
* @return String which must be free()'d after usage. Never returns NULL.
|
* @return String which must be free()'d after usage. Never returns NULL.
|
||||||
|
|||||||
@@ -347,9 +347,12 @@ pub unsafe extern "C" fn dc_get_info(context: *mut dc_context_t) -> *mut libc::c
|
|||||||
return dc_strdup(ptr::null());
|
return dc_strdup(ptr::null());
|
||||||
}
|
}
|
||||||
let ffi_context = &*context;
|
let ffi_context = &*context;
|
||||||
ffi_context
|
let guard = ffi_context.inner.read().unwrap();
|
||||||
.with_inner(|ctx| render_info(ctx.get_info()).unwrap_or_default().strdup())
|
let info = match guard.as_ref() {
|
||||||
.unwrap_or_else(|_| "".strdup())
|
Some(ref ctx) => ctx.get_info(),
|
||||||
|
None => context::get_info(),
|
||||||
|
};
|
||||||
|
render_info(info).unwrap_or_default().strdup()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_info(
|
fn render_info(
|
||||||
|
|||||||
@@ -108,3 +108,25 @@ def test_provider_info():
|
|||||||
|
|
||||||
def test_provider_info_none():
|
def test_provider_info_none():
|
||||||
assert lib.dc_provider_new_from_email(cutil.as_dc_charpointer("email@unexistent.no")) == ffi.NULL
|
assert lib.dc_provider_new_from_email(cutil.as_dc_charpointer("email@unexistent.no")) == ffi.NULL
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_info_closed():
|
||||||
|
ctx = ffi.gc(
|
||||||
|
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
||||||
|
lib.dc_context_unref,
|
||||||
|
)
|
||||||
|
info = cutil.from_dc_charpointer(lib.dc_get_info(ctx))
|
||||||
|
assert 'deltachat_core_version' in info
|
||||||
|
assert 'database_dir' not in info
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_info_open(tmpdir):
|
||||||
|
ctx = ffi.gc(
|
||||||
|
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
||||||
|
lib.dc_context_unref,
|
||||||
|
)
|
||||||
|
db_fname = tmpdir.join("test.db")
|
||||||
|
lib.dc_open(ctx, db_fname.strpath.encode("ascii"), ffi.NULL)
|
||||||
|
info = cutil.from_dc_charpointer(lib.dc_get_info(ctx))
|
||||||
|
assert 'deltachat_core_version' in info
|
||||||
|
assert 'database_dir' in info
|
||||||
|
|||||||
@@ -66,6 +66,30 @@ pub struct RunningState {
|
|||||||
pub shall_stop_ongoing: bool,
|
pub shall_stop_ongoing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return some info about deltachat-core
|
||||||
|
///
|
||||||
|
/// This contains information mostly about the library itself, the
|
||||||
|
/// actual keys and their values which will be present are not
|
||||||
|
/// guaranteed. Calling [Context::get_info] also includes information
|
||||||
|
/// about the context on top of the information here.
|
||||||
|
pub fn get_info() -> HashMap<&'static str, String> {
|
||||||
|
let mut res = HashMap::new();
|
||||||
|
res.insert("deltachat_core_version", format!("v{}", &*DC_VERSION_STR));
|
||||||
|
res.insert("sqlite_version", rusqlite::version().to_string());
|
||||||
|
res.insert(
|
||||||
|
"sqlite_thread_safe",
|
||||||
|
unsafe { rusqlite::ffi::sqlite3_threadsafe() }.to_string(),
|
||||||
|
);
|
||||||
|
res.insert(
|
||||||
|
"arch",
|
||||||
|
(::std::mem::size_of::<*mut libc::c_void>())
|
||||||
|
.wrapping_mul(8)
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
res.insert("level", "awesome".into());
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn new(cb: Box<ContextCallback>, os_name: String, dbfile: PathBuf) -> Result<Context> {
|
pub fn new(cb: Box<ContextCallback>, os_name: String, dbfile: PathBuf) -> Result<Context> {
|
||||||
let mut blob_fname = OsString::new();
|
let mut blob_fname = OsString::new();
|
||||||
@@ -209,19 +233,7 @@ impl Context {
|
|||||||
.get_config(self, "configured_mvbox_folder")
|
.get_config(self, "configured_mvbox_folder")
|
||||||
.unwrap_or_else(|| "<unset>".to_string());
|
.unwrap_or_else(|| "<unset>".to_string());
|
||||||
|
|
||||||
let mut res = HashMap::new();
|
let mut res = get_info();
|
||||||
res.insert("deltachat_core_version", format!("v{}", &*DC_VERSION_STR));
|
|
||||||
res.insert("sqlite_version", rusqlite::version().to_string());
|
|
||||||
res.insert(
|
|
||||||
"sqlite_thread_safe",
|
|
||||||
unsafe { rusqlite::ffi::sqlite3_threadsafe() }.to_string(),
|
|
||||||
);
|
|
||||||
res.insert(
|
|
||||||
"arch",
|
|
||||||
(::std::mem::size_of::<*mut libc::c_void>())
|
|
||||||
.wrapping_mul(8)
|
|
||||||
.to_string(),
|
|
||||||
);
|
|
||||||
res.insert("number_of_chats", chats.to_string());
|
res.insert("number_of_chats", chats.to_string());
|
||||||
res.insert("number_of_chat_messages", real_msgs.to_string());
|
res.insert("number_of_chat_messages", real_msgs.to_string());
|
||||||
res.insert("messages_in_contact_requests", deaddrop_msgs.to_string());
|
res.insert("messages_in_contact_requests", deaddrop_msgs.to_string());
|
||||||
@@ -251,7 +263,6 @@ impl Context {
|
|||||||
pub_key_cnt.unwrap_or_default().to_string(),
|
pub_key_cnt.unwrap_or_default().to_string(),
|
||||||
);
|
);
|
||||||
res.insert("fingerprint", fingerprint_str);
|
res.insert("fingerprint", fingerprint_str);
|
||||||
res.insert("level", "awesome".into());
|
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@@ -504,6 +515,14 @@ mod tests {
|
|||||||
let t = dummy_context();
|
let t = dummy_context();
|
||||||
|
|
||||||
let info = t.ctx.get_info();
|
let info = t.ctx.get_info();
|
||||||
|
assert!(info.get("database_dir").is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_info_no_context() {
|
||||||
|
let info = get_info();
|
||||||
|
assert!(info.get("deltachat_core_version").is_some());
|
||||||
|
assert!(info.get("database_dir").is_none());
|
||||||
assert_eq!(info.get("level").unwrap(), "awesome");
|
assert_eq!(info.get("level").unwrap(), "awesome");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user